yao/openapi/agent/robot/TODO.md
Max 28d5730289 Add Description Field to Task Struct and Enhance Execution Management
- Introduced a new `Description` field in the `Task` struct for a human-readable task description, improving UI clarity.
- Updated the `ParseTask` function to save the description from input data and convert it to a message if no explicit messages are provided.
- Enhanced the `Executor` to update UI fields with localized messages during task execution phases, ensuring better user feedback.
- Implemented a new method in the `ExecutionStore` to persist task status updates, allowing real-time UI updates.
- Added unit tests to validate the new task description handling and UI updates during execution phases.
2026-01-24 12:16:02 +08:00

44 KiB

Robot OpenAPI - Implementation TODO

Based on: openapi/agent/robot/DESIGN.md, openapi/agent/robot/GAPS.md Depends on: yao/agent/robot/api/ (Go API layer) Base Path: /v1/agent/robots


Field Alignment Review Summary

Last reviewed: 2026-01-23

Robot Fields Fully Aligned

Backend (types.go) Frontend (types.ts) Status
member_id member_id
team_id team_id
display_name display_name
bio bio / description
name (← member_id) name
description (← bio) description
robot_status robot_status
autonomous_mode autonomous_mode
robot_config robot_config
robot_email robot_email
All other fields Same

Execution Fields Aligned

Backend (types.go) Frontend (types.ts) Status
id id Aligned
member_id member_id
team_id team_id
trigger_type trigger_type
status status
phase phase
start_time start_time
end_time end_time
error error
input input Optional
Phase outputs Same Detail view
name name Added
current_task_name current_task_name Added
- job_id 🗑️ Dead field, to be removed

Task Fields Aligned

Backend (types.go) Frontend (types.ts) Status
id id
description description Added
goal_ref goal_ref
source source
executor_type executor_type
executor_id executor_id
status status
order order
start_time start_time
end_time end_time

Action Items:

  • Backend: Execution struct - add Name, CurrentTaskName fields (see Improvement Plan below)
  • Backend: RobotConfig struct - add DefaultLocale field (see Improvement Plan below)
  • Backend: TriggerInput struct - add Locale field (see Improvement Plan below)
  • Backend: Database model execution.mod.yao - add name, current_task_name columns
  • Backend: Executor - update Name, CurrentTaskName at each phase
  • Backend: Store layer - add UpdateUIFields() method
  • Backend: Unit tests for UI fields and i18n (executor/standard/ui_fields_test.go, store/execution_test.go)
  • Backend: Task struct - add Description field for human-readable task description
  • Backend: ParseTask() - save description from LLM output to Task.Description
  • Frontend: Task type - add description field
  • Frontend: Task list display - use description as primary title, fallback to executor_id
  • Frontend: Remove job_id field from types.ts
  • Frontend: Remove job_id mock data from mock/data.ts
  • Frontend: Use name and current_task_name directly from API response

Improvement Plan: Execution UI Display Fields Implemented

Problem: Frontend needs to display "execution title" and "current task", which must be dynamically updated at different phases Solution: Backend manages these fields centrally; Execution struct gets new fields, executor updates them at each phase

1. Execution struct fields (agent/robot/types/robot.go):

type Execution struct {
    // ... existing fields ...
    
    // UI display fields (updated by executor at each phase)
    Name            string `json:"name,omitempty"`             // Execution title
    CurrentTaskName string `json:"current_task_name,omitempty"` // Current task description
}

2. Update timeline:

Phase Name CurrentTaskName
Created Human: extract from input.messages[0]
Clock/Event: "Preparing..." (localized)
"Starting..." (localized)
inspiration - "Analyzing context..." (localized)
goals complete Extract first line from goals.content "Planning goals..." (localized)
tasks - "Breaking down tasks..." (localized)
run (each task) - Current task description (e.g., "Task 1/3: ...")
Completed/Failed - "Completed" / "Failed: {error}" (localized)

3. Implementation files:

  • agent/robot/types/robot.go - Execution struct fields
  • agent/robot/store/execution.go - UpdateUIFields() method
  • agent/robot/executor/standard/executor.go - initUIFields(), updateUIFields(), i18n messages
  • agent/robot/executor/standard/inspiration.go - Update CurrentTaskName
  • agent/robot/executor/standard/goals.go - Update Name and CurrentTaskName
  • agent/robot/executor/standard/tasks.go - Update CurrentTaskName
  • agent/robot/executor/standard/run.go - Update CurrentTaskName for each task
  • yao/models/agent/execution.mod.yao - Database columns

Improvement Plan: i18n Default Locale Implemented

Problem: Clock/Event triggers have no user context, unknown which language to use for generated content Solution: RobotConfig gets a default locale configuration field

1. RobotConfig struct field (agent/robot/types/config.go):

type Config struct {
    // ... existing fields ...
    DefaultLocale string `json:"default_locale,omitempty"` // "en" | "zh", default "en"
}

// GetDefaultLocale returns the default locale (default: "en")
func (c *Config) GetDefaultLocale() string {
    if c == nil || c.DefaultLocale == "" {
        return "en"
    }
    return c.DefaultLocale
}

