Skip to content

AgentSession:编码 Agent 的编排层

源码版本v0.73.1

AgentSession 是 pi-coding-agent 里最重的一层——它不直接跑 LLM,也不直接渲染 UI,而是夹在两者中间:对上,接收用户输入和 UI 事件;对下,驱动 pi-agent-coreAgent 跑循环。模型注册、工具定义、系统提示构建、上下文压缩、失败重试、消息排队,都归它管。可以把它理解成「把通用 Agent 包装成一个有状态、可恢复、带技能和工具的编码助手」的装配车间。

职责

AgentSession 做四件事:

  1. 装配:AgentSessionConfig 里塞进 Agent 实例、模型注册表、工具定义、扩展运行时、系统提示构造器,构造时挂上 beforeToolCall/afterToolCall 钩子和事件订阅。见 packages/coding-agent/src/core/agent-session.ts:313-330
  2. 接收输入:prompt(text) 是主入口,处理 / 斜杠命令、展开文件型提示模板、把文本转成 AgentMessage[],再交给底层 Agent。见 packages/coding-agent/src/core/agent-session.ts:967-1000
  3. 事件转发:订阅 Agent 的事件流,重新包装成 AgentSessionEvent 发给上层 UI。见 packages/coding-agent/src/core/agent-session.ts:330-335
  4. 排队与重试:流式输出期间用户继续打字时,按 streamingBehavior 决定走 steer(插话)还是 followUp(排队),而不是简单丢弃或阻塞。见 packages/coding-agent/src/core/agent-session.ts:1181-1296

设计动机

为什么不直接让 UI 调 Agent.prompt?因为编码助手需要一堆「通用 Agent 不管」的横切逻辑:斜杠命令(/model/settings)、提示模板展开、模型/API key 校验、上下文超长时的自动压缩、工具调用前后的鉴权与遥测。把这些塞进 Agent 会让通用循环变重;放到 UI 层又会在 print 模式、rpc 模式、扩展里重复实现。AgentSession 抽出来当唯一入口,三种运行模式共用同一套编排逻辑,UI 只管渲染事件。

关键文件

构造函数里挂钩子和订阅,是整个编排的起点:

typescript
// packages/coding-agent/src/core/agent-session.ts:313-335
constructor(config: AgentSessionConfig) {
  // ... 存 config,初始化状态 ...
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
  // ... 略 ...
}

prompt 把用户文本变成 AgentMessage[] 后交给底层 Agent:

typescript
// packages/coding-agent/src/core/agent-session.ts:1107-1112
  try {
    await this.agent.prompt(messages);
  } catch (error) {
    // ... 失败处理 ...
  }

数据流

用户在 TUI 编辑器按回车 → InteractiveMode.defaultEditor.onSubmitsession.prompt(text):

流式期间用户继续打字时,prompt 不会硬塞,而是分流:

边界与失败

  • 斜杠命令冲突:扩展注册的命令在流式中也能即时执行(自己管 LLM 交互),不走排队。若命令无法排队会直接抛错,见 packages/coding-agent/src/core/agent-session.ts:1255-1259
  • 模型/key 缺失:非流式路径会校验模型和 API key,缺失时抛错而非发空请求。
  • 压缩中止:abort 会同时取消主循环、压缩控制器、分支摘要控制器,见 packages/coding-agent/src/core/agent-session.ts:1744-1752
  • 重试:Agent.emit() 同步调 _handleAgentEvent,而 prompt()waitForRetry(),失败后由重试逻辑决定是否重新发轮。

小结

AgentSession 是编码助手的「装配车间 + 事件总线」:装配 Agent、转发事件、排队插话、管工具钩子。往上看是 InteractiveMode/runPrintMode/runRpcMode 三种 UI 模式,往下看是 pi-agent-core 的通用循环。装配细节看 createAgentSession 装配,底层循环看 双层 while 主循环