Role Creation
A role file (role.yaml) defines your agent — its model, system prompt, tools, guardrails, and everything else. The unified initrunner new command provides multiple seed modes and an interactive refinement loop for creating roles. The web dashboard offers a complementary GUI-based flow.
Quick Comparison
| Method | Command | Best for |
|---|---|---|
| AI Generate | initrunner new "..." | Fastest start — describe what you want in plain English |
| Template | initrunner new --template <name> | Non-interactive scaffolding from a known pattern |
| Blank | initrunner new --blank | Minimal starting point, add everything yourself |
| From Source | initrunner new --from <source> | Start from a local file, bundled example, or InitHub bundle |
| Interactive | initrunner new | No seed — LLM asks what to build in a conversation |
| Copy Example | initrunner examples copy <name> | Learning from complete, runnable examples |
| Dashboard | /roles/new in the web UI | Visual form builder or AI generation in the browser |
| Manual YAML | Create role.yaml by hand | Full control over every field |
Quick Start
# Generate from a description with interactive refinement
initrunner new "A code review assistant that reads git diffs"
# Start from a template, skip refinement
initrunner new --template rag --no-refine
# Blank template with a specific provider
initrunner new --blank --provider anthropic
# Load from a bundled example
initrunner new --from hello-world
# Load from an InitHub bundle (browse at hub.initrunner.ai)
initrunner new --from hub:owner/package
# Fully interactive (no seed -- LLM asks what to build)
initrunner newCLI Flags
| Flag | Description |
|---|---|
DESCRIPTION | Natural language description (generates via LLM) |
--from SOURCE | Local file path, bundled example name, or hub:ref |
--template TEXT | Start from a named template |
--blank | Start from minimal blank template |
--provider TEXT | Model provider (auto-detected if omitted) |
--model TEXT | Model name (uses provider default if omitted) |
--output PATH | Output file path (default: role.yaml) |
--force | Overwrite existing file without prompting |
--no-refine | Skip the interactive refinement loop |
Seed modes are mutually exclusive: specify at most one of DESCRIPTION, --from, --template, or --blank.
Seed Modes
Description (AI-Powered)
initrunner new "A knowledge assistant that searches company docs"Sends the description plus a dynamic schema reference to the configured LLM. The schema reference is built by introspecting Pydantic models (build_schema_reference()) and the live tool registry (build_tool_summary()), so it always stays in sync with the code.
If the generated YAML has validation errors, the builder automatically retries once by sending the errors back to the LLM.
Reasoning-Aware Generation
When your description implies autonomous or planning behavior (e.g., "plans tasks", "works autonomously", "spawns sub-agents", "self-critiques"), the wizard automatically generates spec.reasoning configuration with the appropriate strategy, spec.autonomy settings, and cognitive tools (type: think, type: todo, type: spawn). The schema reference includes the full reasoning primitives spec, so the LLM can produce valid reasoning configurations without manual editing.
initrunner new "An autonomous research agent that plans tasks, spawns sub-agents, and self-critiques"This generates a role with:
spec.reasoning: { pattern: todo_driven, auto_plan: true, reflection_rounds: 1 }type: think(with critique),type: todo, andtype: spawntoolsspec.autonomywith appropriate guardrails
See Reasoning Primitives for the full guide on reasoning strategies and cognitive tools.
Provider Auto-Detection
When --provider is omitted, InitRunner checks for available API keys in the environment (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) and uses the first provider found. Falls back to openai.
Example
initrunner new "A Python tutor that executes code examples and explains errors" \
--provider anthropic \
--output tutor-role.yaml \
--no-refineTemplate
initrunner new --template ragAvailable templates: basic, rag, daemon, memory, ollama, api, telegram, discord.
Blank
initrunner new --blankProduces a minimal valid role YAML with sensible defaults.
From Source
initrunner new --from ./existing-role.yaml # local file
initrunner new --from hello-world # bundled example
initrunner new --from hub:owner/package # hub bundleResolution order for --from SOURCE:
- Starts with
hub:— fetches from InitHub (role YAML only) - Exists as a filesystem path — loads the local file
- Otherwise — looks up as a bundled example name
For multi-file example/hub bundles, only the primary role YAML is loaded into the builder. Omitted sidecar files (skills, configs, etc.) are listed as a warning. Use initrunner examples copy <name> to get all files.
No Seed (Interactive)
initrunner newWhen no seed is specified, the LLM starts a conversation asking what kind of agent to build.
Refinement Loop
After the initial seed, the builder shows a syntax-highlighted YAML panel with the agent name and validation status:
+-- code-reviewer -------------------- VALID --+
| apiVersion: initrunner/v1 |
| kind: Agent |
| ... |
+-----------------------------------------------+
Refine (empty to save, "quit" to discard):
> add memory and change model to claude- Type a refinement request to iterate on the YAML
- Press Enter (empty input) or type
saveto write the file - Type
quitorqto discard without saving - Use
--no-refineto skip the loop entirely
The refinement LLM has the full schema reference and tool registry, so it can add tools, triggers, memory, and other features by name.
Post-Creation Output
After saving, the builder shows contextual next-step hints based on the role's features:
Created role.yaml
Next steps:
initrunner ingest role.yaml
initrunner run role.yaml -p 'hello'
initrunner validate role.yamlTemplates
Scaffold from a built-in template:
initrunner new --template basic
initrunner new --template rag --no-refineAvailable templates: basic, rag, daemon, memory, ollama, api, telegram, discord.
# RAG agent with document search
initrunner new --template rag
# Background daemon that runs on a schedule
initrunner new --template daemon
# Agent with long-term memory
initrunner new --template memoryScaffolding Tools and Skills
Tool and skill scaffolds use dedicated sub-commands instead of new:
# Scaffold a custom tool module
initrunner new --template tool
# Scaffold a skill directory
initrunner skill new my-skillCopy an Example
Browse and copy community examples:
initrunner examples list # browse available examples
initrunner examples show file-reader # preview the YAML
initrunner examples copy file-reader # copy files to current directoryOther notable examples:
- See
examples/policies/agent/in the repository for agent-as-principal delegation and tool policy examples. Docs: Agent Policy Engine.
See Examples for the full catalog.
Dashboard — Create Role
The web dashboard at /roles/new offers two tabs for role creation.
Form Builder Tab
A structured form with fields for:
- Name, description
- Provider, model (dropdown with curated per-provider options and custom input)
- System prompt
- Tool checkboxes
- Memory and ingestion toggles
- Live YAML preview that updates as you fill in the form
Submitting the form calls POST /api/roles with the generated YAML.
AI Generate Tab
- Enter a natural language description
- Click Generate to produce a
role.yamlvia AI - Review and edit the generated YAML
- Click Save to persist
This calls POST /api/roles/generate to get the YAML, then POST /api/roles to save.
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /api/roles | Create a new role from YAML content (RoleCreateRequest) |
POST | /api/roles/generate | Generate YAML from a description (RoleGenerateRequest) |
POST /api/roles returns 409 if a role file with the same name already exists.
Dashboard — Edit Existing Roles
The role detail page (/roles/{role_id}) includes an editable YAML tab with Save and Reset buttons.
- Save calls
PUT /api/roles/{role_id}with the updated YAML content - Creates a
.bakbackup of the existing file before overwriting - Validates the YAML against
RoleDefinitionbefore writing
| Method | Endpoint | Description |
|---|---|---|
PUT | /api/roles/{role_id} | Update an existing role's YAML (RoleYamlUpdateRequest) |
Manual YAML
For full control, create a role.yaml by hand. Every role file has four top-level keys: apiVersion, kind, metadata, and spec. See Configuration for the full schema reference.
Minimum Viable Role
The smallest valid role needs metadata, a system prompt, and a model:
apiVersion: initrunner/v1
kind: Agent
metadata:
name: my-agent
description: A helpful assistant
spec:
role: |
You are a helpful assistant.
model:
provider: openai
name: gpt-4o-miniAdding Tools
Add a tools list under spec:
spec:
tools:
- type: filesystem
root_path: .
read_only: true
- type: shell
require_confirmation: true
timeout_seconds: 30Adding Memory
Add a memory section so the agent remembers across sessions:
spec:
memory:
max_sessions: 10
max_resume_messages: 20
semantic:
max_memories: 500Run with --resume to pick up where you left off. See Memory for details.
Adding Ingestion / RAG
Add an ingest section to let the agent search your documents:
spec:
ingest:
sources:
- "./**/*.md"
chunking:
strategy: paragraph
chunk_size: 512
chunk_overlap: 50Run initrunner ingest role.yaml to index, then ask questions about your docs. See Ingestion for details.
Adding Triggers and Sinks
Triggers automate when the agent runs. Sinks control where output goes:
spec:
triggers:
- type: cron
schedule: "*/30 * * * *"
- type: watch
paths: ["./src/**/*.py"]
sinks:
- type: file
path: ./reports/output.md
- type: slack
channel: "#alerts"See Triggers and Sinks for all options.
Adding Guardrails
Set resource limits to keep the agent safe:
spec:
guardrails:
max_tokens_per_run: 10000
max_tool_calls: 10
timeout_seconds: 60
max_request_limit: 10See Guardrails for the full reference.
Programmatic Usage
The builder service layer (services/agent_builder.py) is UI-agnostic and can be used by CLI, API, and dashboard:
from initrunner.services.agent_builder import BuilderSession
from pathlib import Path
session = BuilderSession()
# Seed from description
turn = session.seed_description("a code review bot", "openai")
# Refine
turn = session.refine("add git and filesystem tools", "openai")
# Save
result = session.save(Path("role.yaml"))
print(result.next_steps)Legacy one-shot generation is still available via generate_role() and generate_role_sync(), which now delegate to BuilderSession internally.
Validation
Check your YAML before running:
initrunner validate role.yamlThis parses the file and validates it against the RoleDefinition schema. Errors are printed with field paths so you can fix them quickly.
Security Notes
- Name validation:
metadata.namemust match^[a-z0-9][a-z0-9-]*[a-z0-9]$ - Directory restrictions: API writes are restricted to configured role directories; path traversal (
..) is rejected - Overwrite protection: CLI prompts before overwriting;
POST /api/rolesreturns409if the file exists;save_role_yaml_sync()creates a.bakbackup before overwriting - Validation before write: YAML is parsed and validated against
RoleDefinitionbefore being written to disk
Next Steps
- Configuration — Full YAML schema reference
- Tools — All available tools and their configuration
- Examples — Complete, runnable agents for common use cases
- Quickstart — Get your first agent running in under five minutes