2. TriggerInput struct field (agent/robot/types/robot.go):

type TriggerInput struct {
    // ... existing fields ...
    Locale string `json:"locale,omitempty"` // Language from human trigger
}

3. Locale determination logic (agent/robot/executor/standard/executor.go):

func getEffectiveLocale(robot *Robot, input *TriggerInput) string {
    // 1. Human trigger: use locale from request
    if input != nil && input.Locale != "" {
        return input.Locale
    }
    // 2. Clock/Event trigger: use Robot config
    if robot != nil && robot.Config != nil {
        return robot.Config.GetDefaultLocale()
    }
    // 3. System default
    return "en"
}

4. Locale source priority:

Trigger Type Locale Source
Human Request locale → Robot default_locale → "en"
Event Robot default_locale → "en"
Clock Robot default_locale → "en"

5. Localized messages (executor.go):

var uiMessages = map[string]map[string]string{
    "en": {
        "preparing":           "Preparing...",
        "starting":            "Starting...",
        "scheduled_execution": "Scheduled execution",
        "event_prefix":        "Event: ",
        "event_triggered":     "Event triggered",
        "analyzing_context":   "Analyzing context...",
        "planning_goals":      "Planning goals...",
        "breaking_down_tasks": "Breaking down tasks...",
        "completed":           "Completed",
        "failed_prefix":       "Failed: ",
        "task_prefix":         "Task",
    },
    "zh": {
        "preparing":           "准备中...",
        "starting":            "启动中...",
        "scheduled_execution": "定时执行",
        // ... more Chinese messages
    },
}

Note: User preference locale fallback deferred to future version

Deferred Features (Phase 5/6)

Feature Current Status Future Plan
Trigger/Intervene UI Backend done, frontend deferred Phase 5 (requires SSE)
Real-time refresh Polling 60s Phase 6 (SSE streams)
Multi-turn chat Not started Phase 5

Implementation Strategy

Integrate frontend immediately after each phase to validate deliverables. Frontend has fallback mechanisms (polling, single-submit mode).

🟢 Phase 1: Core CRUD ✅
  Backend → SDK → Page Integration
  └─ List, Get, Create, Update, Delete robots

✅ Phase 1-FE: Frontend Integration ✅ [Completed]
  └─ SDK (openapi/robot.ts) ✅
  └─ Page Integration (Robot list, detail, create, edit, delete) ✅
  └─ UI/UX (CreatureLoading, bubble animations) ✅

✅ Phase 1.5: Robot Manager Lifecycle ✅ [Completed]
  └─ Auto-start Manager on Yao startup (async)
  └─ Auto-reload cache on robot update
  └─ Auto-remove from cache on robot delete
  └─ Graceful shutdown on Yao unload
  └─ Lazy-load for non-autonomous robots (load on trigger, unload after execution)
  └─ Unit tests: TestManagerLazyLoadNonAutonomous (6 test cases)

🟢 Phase 2: Execution Management
  Backend → SDK → Page Integration
  └─ List, Get, Control executions, Trigger/Intervene

🟢 Phase 3: Results & Activities
  Backend → SDK → Page Integration
  └─ List deliverables, Activity feed

🟢 Phase 4: i18n
  Backend → SDK → Page Integration
  └─ Locale parameter support

🟡 Medium Risk (Deferred):
  Phase 5: Multi-turn Chat API + Trigger/Intervene UI
  Phase 6: Real-time SSE Streams (replace polling)

🟢 Phase 1: Core CRUD [Low Risk]

Goal: Basic robot management endpoints Risk: 🟢 Low - All new code, no changes to existing logic Status: Backend Complete → Proceed to Phase 1.5 Frontend Integration

1.1 Backend Prerequisites

Types & Cache

  • Add Bio field to types.Robot struct in yao/agent/robot/types/robot.go
  • Add bio to memberFields in yao/agent/robot/cache/load.go

Store Layer (Core CRUD - implement first)

  • Create store/robot.go with RobotStore struct
  • Implement RobotStore.Save() - create/update robot member
  • Implement RobotStore.Get() - get by member_id
  • Implement RobotStore.List() - list with filters
  • Implement RobotStore.Delete() - delete robot member
  • Implement RobotStore.UpdateConfig() - update config only
  • Implement RobotStore.UpdateStatus() - update status only
  • Add Yao permission fields support (__yao_created_by, __yao_team_id, etc.)
  • Add tests: store/robot_test.go

API Layer (Thin wrappers calling store)

  • Implement api.CreateRobot() - call store.RobotStore.Save() + cache refresh
    • Auto-generate member_id if not provided (12-digit numeric, matches existing pattern)
  • Implement api.UpdateRobot() - partial update + cache refresh
  • Implement api.RemoveRobot() - call store.RobotStore.Delete() + cache invalidate
  • Implement api.GetRobotResponse() - get robot as API response
  • Add AuthScope for Yao permission fields
  • Add request/response types in api/types.go
  • Add tests: api/robot_test.go

