Each phase in the Robot pipeline is served by a dedicated Agent. You implement these Agents like any other Yao Agent — a `package.yao`, a system prompt, and optionally a Create/Next Hook. The one critical difference is the **`type` field** in `package.yao`.
## The `type` Field — How the UI Finds Your Agent
When you configure a Robot in Mission Control, each phase shows a dropdown to select its agent. That dropdown is populated by querying agents whose `type` matches the phase.
**Without the correct `type`, your agent will not appear in the dropdown and cannot be selected.**
| Phase | Required `type` value |
|-------|----------------------|
| P0 Inspiration | `robot-inspiration` |
| P1 Goals | `robot-goals` |
| P2 Tasks | `robot-tasks` |
| P4 Delivery | `robot-delivery` |
| P5 Learning | `robot-learning` |
| Validation | `robot-validation` |
| Host (cross-phase) | `robot-host` |
> P3 (Run) is the built-in task dispatcher — it has no dedicated phase agent and no `type` value.
A minimal `package.yao` for each phase looks like:
```json
{
"name": "My Inspiration Agent",
"type": "robot-inspiration",
"connector": "$ENV.DEFAULT_CONNECTOR",
"automated": true,
"mentionable": false
}
```
Change `type` to match the phase, keep everything else the same.
---
## Registering Phase Agents
After creating the agents with the correct `type`, tell the framework which agent to use for each phase. There are two levels:
**Global default** — applies to all robots, set in `agent.yml`:
```yaml
uses:
inspiration: myns/inspiration-agent
goals: myns/goals-agent
tasks: myns/tasks-agent
delivery: myns/delivery-agent
learning: myns/learning-agent
host: myns/host-agent
validation: myns/validation-agent
```
**Per-robot override** — overrides the global default for one specific robot, set in its `robot_config` (Mission Control → Advanced Settings):
```json
{
"resources": {
"phases": {
"delivery": "myns/slack-delivery-agent"
}
}
}
```
Priority: per-robot `resources.phases` → global `uses` → error (phase not configured).
---
## P0 — Inspiration (`robot-inspiration`)
**Trigger:** Clock only
**Input:** current time, timezone, robot identity and available resources
**Output:** a Markdown briefing (`InspirationReport`) passed to P1
The Inspiration Agent generates a daily or interval briefing based on what the robot has access to (KB, DB, agents, MCP tools) and the current time context. Human and Event triggers skip P0 entirely.
```json
{
"name": "My Inspiration Agent",
"type": "robot-inspiration",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "P0 — Analyses context and generates a daily briefing.",
"automated": true,
"mentionable": false,
"options": { "max_tokens": 4096 }
}
```
### Example System Prompt
```
You are an Inspiration Agent. Given the current date, time, and the robot's
available resources, produce a concise Markdown briefing:
1. Time context (day of week, notable dates)
2. Outstanding items from the knowledge base
3. Suggested focus areas for today's Goals Agent
Keep it under 300 words.
```
---
## P1 — Goals (`robot-goals`)
**Input:** P0 `InspirationReport` (clock) or trigger payload (human/event)
**Output:** a Markdown goals document with concrete, measurable objectives
```json
{
"name": "My Goals Agent",
"type": "robot-goals",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "P1 — Converts briefing or trigger input into prioritised goals.",
"automated": true,
"mentionable": false
}
```
### Example System Prompt
```
You are a Goals Agent. Given the daily briefing (or intervention request),
define 2–5 concrete, measurable goals for this execution.
Output in Markdown with a ## Goal N heading for each goal.
Each goal must be achievable using the listed available resources.
```
---
## P2 — Tasks (`robot-tasks`)
**Input:** Goals document from P1
**Output:** a structured list of `Task` objects
The Tasks Agent breaks each goal into ordered, executable tasks. Each task declares its executor so P3 knows exactly how to run it.
```json
{
"name": "My Tasks Agent",
"type": "robot-tasks",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "P2 — Decomposes goals into executable tasks.",
"automated": true,
"mentionable": false
}
```
### Task Executor Types
Each task must include `executor_type` and `executor_id`:
| `executor_type` | `executor_id` format | Description |
|-----------------|---------------------|-------------|
| `assistant` | agent path, e.g. `myns/report-agent` | Call a Yao Agent |
| `mcp` | `mcp_server.mcp_tool` | Call a specific MCP tool |
| `process` | Yao Process, e.g. `scripts.report.Generate` | Call a TypeScript function |
**Assistant task:**
```json
{
"executor_type": "assistant",
"executor_id": "myns/report-agent",
"messages": [{ "role": "user", "content": "Summarise last week's data." }],
"expected_output": "A Markdown report with key metrics"
}
```
**MCP task:**
```json
{
"executor_type": "mcp",
"mcp_server": "agents.myns.myagent.tools",
"mcp_tool": "search_records",
"messages": [{ "role": "user", "content": "Find all items tagged 'urgent'." }]
}
```
**Process task:**
```json
{
"executor_type": "process",
"executor_id": "scripts.report.Generate",
"args": ["weekly", "2025-01-01", "2025-01-07"]
}
```
---
## P3 — Run (no dedicated agent)
P3 is handled directly by the Robot executor — it is not a pluggable Agent phase. The executor reads the task list from P2 and dispatches each task to the correct executor:
```
executor_type == "assistant" → call the Agent via Assistant.Stream()
executor_type == "mcp" → invoke the MCP tool
executor_type == "process" → call the Yao Process
```
All results (successes and failures) are collected and passed to P4. By default the executor continues even when a task fails.
---
## P4 — Delivery (`robot-delivery`)
**Input:** full execution context (goals, tasks, all results)
**Output:** `DeliveryContent` (summary + Markdown body + optional attachments)
The Delivery Agent has access to every phase's output and produces the final report. After it completes, the framework pushes the result to the configured channels (Webhook, Yao Process). See [Triggers & Delivery](./triggers).
```json
{
"name": "My Delivery Agent",
"type": "robot-delivery",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "P4 — Formats execution results and triggers delivery channels.",
"automated": true,
"mentionable": false
}
```
### Example System Prompt
```
You are a Delivery Agent. Review the completed execution:
- Goals defined in P1
- Tasks planned in P2
- Results from P3 (including any failures)
Produce:
1. A one-paragraph summary (for notifications and Webhook payload)
2. A full Markdown report (for the body)
Be honest about failures. Suggest next steps where applicable.
```
---
## P5 — Learning (`robot-learning`)
> **Note:** The Learning phase is currently a placeholder in the standard executor — it records a simulated entry but does not yet call a dedicated Learning Agent or use the `learn` configuration below. The design is documented here for completeness; full implementation is planned for a future release.
**Input:** full execution context
**Output:** `LearningEntry` list saved to the robot's private KB
```json
{
"name": "My Learning Agent",
"type": "robot-learning",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "P5 — Extracts patterns and lessons from the execution.",
"automated": true,
"mentionable": false
}
```
Learning types:
| Type | Description |
|------|-------------|
| `execution` | Patterns observed across the full run |
| `feedback` | Error or fix patterns worth remembering |
| `insight` | Tips and optimisations for future executions |
Configure what the robot learns in `robot_config`:
```json
{
"learn": {
"on": true,
"types": ["execution", "feedback"],
"keep": 30
}
}
```
`keep` is in days; `0` means keep forever.
---
## Host Agent — Cross-Phase (`robot-host`)
The Host Agent is not a pipeline phase — it runs alongside the execution to handle real-time human interaction. When a task signals `NeedInput: true`, the Host Agent presents the question to the user and injects the response back.
```json
{
"name": "My Host Agent",
"type": "robot-host",
"connector": "$ENV.DEFAULT_CONNECTOR",
"description": "Mediates between the user and the Robot during execution.",
"automated": false,
"mentionable": false
}
```
Register it in `agent.yml` alongside the pipeline phases:
```yaml
uses:
host: myns/host-agent
```