Skip to main content

a3s_code_core/orchestrator/
events.rs

1//! Orchestrator 事件定义
2
3use crate::agent::AgentEvent;
4use crate::llm::TokenUsage;
5use crate::orchestrator::{ControlSignal, SubAgentConfig, SubAgentState};
6use crate::planning::ExecutionPlan;
7use serde::{Deserialize, Serialize};
8
9/// Orchestrator 事件 - 统一的事件类型
10#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(tag = "event_type", rename_all = "snake_case")]
12#[allow(clippy::large_enum_variant)]
13pub enum OrchestratorEvent {
14    /// SubAgent 启动
15    SubAgentStarted {
16        id: String,
17        agent_type: String,
18        description: String,
19        #[serde(skip_serializing_if = "Option::is_none")]
20        parent_id: Option<String>,
21        config: SubAgentConfig,
22    },
23
24    /// SubAgent 完成
25    SubAgentCompleted {
26        id: String,
27        success: bool,
28        output: String,
29        duration_ms: u64,
30        #[serde(skip_serializing_if = "Option::is_none")]
31        token_usage: Option<TokenUsage>,
32    },
33
34    /// SubAgent 状态变更
35    SubAgentStateChanged {
36        id: String,
37        old_state: SubAgentState,
38        new_state: SubAgentState,
39    },
40
41    /// SubAgent 进度更新
42    SubAgentProgress {
43        id: String,
44        step: usize,
45        total_steps: usize,
46        message: String,
47    },
48
49    /// SubAgent 内部事件(来自 AgentLoop)
50    SubAgentInternalEvent {
51        id: String,
52        #[serde(flatten)]
53        event: AgentEvent,
54    },
55
56    /// 规划开始
57    PlanningStarted { id: String, goal: String },
58
59    /// 规划完成
60    PlanningCompleted { id: String, plan: ExecutionPlan },
61
62    /// 工具执行开始
63    ToolExecutionStarted {
64        id: String,
65        tool_id: String,
66        tool_name: String,
67        args: serde_json::Value,
68    },
69
70    /// 工具执行完成
71    ToolExecutionCompleted {
72        id: String,
73        tool_id: String,
74        tool_name: String,
75        result: String,
76        exit_code: i32,
77        duration_ms: u64,
78    },
79
80    /// 控制信号接收
81    ControlSignalReceived { id: String, signal: ControlSignal },
82
83    /// 控制信号应用
84    ControlSignalApplied {
85        id: String,
86        signal: ControlSignal,
87        success: bool,
88        #[serde(skip_serializing_if = "Option::is_none")]
89        error: Option<String>,
90    },
91
92    /// A tool call inside a SubAgent is waiting for an external worker.
93    ///
94    /// The consumer must call `AgentOrchestrator::complete_external_task()` with
95    /// the matching `task_id` and a result to unblock the SubAgent.
96    ExternalTaskPending {
97        /// SubAgent that owns this task.
98        id: String,
99        task_id: String,
100        lane: crate::hitl::SessionLane,
101        command_type: String,
102        payload: serde_json::Value,
103        timeout_ms: u64,
104    },
105
106    /// An external task was resolved (succeeded or failed).
107    ExternalTaskCompleted {
108        /// SubAgent that owned this task.
109        id: String,
110        task_id: String,
111        success: bool,
112    },
113}
114
115impl OrchestratorEvent {
116    /// 获取 SubAgent ID
117    pub fn subagent_id(&self) -> Option<&str> {
118        match self {
119            OrchestratorEvent::SubAgentStarted { id, .. }
120            | OrchestratorEvent::SubAgentCompleted { id, .. }
121            | OrchestratorEvent::SubAgentStateChanged { id, .. }
122            | OrchestratorEvent::SubAgentProgress { id, .. }
123            | OrchestratorEvent::SubAgentInternalEvent { id, .. }
124            | OrchestratorEvent::PlanningStarted { id, .. }
125            | OrchestratorEvent::PlanningCompleted { id, .. }
126            | OrchestratorEvent::ToolExecutionStarted { id, .. }
127            | OrchestratorEvent::ToolExecutionCompleted { id, .. }
128            | OrchestratorEvent::ControlSignalReceived { id, .. }
129            | OrchestratorEvent::ControlSignalApplied { id, .. }
130            | OrchestratorEvent::ExternalTaskPending { id, .. }
131            | OrchestratorEvent::ExternalTaskCompleted { id, .. } => Some(id),
132        }
133    }
134
135    /// 获取事件类型名称
136    pub fn event_name(&self) -> &'static str {
137        match self {
138            OrchestratorEvent::SubAgentStarted { .. } => "subagent_started",
139            OrchestratorEvent::SubAgentCompleted { .. } => "subagent_completed",
140            OrchestratorEvent::SubAgentStateChanged { .. } => "subagent_state_changed",
141            OrchestratorEvent::SubAgentProgress { .. } => "subagent_progress",
142            OrchestratorEvent::SubAgentInternalEvent { .. } => "subagent_internal_event",
143            OrchestratorEvent::PlanningStarted { .. } => "planning_started",
144            OrchestratorEvent::PlanningCompleted { .. } => "planning_completed",
145            OrchestratorEvent::ToolExecutionStarted { .. } => "tool_execution_started",
146            OrchestratorEvent::ToolExecutionCompleted { .. } => "tool_execution_completed",
147            OrchestratorEvent::ControlSignalReceived { .. } => "control_signal_received",
148            OrchestratorEvent::ControlSignalApplied { .. } => "control_signal_applied",
149            OrchestratorEvent::ExternalTaskPending { .. } => "external_task_pending",
150            OrchestratorEvent::ExternalTaskCompleted { .. } => "external_task_completed",
151        }
152    }
153}
154
155/// SubAgent 事件 Payload(用于 a3s-event)
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct SubAgentEventPayload {
158    pub subagent_id: String,
159    pub event: OrchestratorEvent,
160    pub timestamp: i64,
161}