Utils Layer

  • Create utils/convert.go with unified type conversion functions
  • Implement To<Type> functions (ToBool, ToInt, ToFloat64, ToTimestamp, ToJSONValue)
  • Implement Get<Type> functions for map value extraction
  • Add tests: utils/convert_test.go

1.2 OpenAPI Setup

  • Create openapi/agent/robot/ directory (sub-package under agent)
  • Create robot.go - route registration with Attach() function
  • Register routes in openapi/agent/agent.go via robot.Attach(group.Group("/robots"), oauth)
  • Add OAuth guard middleware

1.3 OpenAPI Types

Note: Core types already exist in agent/robot/api/types.go. OpenAPI layer needs HTTP-specific types.

  • types.go - HTTP request/response types
    • RobotResponse struct (with field mapping: namemember_id, descriptionbio)
    • RobotStatusResponse struct
    • ListRobotsResponse struct
    • CreateRobotRequest struct (HTTP binding)
    • UpdateRobotRequest struct (HTTP binding)
    • NewRobotResponse() - conversion from api.RobotResponse
    • NewRobotStatusResponse() - conversion from api.RobotState

1.4 List Robots

  • list.go - GET /v1/agent/robots
  • Parse query params: status, keywords, page, pagesize, team_id
  • Call robot/api.ListRobots()
  • Team constraint from auth info
  • Test: tests/agent/robot_test.go#TestListRobots

1.5 Get Robot

  • detail.go - GET /v1/agent/robots/:id
  • Parse path param
  • Call robot/api.GetRobotResponse()
  • Team access check
  • Test: tests/agent/robot_test.go#TestGetRobot

1.6 Create Robot

  • POST /v1/agent/robots handler
  • Parse HTTP request to CreateRobotRequest
  • Auto-generate member_id if not provided (12-digit numeric, consistent with existing API)
  • Apply AuthScope with permission fields (CreatedBy, TeamID, TenantID)
  • Call robot/api.CreateRobot()
  • Return created robot (201 Created)
  • Handle duplicate (409 Conflict)
  • Test: tests/agent/robot_test.go#TestCreateRobot

1.7 Update Robot

  • PUT /v1/agent/robots/:id handler
  • Parse HTTP request to UpdateRobotRequest
  • Team permission check
  • Apply AuthScope with UpdatedBy
  • Call robot/api.UpdateRobot()
  • Return updated robot
  • Test: tests/agent/robot_test.go#TestUpdateRobot

1.8 Delete Robot

  • DELETE /v1/agent/robots/:id handler
  • Team permission check
  • Call robot/api.RemoveRobot()
  • Handle running executions (409 Conflict)
  • Return success response
  • Test: tests/agent/robot_test.go#TestDeleteRobot

1.9 Status Endpoint

  • GET /v1/agent/robots/:id/status handler
  • Call robot/api.GetRobotStatus()
  • Return runtime status (running count, max, last/next run)
  • Test: tests/agent/robot_test.go#TestGetRobotStatus

1.10 Utilities

  • utils.go - helper functions
    • GetLocale(c *gin.Context) - extract locale from query/header
    • ParseBoolValue() - parse bool from string

1.11 Permission Logic

  • permission.go - permission check functions
    • CanRead() - read permission check (creator or team member)
    • CanWrite() - write permission check (creator only)
    • GetEffectiveTeamID() - get effective team_id (user_id for personal users)
    • BuildListFilter() - build list filter based on permissions
  • Apply permission checks in handlers:
    • GetRobot - check CanRead() with YaoTeamID and YaoCreatedBy
    • GetRobotStatus - check CanRead()
    • UpdateRobot - check CanWrite()
    • DeleteRobot - check CanWrite()
    • ListRobots - use BuildListFilter() for team filtering
    • CreateRobot - auto-set __yao_team_id to user_id for personal users
  • Add Yao permission fields to API layer:
    • api/types.go - add YaoCreatedBy, YaoTeamID to RobotResponse and RobotState
    • api/robot.go - populate permission fields in recordToResponse() and GetRobotStatus()
    • store/robot.go - add __yao_* fields to robotFields
  • Permission tests in tests/agent/robot_test.go#TestRobotPermissions

Phase 1-FE: Frontend Integration [Completed]

Goal: Implement frontend SDK and integrate pages to validate Phase 1 deliverables Status: Completed

1-FE.1 SDK Implementation

Location: cui/packages/cui/openapi/agent/robot/

  • Create robot/types.ts - TypeScript types for Robot API
    • RobotFilter - filter options for listing (including autonomous_mode)
    • Robot - robot data structure
    • RobotStatusResponse - runtime status
    • RobotCreateRequest / RobotUpdateRequest - CRUD requests
    • RobotDeleteResponse - delete response
  • Create robot/robots.ts - Robot API SDK class (AgentRobots)
    • List(filter) - GET /v1/agent/robots
    • Get(id) - GET /v1/agent/robots/:id
    • GetStatus(id) - GET /v1/agent/robots/:id/status
    • Create(data) - POST /v1/agent/robots
    • Update(id, data) - PUT /v1/agent/robots/:id
    • Delete(id) - DELETE /v1/agent/robots/:id
  • Create robot/index.ts - exports
  • Update agent/api.ts - add robots property to Agent class
  • Update agent/index.ts - export robot module
  • Linter check passed

