Skip to content

feat(provider):Thinking 能力接入#560

Merged
phantom5099 merged 7 commits into1024XEngineer:mainfrom
phantom5099:file-checkpoint
May 6, 2026
Merged

feat(provider):Thinking 能力接入#560
phantom5099 merged 7 commits into1024XEngineer:mainfrom
phantom5099:file-checkpoint

Conversation

@phantom5099
Copy link
Copy Markdown
Collaborator

一、原存在的问题

1. Thinking/Reasoning 能力空缺

  • 系统不识别任何厂商的 thinking/reasoning 字段(reasoning_contentreasoning_details<think> 标签等),所有模型返回的推理内容被丢弃
  • 没有统一的 thinking 开关、深度控制、多轮 continuity 保留机制
  • 无法向 TUI/GUI 暴露 thinking 内容给用户查看

2. 暴露给模型的提示词存在矛盾

  • agent_identity.md 的 Capabilities 段声称 "Read, search, write, and edit files"
  • plan_mode_plan.md 却说 "Do not perform any write action in this stage"
  • 同一个指令优先级列表要模型自己理解"系统指令覆盖能力声明"——不可靠

3. Plan 模式屏蔽了 todo_write

  • 只读白名单(mode_filter.go)仅含 6 个工具,todo_write 不在其中
  • Plan 阶段是任务拆解阶段,模型需要创建 todo,却被工具层直接拒绝

4. Plan 切换时 stale todo 阻塞验证

  • Plan 模式下模型创建 todo → 用户审阅后重新 plan → 新 revision 覆盖
  • 旧 revision 的 pending/in_progress/blocked todo 未自动清理
  • 验证器 (final_acceptance.go) 看到任何 non-terminal todo 即 block completion,阻止用户推进

5. Provider 覆盖不足

  • 仅内置 4 个 provider(OpenAI、Gemini、Qiniu、ModelScope)
  • DeepSeek、Kimi、Qwen、GLM、MiMo、MiniMax 需要用户手动配置
  • 各厂商 thinking 参数格式互不兼容(thinking.type vs enable_thinking vs chat_template_kwargs vs <think> 标签)

二、解决方案与依据

2.1 Thinking 类型系统层

新增字段

结构 字段 用途
ModelCapabilityHints ThinkingThinkingEffortsThinkingDefaultEffortThinkingForceEnabled 按模型标记 thinking 控制能力、可选档位、是否强制开启
Message ThinkingMetadata json.RawMessage adapter-owned 不透明 JSON,承载 continuity 数据
StreamEvent StreamEventThinkingDelta + ThinkingDeltaPayload 统一 thinking 增量事件
GenerateRequest ThinkingConfig runtime→provider 的抽象 thinking 指令

ThinkingForceEnabled 为 Gemini 3 和 MiniMax 设计——这两个模型无法可靠关闭 thinking(关闭后仍可能输出),与其给用户展示一个"关不掉"的开关,不如强行灰掉。

2.2 提示词架构重构

拆分前

agent_identity.md  ← 包含 Capabilities + Limitations(静态,无法随模式变化)

拆分后

agent_identity.md           ← 纯身份、核心原则、工作流、元认知(静态)
capabilitiesSource          ← 动态读取 PlanStage 选择模板:
  ├── capabilities.md       ← build/默认:全部工具可用
  └── capabilities_plan.md  ← plan:仅只读 + todo_write

依据: capabilitiesSource 在 prompt 拼装顺序中排在 corePromptSource 之后、rulesPromptSource 之前。Plan 模式下模型看到的能力声明本身就是只读的,不依赖跨 section 优先级推理。

2.3 Plan 模式工具白名单修复

isReadOnlyVisibleTool 白名单中增加 ToolNameTodoWrite

依据: summary_candidate.active_todo_ids 引用了模型通过 todo_write 创建的任务项。如果 plan 阶段无法写 todo,这些引用就是悬空的,build 阶段需要重建。主流 agent(Claude Code、Devin)的 plan 模式均允许 todo 管理。

2.4 5 个新 Driver + Kimi Vendor Hint

