fix: 修复 #285 的 memo 非法消息窗口与 provider 错误包装#287
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
/simplify |
完成情况已按触发指令完成以下工作并推送到当前 PR 分支
未执行项
|
…ayload Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: Yumiue <188874804+Yumiue@users.noreply.github.com>
|
/review |
|
/simplify |
完成情况已按触发指令完成处理,并推送到当前 PR 分支 本次完成内容:
未完成项:
|
Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: Yumiue <188874804+Yumiue@users.noreply.github.com>
|
/review -codex |
| return nil | ||
| } | ||
|
|
||
| return sanitizeRecentWindowToolMessages(ProjectToolMessagesForModel(cloneContextMessages(selected))) |
There was a problem hiding this comment.
BuildRecentMessagesForModel 把 tool 消息投影后直接送入 memo 提取链路。当前 FormatToolMessageForModel 会保留 meta.path/root/workdir,并附带 content_excerpt(最多 600 rune)。这会把本地路径和工具输出片段跨边界发送到提取模型,数据最小化仍不够。建议在 memo 场景增加专用投影(仅保留必要字段,如 tool_name/status + 更强摘要),默认去掉 meta.* 路径类字段。
| - 调度时会绑定当次 provider/model 快照,后台任务不会重新读取全局当前配置,避免把历史会话消息发送到后续切换后的 provider。 | ||
| - 自动提取失败只记日志,不额外发出 TUI 事件,也不影响主链路完成。 | ||
| - `memo` 的最近消息窗口会复用 `internal/context` 的只读投影规则,只保留 provider-safe 的消息序列。 | ||
| - assistant 含 `tool_calls` 时,只有在窗口内能同时保留对应 `tool` 响应时才会注入;缺响应、空内容或已被 micro compact 清空的 assistant/tool 片段会整组丢弃,保留项会先投影为模型可消费的结构化文本。 |
There was a problem hiding this comment.
这里的描述少了一个实现条件:tool 消息还需要满足“可投影”(ToolMetadata 非空)才会保留。当前文案只写了“缺响应/空内容/cleared”会丢弃,和 matchedToolCallSpan 的真实过滤条件不完全一致。建议补一句,避免读者误解。
| - runtime 将累积过程映射成 `RuntimeEvent` | ||
| - TUI 使用 Bubble Tea `Cmd` 监听事件,并在处理完成后继续订阅 | ||
| - `provider.GenerateText` 只在上游 `Generate` 成功返回时,才把缺失 `message_done` 视为流式中断。 | ||
| - 如果 provider 在真正开始流式输出前直接返回 HTTP/ProviderError,则优先保留原始错误,不再额外包装成 `message_done` 缺失。 |
There was a problem hiding this comment.
这句把错误优先级限定为“真正开始流式前直接返回 ProviderError”。但实现更宽:只要 Generate(...) 返回错误,且流侧唯一问题是 message_done 缺失,就会优先返回原始 provider 错误(包括已有部分 text_delta 的情况)。建议把表述改成与 internal/provider/generate.go 当前逻辑一致。
背景
issue #285 当前问题 3、4 分别表现为:
memo自动提取最近消息时,可能把不完整的assistant tool_calls片段直接发给 provider,触发非法消息序列。provider.GenerateText在非流式 HTTP 错误场景下,可能额外包装成message_done missing,导致最终错误信息失真。修改
internal/context提炼共享消息投影能力:ProjectToolMessagesForModel,统一复用主链路的 tool 消息投影规则。BuildRecentMessagesForModel,从会话尾部构造 provider-safe 的 recent window。assistant tool_calls + toolspan。tool消息。internal/memo/llm_extractor.go改为复用上述共享 helper,避免继续发送非法消息窗口。internal/provider/generate.go的错误优先级:Generate(...)直接返回 provider 错误时,优先返回上游错误。Generate(...) == nil且流正常结束却缺少message_done时,才返回流式中断错误。docs/runtime-provider-event-flow.md,补充 recent window 合法性约束和错误语义说明。测试
已新增/更新以下回归测试:
internal/memo/llm_extractor_test.gointernal/provider/generate_test.gointernal/context/builder_test.gointernal/app/bootstrap_test.go本地验证:
go test ./...