1-FE.2 Page Integration

Location: cui/packages/cui/pages/mission-control/

  • Create useRobots hook for API calls
    • listRobots(filter) - list robots with pagination
    • getRobot(id) - get single robot
    • getRobotStatus(id) - get runtime status
    • createRobot(data) - create robot
    • updateRobot(id, data) - update robot
    • deleteRobot(id) - delete robot
    • Error handling and loading state
  • Robot List Page (mission-control/index.tsx)
    • Replace mock data with listRobots() API (fallback to mock)
    • Fetch status for each robot via getRobotStatus()
    • Refresh list after robot created/updated/deleted
    • Empty state with "Create Agent" button (with bubble animation)
    • Implement pagination (TODO: Phase 2)
    • Implement filters (status, keywords, team) (TODO: Phase 2)
  • Robot Detail Modal (AgentModal)
    • Real-time status refresh via getRobotStatus(id)
    • Auto-refresh every 10 seconds while modal open
    • Merge real-time status with robot data
  • Create Robot (AddAgentModal)
    • Call createRobot() API
    • Handle success/error messages
    • Form validation (existing)
    • Load email domains, managers, agents, MCP servers from API
  • Edit Robot (ConfigTab in AgentModal)
    • Load robot data from API (getRobot())
    • Load email domains, managers, roles from Team API
    • Load agents and MCP servers from API
    • Pre-populate form with existing data
    • Call updateRobot() API with robot_config.clock for schedule
    • Handle success/error messages
    • Work Schedule panel saves correctly
  • Delete Robot (AdvancedPanel in ConfigTab)
    • Confirmation dialog with name input
    • Call deleteRobot() API
    • Handle running execution conflict (409)
    • Refresh list after deletion

1-FE.3 UI/UX Enhancements

  • CreatureLoading component with organic animations
    • Breathing aura, floating creature, orbit ring, particles
    • Three sizes: small, medium, large
    • Used in ConfigTab, ResultsTab, HistoryTab
  • Empty state "Create Agent" button with bubble animation
    • Cyan, purple, pink glowing bubbles rising
  • CSS variable compliance (--color_mission_button_text)
  • Consistent loading animations across all tabs

1-FE.4 Verification

  • Manual test: Create → List → Get → Update → Delete
  • E2E automated test (TODO: Phase 3)
  • Permission test: Personal user vs Team user (manual tested)
  • Error handling: 400, 403, 404, 409, 500

🟢 Phase 2: Execution Management [Backend | Frontend ]

Backend: Steps 1-4 Complete (including UI fields and i18n) Frontend: Step 5 Pending Deferred: Trigger/Intervene UI → Phase 5 (requires SSE)

Goal: Execution listing, details, control, and trigger/intervene (single-submit mode) Risk: 🟢 Low - Wraps existing robot/api functions Workflow: 1. Implement All Endpoints → 2. Linter Check → 3. Code Review → 4. Unit Tests → 5. Frontend Integration


Step 1: Implement All OpenAPI Endpoints

Location: yao/openapi/agent/robot/ Calls: yao/agent/robot/api/ (existing functions)

2.1.1 Types (types.go)

  • ExecutionFilter - query params for listing
  • ExecutionResponse - single execution response
  • ExecutionListResponse - paginated list response
  • ExecutionControlResponse - pause/resume/cancel response
  • TriggerRequest - trigger execution request
  • TriggerResponse - trigger result response
  • InterveneRequest - human intervention request
  • InterveneResponse - intervention result response

2.1.2 Execution Handlers (execution.go)

Permission Note: Execution permissions are inherited from the parent robot. Check robot's __yao_team_id and __yao_created_by for access control.

  • ListExecutions - GET /v1/agent/robots/:id/executions
    • Parse query: status, trigger_type, keyword, page, pagesize
    • Call robot/api.ListExecutions()
    • Permission: Check robot CanRead (via robot ID)
  • GetExecution - GET /v1/agent/robots/:id/executions/:exec_id
    • Call robot/api.GetExecution()
    • Permission: Check robot CanRead (via robot ID)
  • PauseExecution - POST /v1/agent/robots/:id/executions/:exec_id/pause
    • Call robot/api.PauseExecution()
    • Permission: Check robot CanWrite (via robot ID)
  • ResumeExecution - POST /v1/agent/robots/:id/executions/:exec_id/resume
    • Call robot/api.ResumeExecution()
    • Permission: Check robot CanWrite (via robot ID)
  • CancelExecution - POST /v1/agent/robots/:id/executions/:exec_id/cancel
    • Call robot/api.StopExecution()
    • Permission: Check robot CanWrite (via robot ID)

2.1.3 Trigger Handlers (trigger.go)

Permission Note: Same as execution - check robot's permission.

  • TriggerRobot - POST /v1/agent/robots/:id/trigger
    • Parse TriggerRequest (messages, trigger_type)
    • Call robot/api.Trigger()
    • Return execution ID and status
    • Permission: Check robot CanWrite (via robot ID)
  • InterveneRobot - POST /v1/agent/robots/:id/intervene
    • Parse InterveneRequest (action, messages)
    • Call robot/api.Intervene()
    • Return result
    • Permission: Check robot CanWrite (via robot ID)

