SessionActor 是事件驱动的长期存活 Actor
run_session 同时监听命令、chat-state 事件、内部事件、模型切换、任务完成和多个定时器;启动时还建立文件监听、MCP liveness dispatcher 与 replay buffer。
它不像一个简单 while 循环,更像一间控制室:用户输入、工具结果、文件变化、后台任务、模型切换都从不同通道进来,由同一个会话 Actor 排队处理。
这套 Harness 面向长会话、后台工作和 IDE/ACP 集成,控制面复杂度显著高于纯 CLI Agent。
120 pub(super) async fn run_session(
121 session: Arc<SessionActor>,
122 mut cmd_rx: mpsc::UnboundedReceiver<SessionCommand>,
123 mut chat_state_event_rx: mpsc::UnboundedReceiver<xai_chat_state::ChatStateEvent>,
124 mut event_rx: mpsc::UnboundedReceiver<SessionEvent>,
125 fs_notify_config: Option<ClientFsConfig>,
126 codebase_indexes: std::sync::Arc<parking_lot::Mutex<CodebaseIndexManager>>,
127 index_root: std::path::PathBuf,
128 fs_watch_caps: fs_watch::FsWatchCapabilities,
129 ) {
130 let (completion_tx, mut completion_rx) =
131 mpsc::unbounded_channel::<(String, PromptTurnResult)>();
132 tracing::debug!("fs_notify_config: {:?}", fs_notify_config);
133 let mut replay_buffer = ReplayBuffer::new(session.buffering_settings.clone());
134 let event_tx_for_flush_timer = session.event_tx.clone();
135 let buffering_flush_interval = replay_buffer.max_wait_duration_ms();
136 if let Some(buffering_flush_interval) = buffering_flush_interval {
137 tokio::task::spawn_local(async move {
138 let mut interval = tokio::time::interval(Duration::from_millis(std::cmp::max(
139 20,
140 buffering_flush_interval * 2,
141 )));
142 loop {
143 interval.tick().await;
… 30 lines omitted; exact range 120–183 …
174 );
175 tracing::debug!(?fs_watch_caps, "fs-notify: spawning");
176 Some(fs_watch::spawn(fs_watch::FsWatchPlan::build(
177 fs_watch_caps,
178 deps,
179 )))
180 } else {
181 tracing::debug!("fs-notify: skipped (no consumers)");
182 None
183 };
查看全部 3 处证据
-
实现
crates/codegen/xai-grok-shell/src/session/acp_session_impl/run_loop.rs:120–183创建 replay buffer、技能/工作流与文件 watcher。 -
实现
crates/codegen/xai-grok-shell/src/session/acp_session_impl/run_loop.rs:188–246启动 MCP liveness/auto-restart dispatcher 和初始化任务。 -
实现
crates/codegen/xai-grok-shell/src/session/acp_session_impl/run_loop.rs:247–280select loop 同时处理模型切换与定时 memory flush。