- Updated the Task struct in DESIGN.md to replace the Input field with Messages, allowing for rich content input (text, images, files, audio). - Revised the TriggerRequest struct in TECHNICAL.md to utilize Messages instead of Input, enhancing the flexibility of user interactions. - Improved related code examples to demonstrate the new Messages structure, ensuring consistency and clarity in task management and execution processes.
40 KiB
Robot Agent
1. What is it?
A Robot Agent is an AI team member. It works on its own, makes decisions, and runs tasks without waiting for user input.
Key points:
- Belongs to a Team, managed like human members
- Has clear job duties (e.g., "Sales Manager: track KPIs, make reports")
- Created and deleted via Team API
- Runs on schedule, or when triggered by humans or events
- Learns from each run, stores knowledge in private KB
2. Architecture
2.1 System Flow
flowchart TB
subgraph Triggers["Triggers"]
WC[/"⏰ Clock"/]
HI[/"👤 Human"/]
EV[/"📡 Event"/]
end
subgraph Manager["Manager"]
TC{"Enabled?"}
Cache[("Cache")]
Dedup{"Dedup?"}
Queue["Queue"]
end
subgraph Pool["Workers"]
W1["Worker"]
W2["Worker"]
W3["Worker"]
end
subgraph Executor["Executor"]
TT{"Trigger?"}
P0["P0: Inspiration"]
P1["P1: Goals"]
P2["P2: Tasks"]
P3["P3: Run"]
P4["P4: Deliver"]
P5["P5: Learn"]
end
subgraph Storage["Storage"]
KB[("KB")]
DB[("DB")]
Job[("Job")]
end
WC --> TC
HI & EV --> TC
TC -->|Yes| Cache
TC -->|No| X[/Skip/]
Cache --> Dedup
Dedup -->|OK| Queue
Dedup -->|Dup| Cache
Queue --> W1 & W2 & W3
W1 & W2 & W3 --> TT
TT -->|Clock| P0
TT -->|Human/Event| P1
P0 --> P1 --> P2 --> P3 --> P4 --> P5
P5 --> KB & DB & Job
KB -.->|History| P0
2.2 Team Structure
Uses existing __yao.member model (yao/models/member.mod.yao):
┌─────────────────────────────────────────────────────────────────┐
│ Team │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Robot Members │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │Sales Manager│ │Data Analyst │ │CS Specialist│ │ │
│ │ │ • Track KPIs│ │ • Analyze │ │ • Tickets │ │ │
│ │ │ • Reports │ │ • Reports │ │ • Inquiries │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ User Members │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ John (Owner)│ │ Jane (Admin)│ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Key fields in __yao.member for robot agents:
| Field | Type | Description |
|---|---|---|
member_type |
enum | user | robot |
autonomous_mode |
bool | Enable robot execution |
robot_config |
JSON | Agent configuration (see section 5) |
robot_status |
enum | idle | working | paused | error | maintenance |
system_prompt |
text | Identity & role prompt |
agents |
JSON | Accessible agents list |
mcp_servers |
JSON | Accessible MCP servers |
manager_id |
string | Direct manager user ID |
3. How It Works
3.1 Flow: Trigger → Schedule → Run
sequenceDiagram
autonumber
participant T as Trigger
participant M as Manager
participant S as Scheduler
participant W as Worker
participant E as Executor
participant A as Phase Agents
participant KB as KB
T->>M: Event
M->>M: Check enabled
M->>M: Get from cache
M->>M: Check dedup
M->>S: Submit
S->>S: Check quota
S->>S: Sort by priority
S->>W: Dispatch
W->>E: Run
alt Clock trigger
E->>A: P0: Inspiration (with clock context)
A-->>E: Report
end
loop P1 to P5
E->>A: Call agent
A-->>E: Result
end
E->>KB: Save learning
E-->>W: Done
3.2 Triggers
| Type | What | Config |
|---|---|---|
| Clock | Timer (times/interval/daemon) | triggers.clock |
| Human | Manual action | triggers.intervene |
| Event | Webhook, DB change | triggers.event |
All on by default. Turn off per agent:
triggers:
clock: { enabled: true }
intervene: { enabled: true, actions: ["add_task", "pause"] }
event: { enabled: false }
3.3 Concurrency
Two levels to prevent one agent from using all resources:
┌─────────────────────────────────────────────────────────────────┐
│ Global Pool (10 workers) │
└─────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Sales Manager │ │ Data Analyst │ │ CS Specialist │
│ Limit: 3 │ │ Limit: 2 │ │ Limit: 3 │
│ Now: 2 ✓ │ │ Now: 2 (full) │ │ Now: 1 ✓ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
3.4 Dedup
Fast check (in memory):
key := memberID + ":" + triggerType + ":" + window
if has(key) { skip }
Smart check (for goals/tasks):
- Dedup Agent looks at history
- Returns:
skip|merge|proceed
3.5 Cache
Keeps agents in memory. No DB query on each tick:
type AgentCache struct {
agents map[string]*Agent // member_id -> agent
byTeam map[string][]string // team_id -> member_ids
}
// Refresh: on start, on change, every hour
4. Phases
4.1 Overview
Clock: P0 → P1 → P2 → P3 → P4 → P5
Human/Event: P1 → P2 → P3 → P4 → P5
| Phase | Agent | In | Out | When |
|---|---|---|---|---|
| P0 | Inspiration | Clock + Data + News | Report | Clock only |
| P1 | Goal Gen | Report + history | Goals | Always |
| P2 | Task Plan | Goals + tools | Tasks | Always |
| P3 | Validator | Results | Checked results | Always |
| P4 | Delivery | All results | Email/File | Always |
| P5 | Learning | Summary | KB entries | Always |
4.2 P0: Inspiration (Clock only)
Skipped for Human/Event triggers. They already have clear intent.
Gathers info to help make good goals. Clock context is key input - Agent knows what time it is and can decide what to do (e.g., 5pm Friday → write weekly report).
type InspirationReport struct {
Clock *ClockContext `json:"clock"` // time context
Content string `json:"content"` // markdown text for LLM
}
// Content is markdown like:
// ## Summary
// ...
// ## Highlights
// - [High] Sales up 50%
// ## Opportunities / Risks / World News / Pending
// ...
type ClockContext struct {
Now time.Time // Current time
Hour int // 0-23
DayOfWeek string // Monday, Tuesday...
DayOfMonth int // 1-31
IsWeekend bool
IsMonthStart bool // 1st-3rd
IsMonthEnd bool // last 3 days
IsQuarterEnd bool
// Agent uses this to decide: "It's 5pm Friday, time for weekly report"
}
Sources:
- Clock: Current time, day of week, month end, etc.
- Internal: Data changes, events, feedback, pending work
- External: Web search (news, competitors)
4.3 P1: Goals
For Clock: Uses inspiration report (with clock context) to make goals. Agent decides based on time what's important now.
For Human/Event: Uses the input directly as goals (or to generate goals).
Prompt:
You are [Sales Manager]. Your job: [track KPIs, make reports].
## Report
### Key Items
- [High] Data: 15 new sales (+50%)
- [High] Deadline: Friday report due
- [High] News: Competitor launched product
### Chances
- Sales up 20% vs last week
- Market growing
Make today's goals.
4.4 P2: Tasks
P2 Agent reads Goals markdown and breaks into executable tasks:
type Task struct {
ID string // unique task ID
Messages []context.Message // original input (text, images, files, audio)
GoalRef string // reference to goal (e.g., "Goal 1")
Source TaskSource // auto | human | event
ExecutorType ExecutorType // assistant | mcp | process
ExecutorID string // agent ID or mcp tool name
Args []any // arguments for executor
Order int // execution order
}
4.5 P3: Run
For each task:
- Call Assistant or MCP Tool
- Get result
- Validate
- Update status
4.6 P4: Deliver
Send output:
delivery:
type: email # email | file | webhook | notify
opts:
to: ["manager@company.com"]
4.7 P5: Learn
Save to KB:
| Type | Examples |
|---|---|
execution |
What worked, what failed |
feedback |
Errors, fixes |
insight |
Patterns, tips |
5. Config
5.1 Structure
type Config struct {
Triggers *Triggers `json:"triggers,omitempty"`
Clock *Clock `json:"clock,omitempty"`
Identity *Identity `json:"identity"`
Quota *Quota `json:"quota"`
KB *KB `json:"kb,omitempty"` // shared KB (same as assistant)
DB *DB `json:"db,omitempty"` // shared DB (same as assistant)
Learn *Learn `json:"learn,omitempty"` // learning for private KB
Resources *Resources `json:"resources"`
Delivery *Delivery `json:"delivery"`
Events []Event `json:"events,omitempty"`
}
5.2 Types
// Phase - execution phase enum
type Phase string
const (
PhaseInspiration Phase = "inspiration" // P0: Clock only
PhaseGoals Phase = "goals" // P1
PhaseTasks Phase = "tasks" // P2
PhaseValidation Phase = "validation" // P3
PhaseDelivery Phase = "delivery" // P4
PhaseLearning Phase = "learning" // P5
)
// AllPhases for iteration
var AllPhases = []Phase{
PhaseInspiration, PhaseGoals, PhaseTasks,
PhaseValidation, PhaseDelivery, PhaseLearning,
}
// ClockMode - clock trigger mode enum
type ClockMode string
const (
ClockModeTimes ClockMode = "times" // run at specific times
ClockModeInterval ClockMode = "interval" // run every X duration
ClockModeDaemon ClockMode = "daemon" // run continuously
)
// DeliveryType - output delivery type enum
type DeliveryType string
const (
DeliveryEmail DeliveryType = "email"
DeliveryFile DeliveryType = "file"
DeliveryWebhook DeliveryType = "webhook"
DeliveryNotify DeliveryType = "notify"
)
// ExecStatus - execution status enum
type ExecStatus string
const (
ExecPending ExecStatus = "pending"
ExecRunning ExecStatus = "running"
ExecCompleted ExecStatus = "completed"
ExecFailed ExecStatus = "failed"
)
// RobotStatus - matches __yao.member.robot_status enum
type RobotStatus string
const (
RobotIdle RobotStatus = "idle" // ready to run
RobotWorking RobotStatus = "working" // currently executing
RobotPaused RobotStatus = "paused" // manually paused
RobotError RobotStatus = "error" // encountered error
RobotMaintenance RobotStatus = "maintenance" // under maintenance
)
// Triggers - all on by default
type Triggers struct {
Clock *Trigger `json:"clock,omitempty"`
Intervene *Trigger `json:"intervene,omitempty"`
Event *Trigger `json:"event,omitempty"`
}
type Trigger struct {
Enabled bool `json:"enabled"`
Actions []string `json:"actions,omitempty"` // for intervene
}
// Clock - when to wake up
type Clock struct {
Mode ClockMode `json:"mode"`
Times []string `json:"times"` // for times: ["09:00", "14:00"]
Days []string `json:"days"` // ["Mon", "Tue"...] or ["*"]
Every string `json:"every"` // for interval: "30m", "1h"
TZ string `json:"tz"` // Asia/Shanghai
Timeout string `json:"timeout"` // max run time
}
// Identity
type Identity struct {
Role string `json:"role"`
Duties []string `json:"duties"`
Rules []string `json:"rules"`
}
// Quota
type Quota struct {
Max int `json:"max"` // max running (default: 2)
Queue int `json:"queue"` // queue size (default: 10)
Priority int `json:"priority"` // 1-10 (default: 5)
}
// KB
// KB - shared knowledge base (same as assistant)
type KB struct {
Collections []string `json:"collections,omitempty"` // KB collection IDs
Options map[string]interface{} `json:"options,omitempty"`
}
// DB - shared database (same as assistant)
type DB struct {
Models []string `json:"models,omitempty"` // database model names
Options map[string]interface{} `json:"options,omitempty"`
}
// Learn - learning config for robot's private KB
// Private KB auto-created: robot_{team_id}_{member_id}_kb
type Learn struct {
On bool `json:"on"`
Types []string `json:"types"` // execution, feedback, insight
Keep int `json:"keep"` // days, 0 = forever
}
// Resources
type Resources struct {
Phases map[Phase]string `json:"phases,omitempty"` // optional, defaults to __yao.{phase}
Agents []string `json:"agents"`
MCP []MCP `json:"mcp"`
}
type MCP struct {
ID string `json:"id"`
Tools []string `json:"tools,omitempty"` // empty = all
}
// Delivery
type Delivery struct {
Type DeliveryType `json:"type"`
Opts map[string]interface{} `json:"opts"`
}
// Monitor
5.3 Example
Example record in __yao.member table:
{
"member_id": "mem_abc123",
"team_id": "team_xyz",
"member_type": "robot",
"display_name": "Sales Bot",
"autonomous_mode": true,
"robot_status": "idle",
"system_prompt": "You are a sales analyst...",
"robot_config": {
"triggers": {
"clock": { "enabled": true },
"intervene": { "enabled": true },
"event": { "enabled": false }
},
"clock": {
"mode": "times",
"times": ["09:00", "14:00", "17:00"],
"days": ["Mon", "Tue", "Wed", "Thu", "Fri"],
"tz": "Asia/Shanghai",
"timeout": "30m"
},
"identity": {
"role": "Sales Analyst",
"duties": ["Analyze sales", "Make weekly reports"],
"rules": ["Only access sales data"]
},
"quota": { "max": 2, "queue": 10, "priority": 5 },
"kb": { "collections": ["sales-policies", "products"] },
"db": { "models": ["sales", "customers"] },
"learn": {
"on": true,
"types": ["execution", "feedback", "insight"],
"keep": 90
},
"resources": {
"phases": {
"inspiration": "__yao.inspiration",
"goals": "__yao.goals",
"tasks": "__yao.tasks",
"validation": "__yao.validation",
"delivery": "__yao.delivery",
"learning": "__yao.learning"
},
"agents": ["data-analyst", "chart-gen"],
"mcp": [{ "id": "database", "tools": ["query"] }]
},
"delivery": {
"type": "email",
"opts": { "to": ["manager@company.com"] }
}
},
"agents": ["data-analyst", "chart-gen"],
"mcp_servers": ["database"]
}
6. Lifecycle
6.1 Agent States
stateDiagram-v2
[*] --> Idle: POST create
Idle --> Working: trigger
Working --> Idle: done
Idle --> Paused: PATCH pause
Working --> Paused: PATCH pause
Paused --> Idle: PATCH resume
Idle --> Error: error
Working --> Error: error
Error --> Idle: PATCH reset
Idle --> [*]: DELETE
Paused --> [*]: DELETE
| From | To | How |
|---|---|---|
| - | idle | POST create |
| idle | working | trigger (clock/human/event) |
| working | idle | execution done |
| idle | paused | PATCH robot_status="paused" |
| paused | idle | PATCH robot_status="idle" |
| any | error | execution error |
| error | idle | PATCH robot_status="idle" |
| any | deleted | DELETE |
6.2 On Create
- Check config
- Generate member_id if missing
- Create KB:
robot_{team_id}_{member_id}_kb - Add to cache
- Create Job
- Set active
6.3 On Delete
- Stop running jobs
- Remove from cache
- Delete Job
- Delete or archive KB
- Soft delete record
6.4 Execution Flow
Single execution flow, depends on trigger type:
flowchart LR
subgraph Trigger
T{Trigger}
end
subgraph Schedule Path
P0[P0: Inspiration]
end
subgraph Common Path
P1[P1: Goals]
P2[P2: Tasks]
P3[P3: Run]
P4[P4: Deliver]
P5[P5: Learn]
end
T -->|Clock| P0
T -->|Human/Event| P1
P0 --> P1
P1 --> P2 --> P3 --> P4 --> P5
stateDiagram-v2
[*] --> Triggered
Triggered --> P0_Inspiration: Clock
Triggered --> P1_Goals: Human/Event
P0_Inspiration --> P1_Goals
P1_Goals --> P2_Tasks
P2_Tasks --> P3_Run
P3_Run --> P4_Deliver
P4_Deliver --> P5_Learn
P5_Learn --> [*]
7. Integrations
7.1 Job System
Relationship: 1 Robot : N Executions (concurrent), 1 Execution = 1 job.Job
Each trigger creates a new Execution, mapped to a job.Job for monitoring.
┌─────────────────────────────────────────────────────────────────┐
│ Activity Monitor (UI) │
│ • List jobs │
│ • See progress │
│ • View logs │
│ • Cancel/retry │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Job Framework │
│ Job → Execution → Progress → Logs │
└─────────────────────────────────────────────────────────────────┘
Go APIs (yao/job package):
| Action | API |
|---|---|
| List Jobs | job.ListJobs(param, page, pagesize) |
| Get Job | job.GetJob(jobID, param) |
| Save Job | job.SaveJob(j) |
| List Execs | job.ListExecutions(param, page, pagesize) |
| Get Exec | job.GetExecution(execID, param) |
| Save Exec | job.SaveExecution(exec) |
| List Logs | job.ListLogs(param, page, pagesize) |
| Save Log | job.SaveLog(log) |
| Push (start) | j.Push() |
| Stop | j.Stop() |
| Destroy | j.Destroy() |
| Active Jobs | job.GetActiveJobs() |
| Query by Cat | job.ListJobs({Wheres: [{Column: "category_id", ...}]}) |
7.2 Private KB
Made on robot member create: robot_{team_id}_{member_id}_kb
What it stores:
execution: What worked, what failedfeedback: Errors, fixesinsight: Patterns, tips
When:
- Create: On robot member create
- Update: After P5
- Clean: Based on
keepdays - Delete: On robot member delete
7.3 External Input
Types:
clock: Timer (with time context)intervene: Human actionevent: Webhook, DB changecallback: Async result
Human actions:
adjust_goal: Change goaladd_task: Add taskcancel_task: Stop taskpause/resume/abortplan: Do later
Plan Queue:
- Holds tasks for later
- Runs at next cycle start
8. API
8.1 Manager (Internal)
type Manager interface {
// Lifecycle
Start() error
Stop() error
// Cache
LoadActiveRobots(ctx context.Context) error
GetRobot(teamID, memberID string) *Robot
// Clock trigger (internal, called by ticker)
Tick(ctx context.Context, now time.Time) error
}
8.2 Trigger (Called by openapi layer)
// TriggerType enum
type TriggerType string
const (
TriggerClock TriggerType = "clock"
TriggerHuman TriggerType = "human"
TriggerEvent TriggerType = "event"
)
// Trigger interface - called by openapi handlers
type Trigger interface {
// Human intervention
Intervene(ctx context.Context, req InterveneRequest) (*ExecutionResult, error)
// Event trigger (webhook, db change)
HandleEvent(ctx context.Context, req EventRequest) (*ExecutionResult, error)
// Query & control
GetStatus(ctx context.Context, teamID, memberID string) (*RobotState, error)
Pause(ctx context.Context, teamID, memberID string) error
Resume(ctx context.Context, teamID, memberID string) error
}
type InterveneRequest struct {
TeamID string
MemberID string
Action string // add_task | adjust_goal | cancel_task | pause | resume | abort | plan
Description string
Priority string // high | normal | low
PlanTime time.Time // for action=plan
}
type EventRequest struct {
MemberID string
Source string // webhook path or table name
EventType string // lead.created, etc.
Data map[string]interface{}
}
type ExecutionResult struct {
ExecutionID string // Job execution ID
Status ExecStatus // pending | running | completed | failed
}
type RobotState struct {
MemberID string // member_id from __yao.member
Status RobotStatus // idle | working | paused | error | maintenance
LastRun time.Time
NextRun time.Time
Running int // current running execution count
MaxRunning int // max concurrent executions (from Quota.Max)
RunningIDs []string // list of running execution IDs
}
8.3 Execution (Uses Job System)
No separate autonomous_executions table. Uses existing Job system.
Each trigger creates a new job.Job:
// On each trigger (clock/human/event), create a new Job
execID := gonanoid.Must()
j, _ := job.Once(job.GOROUTINE, map[string]interface{}{
"job_id": "robot_exec_" + execID, // unique per execution
"category_id": "autonomous_robot",
"name": fmt.Sprintf("%s - %s", member.DisplayName, triggerType),
"metadata": map[string]interface{}{
"member_id": memberID,
"team_id": teamID,
"trigger_type": triggerType,
"exec_id": execID,
},
})
job.SaveJob(j)
// Configure and start
j.ExecutionConfig = &job.ExecutionConfig{
Type: job.ExecutionTypeProcess,
ProcessName: "robot.Execute",
ProcessArgs: []interface{}{memberID, execID, triggerData},
}
j.Push()
Query executions for a robot:
// List all executions for a robot member
param := model.QueryParam{
Wheres: []model.QueryWhere{
{Column: "category_id", Value: "autonomous_robot"},
{Column: "metadata->member_id", Value: memberID},
},
Orders: []model.QueryOrder{{Column: "created_at", Option: "desc"}},
}
jobs, _ := job.ListJobs(param, 1, 10)
Query examples:
// List all robot jobs (all robots, all executions)
param := model.QueryParam{
Wheres: []model.QueryWhere{
{Column: "category_id", Value: "autonomous_robot"},
},
}
jobs, _ := job.ListJobs(param, 1, 20)
// Get executions for a robot
execParam := model.QueryParam{
Wheres: []model.QueryWhere{
{Column: "job_id", Value: "robot_" + memberID},
},
Orders: []model.QueryOrder{{Column: "created_at", Option: "desc"}},
}
execs, _ := job.ListExecutions(execParam, 1, 10)
// Get logs for an execution
logParam := model.QueryParam{
Wheres: []model.QueryWhere{
{Column: "execution_id", Value: execID},
},
}
logs, _ := job.ListLogs(logParam, 1, 100)
9. Security
- Team only: Agent sees only its team's data
- Role rules: Uses role_id permissions
- Limited tools: Only what's in
resources - Timeout: Stops if runs too long
- Logs: All runs saved
10. Quick Ref
Triggers
triggers:
clock: { enabled: true }
intervene: { enabled: true, actions: [...] }
event: { enabled: false }
Clock
# Mode 1: Specific times
clock:
mode: times
times: ["09:00", "14:00", "17:00"]
days: ["Mon", "Tue", "Wed", "Thu", "Fri"]
tz: Asia/Shanghai
timeout: 30m
# Mode 2: Interval
clock:
mode: interval
every: 30m # run every 30 minutes
timeout: 10m
# Mode 3: Daemon (continuous thinking/analysis)
clock:
mode: daemon # restart immediately after each run
timeout: 10m # max time per run
# Use case: Research analyst, market monitor
Phase Agents
# Optional - defaults to __yao.{phase} if not specified
resources:
phases:
inspiration: "__yao.inspiration" # Clock only
goals: "__yao.goals"
tasks: "__yao.tasks"
validation: "__yao.validation"
delivery: "__yao.delivery"
learning: "__yao.learning"
Quota
quota:
max: 2 # max running
queue: 10 # queue size
priority: 5 # 1-10
11. Examples
Each example shows a different trigger mode:
| Example | Trigger | Mode | Scenario |
|---|---|---|---|
| 11.1 | Clock | times | SEO/GEO Content - daily content optimization |
| 11.2 | Clock | interval | Competitor Monitor - check every 2 hours |
| 11.3 | Clock | daemon | Research Analyst - continuous insight mining |
| 11.4 | Human | intervene | Sales Assistant - manager assigns tasks |
| 11.5 | Event | webhook | Lead Processor - qualify and route new leads |
11.1 SEO/GEO Content Agent (Clock: times)
Trigger: Clock - specific times daily
Role: AI Marketing - auto-generate and optimize SEO/GEO content.
// robot_config for SEO Content Agent
{
"triggers": {
"clock": { "enabled": true },
"intervene": { "enabled": true }
},
"clock": {
"mode": "times",
"times": ["06:00", "18:00"],
"days": ["Mon", "Tue", "Wed", "Thu", "Fri"],
"tz": "Asia/Shanghai"
},
"identity": {
"role": "SEO/GEO Content Specialist",
"duties": [
"Research trending keywords in our industry",
"Generate SEO-optimized articles (2-3 per day)",
"Optimize existing content for GEO (AI search)",
"Track keyword rankings and adjust strategy",
"A/B test titles and meta descriptions"
]
},
"resources": {
"agents": ["keyword-researcher", "content-writer", "seo-optimizer"],
"mcp": [
{ "id": "google-search", "tools": ["trends", "rankings"] },
{ "id": "cms", "tools": ["create", "update", "publish"] }
]
},
"delivery": {
"type": "notify",
"opts": { "channel": "marketing-team" }
}
}
Example run at 06:00 Monday:
P0 Inspiration:
Clock: Monday 06:00, start of week
Data:
- Keyword "AI app development" trending (+45% this week)
- Our article ranks #8, competitor #2
- 3 articles need GEO optimization
World: New AI regulation announced last Friday
P1 Goals:
1. Write new article targeting "AI app development"
2. Optimize 3 old articles for GEO
3. Update meta descriptions for top 5 pages
P2 Tasks:
1. Research "AI app development" keywords → keyword-researcher
2. Write article with SEO structure → content-writer
3. Add FAQ schema for GEO → seo-optimizer
4. Publish to CMS → cms.publish
P3 Execute:
- Keywords: "AI app development", "build AI apps", "AI dev guide" (12 total)
- Article: 2500 words, 8 sections, FAQ schema added
- Published to CMS, indexed by Google
P4 Delivery:
→ Notify: "Published: 'Complete Guide to AI App Development' - targeting 12 keywords"
P5 Learn:
- "AI app development" articles perform well on Monday morning
- FAQ schema improves GEO visibility by 30%
11.2 Competitor Monitor (Clock: interval)
Trigger: Clock - every 2 hours
Role: Monitor competitors, track market changes, alert on important updates.
// robot_config for Competitor Monitor
{
"triggers": {
"clock": { "enabled": true }
},
"clock": {
"mode": "interval",
"every": "2h"
},
"identity": {
"role": "Competitor Intelligence Analyst",
"duties": [
"Monitor competitor websites for changes",
"Track competitor pricing updates",
"Watch for new product launches",
"Analyze competitor content strategy",
"Alert team on significant changes"
]
},
"resources": {
"agents": ["web-scraper", "diff-analyzer", "report-writer"],
"mcp": [{ "id": "web-search", "tools": ["search", "news"] }]
},
"delivery": {
"type": "webhook",
"opts": { "url": "https://slack.com/webhook/competitor-alerts" }
}
}
Example run detecting competitor change:
P0 Inspiration:
Clock: Tuesday 14:00
Data:
- Competitor A: pricing page changed
- Competitor B: new blog post about "AI agents"
- Competitor C: no changes
P1 Goals:
1. Analyze Competitor A pricing change
2. Summarize Competitor B's new content
3. Assess impact on our positioning
P2 Tasks:
1. Scrape old vs new pricing → web-scraper
2. Compare pricing tiers → diff-analyzer
3. Generate competitive analysis → report-writer
P3 Execute:
- Competitor A: dropped price 20% on enterprise tier
- Competitor B: targeting same keywords as us
P4 Delivery:
→ Slack: "🚨 Competitor A cut enterprise price 20% - review needed"
P5 Learn:
- Competitor A tends to change pricing on Tuesdays
- Price changes often precede feature launches
11.3 Industry Research Analyst (Clock: daemon)
Trigger: Clock - continuous daemon mode
Role: Continuously read industry news, papers, social media; extract insights; build knowledge.
// robot_config for Research Analyst
{
"triggers": {
"clock": { "enabled": true }
},
"clock": {
"mode": "daemon",
"timeout": "10m"
},
"identity": {
"role": "Industry Research Analyst",
"duties": [
"Continuously scan industry news and papers",
"Analyze trends and extract key insights",
"Identify emerging technologies and competitors",
"Build and maintain industry knowledge base",
"Alert team on significant developments"
]
},
"resources": {
"agents": ["content-reader", "insight-extractor", "report-writer"],
"mcp": [
{ "id": "web-search", "tools": ["search", "news"] },
{ "id": "arxiv", "tools": ["search", "fetch"] },
{ "id": "twitter", "tools": ["search", "trends"] }
]
},
"delivery": {
"type": "notify",
"opts": { "channel": "research-insights" }
}
}
Example continuous run:
Run #1 (09:00):
P0: Scan sources
- 15 new AI news articles
- 3 new papers on arXiv
- Twitter: "AI Agent" trending
P1: Goals:
1. Read and analyze new content
2. Extract insights relevant to our business
3. Update knowledge base
P2: Tasks:
1. Read articles → content-reader
2. Analyze papers → content-reader
3. Extract insights → insight-extractor
P3: Execute:
- Article: "OpenAI releases new agent framework"
Insight: Validates our direction, watch for API changes
- Paper: "Multi-agent collaboration patterns"
Insight: Useful for our agent design, save to KB
- Twitter: Sentiment positive on AI agents
P4: Notify: "📚 3 new insights added to KB"
P5: Learn: OpenAI news = high relevance, prioritize
→ Restart immediately
Run #2 (09:12):
P0: Scan sources
- 2 new articles (low relevance)
- No new papers
- Twitter: Normal activity
P1: Low-value content, skip deep analysis
P5: Learn: Mid-morning usually quiet
→ Restart immediately
Run #3 (09:25):
P0: Scan sources
- Breaking: "Competitor X raises $100M for AI platform"
P1: Goals:
1. Deep analyze competitor news
2. Assess impact on our market
3. Alert team immediately
P2: Tasks:
1. Gather all competitor X info → web-search
2. Analyze their positioning → insight-extractor
3. Write competitive brief → report-writer
P3: Execute:
- Competitor X: Focus on enterprise, similar target market
- Funding: Will likely expand sales team
- Threat level: Medium-High
P4: Notify: "🚨 Competitor X raised $100M - brief attached"
P5: Learn: Funding news = always high priority
→ Restart immediately
11.4 Sales Assistant (Human: intervene)
Trigger: Human intervention - sales manager assigns tasks
Role: Help sales team with research, proposals, follow-ups when manager assigns work.
// robot_config for Sales Assistant
{
"triggers": {
"clock": { "enabled": false },
"intervene": {
"enabled": true,
"actions": ["add_task", "adjust_goal", "pause"]
}
},
"identity": {
"role": "Sales Assistant",
"duties": [
"Research assigned prospects and companies",
"Prepare customized proposals and presentations",
"Draft follow-up emails",
"Analyze deal history and suggest strategies",
"Prepare meeting briefs"
]
},
"resources": {
"agents": ["company-researcher", "proposal-writer", "email-drafter"],
"mcp": [
{ "id": "crm", "tools": ["query", "update"] },
{ "id": "linkedin", "tools": ["search", "profile"] },
{ "id": "email", "tools": ["draft", "send"] }
]
},
"delivery": {
"type": "email",
"opts": { "to": ["sales-manager@company.com"] }
}
}
Example: Sales manager assigns task:
Sales Manager Input:
Action: add_task
Description: "Meeting with BigCorp CTO tomorrow. Prepare materials.
They do smart manufacturing, $150M revenue, digital transformation."
Agent Execution (no P0 for human trigger):
P1 Goals (from human input):
1. Research BigCorp and their CTO
2. Prepare meeting brief
3. Draft customized proposal
P2 Tasks:
1. Research BigCorp → company-researcher
- Company background, recent news
- Digital transformation status
- Potential pain points
2. Research CTO profile → linkedin.profile
- Background, interests
- Recent posts/articles
3. Prepare meeting brief → proposal-writer
4. Draft proposal → proposal-writer
P3 Execute:
- BigCorp: Leading smart manufacturing, 3 factories, implementing MES
- CTO John: Ex-Google, focused on AI+Manufacturing, recent post on "AI QC"
- Pain point: High QC labor cost, 2% defect miss rate
- Opportunity: Our AI QC solution can reduce miss rate to 0.1%
P4 Delivery:
→ Email to sales manager:
- Attachment 1: BigCorp Research Report (PDF)
- Attachment 2: CTO Profile Brief
- Attachment 3: Custom Proposal - AI QC Solution
- Attachment 4: Meeting Agenda Suggestion
Sales Manager Follow-up:
Action: add_task
Description: "Also prepare some similar case studies, manufacturing preferred"
Agent Continues:
P1: Find similar manufacturing case studies
P2: Search CRM for manufacturing wins
P3: Found 3 cases: Auto parts factory, Electronics plant, Food processing
P4: Email: "3 manufacturing case studies attached"
P5: Learn: Manufacturing prospects often need QC case studies
11.5 Lead Processor (Event: webhook)
Trigger: Event - new lead from website/CRM
Role: Instantly process and qualify new leads, route to sales.
// robot_config for Lead Processor
{
"triggers": {
"clock": { "enabled": false },
"event": { "enabled": true }
},
"events": [
{
"type": "webhook",
"source": "/webhook/leads",
"filter": { "event_types": ["lead.created"] }
},
{
"type": "database",
"source": "crm_leads",
"filter": { "trigger": "insert" }
}
],
"identity": {
"role": "Lead Qualification Specialist",
"duties": [
"Instantly process new leads",
"Enrich lead data (company info, LinkedIn)",
"Score lead quality (1-100)",
"Route hot leads to sales immediately",
"Add cold leads to nurture sequence"
]
},
"resources": {
"agents": ["data-enricher", "lead-scorer"],
"mcp": [
{ "id": "clearbit", "tools": ["enrich"] },
{ "id": "crm", "tools": ["update", "assign"] },
{ "id": "email", "tools": ["send"] }
]
},
"delivery": {
"type": "webhook",
"opts": { "url": "https://slack.com/webhook/sales-leads" }
}
}
Example: New lead event:
Event Received:
Type: lead.created
Data: {
name: "John Smith",
email: "john@bigcorp.com",
company: "BigCorp",
message: "Interested in Enterprise pricing, team of 50"
}
Agent Execution (no P0 for events):
P1 Goals:
1. Enrich lead data
2. Score lead quality
3. Route appropriately
P2 Tasks:
1. Lookup company info → clearbit.enrich
2. Calculate lead score → lead-scorer
3. Update CRM → crm.update
4. Notify sales → slack webhook
P3 Execute:
- Company: BigCorp, 500 employees, Series C
- LinkedIn: VP of Engineering
- Lead Score: 85/100 (HOT)
- Reason: Enterprise inquiry, decision maker, funded company
P4 Delivery:
→ Slack: "🔥 HOT LEAD (85/100): John Smith @ BigCorp
- 500 employees, Series C
- Interested in Enterprise (50 seats)
- Assigned to: Sales Rep A"
→ CRM: Lead updated, assigned to Sales Rep A
→ Email to lead: "Thanks for your inquiry. Our sales rep will contact you within 1 hour."
P5 Learn:
- BigCorp profile saved for future reference
- VP-level leads from funded companies = high conversion