2.1.4 Route Registration (robot.go)

  • Add execution routes to Attach():
    • GET /:id/executions
    • GET /:id/executions/:exec_id
    • POST /:id/executions/:exec_id/pause
    • POST /:id/executions/:exec_id/resume
    • POST /:id/executions/:exec_id/cancel
    • POST /:id/trigger
    • POST /:id/intervene

Step 2: Linter Check

  • Run ReadLints on all modified files
  • Fix any linter errors
  • Verify imports are correct
  • Build verification passed

Step 3: Code Review

  • Review type definitions (types.go)
    • ExecutionFilter, ExecutionResponse, ExecutionListResponse, ExecutionControlResponse
    • TriggerRequest, TriggerResponse, InterveneRequest, InterveneResponse
    • Conversion functions: NewExecutionListResponse, NewExecutionResponseFromExecution, NewExecutionResponseBrief
  • Review permission handling
    • All execution/trigger handlers check robot permission first
    • Read permission for listing and getting executions
    • Write permission for control (pause/resume/cancel), trigger, and intervene
    • Permission inherited from parent robot (check via YaoTeamID and YaoCreatedBy)
  • Review error handling
    • Fixed: Use errors.Is() instead of == for error comparison
    • Proper HTTP status codes (400, 404, 403, 500)
    • Consistent error response format
  • Review response formats
    • Brief format for list view (omits phase outputs)
    • Full format for detail view (includes all fields)
    • Consistent with existing robot responses

Step 4: Unit Tests

Location: yao/openapi/tests/agent/ Uses testing.Short() to skip AI/manager-dependent tests

  • Create robot_execution_test.go
    • TestListExecutions - list executions with pagination/filters
    • TestGetExecution - get execution details, not found cases
    • TestExecutionControl - pause/resume/cancel endpoints
    • TestExecutionPermissions - permission inheritance from robot
  • Create robot_trigger_test.go
    • TestTriggerRobot - trigger with messages, action, invalid body
    • TestInterveneRobot - intervene with action, missing action validation
    • TestTriggerPermissions - permission inheritance from robot
  • All tests use testing.Short() to skip AI-dependent tests
  • Tests compile successfully
  • All tests pass (with manager not started gracefully handled)

Step 5: Frontend Integration

Location: cui/packages/cui/openapi/agent/robot/ Note: Trigger/Intervene API deferred to Phase 5 (waiting for SSE support) Note: Use 1-minute polling for execution list refresh (will switch to SSE in Phase 6)

5.1 Prerequisites

Dependency: Backend improvement plans completed (see "Improvement Plan" sections above)

Backend (Completed):

  • Execution struct - add Name, CurrentTaskName fields
  • RobotConfig struct - add DefaultLocale field
  • TriggerInput struct - add Locale field
  • Executor - update Name, CurrentTaskName at each phase
  • Store - add UpdateUIFields() method
  • Unit tests for UI fields and i18n

Frontend Cleanup (Completed):

  • Components already use exec.id (no changes needed)
  • Remove job_id field from types.ts
  • Remove job_id from mock/data.ts (mock kept for reference, not used)
  • Use name/current_task_name directly from API response (string, not {en, cn})

5.2 SDK Types (types.ts)

  • ExecutionFilter interface
  • ExecutionResponse interface (align with backend)
  • ExecutionListResponse interface
  • ExecutionControlResponse interface
  • ExecStatus, TriggerType, Phase type aliases

Deferred to Phase 5 (SSE):

  • TriggerRequest / TriggerResponse interfaces
  • InterveneRequest / InterveneResponse interfaces

5.3 SDK Methods (robots.ts)

  • ListExecutions(robotId, filter)
  • GetExecution(robotId, execId)
  • PauseExecution(robotId, execId)
  • ResumeExecution(robotId, execId)
  • CancelExecution(robotId, execId)

Deferred to Phase 5 (SSE):

  • Trigger(robotId, data)
  • Intervene(robotId, data)

5.4 Page Integration

  • ActiveTab: Replace mock with ListExecutions() API
    • Filter: status=running|pending
    • Polling: 1-minute interval (60000ms) - will switch to SSE in Phase 6
  • HistoryTab: Replace mock with ListExecutions() API
    • Filter: status filter, keyword search
    • Pagination: page/pagesize
    • Polling: 1-minute interval for list refresh
  • Execution Detail: Call GetExecution() API
    • Display execution phases and outputs
    • Display name and current_task_name from API
    • Display error field for failed executions
    • Execution controls: Pause/Resume/Cancel buttons (call control APIs)
    • Auto-refresh while execution is running (5s for running)
  • useRobots hook extended with execution methods

Deferred to Phase 5 (SSE):

  • Assign Task Modal: Call Trigger() API
  • GuideExecution: Call Intervene() API

5.5 Polling vs SSE Strategy

Current (Phase 2): Polling

  • Refresh execution list every 60 seconds
  • Manual refresh button for immediate update
  • Acceptable latency for status display