按 RFC §6.10 的分层策略为每个厂商选择合适的实现层级:

厂商 策略 原因
DeepSeek 独立 deepseek driver thinking.type + reasoning_effort + V4 全多轮必须回传 reasoning_content
Kimi openaicompat + vendor hint 参数结构同 DeepSeek,仅字段映射;K2.6 响应字段为 reasoning(非 reasoning_content
Qwen openaicompat qwen 子模块 enable_thinking平级布尔非嵌套对象,属于参数结构差异
GLM openaicompat glm 子模块 chat_template_kwargs 额外嵌套层,属于参数结构差异
MiMo 独立 mimo driver 默认行为差异 + thinking 参数兼容性问题
MiniMax 独立 minimax driver 同时命中三项独立 driver 判定:响应格式差异(<think> 标签)、参数结构差异(reasoning_split)、默认行为不可预测(enable_thinking 不可靠)

2.5 Session Schema 迁移

SQLite schema v6→v7:messages 表新增 thinking_metadata_json TEXT NOT NULL DEFAULT ''

依据: ThinkingMetadata 是 message 级 opaque JSON。随 Message 自动序列化/反序列化,checkpoint 自动覆盖,无需额外 session-level 状态。

2.6 Runtime Thinking 集成

新增 位置 作用
resolveThinkingConfig runtime/thinking.go 综合 CapabilityHintsThinkingOverride(预留)、全局开关、ThinkingForceEnabled,产出 *ThinkingConfig
EventThinkingDelta runtime/events.go runtime 事件类型,向 TUI/GUI 暴露 thinking 内容
OnThinkingDelta hook streaming/handler.go thinking 流事件→runtime 事件的桥接,不进入 accumulator(不与正文混合)
ErrThinkingNotSupported 重试 run.go callProvider unknown 模型返回不支持错误时,自动重试一次不带 ThinkingConfig
SetThinkingEnabled/IsThinkingEnabled runtime/runtime.go 进程级 thinking 全局开关,默认 true,不持久化

2.7 厂商适配已确认维度

实现阶段对 6 个新增厂商的 8 个维度做了实际 API 调研(2026-05),填入 builtin 模型列表:

维度 DeepSeek V4 Kimi K2.6 Qwen 3.6 GLM-5.1 MiMo V2.5 MiniMax M2.7
开关参数 thinking.type thinking.type enable_thinking (bool) enable_thinking + chat_template_kwargs thinking.type enable_thinking + reasoning_split
响应字段 reasoning_content reasoning reasoning_content reasoning_content reasoning_content reasoning_details / <think>
Continuity 全多轮强制回传 tool-call 回传 建议回传 回传 + clear_thinking tool-call 回传 必须回传
ForceEnabled

2.8 Plan 切换自动清理 stale todo

问题: Plan 创建新 revision 时,旧 revision 遗留的 pending/in_progress/blocked 状态的 todo 未被清理。验证器看到 non-terminal todo 即拒绝 completion。

方案: 在 applyCurrentPlanRevision(plan revision 切换唯一切入点)中,检测到 revision 递增时调用 agentsession.CancelNonTerminalTodos 将旧 todo 的非终态标记为 canceled

依据: todo_writecanceled 状态本身存在但未使用。终态(completed/failed)的 todo 保持原样,因为这些是跨 revision 可能仍有参考价值的记录。非终态(pending/in_progress/blocked)在新的 revision 下已无意义,自动取消避免阻塞验证。


三、修改范围

3.1 Provider 层(核心实现)

文件 改动类型 内容
provider/types/model.go 修改 +4 字段、update merge/normalize/fromValue
provider/types/message.go 修改 +ThinkingMetadata json.RawMessage
provider/types/event.go 修改 +StreamEventThinkingDelta、payload、constructor、accessor
provider/types/request.go 修改 +ThinkingConfig struct
provider/errors.go 修改 +ErrThinkingNotSupportedIsThinkingNotSupportedError
provider/stream_events.go 修改 +EmitThinkingDelta
provider/constants.go 修改 +5 个 driver 常量
provider/generate_attempt.go 修改 IsEffectiveGeneratePayloadEvent 加入 ThinkingDelta
provider/builtin/builtin.go 修改 注册 5 个新 driver
provider/deepseek/ 新增 driver + provider + request + 2 测试文件
provider/mimo/ 新增 driver + provider + 测试
provider/minimax/ 新增 driver + provider + adapter(SSE 解析 + <think> 兜底)+ 测试
provider/openaicompat/qwen/ 新增 driver + provider(enable_thinking 平级布尔 + 采样参数)+ 测试
provider/openaicompat/glm/ 新增 driver + provider(chat_template_kwargs)+ 测试
provider/openaicompat/chatcompletions/adapter.go 修改 streamChunk 加入 reasoning_content + reasoning(Kimi K2.6),ConsumeStream 发出 thinking_delta
provider/openaicompat/chatcompletions/types.go 修改 Message 加入 ReasoningContent
provider/openaicompat/chatcompletions/request.go 修改 toOpenAIMessageWithBudget 从 ThinkingMetadata 恢复 continuity

3.2 Config 层

文件 改动内容
config/provider.go +6 组常量、static models、工厂函数;更新 OpenAI→gpt-5.5、Gemini→3.1;新增 builtinCapabilitiesV2supportsChatAPIModeisOpenAICompatLikehintsAreZero
config/provider_custom_normalize.go +hintsAreZero 辅助函数
config/defaults_test.go 更新 provider 数量断言(4→10)
config/provider_test.go 同上
config/state/service_test.go 更新 expected providers map

3.3 Session 层

文件 改动内容
session/store.go schema version 6→7
session/sqlite_store.go +thinking_metadata_json 列、migration V6→V7、Scan/INSERT/SELECT/buildMessageFromRow 更新

3.4 Runtime 层

文件 改动内容
runtime/thinking.go 新增:resolveThinkingConfigmodelCapabilityHintsForRequestcontainsEffort
runtime/streaming/handler.go Hooks.OnThinkingDelta + HandleEvent 新增 thinking 分支(不进入 accumulator)
runtime/events.go +EventThinkingDelta 事件类型
runtime/runtime.go thinkingEnabled 字段 + SetThinkingEnabled/IsThinkingEnabled,默认 true
runtime/run.go GenerateRequest 注入 ThinkingConfigcallProvider 注入 OnThinkingDelta + ErrThinkingNotSupported 重试
runtime/state.go runState 预留 thinkingOverride 字段

3.5 提示词 & Gateway

文件 改动内容
promptasset/templates/core/agent_identity.md 删除 Capabilities、Limitations 两段
promptasset/templates/core/capabilities.md 新增:默认/构建模式全能力声明
promptasset/templates/core/capabilities_plan.md 新增:计划模式只读能力声明
promptasset/assets.go +CapabilitiesPrompt(stage)
context/source_capabilities.go 新增:动态能力注入 SectionSource
context/builder.go 加入 capabilitiesSource{}
gateway/contracts.go ModelEntry +CapabilityHints
cli/gateway_runtime_bridge.go ListModels 填充 CapabilityHints

3.6 Bug 修复

文件 问题 修复
tools/mode_filter.go Plan 模式 todo_write 被屏蔽 加入只读白名单
session/todo.go + runtime/planning.go Plan 切换时 stale non-terminal todo 阻塞验证 applyCurrentPlanRevision 中自动取消旧 todo
provider/types/model_test.go struct with []string 不能 != 比较 reflect.DeepEqual
provider/catalog/service_test.go model count 断言过期(6→7) 更新为 8 和 7

四、预期收益

4.1 对用户

  • DeepSeek/Kimi/Qwen/GLM/MiMo/MiniMax 开箱即用:无需手动配置 baseURL、模型 ID、thinking 参数
  • Thinking 内容可见:TUI/GUI 可消费 EventThinkingDelta,展示模型推理过程
  • Plan 模式语义完整:能力声明与实际工具集合一致,不会出现"说能写但调不了"或"说不能写但让写 todo"的矛盾
  • Plan 切换无阻塞:新 revision 覆盖时自动取消旧 todo,不会因 stale pending todo 阻止用户推进
  • 多轮推理连续性ThinkingMetadata 随消息持久化,checkpoint 恢复后自动延续

4.2 对开发者

  • 厂商差异完全收敛在 provider 层:上层不感知 thinking.type vs enable_thinking vs <think> 标签差异
  • 新增厂商只需 4 个文件:driver.go + provider.go + request/adapter + 测试
  • ThinkingForceEnabled 避免假开关:新增厂商如果关闭不可靠,标记 true 即可,UI 自动灰掉

五、TUI / GUI / Gateway 后续可接入

以下为本次已预留接口、暂未实现 TUI 交互的部分,上层可随时接入:

5.1 Thinking 开关控件

  • gateway.listModels 返回的 ModelEntry.CapabilityHints 已包含 ThinkingThinkingEffortsThinkingDefaultEffortThinkingForceEnabled
  • TUI/GUI 据此判断:开关是否可用、是否灰掉、是否展示 depth 下拉框、默认选中哪个档位

5.2 Thinking 内容展示

  • Runtime 已通过 EventThinkingDelta 向上游推送 thinking 文本增量
  • TUI 可渲染为折叠面板、侧边栏或流式 thinking 区域
  • Gateway 透传此事件即可让 Web GUI 消费

5.3 用户 ThinkingOverride

  • PrepareInput.ThinkingOverrideEnabled *bool + Effort string)已定义
  • TUI/Gateway 将用户操作(开关和 depth 下拉框)转为 ThinkingOverride 传入 Runtime Submit
  • 当前 Runtime 已预留 ThinkingOverride 字段在 runState 中,默认值走全局开关(true

5.4 全局 Thinking 开关

  • Service.SetThinkingEnabled(bool) / IsThinkingEnabled() 已实现
  • 默认 true,进程级有效,不持久化
  • TUI 可通过 Gateway RPC 调用切换

六、测试覆盖

6.1 新增测试文件

测试文件 覆盖内容
deepseek/request_test.go InjectThinkingParams(enabled/disabled/effort)、ExtractContinuity
deepseek/driver_test.go Driver 注册、配置校验
mimo/provider_test.go InjectThinkingParams(enabled/disabled)
minimax/provider_test.go injectMiniMaxParams、ExtractThinkContent(单标签/多标签/无标签)
qwen/provider_test.go injectQwenParams(enabled/disabled/保留已有温度)
glm/provider_test.go injectGLMParams(enabled→clear_thinking=false, disabled→clear_thinking=true)

6.2 更新已有测试

  • model_test.go: struct 比较 → reflect.DeepEqual
  • catalog/service_test.go: model count(6→7→8)
  • config/defaults_test.go: provider count(4→10)
  • config/provider_test.go: 同上
  • config/state/service_test.go: expected providers map 更新

6.3 运行结果

go build ./...        # 通过
go test ./...         # 全部通过

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copy link
Copy Markdown

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a few behavior regressions in the thinking rollout and plan revision handling that are worth fixing before merge.

Comment thread internal/runtime/planning.go Outdated
Comment thread internal/runtime/run.go
Comment thread internal/config/provider.go
Comment thread internal/provider/minimax/adapter.go
phantom5099 and others added 3 commits May 5, 2026 22:52
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
@phantom5099
Copy link
Copy Markdown
Collaborator Author

/code 将测试覆盖率提到100%

@1024XEngineer 1024XEngineer deleted a comment from fennoai Bot May 5, 2026
@fennoai

This comment was marked as resolved.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
@phantom5099

This comment was marked as low quality.

@fennoai

This comment was marked as resolved.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
@fennoai
Copy link
Copy Markdown

fennoai Bot commented May 5, 2026

Completed

Implemented the prompt update in English so user-driven task switches are handled explicitly.

Summary

Verification

  • go test ./internal/context/...

Delivery

View job run

fix(prompt): handle todo cleanup on task switches
@phantom5099 phantom5099 merged commit 51f4f6f into 1024XEngineer:main May 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants