Skip to content

会话与请求生命周期 ​

会话记录、一次 Agent 运行、一个 HTTP 响应和后台进程各有独立生命周期。本页沿发送、工具循环、取消与继续说明状态如何流动。

打开
在 GitHub 查看

状态与所有权 ​

对象所有者/入口结束条件
会话历史与元数据ConversationStore显式删除;运行结束后仍保留
会话运行 JobChatController 的运行管理完成、异常或取消并清理
同会话运行锁ConversationRunGate.run持有至 block 及取消清理完成
单次 HTTP 响应Call.useModelResponse正常结束、异常、取消并关闭
工具审批/问题等待器控制器回答、拒绝、中断或清理
后台命令进程对应运行环境/执行器单独停止或环境结束

持久化会话状态主要为 idle、running、interrupted。等待审批、压缩、网络读取等更细状态由运行操作和 UI 状态表达,不能把所有文案都当成数据库枚举。

发送链路 ​

1. 控制器接受输入 ​

send 校验文本/附件,创建必要的持久化会话,恢复该会话工作区,选择模型配置。它写入用户消息、更新列表,再启动会话 Job。

2. Agent 接受已保存消息 ​

OpenAiAgent.chat 在 IO 调度器运行,接收 userMessagePersisted=true,避免重复写入同一用户消息;直接调用该接口时,需明确谁负责持久化。

kotlin
// 控制器调用语境中的简化示例;对象由宿主提供。
agent.chat(
    conversationId, userInput, profile, model,
    userMessagePersisted = true,
) { update ->
    withContext(Dispatchers.Main) {
        if (activeConversationId.value == conversationId) {
            applyChatUpdate(update)
        }
    }
}

ChatUpdate 包含完整的 content、thinking、status、messageId 及速度/缓存指标。控制器按消息 ID 更新显示;它不等同于可任意拼接的单 Token 增量。

3. 工具循环 ​

runLoop 检查取消与作用域,构造历史和工具定义,调用协议实现。模型请求工具时,执行检查与审批,保存工具结果,再发起下一轮。模型结束回复后才走本次运行收尾。

网络响应的结束与取消 ​

响应所有权 ​

ai/ModelResponseLifecycle.kt 的 useModelResponse 使用 Response.use 释放响应,并安装取消监听;即使 execute() 或读取阻塞,也会通过 Call.cancel() 关闭网络调用。

流终止事件 ​

consumeModelStream 在回调返回 false 时停止读取,不等待服务器关闭 TCP。协议解析器必须识别终止事件,区分正常结束与不完整流。读取超时常量为 MODEL_RESPONSE_READ_TIMEOUT_SECONDS,不要在新增解析器中绕过统一响应管理。

停止、继续与切换 ​

stopActive 取消 Job、标记 interrupted,结束对应审批和问题等待器并刷新消息。取消不是成功,应继续传播 CancellationException,并在 finally 释放临时状态。

continueActive 仅接受中断且未运行的会话,恢复工作区后继续模型循环。ConversationRunGate 按会话 ID 使用 Mutex,取消清理尚未完成时,下一次运行不能提前进入。

切换对话不等于取消所有任务。异步历史读取和流更新应校验会话 ID;reloadMessages 使用读取锁、取消和更新缓冲,防止快速切换后旧历史覆盖新界面。

验证场景 ​

至少覆盖:读取阻塞时停止、终止事件后连接不关闭、停止后立即继续、切换对话时旧请求回调、审批期间中断、工具失败后历史完整性。入口测试为 ConversationRunLifecycleTest 与 ModelResponseLifecycleTest,命令见测试指南。后台进程验证另见工作区运行时。

Lyra Code 保留所有权利。