Future (Phase 6): SSE Real-time

  • GET /robots/:id/executions/stream - real-time execution updates
  • GET /robots/stream - robot status changes
  • Instant updates, no polling delay

🟢 Phase 3: Results & Activities [Low Risk]

Goal: Deliverables listing and activity feed Risk: 🟢 Low - Read-only queries, derived from existing data

3.1 Backend Prerequisites

Store Layer (Core implementation)

  • Add ExecutionStore.ListResults() - query deliverables from execution delivery data
  • Add ExecutionStore.GetResult() - get single deliverable detail
  • Add ExecutionStore.ListActivities() - derive activities from execution history

API Layer (Thin wrappers)

  • Create api/results.go with ListResults(), GetResult() - call store
  • Create api/activities.go with ListActivities() - call store

3.2 Results Endpoints

  • results.go - results handlers
  • GET /v1/robots/:id/results
    • Parse filters: trigger_type, keyword, page, pagesize
    • Call robot/api.ListResults()
    • Format response
  • GET /v1/robots/:id/results/:result_id
    • Call robot/api.GetResult()
    • Return full delivery content
  • Test: tests/robot/results_test.go

3.3 Results Types

  • Add to types.go:
    • ResultResponse struct
    • ResultDetailResponse struct
    • DeliveryContentResponse struct
    • DeliveryAttachmentResponse struct

3.4 Activities Endpoints

  • activities.go - activities handlers
  • GET /v1/robots/activities
    • Parse: limit, since
    • Call robot/api.ListActivities()
    • Format response
  • Test: tests/robot/activities_test.go

3.5 Activity Types

  • Add to types.go:
    • ActivityResponse struct
    • ActivityType constants

3.6 Frontend Integration

Integrate immediately after backend completion

  • SDK: Add results/activities methods to robot.ts
    • listResults(robotId, params)
    • getResult(robotId, resultId)
    • listActivities(params)
  • Page: Results Tab integration
  • Page: Activity Feed integration
  • Verify: E2E testing

🟢 Phase 4: i18n [Low Risk]

Goal: Locale parameter support Risk: 🟢 Low - Additive, optional parameter

4.1 Locale Handling

  • Add getLocale(r *http.Request) to utils.go
  • Parse locale from query param, body, or header
  • Add Locale field to context if needed

4.2 Localized Responses

  • Localize display_name in RobotResponse
  • Localize description in RobotResponse
  • Localize name in ExecutionResponse (derive from goals/input)
  • Localize current_task_name in ExecutionResponse

4.3 Frontend Integration

Integrate immediately after backend completion

  • SDK: Add locale parameter support to all API calls
  • Page: Use current language setting when calling APIs
  • Verify: Data correctly localized after language switch

🟡 Phase 5: Multi-turn Chat API + Trigger/Intervene UI [Medium Risk - Deferred]

Frontend Fallback: Single-submit mode (user input → immediate execution) Risk: 🟡 Medium - New stateful component Dependency: Requires SSE infrastructure (partially)

Goal: Multi-turn conversation before execution + Human trigger/intervene UI

5.1 Backend Prerequisites

  • Create store/conversation.go - temporary conversation storage (redis/memory)
  • Create types/conversation.go - Conversation, ChatRequest, ChatResponse types
  • Create api/chat.go - Chat() handler with LLM call
  • Extend api/trigger.go - support conversation_id parameter

5.2 Chat Endpoint

  • POST /v1/robots/:id/chat (SSE)
  • Parse ChatRequest (conversation_id, messages, attachments)
  • Create or continue conversation
  • Call LLM for response
  • Store updated conversation
  • Return assistant message + conversation_id
  • Test: tests/robot/chat_test.go

5.3 Trigger with Conversation

  • Extend POST /v1/robots/:id/trigger
  • Accept conversation_id parameter
  • Use conversation history as execution input
  • Auto-cleanup conversation after execution starts

5.4 Frontend Trigger/Intervene Integration (Deferred from Phase 2)

Note: These features require SSE for proper UX (streaming response) Currently backend /trigger and /intervene endpoints exist but return immediately Frontend needs streaming response to show assistant's reaction before confirming

SDK Types:

  • TriggerRequest / TriggerResponse interfaces
  • InterveneRequest / InterveneResponse interfaces
  • ChatMessage interface for multi-turn

SDK Methods:

  • Trigger(robotId, data) - with SSE support
  • Intervene(robotId, data) - with SSE support
  • Chat(robotId, data) - multi-turn conversation SSE

Page Integration:

  • AssignTaskDrawer: Multi-turn chat before trigger
  • GuideExecutionDrawer: Multi-turn intervention
  • Real-time streaming response display

🟡 Phase 6: Real-time SSE Streams [Medium Risk - Deferred]

Frontend Current: Polling every 60 seconds (1 minute) Frontend Future: SSE streams for instant updates Risk: 🟡 Medium - Requires modification of executor/manager

Goal: SSE streams for real-time status updates, replacing polling

6.1 Backend Event System

