diff --git a/agent/autonomous/DESIGN.md b/agent/autonomous/DESIGN.md index 3d32f01f..f722ad4e 100644 --- a/agent/autonomous/DESIGN.md +++ b/agent/autonomous/DESIGN.md @@ -1,2264 +1,1403 @@ -# Autonomous Agent Design Document +# Autonomous Agent -## Overview +## 1. What is it? -An Autonomous Agent is an **AI member** within a team, belonging to a Team just like human members. From the user's perspective, it's simply a team member with clearly defined job responsibilities (such as Sales Manager, Data Analyst, Customer Service Representative, etc.). It can operate independently, make autonomous decisions, and execute tasks. Unlike Assistants that passively respond to user requests, Autonomous Agents are proactive, capable of running periodically based on job responsibilities and rules to complete complex multi-step tasks. +An **Autonomous Agent** is an AI team member. It works on its own, makes decisions, and runs tasks without waiting for user input. -**Core Features:** +**Key points:** -- **Team Member**: From the user's perspective, it's an AI member managed like human members -- **Job Responsibilities**: Each AI member has clearly defined duties and knows what to do -- **Dynamic Lifecycle**: Dynamically created/destroyed based on team needs -- **Autonomous Operation**: Triggered by the World Clock, periodically executing job responsibilities +- 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 -## Relationship with Team +--- -From the user's perspective, an Autonomous Agent is an **AI member** within the team. Each AI member has clearly defined job responsibilities, and a Team can have multiple AI members. +## 2. Architecture + +### 2.1 System Flow + +```mermaid +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 β”‚ -β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ AI Members β”‚ β”‚ +β”‚ β”‚ Robot Members β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚Sales Managerβ”‚ β”‚Data Analyst β”‚ β”‚CS Specialistβ”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ (AI Member) β”‚ β”‚ (AI Member) β”‚ β”‚ (AI Member) β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Duties: β”‚ β”‚ Duties: β”‚ β”‚ Duties: β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β€’ Track KPIsβ”‚ β”‚ β€’ Analyze β”‚ β”‚ β€’ Handle β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β€’ Generate β”‚ β”‚ data β”‚ β”‚ tickets β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ reports β”‚ β”‚ β€’ Generate β”‚ β”‚ β€’ Reply to β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ reports β”‚ β”‚ inquiries β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Track KPIsβ”‚ β”‚ β€’ Analyze β”‚ β”‚ β€’ Tickets β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Reports β”‚ β”‚ β€’ Reports β”‚ β”‚ β€’ Inquiries β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Human Members β”‚ β”‚ +β”‚ β”‚ User Members β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ John β”‚ β”‚ Jane β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ (Owner) β”‚ β”‚ (Admin) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ John (Owner)β”‚ β”‚ Jane (Admin)β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` -### Team Member Table Extension +**Key fields in `__yao.member` for autonomous agents:** -AI members reuse the `team_members` table, distinguished by `member_type`: +| Field | Type | Description | +| ----------------- | ------ | ----------------------------------------------------------- | +| `member_type` | enum | `user` \| `robot` | +| `autonomous_mode` | bool | Enable autonomous 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 | -```sql --- team_members table -CREATE TABLE team_members ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - team_id VARCHAR(64) NOT NULL, - user_id VARCHAR(64), -- user_id for human members - member_type VARCHAR(32) NOT NULL, -- "user" | "ai" - role_id VARCHAR(64), +--- - -- AI member specific fields - agent_id VARCHAR(64), -- Autonomous Agent ID (AI members only) - agent_config JSON, -- Agent configuration (identity, resources, delivery, etc.) +## 3. How It Works - is_owner BOOLEAN DEFAULT FALSE, - status VARCHAR(32) DEFAULT 'active', - joined_at DATETIME, - created_at DATETIME, - updated_at DATETIME, - - INDEX idx_team_id (team_id), - INDEX idx_member_type (member_type), - INDEX idx_agent_id (agent_id) -); -``` - -## System Architecture - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ World Clock β”‚ -β”‚ (Global timer, e.g., every minute) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ Tick - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Autonomous Agent Manager β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β€’ Get active AI members from memory cache β”‚ β”‚ -β”‚ β”‚ (loaded at startup, refreshed on changes) β”‚ β”‚ -β”‚ β”‚ β€’ Check scheduling conditions β”‚ β”‚ -β”‚ β”‚ β€’ Execution-level deduplication (prevent duplicate β”‚ β”‚ -β”‚ β”‚ submissions) β”‚ β”‚ -β”‚ β”‚ β€’ Dispatch execution requests to eligible members β”‚ β”‚ -β”‚ β”‚ β€’ Monitor execution status, handle failures and retries β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Team A β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ AI: Sales Mgr β”‚ β”‚ AI: Analyst β”‚ β”‚ AI: Editor β”‚ β”‚ -β”‚ β”‚ (sales-manager) β”‚ β”‚ (data-analyst) β”‚ β”‚ (content-editor)β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Duties: β”‚ β”‚ Duties: β”‚ β”‚ Duties: β”‚ β”‚ -β”‚ β”‚ β€’ Track sales β”‚ β”‚ β€’ Analyze data β”‚ β”‚ β€’ Generate β”‚ β”‚ -β”‚ β”‚ performance β”‚ β”‚ β€’ Generate β”‚ β”‚ marketing β”‚ β”‚ -β”‚ β”‚ β€’ Generate β”‚ β”‚ analysis β”‚ β”‚ content β”‚ β”‚ -β”‚ β”‚ sales reports β”‚ β”‚ reports β”‚ β”‚ β€’ Maintain KB β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Human: John β”‚ β”‚ Human: Jane β”‚ β”‚ -β”‚ β”‚ (owner) β”‚ β”‚ (admin) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## Core Design Philosophy - -### 1. AI Member = Team Member with Job Responsibilities - -Each Autonomous Agent is simply an **AI member** to the user, but internally has clearly defined job responsibilities: - -- **Job Responsibilities**: Clearly knows what to do (e.g., "Sales Manager tracks performance and generates reports") -- **Resource Permissions**: Accessible resources and callable tools are defined by configuration -- **Private Knowledge Base**: Dedicated KB for accumulating work experience and expertise -- **Goal-Driven**: Autonomously generates work goals based on job responsibilities -- **Task Execution**: Breaks down goals into specific tasks, calls Assistants/MCP Tools to execute -- **Result Delivery**: Generates deliverables (reports, emails, notifications, etc.) -- **Continuous Learning**: Learns from execution to continuously improve capabilities - -### 2. Multi-Trigger Source Concurrent Execution - -The same AI member can be triggered in multiple ways, supporting concurrent execution: - -- **World Clock**: Scheduled triggers (cron/interval) -- **Human Intervention**: Manually add tasks, adjust goals -- **Event Triggers**: webhooks, database changes, etc. - -> **Note**: Agent-to-agent collaboration (one Agent calling another Agent) is implemented at the Assistant layer, not part of the scheduling layer's responsibility. - -### 3. Concurrency Control and Resource Quotas - -To prevent resources from being monopolized by a single member, the system implements two-level control: - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Global Worker Pool β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Total Workers: 10 (configurable) β”‚ β”‚ -β”‚ β”‚ Currently Used: 6 β”‚ β”‚ -β”‚ β”‚ Queued Tasks: 3 β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β–Ό β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Sales Manager β”‚ β”‚ Data Analyst β”‚ β”‚ CS Specialist β”‚ -β”‚ Quota: 3 β”‚ β”‚ Quota: 2 β”‚ β”‚ Quota: 3 β”‚ -β”‚ Current: 2 βœ“ β”‚ β”‚ Current: 2(full)β”‚ β”‚ Current: 2 βœ“ β”‚ -β”‚ Queued: 1 β”‚ β”‚ Queued: 2 β”‚ β”‚ Queued: 0 β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -**Two-Level Control:** - -1. **Global Worker Pool**: Limits total system concurrency, shared by all members -2. **Member Quota**: Maximum concurrent executions per member, prevents single member from monopolizing resources - -### 4. Member Cache (Avoiding Frequent DB Queries) - -Manager loads all active members into memory at startup, refreshes via events: - -```go -// AgentCache member cache -type AgentCache struct { - agents map[string]*AutonomousAgent // agent_id -> agent - byTeam map[string][]string // team_id -> []agent_id - mutex sync.RWMutex - lastLoad time.Time -} - -// Cache refresh timing -// 1. Full load at Manager startup -// 2. Incremental refresh on member create/update/delete (via event notification) -// 3. Periodic full refresh (e.g., hourly, as fallback) - -func (c *AgentCache) Refresh(agentID string) { - // Load single member from database, update cache -} - -func (c *AgentCache) RefreshAll() { - // Full refresh -} - -func (c *AgentCache) GetActive() []*AutonomousAgent { - // Return all active members (from memory, no database query) -} -``` - -### 5. Deduplication - -Uses **Agent semantic understanding** for deduplication, determining duplicates based on historical task data: - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Deduplication Service β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Core idea: Let Agent determine "has this task been done β”‚ β”‚ -β”‚ β”‚ before" β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Input: β”‚ β”‚ -β”‚ β”‚ β€’ Goal/task to be evaluated β”‚ β”‚ -β”‚ β”‚ β€’ Historical execution records (retrieved from DB) β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Output: β”‚ β”‚ -β”‚ β”‚ β€’ is_duplicate: whether it's a duplicate β”‚ β”‚ -β”‚ β”‚ β€’ reason: reasoning for the judgment β”‚ β”‚ -β”‚ β”‚ β€’ similar_task_id: ID of similar historical task β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -**Deduplication Approach:** - -```go -// DeduplicationService deduplication service -type DeduplicationService struct { - dedupAgent string // Dedup Agent ID (e.g., __yao.dedup-checker) -} - -// DedupRequest deduplication request -type DedupRequest struct { - AgentID string `json:"agent_id"` - Type string `json:"type"` // goal | task - Content string `json:"content"` // goal/task description - Context interface{} `json:"context"` // context information -} - -// DedupResult deduplication result -type DedupResult struct { - IsDuplicate bool `json:"is_duplicate"` - Confidence float64 `json:"confidence"` // confidence 0-1 - Reason string `json:"reason"` // reasoning - SimilarID string `json:"similar_id"` // similar historical record ID - SimilarDesc string `json:"similar_desc"` // similar record description - Suggestion string `json:"suggestion"` // suggestion (skip | merge | proceed) -} -``` - -**Agent Semantic Deduplication Flow:** - -``` -Goal/Task to be checked - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Step 1: Retrieve Historical Records β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Query from database for this member's recent: β”‚ β”‚ -β”‚ β”‚ β€’ Goal records (last 7 days) β”‚ β”‚ -β”‚ β”‚ β€’ Task records (last 24 hours) β”‚ β”‚ -β”‚ β”‚ β€’ Execution results (success/failure/in-progress) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Step 2: Agent Semantic Judgment β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call Dedup Agent with Prompt: β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ "Please determine if the following goal duplicates β”‚ β”‚ -β”‚ β”‚ historical records: β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Goal to check: {content} β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Historical records: β”‚ β”‚ -β”‚ β”‚ 1. [2024-01-09] Analyze weekly sales data - Completed β”‚ β”‚ -β”‚ β”‚ 2. [2024-01-08] Generate customer analysis - Completed β”‚ β”‚ -β”‚ β”‚ 3. [2024-01-10] Track key customers - In progress β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Please determine: β”‚ β”‚ -β”‚ β”‚ - Is it essentially the same as any historical record? β”‚ β”‚ -β”‚ β”‚ - If so, suggest how to handle (skip/merge/proceed)?" β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Step 3: Decision Based on Result β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β€’ skip: Skip, don't execute β”‚ β”‚ -β”‚ β”‚ β€’ merge: Merge into existing task β”‚ β”‚ -β”‚ β”‚ β€’ proceed: Continue execution (not duplicate, or needs β”‚ β”‚ -β”‚ β”‚ re-execution) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -**Dedup Agent Implementation:** - -```go -// Call Dedup Agent for semantic judgment -func (s *DeduplicationService) CheckDuplicate(ctx *context.Context, req *DedupRequest) (*DedupResult, error) { - - // 1. Retrieve historical records - var history []HistoryRecord - switch req.Type { - case "goal": - history = s.getRecentGoals(req.AgentID, 7*24*time.Hour) - case "task": - history = s.getRecentTasks(req.AgentID, 24*time.Hour) - } - - // If no historical records, return not duplicate - if len(history) == 0 { - return &DedupResult{IsDuplicate: false, Suggestion: "proceed"}, nil - } - - // 2. Build dedup prompt - prompt := buildDedupPrompt(req.Content, history) - - // 3. Call Dedup Agent - messages := []context.Message{ - {Role: "system", Content: dedupSystemPrompt}, - {Role: "user", Content: prompt}, - } - - response, err := s.callAgent(ctx, s.dedupAgent, messages) - if err != nil { - // On dedup failure, default to not blocking execution - return &DedupResult{IsDuplicate: false, Suggestion: "proceed"}, nil - } - - // 4. Parse Agent's structured response - return parseDedupResponse(response) -} - -// Dedup Agent system prompt -var dedupSystemPrompt = `You are a task deduplication assistant. Your job is to determine if a new task duplicates historical tasks. - -Judgment criteria: -1. Essentially the same: The core intent of the goal/task is the same, even if worded differently -2. Time sensitivity: Consider if the task is time-sensitive (e.g., "today's report" vs "yesterday's report" are not duplicates) -3. Execution status: If a historical task failed, it may need re-execution - -Output format (JSON): -{ - "is_duplicate": true/false, - "confidence": 0.0-1.0, - "reason": "reasoning", - "similar_id": "similar historical record ID, if any", - "suggestion": "skip | merge | proceed" -} - -Suggestion meanings: -- skip: Complete duplicate, suggest skipping -- merge: Partial duplicate, suggest merging into existing task -- proceed: Not duplicate, or similar but needs re-execution` -``` - -**Deduplication Timing:** - -| Phase | Dedup Type | Description | -| ---------------- | --------------- | ------------------------------------------------------------------- | -| After Phase 1 | Goal dedup | Compare generated goals with historical goals | -| After Phase 2 | Task dedup | Compare decomposed tasks with historical tasks | -| Before execution | Execution dedup | Prevent same trigger from duplicate submission (memory-level, fast) | - -**Execution-Level Deduplication (Fast, Memory):** - -```go -// Execution-level dedup (no Agent needed, pure memory check) -type ExecutionDedup struct { - runningSet map[string]bool // agent_id + trigger_type + trigger_id - queuedSet map[string]bool - mutex sync.RWMutex -} - -func (d *ExecutionDedup) IsDuplicate(agentID, triggerType, triggerID string) bool { - key := fmt.Sprintf("%s:%s:%s", agentID, triggerType, triggerID) - d.mutex.RLock() - defer d.mutex.RUnlock() - return d.runningSet[key] || d.queuedSet[key] -} -``` - -### 6. Inspiration Factor - -The Inspiration Factor is input on the executing Agent side, collected in **Phase 0** by calling a dedicated **Inspiration Agent**. - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Execution Start (Executor Side) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 0: Inspiration Collection β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call: Inspiration Agent (dedicated inspiration collector)β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Input: β”‚ β”‚ -β”‚ β”‚ β€’ Member identity info (job responsibilities) β”‚ β”‚ -β”‚ β”‚ β€’ List of accessible data sources β”‚ β”‚ -β”‚ β”‚ β€’ Last execution time β”‚ β”‚ -β”‚ β”‚ β€’ Private knowledge base ID β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Inspiration Agent Responsibilities: β”‚ β”‚ -β”‚ β”‚ β€’ Query data sources, discover changes β”‚ β”‚ -β”‚ β”‚ β€’ Check time factors (periodic tasks, deadlines) β”‚ β”‚ -β”‚ β”‚ β€’ Retrieve historical experience (success/failure β”‚ β”‚ -β”‚ β”‚ patterns) β”‚ β”‚ -β”‚ β”‚ β€’ Get pending items β”‚ β”‚ -β”‚ β”‚ β€’ Web Search: Perceive external world changes related β”‚ β”‚ -β”‚ β”‚ to job responsibilities β”‚ β”‚ -β”‚ β”‚ β€’ Comprehensive analysis, generate inspiration report β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Output: InspirationReport β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - Phase 1: Goal Generation - (Use inspiration report to generate high-value goals) -``` - -**Inspiration Agent Configuration:** - -```go -// Configured in AgentConfig.Resources -type Resources struct { - // Phase assistants - Inspiration string `json:"inspiration"` // Inspiration Agent (Phase 0) - GoalGenerator string `json:"goal_generator"` // Goal Generator Agent (Phase 1) - TaskPlanner string `json:"task_planner"` // Task Planner Agent (Phase 2) - Validator string `json:"validator"` // Validator Agent (Phase 3) - Delivery string `json:"delivery"` // Delivery Agent (Phase 4) - Learning string `json:"learning"` // Learning Agent (Phase 5) - - // ... -} -``` - -**Inspiration Report Structure:** - -```go -// InspirationReport (generated by Inspiration Agent) -type InspirationReport struct { - // Structured output from Agent analysis - Summary string `json:"summary"` // Overall situation summary - Highlights []Highlight `json:"highlights"` // Key findings - Opportunities []Opportunity `json:"opportunities"` // Discovered opportunities - Risks []Risk `json:"risks"` // Potential risks - WorldInsights []WorldInsight `json:"world_insights"` // External world insights - Suggestions []string `json:"suggestions"` // Suggested focus areas - - // Raw data (for Goal Generator reference) - RawData *InspirationData `json:"raw_data"` -} - -// Highlight key finding -type Highlight struct { - Type string `json:"type"` // data_change | event | feedback | deadline | world_news - Title string `json:"title"` // Title - Description string `json:"description"` // Description - Importance string `json:"importance"` // high | medium | low - Source string `json:"source"` // internal | external -} - -// Opportunity -type Opportunity struct { - Description string `json:"description"` - Reason string `json:"reason"` // Why it's an opportunity - TimeWindow string `json:"time_window"` // Time window - Source string `json:"source"` // internal | external -} - -// Risk -type Risk struct { - Description string `json:"description"` - Impact string `json:"impact"` // Impact - Mitigation string `json:"mitigation"` // Suggested mitigation - Source string `json:"source"` // internal | external -} - -// WorldInsight external world insight -type WorldInsight struct { - Topic string `json:"topic"` // Topic - Insight string `json:"insight"` // Insight - ActionSuggestion string `json:"action_suggestion"` // Suggested action -} - -// InspirationData raw inspiration data -type InspirationData struct { - // Internal changes (system data) - DataChanges []DataChange `json:"data_changes"` - Events []Event `json:"events"` - Feedbacks []Feedback `json:"feedbacks"` - - // External world changes (Web Search) - WorldNews []WorldNews `json:"world_news"` - - // Time factors - TimeContext *TimeContext `json:"time_context"` - Deadlines []Deadline `json:"deadlines"` - - // Historical experience - RecentGoals []GoalRecord `json:"recent_goals"` - - // Pending items - PendingItems []PendingItem `json:"pending_items"` -} - -// WorldNews external world news -type WorldNews struct { - Topic string `json:"topic"` // Search topic (based on job responsibilities) - Title string `json:"title"` // News/update title - Summary string `json:"summary"` // Summary - Source string `json:"source"` // Source - URL string `json:"url"` // Link - PublishedAt time.Time `json:"published_at"` // Published time - Relevance float64 `json:"relevance"` // Relevance to job (0-1) -} - -// DataChange data change -type DataChange struct { - Source string `json:"source"` // Data source - ChangeType string `json:"change_type"` // insert | update | threshold - Description string `json:"description"` // Change description - Timestamp time.Time `json:"timestamp"` -} - -// TimeContext time context -type TimeContext struct { - Now time.Time `json:"now"` - DayOfWeek string `json:"day_of_week"` // Monday, Tuesday... - IsWeekend bool `json:"is_weekend"` - IsMonthStart bool `json:"is_month_start"` - IsMonthEnd bool `json:"is_month_end"` - IsQuarterEnd bool `json:"is_quarter_end"` - // Extensible: holidays, special dates, etc. -} -``` - -**Inspiration Agent Call:** - -```go -// Phase 0: Call Inspiration Agent to collect inspiration -func (e *Executor) collectInspiration(ctx *context.Context, agent *AutonomousAgent) (*InspirationReport, error) { - - // 1. Prepare raw data (collected by system, provided to Agent) - rawData := &InspirationData{ - // Internal data changes - DataChanges: e.dataMonitor.GetChanges(agent.AgentID, agent.LastExecutionTime), - Events: e.eventQueue.GetPending(agent.AgentID), - Feedbacks: e.feedbackStore.GetRecent(agent.AgentID), - - // External world news (Web Search) - WorldNews: e.searchWorldNews(agent.Config.Identity), - - // Time and history - TimeContext: buildTimeContext(time.Now()), - Deadlines: e.getUpcomingDeadlines(agent.AgentID), - RecentGoals: e.getRecentGoals(agent.AgentID), - PendingItems: e.getPendingItems(agent.AgentID), - } - -// searchWorldNews searches for external world news related to job responsibilities -func (e *Executor) searchWorldNews(identity *Identity) []WorldNews { - // 1. Generate search keywords based on job responsibilities - keywords := e.generateSearchKeywords(identity) - - // 2. Call Web Search MCP Tool - var news []WorldNews - for _, keyword := range keywords { - results, err := e.mcpClient.Call("web_search", map[string]interface{}{ - "query": keyword, - "limit": 5, - "recent": "24h", // Only search last 24 hours - }) - if err != nil { - continue - } - - // 3. Filter and evaluate relevance - for _, r := range results { - news = append(news, WorldNews{ - Topic: keyword, - Title: r.Title, - Summary: r.Snippet, - Source: r.Source, - URL: r.URL, - PublishedAt: r.PublishedAt, - Relevance: e.evaluateRelevance(r, identity), - }) - } - } - - // 4. Sort by relevance, take Top N - sort.Slice(news, func(i, j int) bool { - return news[i].Relevance > news[j].Relevance - }) - if len(news) > 10 { - news = news[:10] - } - - return news -} - - // 2. Build prompt for Inspiration Agent to analyze - prompt := buildInspirationPrompt(agent.Config.Identity, rawData) - - messages := []context.Message{ - {Role: "system", Content: inspirationSystemPrompt}, - {Role: "user", Content: prompt}, - } - - // 3. Call Inspiration Agent - response, err := e.callAssistant(ctx, agent.Config.Resources.Inspiration, messages) - if err != nil { - return nil, err - } - - // 4. Parse returned inspiration report - report := parseInspirationReport(response) - report.RawData = rawData - - return report, nil -} - -// Inspiration Agent system prompt -var inspirationSystemPrompt = `You are an inspiration collection assistant. Your job is to analyze the current situation and discover valuable work directions for AI members. - -You will receive: -1. The member's job responsibilities -2. Recent data changes, events, feedback -3. External world news (industry news, market changes related to the job) -4. Time context (day of week, end of month, etc.) -5. Historical goal execution status -6. Pending items - -Please analyze this information and output a structured inspiration report (JSON): -{ - "summary": "One-sentence summary of the overall situation", - "highlights": [ - {"type": "data_change|event|feedback|deadline|world_news", "title": "Title", "description": "Description", "importance": "high|medium|low"} - ], - "opportunities": [ - {"description": "Opportunity description", "reason": "Why it's an opportunity", "time_window": "Time window", "source": "internal|external"} - ], - "risks": [ - {"description": "Risk description", "impact": "Impact", "mitigation": "Suggested measures", "source": "internal|external"} - ], - "world_insights": [ - {"topic": "Topic", "insight": "Insight", "action_suggestion": "Suggested action"} - ], - "suggestions": ["Suggested focus area 1", "Suggested focus area 2"] -} - -Key points: -- Identify important changes and anomalies (internal data + external world) -- Discover potential opportunities (combined with industry trends) -- Alert potential risks (including risks from external environment changes) -- Extract job-relevant insights from external world news -- Give suggestions based on time factors` -``` - -**Injecting Inspiration Report into Goal Generation:** - -```go -// Phase 1: Generate goals using inspiration report -func (e *Executor) generateGoals(ctx *context.Context, agent *AutonomousAgent, report *InspirationReport) ([]Goal, error) { - - // Build goal generation prompt, inject inspiration report - prompt := buildGoalPrompt(agent.Config.Identity, report) - - /* - Prompt example: - - You are [Sales Manager], responsible for [tracking sales performance, generating reports]. - - ## Inspiration Report - - ### Summary - This week's sales data shows significant changes, and there are new industry developments to focus on. - - ### Key Findings - - [High] Data change: 15 new sales records yesterday, 50% increase - - [High] Deadline: Today is Friday, need to prepare weekly report - - [Medium] Customer feedback: Customer A submitted product feedback - - [High] External news: Competitor released new product, may affect market landscape - - ### Opportunities - - [Internal] This week's sales exceeded last week by 20%, can analyze growth reasons - - [Internal] TOP3 customers contributed 60% of sales, worth deep analysis - - [External] Industry report shows market demand growth, opportunity to expand - - ### Risks - - [Internal] 3 days until month end, monthly target only 80% complete - - [External] Competitor price promotion, need to watch for customer churn risk - - ### External World Insights - - Topic: Industry Trends - Insight: AI adoption in sales accelerating, automation tool demand growing - Suggestion: Evaluate automation opportunities in current sales process - - Topic: Competitors - Insight: XX company released new product line, focusing on value - Suggestion: Prepare differentiation strategy, emphasize service advantages - - ### Suggested Directions - - Analyze this week's sales growth reasons - - Prepare weekly report - - Follow up on monthly target progress - - Monitor competitor developments, prepare response strategy - - Please generate today's most valuable work goals based on the above inspiration report. - */ - - messages := []context.Message{ - {Role: "system", Content: goalGeneratorSystemPrompt}, - {Role: "user", Content: prompt}, - } - - return e.callAssistant(ctx, agent.Config.Resources.GoalGenerator, messages) -} -``` - -**Manager-Side Tick Processing Flow:** - -```go -func (m *Manager) onTick() { - // Get active members from cache (no database query) - agents := m.cache.GetActive() - - for _, agent := range agents { - // 1. Check scheduling time - if !agent.ShouldRun(time.Now()) { - continue - } - - // 2. Execution-level deduplication (fast, memory) - dedupKey := fmt.Sprintf("%s:schedule:%s", agent.AgentID, getScheduleWindow(time.Now())) - if m.executionDedup.IsDuplicate(dedupKey) { - continue - } - - // 3. Build execution request (no inspiration factor, collected on Executor side) - req := &ExecutionRequest{ - AgentID: agent.AgentID, - TriggerType: "schedule", - TriggerTime: time.Now(), - } - - // 4. Submit to scheduler - m.scheduler.Submit(req) - } -} -``` - -**Executor-Side Execution Flow:** - -```go -func (e *Executor) Execute(ctx *context.Context, req *ExecutionRequest, agent *AutonomousAgent) (*ExecutionState, error) { - state := &ExecutionState{ - AgentID: agent.AgentID, - StartTime: time.Now(), - Status: StatusRunning, - } - - // Phase 0: Inspiration collection (call Inspiration Agent) - state.Phase = PhaseInspiration - report, err := e.collectInspiration(ctx, agent) - if err != nil { - // Inspiration collection failure doesn't block execution, use empty report - report = &InspirationReport{Summary: "Inspiration collection failed, using default mode"} - } - - // Phase 1: Goal generation (using inspiration report) - state.Phase = PhaseGoalGeneration - goals, err := e.generateGoals(ctx, agent, report) - if err != nil { - return state.Failed(err) - } - - // Phase 1.5: Goal deduplication (call Dedup Agent) - goals, err = e.deduplicateGoals(ctx, agent, goals) - if err != nil { - return state.Failed(err) - } - state.Goals = goals - - // Phase 2: Task decomposition - state.Phase = PhaseTaskDecomposition - tasks, err := e.decomposeTasks(ctx, agent, goals) - if err != nil { - return state.Failed(err) - } - - // Phase 2.5: Task deduplication (call Dedup Agent) - tasks, err = e.deduplicateTasks(ctx, agent, tasks) - if err != nil { - return state.Failed(err) - } - state.Tasks = tasks - - // Phase 3: Task execution - state.Phase = PhaseTaskExecution - for i := range tasks { - if err := e.executeTask(ctx, agent, &tasks[i]); err != nil { - tasks[i].Status = TaskStatusFailed - tasks[i].Error = err.Error() - } - } - - // Phase 4: Result delivery - state.Phase = PhaseDelivery - if err := e.deliver(ctx, agent, state); err != nil { - // Delivery failure is recorded but doesn't interrupt - state.DeliveryError = err.Error() - } - - // Phase 5: Learning - state.Phase = PhaseLearning - if err := e.learn(ctx, agent, state); err != nil { - // Learning failure is recorded but doesn't interrupt - } - - state.Status = StatusCompleted - state.EndTime = time.Now() - return state, nil -} -``` - -### Scheduling Flow - -``` -Trigger Source (World Clock/Human Intervention/Event) - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Scheduler β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ 1. Check member quota: current concurrent < max? β”‚ β”‚ -β”‚ β”‚ β€’ Yes β†’ Enter global queue β”‚ β”‚ -β”‚ β”‚ β€’ No β†’ Enter member wait queue β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ 2. Global queue sorted by priority β”‚ β”‚ -β”‚ β”‚ β€’ Member priority β”‚ β”‚ -β”‚ β”‚ β€’ Trigger time (FIFO) β”‚ β”‚ -β”‚ β”‚ β€’ Trigger type weight (intervention > event > schedule)β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Global Worker Pool β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Worker gets task: β”‚ β”‚ -β”‚ β”‚ 1. Take highest priority task from global queue β”‚ β”‚ -β”‚ β”‚ 2. Double check member quota β”‚ β”‚ -β”‚ β”‚ 3. Execute task, update member concurrent count β”‚ β”‚ -β”‚ β”‚ 4. On completion, release and check member wait queue β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Global Configuration - -```go -// ManagerConfig global manager configuration -type ManagerConfig struct { - // Worker pool configuration - GlobalWorkerCount int `json:"global_worker_count"` // Global worker count (default: 10) - GlobalQueueSize int `json:"global_queue_size"` // Global queue size (default: 100) - - // Default member quota (can be overridden by member config) - DefaultMaxConcurrent int `json:"default_max_concurrent"` // Default max concurrent (default: 2) - DefaultQueueSize int `json:"default_queue_size"` // Default queue size (default: 10) - - // Trigger type weights (for priority sorting) - TriggerWeights map[string]int `json:"trigger_weights"` // intervene: 100, event: 50, schedule: 10 -} -``` - -### Execution Request - -```go -// ExecutionRequest execution request -type ExecutionRequest struct { - ID string `json:"id"` - AgentID string `json:"agent_id"` - TeamID string `json:"team_id"` - TriggerType string `json:"trigger_type"` // schedule | intervene | event - TriggerData interface{} `json:"trigger_data"` // Trigger-related data - Priority int `json:"priority"` // Calculated priority - CreatedAt time.Time `json:"created_at"` - Status string `json:"status"` // queued | running | completed | failed -} - -// Priority calculation -func (r *ExecutionRequest) CalculatePriority(config *ManagerConfig, agentConfig *AgentConfig) int { - // Base priority = member priority - priority := agentConfig.Concurrency.Priority * 10 - - // + trigger type weight - if weight, ok := config.TriggerWeights[r.TriggerType]; ok { - priority += weight - } - - // + wait time bonus (every minute waiting +1) - waitMinutes := int(time.Since(r.CreatedAt).Minutes()) - priority += waitMinutes - - return priority -} -``` - -## Execution Flow - -### Execution Flow Diagram (Mermaid) - -```mermaid -flowchart TB - subgraph Trigger["Trigger Sources"] - WC[/"World Clock
(Schedule)"/] - HI[/"Human Intervention
(Intervene)"/] - EV[/"External Events
(Event)"/] - end - - subgraph Manager["Autonomous Agent Manager"] - Cache[("Agent Cache
(Memory)")] - Check{Schedule Check
& Dedup} - Queue["Global Queue
(Priority Sorted)"] - end - - subgraph WorkerPool["Global Worker Pool"] - W1["Worker 1"] - W2["Worker 2"] - W3["Worker N..."] - end - - subgraph Executor["Agent Executor"] - subgraph Phase0["Phase 0: Inspiration"] - P0_1["Collect Internal Data Changes"] - P0_2["Web Search: External World"] - P0_3["Call Inspiration Agent"] - P0_4[/"Inspiration Report"/] - end - - subgraph Phase1["Phase 1: Goal Generation"] - P1_1["Inject Inspiration Report"] - P1_2["Call Goal Generator Agent"] - P1_3["Goal Deduplication"] - P1_4[/"Goals List"/] - end - - subgraph Phase2["Phase 2: Task Decomposition"] - P2_1["Analyze Goals"] - P2_2["Call Task Planner Agent"] - P2_3["Task Deduplication"] - P2_4[/"Tasks List"/] - end - - subgraph Phase3["Phase 3: Task Execution"] - P3_1["Execute Task via Assistant/MCP"] - P3_2["Call Validator Agent"] - P3_3{All Tasks
Complete?} - P3_4[/"Task Results"/] - end - - subgraph Phase4["Phase 4: Delivery"] - P4_1["Aggregate Results"] - P4_2["Call Delivery Agent"] - P4_3[/"Deliverables
(Email/Report/File)"/] - end - - subgraph Phase5["Phase 5: Learning"] - P5_1["Analyze Execution"] - P5_2["Call Learning Agent"] - P5_3["Write to Private KB"] - end - end - - subgraph Storage["Persistence"] - KB[("Private KB")] - DB[("autonomous_executions")] - Job[("Job System
(Activity Monitor)")] - end - - %% Trigger to Manager - WC --> Cache - HI --> Cache - EV --> Cache - Cache --> Check - Check -->|Pass| Queue - Check -->|Duplicate/Skip| Cache - - %% Manager to Worker - Queue --> W1 - Queue --> W2 - Queue --> W3 - - %% Worker to Executor - W1 --> Phase0 - W2 --> Phase0 - W3 --> Phase0 - - %% Phase 0 Flow - P0_1 --> P0_3 - P0_2 --> P0_3 - P0_3 --> P0_4 - - %% Phase 1 Flow - P0_4 --> P1_1 - P1_1 --> P1_2 - P1_2 --> P1_3 - P1_3 --> P1_4 - - %% Phase 2 Flow - P1_4 --> P2_1 - P2_1 --> P2_2 - P2_2 --> P2_3 - P2_3 --> P2_4 - - %% Phase 3 Flow - P2_4 --> P3_1 - P3_1 --> P3_2 - P3_2 --> P3_3 - P3_3 -->|No| P3_1 - P3_3 -->|Yes| P3_4 - - %% Phase 4 Flow - P3_4 --> P4_1 - P4_1 --> P4_2 - P4_2 --> P4_3 - - %% Phase 5 Flow - P4_3 --> P5_1 - P5_1 --> P5_2 - P5_2 --> P5_3 - - %% Storage connections - P5_3 --> KB - P5_3 --> DB - P5_3 --> Job - - %% KB feedback to Phase 0 - KB -.->|Historical Experience| P0_1 -``` - -### Execution Sequence Diagram (Mermaid) +### 3.1 Flow: Trigger β†’ Schedule β†’ Run ```mermaid sequenceDiagram autonumber - participant WC as World Clock + participant T as Trigger participant M as Manager participant S as Scheduler participant W as Worker participant E as Executor - participant IA as Inspiration Agent - participant GA as Goal Agent - participant TA as Task Planner - participant VA as Validator - participant DA as Delivery Agent - participant LA as Learning Agent - participant KB as Private KB - participant Job as Job System + participant A as Phase Agents + participant KB as KB - WC->>M: Tick Event - M->>M: Get active agents from cache - M->>M: Check schedule & dedup - M->>S: Submit ExecutionRequest + T->>M: Event + M->>M: Check enabled + M->>M: Get from cache + M->>M: Check dedup + M->>S: Submit - S->>S: Check member quota - S->>S: Priority queue sorting - S->>W: Dispatch to worker + S->>S: Check quota + S->>S: Sort by priority + S->>W: Dispatch - W->>E: Execute(agent) - E->>Job: Create Execution record + W->>E: Run - rect rgb(240, 248, 255) - Note over E,IA: Phase 0: Inspiration Collection - E->>E: Collect data changes - E->>E: Web search for world news - E->>IA: Analyze & generate report - IA-->>E: InspirationReport + alt Clock trigger + E->>A: P0: Inspiration (with clock context) + A-->>E: Report end - rect rgb(255, 250, 240) - Note over E,GA: Phase 1: Goal Generation - E->>KB: Retrieve historical experience - KB-->>E: Past goals & insights - E->>GA: Generate goals (with inspiration) - GA-->>E: Goals[] - E->>E: Deduplicate goals + loop P1 to P5 + E->>A: Call agent + A-->>E: Result end - rect rgb(240, 255, 240) - Note over E,TA: Phase 2: Task Decomposition - E->>TA: Decompose goals into tasks - TA-->>E: Tasks[] - E->>E: Deduplicate tasks - end - - rect rgb(255, 240, 245) - Note over E,VA: Phase 3: Task Execution - loop For each task - E->>E: Execute via Assistant/MCP - E->>VA: Validate result - VA-->>E: Validation result - E->>Job: Update progress - end - end - - rect rgb(245, 245, 255) - Note over E,DA: Phase 4: Delivery - E->>DA: Generate deliverables - DA-->>E: Email/Report/File - end - - rect rgb(255, 255, 240) - Note over E,LA: Phase 5: Learning - E->>LA: Analyze execution - LA-->>E: Knowledge entries - E->>KB: Store learned knowledge - end - - E->>Job: Complete Execution - E-->>W: ExecutionState - W-->>S: Release worker - S-->>M: Execution complete + E->>KB: Save learning + E-->>W: Done ``` -### Phase Details +### 3.2 Triggers -Each Autonomous Agent executes the following standard flow when scheduling conditions are met: +| 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: + +```yaml +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: ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Autonomous Agent Execution β”‚ -β”‚ β”‚ -β”‚ Input: Identity + Private KB + Current State β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 1: Goal Generation β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call: Goal Generator Assistant β”‚ β”‚ -β”‚ β”‚ Input: Identity + Private KB + Historical Context β”‚ β”‚ -β”‚ β”‚ Output: Goal list (with priorities) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 2: Task Decomposition β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call: Task Planner Assistant β”‚ β”‚ -β”‚ β”‚ Input: Goal list + Available resources (Agents/MCP Tools)β”‚ β”‚ -β”‚ β”‚ Output: Task list (with dependencies and executor β”‚ β”‚ -β”‚ β”‚ assignments) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 3: Task Execution β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Loop through each task: β”‚ β”‚ -β”‚ β”‚ 1. Call specified Agent or MCP Tool to execute task β”‚ β”‚ -β”‚ β”‚ 2. Collect execution results β”‚ β”‚ -β”‚ β”‚ 3. Call Validator Assistant to verify results β”‚ β”‚ -β”‚ β”‚ 4. Update task status β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 4: Delivery β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call: Delivery Assistant β”‚ β”‚ -β”‚ β”‚ Input: All task results + Delivery config β”‚ β”‚ -β”‚ β”‚ Output: Final deliverables (email/report/file/ β”‚ β”‚ -β”‚ β”‚ notification, etc.) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 5: Learning (Self-Learning) β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Call: Learning Assistant β”‚ β”‚ -β”‚ β”‚ Input: Execution process + Results + Feedback β”‚ β”‚ -β”‚ β”‚ Output: Experience summary β†’ Write to Private KB β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ Global Pool (10 workers) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Sales Manager β”‚ β”‚ Data Analyst β”‚ β”‚ CS Specialist β”‚ +β”‚ Limit: 3 β”‚ β”‚ Limit: 2 β”‚ β”‚ Limit: 3 β”‚ +β”‚ Now: 2 βœ“ β”‚ β”‚ Now: 2 (full) β”‚ β”‚ Now: 1 βœ“ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` -## Data Structures +### 3.4 Dedup -### Agent Configuration (stored in team_members.agent_config) +**Fast check** (in memory): ```go -// AgentConfig AI member configuration (stored in team_members.agent_config JSON field) -type AgentConfig struct { - // Scheduling configuration - Schedule *Schedule `json:"schedule"` +key := memberID + ":" + triggerType + ":" + window +if has(key) { skip } +``` - // Identity settings - Identity *Identity `json:"identity"` +**Smart check** (for goals/tasks): - // Concurrency quota - Concurrency *ConcurrencyConfig `json:"concurrency"` +- Dedup Agent looks at history +- Returns: `skip` | `merge` | `proceed` - // Private knowledge base (Agent exclusive, for self-learning) - PrivateKB *PrivateKB `json:"private_kb"` +### 3.5 Cache - // Shared knowledge base (optional, team-shared knowledge) - SharedKB *SharedKB `json:"shared_kb,omitempty"` +Keeps agents in memory. No DB query on each tick: - // Available resources - Resources *Resources `json:"resources"` +```go +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 +``` - // Delivery configuration - Delivery *Delivery `json:"delivery"` +--- + +## 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). + +```go +type InspirationReport struct { + Clock ClockContext // Current time context + Summary string // What's happening + Highlights []Highlight // Key changes + Opportunities []Opportunity // Chances to act + Risks []Risk // Things to watch + WorldInsights []WorldInsight // News from outside + Suggestions []string // What to focus on } -// ConcurrencyConfig concurrency quota configuration -type ConcurrencyConfig struct { - MaxConcurrent int `json:"max_concurrent"` // Max concurrent executions for this member (default: 2) - QueueSize int `json:"queue_size"` // Queue size (default: 10) - Priority int `json:"priority"` // Scheduling priority (1-10, default: 5) -} - -// Schedule scheduling configuration -type Schedule struct { - Type string `json:"type"` // cron | interval - Expression string `json:"expression"` // cron: "0 9 * * 1-5" or interval: "1h" - Timezone string `json:"timezone"` // Timezone - MaxExecutionTime string `json:"max_execution_time"` // Max execution time -} - -// Identity identity settings -type Identity struct { - Role string `json:"role"` // Role name - Responsibilities []string `json:"responsibilities"` // Responsibility list - Constraints []string `json:"constraints"` // Constraints -} - -// PrivateKB Agent private knowledge base (auto-created, for self-learning) -type PrivateKB struct { - CollectionID string `json:"collection_id"` // KB collection ID (auto-generated: agent_{agent_id}_kb) - - // Learning configuration - Learning *LearningConfig `json:"learning,omitempty"` -} - -// LearningConfig learning configuration -type LearningConfig struct { - Enabled bool `json:"enabled"` // Enable self-learning - Categories []string `json:"categories"` // Learning categories: ["execution", "feedback", "insight"] - RetentionDays int `json:"retention_days"` // Knowledge retention days, 0 means permanent -} - -// SharedKB shared knowledge base (optional, references team or global knowledge) -type SharedKB struct { - Collections []string `json:"collections"` // Referenced KB collection list -} - -// Resources available resources -type Resources struct { - // Phase assistants (built-in or custom) - Inspiration string `json:"inspiration"` // Inspiration Agent (Phase 0) - GoalGenerator string `json:"goal_generator"` // Goal generation assistant (Phase 1) - TaskPlanner string `json:"task_planner"` // Task planning assistant (Phase 2) - Validator string `json:"validator"` // Result validation assistant (Phase 3) - Delivery string `json:"delivery"` // Delivery assistant (Phase 4) - Learning string `json:"learning"` // Learning assistant (Phase 5) - - // Execution resources - Assistants []string `json:"assistants"` // Callable assistant list - MCP []MCPServerConfig `json:"mcp"` // Callable MCP services -} - -// MCPServerConfig MCP service configuration -type MCPServerConfig struct { - ServerID string `json:"server_id"` - Tools []string `json:"tools"` // Available tools list, empty means all -} - -// Delivery delivery configuration -type Delivery struct { - Type string `json:"type"` // email | file | webhook | notification - Config map[string]interface{} `json:"config"` // Type-specific configuration +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" } ``` -### Execution State +**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 + +Breaks goals into steps: ```go -// ExecutionState execution state (persisted to database) -type ExecutionState struct { - ID string `json:"id"` - TeamID string `json:"team_id"` - AgentID string `json:"agent_id"` - StartTime time.Time `json:"start_time"` - EndTime *time.Time `json:"end_time,omitempty"` - Status ExecutionStatus `json:"status"` - Phase ExecutionPhase `json:"phase"` - Goals []Goal `json:"goals,omitempty"` - Tasks []Task `json:"tasks,omitempty"` - Error string `json:"error,omitempty"` - DeliveryResult interface{} `json:"delivery_result,omitempty"` -} - -type ExecutionStatus string - -const ( - StatusPending ExecutionStatus = "pending" - StatusRunning ExecutionStatus = "running" - StatusCompleted ExecutionStatus = "completed" - StatusFailed ExecutionStatus = "failed" -) - -type ExecutionPhase string - -const ( - PhaseInspiration ExecutionPhase = "inspiration" // Phase 0 - PhaseGoalGeneration ExecutionPhase = "goal_generation" // Phase 1 - PhaseTaskDecomposition ExecutionPhase = "task_decomposition" // Phase 2 - PhaseTaskExecution ExecutionPhase = "task_execution" // Phase 3 - PhaseDelivery ExecutionPhase = "delivery" // Phase 4 - PhaseLearning ExecutionPhase = "learning" // Phase 5 -) - -// Goal -type Goal struct { - ID string `json:"id"` - Description string `json:"description"` - Priority int `json:"priority"` - Status string `json:"status"` -} - -// Task type Task struct { - ID string `json:"id"` - GoalID string `json:"goal_id"` - Description string `json:"description"` - ExecutorType string `json:"executor_type"` // assistant | mcp - ExecutorID string `json:"executor_id"` - Status string `json:"status"` - Result interface{} `json:"result,omitempty"` - Error string `json:"error,omitempty"` + ID string + GoalID string + Description string + ExecutorType string // "assistant" | "mcp" + ExecutorID string } ``` -## Core Interfaces +### 4.5 P3: Run -### Manager Interface +For each task: + +1. Call Assistant or MCP Tool +2. Get result +3. Validate +4. Update status + +### 4.6 P4: Deliver + +Send output: + +```yaml +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 + +```go +type Config struct { + Triggers *Triggers `json:"triggers,omitempty"` + Clock *Clock `json:"clock,omitempty"` + Identity *Identity `json:"identity"` + Quota *Quota `json:"quota"` + PrivateKB *KB `json:"private_kb"` + SharedKB *KB `json:"shared_kb,omitempty"` + Resources *Resources `json:"resources"` + Delivery *Delivery `json:"delivery"` + Input *Input `json:"input,omitempty"` + Events []Event `json:"events,omitempty"` + Monitor *Monitor `json:"monitor,omitempty"` +} +``` + +### 5.2 Types + +```go +// 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 +type KB struct { + ID string `json:"id,omitempty"` + Refs []string `json:"refs,omitempty"` + Learn *Learn `json:"learn,omitempty"` +} + +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 +type Monitor struct { + On bool `json:"on"` + Alerts []Alert `json:"alerts,omitempty"` +} + +type Alert struct { + Name string `json:"name"` + When string `json:"when"` // failed | timeout | error_rate + Value float64 `json:"value"` + Window string `json:"window"` // 1h | 24h + Do []Action `json:"do"` + Cooldown string `json:"cooldown"` +} + +type Action struct { + Type string `json:"type"` // email | webhook | notify + Opts map[string]interface{} `json:"opts"` +} +``` + +### 5.3 Example + +Example record in `__yao.member` table: + +```json +{ + "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 }, + "private_kb": { + "learn": { + "on": true, + "types": ["execution", "feedback", "insight"], + "keep": 90 + } + }, + "shared_kb": { "refs": ["sales-policies", "products"] }, + "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 + +```mermaid +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 + +1. Check config +2. Generate member_id if missing +3. Create KB: `robot_{team_id}_{member_id}_kb` +4. Add to cache +5. Create Job +6. Set active + +### 6.3 On Delete + +1. Stop running jobs +2. Remove from cache +3. Delete Job +4. Delete or archive KB +5. Soft delete record + +### 6.4 Execution Flow + +Single execution flow, depends on trigger type: + +```mermaid +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 +``` + +```mermaid +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 + +Each agent = 1 Job. Each run = 1 Execution. + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 failed +- `feedback`: Errors, fixes +- `insight`: Patterns, tips + +**When:** + +- Create: On robot member create +- Update: After P5 +- Clean: Based on `keep` days +- Delete: On robot member delete + +### 7.3 External Input + +**Types:** + +- `clock`: Timer (with time context) +- `intervene`: Human action +- `event`: Webhook, DB change +- `callback`: Async result + +**Human actions:** + +- `adjust_goal`: Change goal +- `add_task`: Add task +- `cancel_task`: Stop task +- `pause` / `resume` / `abort` +- `plan`: Do later + +**Plan Queue:** + +- Holds tasks for later +- Runs at next cycle start + +--- + +## 8. API + +### 8.1 Manager (Internal) ```go -// Manager Autonomous Agent manager type Manager interface { - // Start/stop world clock + // Lifecycle Start() error Stop() error - // Load active AI members from database - LoadActiveAgents(ctx context.Context) ([]*AutonomousAgent, error) + // Cache + LoadActiveRobots(ctx context.Context) error + GetRobot(teamID, memberID string) *Robot - // Check if Agent should execute - ShouldExecute(agent *AutonomousAgent, now time.Time) bool - - // Execute single Agent - Execute(ctx context.Context, agent *AutonomousAgent) (*ExecutionState, error) - - // Manually trigger execution - Trigger(ctx context.Context, teamID, agentID string) (*ExecutionState, error) - - // Query execution history - GetExecutionHistory(ctx context.Context, teamID, agentID string, limit int) ([]*ExecutionState, error) + // Clock trigger (internal, called by ticker) + Tick(ctx context.Context, now time.Time) error } ``` -### AutonomousAgent Structure +### 8.2 Trigger (Called by openapi layer) ```go -// AutonomousAgent autonomous agent (loaded from database) -type AutonomousAgent struct { - // From team_members table - TeamID string `json:"team_id"` - AgentID string `json:"agent_id"` - RoleID string `json:"role_id"` - Status string `json:"status"` +// TriggerType enum +type TriggerType string - // From agent_config JSON - Config *AgentConfig `json:"config"` +const ( + TriggerClock TriggerType = "clock" + TriggerHuman TriggerType = "human" + TriggerEvent TriggerType = "event" +) - // Runtime state - LastExecutionTime *time.Time `json:"last_execution_time,omitempty"` +// 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 + RunningID string // current execution ID if working } ``` -## Private Knowledge Base and Self-Learning +### 8.3 Execution (Uses Job System) -Each Autonomous Agent has a dedicated private knowledge base for storing learning outcomes and accumulated experience. - -### Automatic KB Creation - -When an AI member is created, the system automatically creates a private knowledge base: +No separate `autonomous_executions` table. Uses existing Job system: ```go -// Auto-create private KB when creating AI member -func createAgentPrivateKB(teamID, agentID string) (string, error) { - collectionID := fmt.Sprintf("agent_%s_%s_kb", teamID, agentID) +// On robot member create - use Once/Cron/Daemon based on clock mode +j, _ := job.Once(job.GOROUTINE, map[string]interface{}{ + "job_id": "robot_" + memberID, + "category_id": "autonomous_robot", + "name": member.DisplayName, +}) +job.SaveJob(j) - // Call KB API to create collection - err := kb.CreateCollection(collectionID, &kb.CollectionConfig{ - Name: fmt.Sprintf("Agent %s Private KB", agentID), - Description: "Auto-created private knowledge base for autonomous agent", - Type: "agent_private", - TeamID: teamID, - AgentID: agentID, - }) - - return collectionID, err +// Add execution with config +exec := &job.Execution{ + ExecutionID: gonanoid.Must(), + JobID: j.JobID, + Status: "queued", + TriggerCategory: string(TriggerClock), // or TriggerHuman, TriggerEvent + ExecutionConfig: &job.ExecutionConfig{ + Type: job.ExecutionTypeProcess, + ProcessName: "autonomous.Execute", + ProcessArgs: []interface{}{memberID, triggerData}, + }, } -``` +job.SaveExecution(exec) -### Learning Content Categories +// Start execution +j.Push() -The private knowledge base stores the following types of knowledge: - -| Category | Description | Examples | -| ----------- | ------------------------- | ------------------------------------------------------------- | -| `execution` | Execution records/results | Task execution process, success/failure cases | -| `feedback` | Feedback and evaluation | Validation results, user feedback, error analysis | -| `insight` | Insights and summaries | Pattern recognition, optimization suggestions, best practices | - -### Learning Flow (Phase 5) - -``` -After execution β†’ Learning Assistant analyzes execution process - β”‚ - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Analysis content: β”‚ - β”‚ β€’ Goal achievementβ”‚ - β”‚ β€’ Task efficiency β”‚ - β”‚ β€’ Errors/anomaliesβ”‚ - β”‚ β€’ Success patternsβ”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Generate knowledgeβ”‚ - β”‚ entries: β”‚ - β”‚ β€’ Experience β”‚ - β”‚ summary β”‚ - β”‚ β€’ Improvement β”‚ - β”‚ suggestions β”‚ - β”‚ β€’ Cautions β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - Write to Private KB (vectorized storage) -``` - -### Knowledge Application - -In Phase 1 (Goal Generation), the Goal Generator Assistant retrieves from the private knowledge base: - -```go -// Retrieve relevant experience during goal generation -func (e *Executor) generateGoals(ctx *context.Context, agent *AutonomousAgent) ([]Goal, error) { - // 1. Build retrieval query - query := buildGoalQuery(agent.Config.Identity) - - // 2. Retrieve relevant experience from private KB - experiences, err := kb.Search(agent.Config.PrivateKB.CollectionID, query, &kb.SearchOptions{ - Categories: []string{"insight", "feedback"}, - Limit: 10, - }) - - // 3. Call Goal Generator Assistant, inject historical experience - messages := []context.Message{ - {Role: "system", Content: buildGoalPrompt(agent.Config.Identity, experiences)}, - {Role: "user", Content: "Please generate today's goals based on current state and historical experience"}, - } - - return e.callAssistant(ctx, agent.Config.Resources.GoalGenerator, messages) +// Query history +param := model.QueryParam{ + Wheres: []model.QueryWhere{{Column: "job_id", Value: j.JobID}}, } +execs, _ := job.ListExecutions(param, 1, 10) ``` -### Knowledge Base Lifecycle - -- **Creation**: Auto-created when AI member is created -- **Update**: New knowledge written after each execution -- **Cleanup**: Auto-cleanup of expired knowledge based on `retention_days` config -- **Deletion**: When AI member is deleted, KB can be retained or deleted - -## Integration with Assistant - -Autonomous Agents complete various phase tasks by calling existing Assistants: +**Query examples:** ```go -// Call Assistant example -func (e *Executor) callAssistant(ctx *context.Context, assistantID string, messages []context.Message) (*context.Response, error) { - ast, err := assistant.Get(assistantID) - if err != nil { - return nil, err - } - - return ast.Stream(ctx, messages, &context.Options{ - // Configuration options - }) +// List robot jobs +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) ``` -## Lifecycle Management +--- -### AI Member Lifecycle Diagram +## 9. Security -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ AI Member Lifecycle β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +1. **Team only**: Agent sees only its team's data +2. **Role rules**: Uses role_id permissions +3. **Limited tools**: Only what's in `resources` +4. **Timeout**: Stops if runs too long +5. **Logs**: All runs saved - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Create β”‚ POST /api/teams/:team_id/members - β”‚ (member_type: "ai") - β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Initialization β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ 1. Validate agent_config β”‚ β”‚ -β”‚ β”‚ 2. Generate agent_id (if not provided) β”‚ β”‚ -β”‚ β”‚ 3. Create private KB: agent_{team_id}_{agent_id}_kb β”‚ β”‚ -β”‚ β”‚ 4. Register with Manager (add to cache) β”‚ β”‚ -β”‚ β”‚ 5. Create Job entry for scheduling β”‚ β”‚ -β”‚ β”‚ 6. Set status = "active" β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Active State β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Idle │────▢│ Triggered│────▢│ Running │────▢│ Learning β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ │◀────│ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β–² β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ Triggers: β”‚ β”‚ -β”‚ β”‚ β€’ World Clock (schedule) β”‚ β”‚ -β”‚ β”‚ β€’ Human Intervention (intervene) β”‚ β”‚ -β”‚ β”‚ β€’ External Events (event) β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”‚ PATCH /api/teams/:team_id/members/:member_id - β”‚ (status: "paused") - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Paused State β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β€’ Removed from active cache β”‚ β”‚ -β”‚ β”‚ β€’ No longer triggered by World Clock β”‚ β”‚ -β”‚ β”‚ β€’ Private KB preserved β”‚ β”‚ -β”‚ β”‚ β€’ Can be resumed: PATCH status = "active" β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”‚ DELETE /api/teams/:team_id/members/:member_id - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Termination β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ 1. Cancel running executions (if any) β”‚ β”‚ -β”‚ β”‚ 2. Remove from Manager cache β”‚ β”‚ -β”‚ β”‚ 3. Delete Job entry β”‚ β”‚ -β”‚ β”‚ 4. Handle private KB: β”‚ β”‚ -β”‚ β”‚ β€’ Option A: Delete KB (default) β”‚ β”‚ -β”‚ β”‚ β€’ Option B: Archive KB (if preserve_kb=true) β”‚ β”‚ -β”‚ β”‚ 5. Mark record as deleted (soft delete) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Deleted β”‚ - β”‚ (archived) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +--- +## 10. Quick Ref -State Transitions: -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ From β”‚ To β”‚ Trigger β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ - β”‚ active β”‚ POST create member β”‚ -β”‚ active β”‚ paused β”‚ PATCH status="paused" β”‚ -β”‚ paused β”‚ active β”‚ PATCH status="active" β”‚ -β”‚ active β”‚ deleted β”‚ DELETE member β”‚ -β”‚ paused β”‚ deleted β”‚ DELETE member β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +### Triggers + +```yaml +triggers: + clock: { enabled: true } + intervene: { enabled: true, actions: [...] } + event: { enabled: false } ``` -### Creating AI Member +### Clock -```go -// Add AI member via Team API -POST /api/teams/:team_id/members +```yaml +# 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 + +```yaml +# 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 + +```yaml +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. + +```json +// robot_config for SEO Content Agent { - "member_type": "ai", - "agent_id": "sales-bot", - "role_id": "analyst", - "agent_config": { - "schedule": { - "type": "cron", - "expression": "0 9 * * 1-5", - "timezone": "Asia/Shanghai", - "max_execution_time": "30m" - }, - "identity": { - "role": "Sales Analyst", - "responsibilities": ["Analyze sales data", "Generate weekly reports"], - "constraints": ["Only access sales-related data"] - }, - "concurrency": { - "max_concurrent": 2, - "queue_size": 10, - "priority": 5 - }, - "private_kb": { - "learning": { - "enabled": true, - "categories": ["execution", "feedback", "insight"], - "retention_days": 90 - } - }, - "shared_kb": { - "collections": ["sales-policies", "product-catalog"] - }, - "resources": { - "goal_generator": "__yao.goal-generator", - "task_planner": "__yao.task-planner", - "validator": "__yao.validator", - "delivery": "__yao.report-generator", - "learning": "__yao.learning", - "assistants": ["data-analyst", "chart-generator"], - "mcp": [ - {"server_id": "database", "tools": ["query"]} - ] - }, - "delivery": { - "type": "email", - "config": {"recipients": ["manager@company.com"]} - } + "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. + +```json +// 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. + +```json +// 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. + +```json +// robot_config for Sales Assistant +{ + "triggers": { + "clock": { "enabled": false }, + "intervene": { + "enabled": true, + "actions": ["add_task", "adjust_goal", "pause"] } -} - -// System automatically: -// 1. Creates private KB: agent_{team_id}_{agent_id}_kb -// 2. Registers with scheduler, allocates resources by quota -``` - -### Deleting AI Member - -```go -// Remove AI member via Team API -DELETE /api/teams/:team_id/members/:member_id - -// Manager will automatically stop this Agent on next Tick -``` - -## Execution State Persistence - -```sql --- Execution history table -CREATE TABLE autonomous_executions ( - id VARCHAR(64) PRIMARY KEY, - team_id VARCHAR(64) NOT NULL, - agent_id VARCHAR(64) NOT NULL, - start_time DATETIME NOT NULL, - end_time DATETIME, - status VARCHAR(32) NOT NULL, - phase VARCHAR(32), - goals JSON, - tasks JSON, - error TEXT, - delivery_result JSON, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - - INDEX idx_team_agent (team_id, agent_id), - INDEX idx_status (status), - INDEX idx_start_time (start_time) -); -``` - -## Security Considerations - -1. **Team Isolation**: AI members can only access resources belonging to their team -2. **Permission Inheritance**: AI member permissions are determined by their role_id -3. **Resource Restrictions**: Callable resources limited via agent_config.resources -4. **Execution Timeout**: Prevent infinite execution via max_execution_time -5. **Audit Logs**: All execution records persisted to autonomous_executions table - -## External Input and Intervention Mechanism - -Besides scheduled triggers, Autonomous Agents need to respond to external inputs (human intervention, event notifications, etc.). - -### Input Types - -```go -// InputType input type -type InputType string - -const ( - InputTypeSchedule InputType = "schedule" // Scheduled trigger - InputTypeIntervene InputType = "intervene" // Human intervention (adjust goals/tasks) - InputTypeEvent InputType = "event" // External event (webhook, system event) - InputTypeCallback InputType = "callback" // Async task callback -) - -// ExternalInput external input -type ExternalInput struct { - ID string `json:"id"` - Type InputType `json:"type"` - Source string `json:"source"` // Source identifier - Priority int `json:"priority"` // Priority (1-10, 10 highest) - Content interface{} `json:"content"` // Input content - Metadata map[string]interface{} `json:"metadata"` - CreatedAt time.Time `json:"created_at"` + }, + "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"] } + } } ``` -### Input Queue and Isolation - -Each Agent maintains an independent input queue for input isolation: +**Example: Sales manager assigns task:** ``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Autonomous Agent β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Input Queue (Isolated) β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Schedule β”‚ β”‚ Intervene β”‚ β”‚ Event β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Queue β”‚ β”‚ Queue β”‚ β”‚ Queue β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚(Scheduled)β”‚ β”‚(Intervention)β”‚(Events) β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β–Ό β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Input Router β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ (Priority Sort) β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β–Ό β”‚ -β”‚ Execution Engine β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +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 ``` -### Input Processing Strategy +--- -```go -// InputConfig input configuration (in AgentConfig) -type InputConfig struct { - // Input isolation settings - Isolation *IsolationConfig `json:"isolation"` +### 11.5 Lead Processor (Event: webhook) - // Processing strategy for each input type - Strategies map[InputType]*InputStrategy `json:"strategies"` -} +**Trigger:** Event - new lead from website/CRM -// IsolationConfig isolation configuration -type IsolationConfig struct { - QueueSize int `json:"queue_size"` // Queue size limit - EnableRateLimit bool `json:"enable_rate_limit"` // Enable rate limiting - RatePerMinute int `json:"rate_per_minute"` // Max inputs per minute -} +**Role:** Instantly process and qualify new leads, route to sales. -// InputStrategy input processing strategy -type InputStrategy struct { - Enabled bool `json:"enabled"` // Enable this input type - Priority int `json:"priority"` // Default priority - Action string `json:"action"` // immediate | queue | merge - // immediate: Process immediately, can interrupt current execution - // queue: Queue up, process by priority - // merge: Merge into current/next execution plan -} -``` - -### Intervention Processing Flow - -When receiving human intervention input: - -``` -External Intervention Input - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Intervene Handler β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ 1. Parse intervention intent β”‚ β”‚ -β”‚ β”‚ β€’ adjust_goal: Adjust current goal β”‚ β”‚ -β”‚ β”‚ β€’ add_task: Add new task β”‚ β”‚ -β”‚ β”‚ β€’ cancel_task: Cancel task β”‚ β”‚ -β”‚ β”‚ β€’ pause: Pause execution β”‚ β”‚ -β”‚ β”‚ β€’ resume: Resume execution β”‚ β”‚ -β”‚ β”‚ β€’ abort: Abort current execution β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Decide handling based on intervention type and current state β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ If currently executing: β”‚ β”‚ -β”‚ β”‚ β€’ High priority intervention β†’ Interrupt current task,β”‚ β”‚ -β”‚ β”‚ process immediately β”‚ β”‚ -β”‚ β”‚ β€’ Low priority intervention β†’ Schedule into current β”‚ β”‚ -β”‚ β”‚ task list β”‚ β”‚ -β”‚ β”‚ If currently idle: β”‚ β”‚ -β”‚ β”‚ β€’ Trigger new execution cycle β”‚ β”‚ -β”‚ β”‚ If intervention is plan-type: β”‚ β”‚ -β”‚ β”‚ β€’ Write to plan queue for later β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Intervention Type Definitions - -```go -// InterveneAction intervention action -type InterveneAction string - -const ( - InterveneAdjustGoal InterveneAction = "adjust_goal" // Adjust goal - InterveneAddTask InterveneAction = "add_task" // Add task - InterveneCancelTask InterveneAction = "cancel_task" // Cancel task - IntervenePause InterveneAction = "pause" // Pause - InterveneResume InterveneAction = "resume" // Resume - InterveneAbort InterveneAction = "abort" // Abort - IntervenePlan InterveneAction = "plan" // Queue for later plan -) - -// InterveneInput intervention input content -type InterveneInput struct { - Action InterveneAction `json:"action"` - TargetID string `json:"target_id,omitempty"` // Goal/task ID - Description string `json:"description"` // Intervention description - Data map[string]interface{} `json:"data,omitempty"` // Additional data - ScheduleAt *time.Time `json:"schedule_at,omitempty"` // Scheduled execution time -} -``` - -## Event Trigger Mechanism - -Besides scheduled triggers, supports multiple event sources to trigger Agent execution. - -### Event Sources - -```go -// EventSource event source configuration -type EventSource struct { - Type string `json:"type"` // webhook | database | mq | system - Config map[string]interface{} `json:"config"` - Filter *EventFilter `json:"filter"` // Event filter conditions - Mapping *EventMapping `json:"mapping"` // Event to input mapping -} - -// EventFilter event filter -type EventFilter struct { - EventTypes []string `json:"event_types"` // Subscribed event types - Conditions map[string]interface{} `json:"conditions"` // Filter conditions -} -``` - -### Configuration Example - -```yaml -agent_config: - # ... other config ... - - # Input configuration - input: - isolation: - queue_size: 100 - enable_rate_limit: true - rate_per_minute: 10 - - strategies: - schedule: - enabled: true - priority: 5 - action: "immediate" - - intervene: - enabled: true - priority: 10 # Highest priority - action: "immediate" - - event: - enabled: true - priority: 7 - action: "queue" - - # Event source configuration - event_sources: - - type: "webhook" - config: - endpoint: "/webhook/agent/{agent_id}" - filter: - event_types: ["order.created", "customer.feedback"] - - - type: "database" - config: - table: "sales_orders" - trigger: "insert" - filter: - conditions: - amount: { "$gt": 10000 } -``` - -## Plan Queue - -Supports queuing tasks for later plans, enabling delayed execution and batch processing. - -### Plan Queue Structure - -```go -// PlanQueue plan queue -type PlanQueue struct { - AgentID string `json:"agent_id"` - Items []PlanItem `json:"items"` -} - -// PlanItem plan item -type PlanItem struct { - ID string `json:"id"` - Type string `json:"type"` // goal | task | input - Content interface{} `json:"content"` - Priority int `json:"priority"` - ScheduleAt *time.Time `json:"schedule_at"` // nil means process on next execution - Source string `json:"source"` // Source (intervene, event) - CreatedAt time.Time `json:"created_at"` - Status string `json:"status"` // pending | processed | cancelled -} -``` - -### Plan Processing - -Before Phase 1 (Goal Generation), check the plan queue: - -``` -Execution Start - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Phase 0: Plan Processing β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ 1. Check due items in plan queue β”‚ β”‚ -β”‚ β”‚ 2. Sort by priority β”‚ β”‚ -β”‚ β”‚ 3. Merge into current execution: β”‚ β”‚ -β”‚ β”‚ β€’ goal type β†’ Inject into goal generation β”‚ β”‚ -β”‚ β”‚ β€’ task type β†’ Add directly to task list β”‚ β”‚ -β”‚ β”‚ β€’ input type β†’ Process as additional input β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -Phase 1: Goal Generation - β”‚ - ... -``` - -## Integration with Job System (Activity Monitor) - -Autonomous Agent task execution is based on the existing Job framework (`yao/job`), reusing its complete task scheduling, execution monitoring, and logging capabilities, with visual management through the **Activity Monitor** UI. - -### Job System Architecture - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Activity Monitor β”‚ -β”‚ (UI Dashboard) β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β€’ Task list and status β”‚ β”‚ -β”‚ β”‚ β€’ Real-time progress tracking β”‚ β”‚ -β”‚ β”‚ β€’ Execution log viewing β”‚ β”‚ -β”‚ β”‚ β€’ Cancel/pause/retry operations β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Job Framework (yao/job) β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ β€’ Job: Task definition (once/cron/daemon) β”‚ β”‚ -β”‚ β”‚ β€’ Execution: Execution instance (supports parent-child) β”‚ β”‚ -β”‚ β”‚ β€’ Worker: Executor (goroutine/process) β”‚ β”‚ -β”‚ β”‚ β€’ Log: Multi-level execution logs β”‚ β”‚ -β”‚ β”‚ β€’ Progress: Real-time progress tracking β”‚ β”‚ -β”‚ β”‚ β€’ Health: Health check β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Autonomous Agent Executor β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Phase 0 β†’ Phase 1 β†’ Phase 2 β†’ Phase 3 β†’ Phase 4 β†’ Phase 5β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Agent Execution Mapping to Job - -Each Autonomous Agent corresponds to a Job, each execution cycle corresponds to an Execution: - -```go -// Create Job corresponding to Agent -func createAgentJob(agent *AutonomousAgent) (*job.Job, error) { - jobData := map[string]interface{}{ - "name": fmt.Sprintf("Agent: %s", agent.AgentID), - "description": fmt.Sprintf("Autonomous Agent for team %s", agent.TeamID), - "category_id": "autonomous_agent", - "__yao_team_id": agent.TeamID, +```json +// 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" } } - - var j *job.Job - var err error - - switch agent.Config.Schedule.Type { - case "cron": - j, err = job.CronAndSave(job.GOROUTINE, jobData, agent.Config.Schedule.Expression) - case "daemon": - j, err = job.DaemonAndSave(job.GOROUTINE, jobData) - default: - j, err = job.OnceAndSave(job.GOROUTINE, jobData) - } - - if err != nil { - return nil, err - } - - // Associate Agent configuration - j.SetConfig(map[string]interface{}{ - "agent_id": agent.AgentID, - "team_id": agent.TeamID, - "agent_config": agent.Config, - }) - - return j, nil + ], + "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" } + } } ``` -### Execution and Execution Phases +**Example: New lead event:** -Each Execution runs the complete Agent cycle, tracking each phase via Progress and Log: - -```go -// Agent execution function (registered to Job) -func agentExecutionHandler(ctx *job.ExecutionContext) error { - execution := ctx.Execution - agentConfig := ctx.Args["agent_config"].(*AgentConfig) - - // Phase 0: Plan Processing - execution.Info("Phase 0: Processing plan queue") - execution.SetProgress(5, "Processing pending plans...") - processPlanQueue(ctx, agentConfig) - - // Phase 1: Goal Generation - execution.Info("Phase 1: Generating goals") - execution.SetProgress(15, "Generating goals...") - goals, err := generateGoals(ctx, agentConfig) - if err != nil { - execution.Error("Goal generation failed: %v", err) - return err - } - - // Phase 2: Task Decomposition - execution.Info("Phase 2: Decomposing tasks") - execution.SetProgress(30, "Decomposing tasks...") - tasks, err := decomposeTasks(ctx, agentConfig, goals) - if err != nil { - execution.Error("Task decomposition failed: %v", err) - return err - } - - // Phase 3: Task Execution (create child Execution for each task) - execution.Info("Phase 3: Executing %d tasks", len(tasks)) - for i, task := range tasks { - progress := 30 + (50 * (i + 1) / len(tasks)) - execution.SetProgress(progress, fmt.Sprintf("Task %d/%d: %s", i+1, len(tasks), task.Description)) - executeTaskWithChildExecution(ctx, execution, agentConfig, &task) - } - - // Phase 4: Delivery - execution.Info("Phase 4: Delivering results") - execution.SetProgress(85, "Generating deliverables...") - deliver(ctx, agentConfig, tasks) - - // Phase 5: Learning - execution.Info("Phase 5: Learning from execution") - execution.SetProgress(95, "Updating knowledge base...") - learn(ctx, agentConfig, goals, tasks) - - execution.SetProgress(100, "Completed") - return nil -} ``` +Event Received: + Type: lead.created + Data: { + name: "John Smith", + email: "john@bigcorp.com", + company: "BigCorp", + message: "Interested in Enterprise pricing, team of 50" + } -### Child Task Tracking (Parent-Child Execution) +Agent Execution (no P0 for events): + P1 Goals: + 1. Enrich lead data + 2. Score lead quality + 3. Route appropriately -Each task in Agent execution creates a child Execution, expandable in the Activity Monitor: + P2 Tasks: + 1. Lookup company info β†’ clearbit.enrich + 2. Calculate lead score β†’ lead-scorer + 3. Update CRM β†’ crm.update + 4. Notify sales β†’ slack webhook -```go -// Create child Execution for Agent task -func executeTaskWithChildExecution(ctx *job.ExecutionContext, parent *job.Execution, config *AgentConfig, task *Task) error { - // Create child Execution - childExec := &job.Execution{ - JobID: parent.JobID, - ParentExecutionID: &parent.ExecutionID, - Status: "running", - TriggerCategory: "agent_task", - ExecutionConfig: &job.ExecutionConfig{ - Type: job.ExecutionTypeFunc, - FuncID: fmt.Sprintf("task_%s", task.ID), - FuncName: task.Description, - }, - } - job.SaveExecution(childExec) + P3 Execute: + - Company: BigCorp, 500 employees, Series C + - LinkedIn: VP of Engineering + - Lead Score: 85/100 (HOT) + - Reason: Enterprise inquiry, decision maker, funded company - // Execute task - childExec.Info("Starting task: %s", task.Description) - err := executeTask(ctx, config, task) + 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." - // Update child Execution status - if err != nil { - childExec.Status = "failed" - childExec.Error("Task failed: %v", err) - } else { - childExec.Status = "completed" - childExec.Info("Task completed successfully") - } - job.SaveExecution(childExec) - - return err -} -``` - -### Activity Monitor Features - -Via Job API (`yao/openapi/job`), the Activity Monitor provides: - -| Feature | API | Description | -| ------------------ | ------------------------------------------------ | -------------------------- | -| Agent task list | `GET /api/jobs?category_id=autonomous_agent` | View all Agent Jobs | -| Execution history | `GET /api/jobs/:job_id/executions` | View execution history | -| Real-time progress | `GET /api/jobs/:job_id/executions/:id` | View current progress | -| Execution logs | `GET /api/jobs/:job_id/executions/:id/logs` | View detailed logs | -| Expand child tasks | `GET /api/jobs/:job_id/executions?parent_id=:id` | View child tasks | -| Cancel execution | `POST /api/jobs/:job_id/stop` | Cancel running task | -| Manual trigger | `POST /api/jobs/:job_id/trigger` | Manually trigger execution | - -### Log Levels - -Agent execution logs map to Job log levels: - -```go -// Log level mapping -execution.Debug("Detailed debug info") // Debug -execution.Info("Phase start/complete") // Info -execution.Warn("Non-fatal warning") // Warn -execution.Error("Error, interrupt execution") // Error -``` - -### Job Configuration - -```yaml -agent_config: - # ... other config ... - - # Job execution configuration - job: - mode: "goroutine" # goroutine | process - max_worker_nums: 1 # Max concurrent executions - max_retry_count: 3 # Max retry count - default_timeout: 1800 # Default timeout (seconds) - priority: 5 # Execution priority (affects queue sorting) -``` - -## Complete AgentConfig Structure - -```go -// AgentConfig AI member complete configuration -type AgentConfig struct { - // Scheduling configuration - Schedule *Schedule `json:"schedule"` - - // Identity settings - Identity *Identity `json:"identity"` - - // Concurrency quota - Concurrency *ConcurrencyConfig `json:"concurrency"` - - // Private knowledge base - PrivateKB *PrivateKB `json:"private_kb"` - - // Shared knowledge base - SharedKB *SharedKB `json:"shared_kb,omitempty"` - - // Available resources - Resources *Resources `json:"resources"` - - // Delivery configuration - Delivery *Delivery `json:"delivery"` - - // Input configuration (isolation, strategies) - Input *InputConfig `json:"input,omitempty"` - - // Event source configuration - EventSources []EventSource `json:"event_sources,omitempty"` - - // Monitoring configuration - Monitoring *MonitoringConfig `json:"monitoring,omitempty"` -} - -// MonitoringConfig monitoring configuration -type MonitoringConfig struct { - Enabled bool `json:"enabled"` - Alerts []AlertRule `json:"alerts,omitempty"` -} - -// AlertRule alert rule definition -type AlertRule struct { - Name string `json:"name"` // Rule name - Condition string `json:"condition"` // Trigger condition: "execution_failed" | "timeout" | "error_rate_high" - Threshold float64 `json:"threshold"` // Threshold value (e.g., error rate > 0.1) - Window string `json:"window"` // Time window (e.g., "1h", "24h") - Actions []AlertAction `json:"actions"` // Actions to take when triggered - Cooldown string `json:"cooldown"` // Cooldown period between alerts -} - -// AlertAction alert action -type AlertAction struct { - Type string `json:"type"` // "email" | "webhook" | "notification" - Config map[string]interface{} `json:"config"` // Action-specific configuration -} + P5 Learn: + - BigCorp profile saved for future reference + - VP-level leads from funded companies = high conversion ``` diff --git a/sui/api/request.go b/sui/api/request.go index a8f1e9cf..a49716f2 100644 --- a/sui/api/request.go +++ b/sui/api/request.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/fatih/color" "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" "github.com/yaoapp/gou/application" @@ -94,9 +93,7 @@ func (r *Request) Render() (string, int, error) { if c == nil { - message := fmt.Sprintf("[SUI] The page %s is not cached. file=%s DisableCache=%v", r.Request.URL.Path, r.File, r.Request.DisableCache()) - go fmt.Println(color.YellowString(message)) - go log.Warn("%s", message) + go log.Warn("[SUI] The page %s is not cached. file=%s DisableCache=%v", r.Request.URL.Path, r.File, r.Request.DisableCache()) var status int var err error