Need to add in robot/:

  • Create events/bus.go - Event bus for pub/sub
  • Integrate event publishing in manager/manager.go
  • Integrate event publishing in executor/standard/executor.go
  • Publish: robot_status, execution_start, execution_complete, phase, task events

6.2 Robot Status Stream

  • stream.go - stream handlers
  • GET /v1/robots/stream
    • Subscribe to manager status updates
    • Stream robot_status events
    • Stream execution_start events
    • Stream execution_complete events
    • Stream activity events
  • Test: tests/robot/stream_test.go

6.3 Execution Progress Stream

  • GET /v1/robots/:id/executions/:exec_id/stream
    • Subscribe to execution updates
    • Stream phase events
    • Stream task_start / task_complete events
    • Stream message events
    • Stream delivery event
    • Stream complete / error events
  • Test: tests/robot/execution_stream_test.go

Backend Extensions Required

Architecture: Store layer handles CRUD, API layer handles business logic. This enables reuse across Golang API, JSAPI, and Yao Process.

robot/store/ Extensions (Core CRUD)

Function Phase Risk Status Description
RobotStore.Save() 1 🟢 Low Create/update robot member
RobotStore.Get() 1 🟢 Low Get robot by member_id
RobotStore.List() 1 🟢 Low List robots with filters
RobotStore.Delete() 1 🟢 Low Delete robot member
RobotStore.UpdateConfig() 1 🟢 Low Update config only
RobotStore.UpdateStatus() 1 🟢 Low Update status only
ExecutionStore.ListResults() 3 🟢 Low Query deliverables from executions
ExecutionStore.GetResult() 3 🟢 Low Get single deliverable
ExecutionStore.ListActivities() 3 🟢 Low Derive activities from history
Conversation store 5 🟡 Medium Temporary chat history (Deferred)

robot/types/ Extensions

Type/Field Phase Risk Status Description
Robot.Bio 1 🟢 Low Add field, maps to __yao.member.bio
Execution name derivation 2 🟢 Low Derive in OpenAPI layer from goals or input

Note: Robot.Name is NOT needed. Frontend name maps to existing Robot.MemberID.

robot/cache/ Extensions

File Phase Risk Status Description
load.go 1 🟢 Low Add bio to memberFields slice

robot/utils/ Extensions

File Phase Risk Status Description
convert.go 1 🟢 Low Unified type conversion utilities
convert_test.go 1 🟢 Low Tests for conversion utilities

robot/api/ Extensions (Thin wrappers calling store)

Function Phase Risk Status Description
CreateRobot() 1 🟢 Low Call store.RobotStore.Save() + cache refresh
UpdateRobot() 1 🟢 Low Partial update + cache refresh
RemoveRobot() 1 🟢 Low Call store.RobotStore.Delete() + cache invalidate
GetRobotResponse() 1 🟢 Low Get robot as API response
ListResults() 3 🟢 Low Call store.ExecutionStore.ListResults()
GetResult() 3 🟢 Low Call store.ExecutionStore.GetResult()
ListActivities() 3 🟢 Low Call store.ExecutionStore.ListActivities()
RetryExecution() 2 🟢 Low Re-trigger with same input
Chat() 5 🟡 Medium Multi-turn conversation (Deferred)

Event System (Phase 6 - Deferred)

Component Phase Risk Description
Event bus 6 🟡 Medium Pub/sub for real-time updates
Manager events 6 🟡 Medium Publish robot status changes
Executor events 6 🟡 Medium Publish execution progress

Testing Strategy

Test Files Structure

yao/openapi/tests/robot/
├── list_test.go
├── get_test.go
├── create_test.go
├── update_test.go
├── delete_test.go
├── execution_list_test.go
├── execution_get_test.go
├── execution_control_test.go
├── trigger_test.go
├── intervene_test.go
├── results_test.go
├── activities_test.go
├── stream_test.go
└── execution_stream_test.go

Test Utilities

  • Create test robot helper
  • Create test execution helper
  • SSE client for streaming tests
  • Mock data generators

Progress Tracking

Phase Risk Backend Frontend Description
1. Core CRUD 🟢 Robot CRUD endpoints
1-FE Frontend Integration 🟢 - SDK , Page Integration , UI/UX
1.5 Manager Lifecycle 🟢 - Auto-start, auto-reload, graceful shutdown
2. Execution 🟢 Execution listing, control, trigger (backend complete with UI fields & i18n)
3. Results/Activities 🟢 Deliverables and activity feed
4. i18n 🟢 Locale parameter support (backend executor i18n complete)
5. Chat API 🟡 Multi-turn conversation (Deferred)
6. SSE Streams 🟡 Real-time status updates (Deferred)

Legend: Not started | 🟡 In progress | Complete

Phase 1 Detailed Status

Component Status Notes
types.Robot.Bio Field added
cache/load.go bio in memberFields
store/robot.go Full CRUD with permission fields
store/robot_test.go Integration tests
api/robot.go Create/Update/Remove/GetResponse
api/types.go Request/Response types, AuthScope
api/robot_test.go API tests
utils/convert.go Type conversion utilities
utils/convert_test.go Unit tests
openapi/agent/robot/robot.go Route registration with Attach()
openapi/agent/robot/types.go HTTP request/response types
openapi/agent/robot/list.go List robots handler with permission filter
openapi/agent/robot/detail.go CRUD handlers with permission checks
openapi/agent/robot/permission.go Permission check functions (CanRead/CanWrite)
openapi/agent/robot/utils.go Helper functions
openapi/agent/agent.go Robot routes registered
openapi/tests/agent/robot_test.go Integration tests + Permission tests

Quick Reference

Current Location

yao/openapi/agent/robot/           # This directory (sub-package under agent)
├── DESIGN.md       # Design document ✅
├── TODO.md         # This file ✅
├── robot.go        # Route registration (Attach function) ✅
├── types.go        # All request/response types ✅
├── list.go         # GET /v1/agent/robots ✅
├── detail.go       # GET/POST/PUT/DELETE /v1/agent/robots/:id ✅
├── permission.go   # Permission check functions (CanRead/CanWrite) ✅
├── utils.go        # Utilities ✅
├── execution.go    # Execution endpoints (Phase 2)
├── trigger.go      # Trigger/Intervene SSE (Phase 2)
├── results.go      # Results endpoints (Phase 3)
├── activities.go   # Activities endpoint (Phase 3)
├── stream.go       # Real-time streams (Phase 6 - Deferred)
└── filter.go       # Query filtering (optional)

Parent Directory

yao/openapi/agent/
├── agent.go        # MODIFY: add robot.Attach() call
├── assistant.go    # Existing
├── filter.go       # Existing
├── models.go       # Existing
├── types.go        # Existing
│
└── robot/          # NEW sub-package (this directory)
    └── ...

Route Registration (in agent/agent.go)

import "github.com/yaoapp/yao/openapi/agent/robot"

func Attach(group *gin.RouterGroup, oauth types.OAuth) {
    group.Use(oauth.Guard)
    
    // Existing assistant routes
    group.GET("/assistants", ListAssistants)
    group.POST("/assistants", CreateAssistant)
    group.GET("/assistants/tags", ListAssistantTags)
    group.GET("/assistants/:id", GetAssistant)
    group.GET("/assistants/:id/info", GetAssistantInfo)
    group.PUT("/assistants/:id", UpdateAssistant)
    
    // Robot routes (NEW)
    robot.Attach(group.Group("/robots"), oauth)
}

Dependencies

Package Usage
yao/agent/robot/api Go API functions (Get, List, Trigger, etc.)
yao/agent/robot/types Robot types (Robot, Execution, etc.)
yao/openapi/oauth Authentication, Guard middleware
yao/openapi/oauth/types OAuth types (AuthorizedInfo)
yao/openapi/response Response helpers

Import Path

package robot

import (
    "github.com/gin-gonic/gin"
    robotapi "github.com/yaoapp/yao/agent/robot/api"
    robottypes "github.com/yaoapp/yao/agent/robot/types"
    "github.com/yaoapp/yao/openapi/oauth/types"
)

Notes

Priority

Priority Phase Required For Risk
1 Phase 1 (CRUD) Basic UI functionality 🟢 Low
2 Phase 2 (Execution) Active/History tabs, Assign Task 🟢 Low
3 Phase 3 (Results) Results tab 🟢 Low
4 Phase 4 (i18n) Multi-language support 🟢 Low
5 Phase 5 (Chat) Enhanced UX (deferred) 🟡 Medium
6 Phase 6 (SSE) Real-time updates (deferred) 🟡 Medium

Frontend Fallbacks

Feature Full Implementation Fallback
Assign Task Multi-turn chat → Confirm → Execute Single-submit → Execute
Real-time Status SSE push Polling every 3-5s

Frontend Integration

Execute immediately after each phase backend completion:

  1. SDK Implementation - cui/packages/cui/openapi/agent/robot/
  2. Type Definitions - TypeScript request/response types
  3. Hook Implementation - cui/packages/cui/hooks/useRobots.ts
  4. Page Integration - Replace mock data, call real APIs
  5. E2E Verification - Full flow testing

File Locations:

cui/packages/cui/
├── openapi/
│   └── agent/
│       └── robot/
│           ├── types.ts      # TypeScript types
│           ├── robots.ts     # AgentRobots SDK class
│           └── index.ts      # Exports
├── hooks/
│   └── useRobots.ts          # React hook for robot API calls
├── styles/
│   └── preset/
│       └── vars.less         # CSS variables (--color_mission_button_text)
└── pages/
    └── mission-control/
        ├── index.tsx         # Robot list (grid) page
        ├── index.less        # Styles with bubble animations
        └── components/
            ├── AgentModal/           # Robot detail modal
            ├── AddAgentModal/        # Create robot modal
            └── CreatureLoading/      # Branded loading component
                ├── index.tsx
                └── index.less

Incremental Deployment

Each phase independently deliverable:

Phase Backend Frontend Verifiable Features
1 Robot CRUD basic management
2 Execution list/control/trigger (backend with UI fields & i18n)
3 Results/Activities viewing
4 Multi-language support (backend executor i18n)
5 Multi-turn chat UX (optional)
6 Real-time push (optional)