Skip to content

feat(runtime):增加build/plan模式#519

Merged
pionxe merged 6 commits into1024XEngineer:mainfrom
phantom5099:0429-planMode
May 1, 2026
Merged

feat(runtime):增加build/plan模式#519
pionxe merged 6 commits into1024XEngineer:mainfrom
phantom5099:0429-planMode

Conversation

@phantom5099
Copy link
Copy Markdown
Collaborator

Summary

本次改动围绕新增正式的 plan/build 后端机制展开,目标是在现有主链路上补齐一套可落地、可持久化、可复用的 planning 语义,让系统不仅能执行任务,也能稳定承载“规划”“计划复用”“计划审批”和“计划完成收口”。

本次改动只涉及后端链路:

  • session
  • runtime
  • context
  • promptasset

本次不修改 TUIgateway 的现有 contract,只先把后端接口、状态和运行语义补齐。


原来存在的问题

当前后端缺少正式的 plan/build 模式。

系统原本只有统一的执行主链路,没有一套明确的 planning 领域模型、运行阶段语义和 prompt 注入机制来表达下面这些能力:

  • 当前回合是在规划还是在执行
  • 当前是否存在一份可复用的完整计划
  • 执行时应该注入计划摘要还是完整计划
  • 计划何时被批准、何时完成、何时需要重新对齐

这意味着“规划”只能散落在消息历史里,无法作为稳定的会话对象被保存、复用和收口,也无法为后续上层接入提供可靠后端基础。


采取的解决方案

本次方案的核心是:

  • AgentMode 表达当前工作模式
  • CurrentPlan 表达当前完整计划
  • SummaryView 表达默认注入给模型的紧凑计划摘要
  • 用 runtime 状态机控制计划创建、审批、完成和完整计划注入
  • 用独立的 context source 和 prompt 模板把这些状态稳定投影给模型

具体语义如下:

1. 新增正式的 plan/build 模式

在会话层新增 AgentMode,明确区分:

  • plan
  • build

plan 用于分析、调研、创建或重写完整计划。
build 用于执行任务,不负责重写完整计划。

2. 新增会话级 CurrentPlan

在会话层新增正式的计划模型,核心包括:

  • PlanArtifact
  • PlanSpec
  • SummaryView
  • PlanStatus

其中:

  • PlanSpec 表示完整计划正文
  • SummaryView 表示摘要视图
  • PlanStatus 表示计划生命周期状态
  • RevisionLastFullPlanRevision 用于判断全文是否已经重新对齐

3. 明确 SummaryView 的来源

SummaryView 不是额外维护的一份独立手写文档,而是围绕 PlanSpec 生成和归一化出来的紧凑投影。

当前实现里,SummaryView 的来源分成两层:

  • 第一层:assistant 在 planning JSON 中可显式返回 summary_candidate
  • 第二层:runtime/session 会对这个摘要做归一化校验;如果摘要缺字段、结构不合法,或根本没有提供,就回退到基于 PlanSpec 确定性投影出来的 BuildSummaryView(...)

BuildSummaryView(...) 本身不是额外的智能摘要算法,而是按固定字段映射从 PlanSpec 生成摘要:

  • Goal <- PlanSpec.Goal
  • KeySteps <- PlanSpec.Steps
  • Constraints <- PlanSpec.Constraints
  • Verify <- PlanSpec.Verify
  • ActiveTodoIDs <- PlanSpec.Todos[*].ID

这样做的目的有两个:

  • 让模型在规划时可以主动给出更贴近当前语义的摘要
  • 同时保证后端始终能够从完整计划稳定推出一份可注入、可持久化的摘要,不依赖模型每次都写对

因此,执行态默认使用的 SummaryView 本质上是“由完整计划字段投影出来、且经过后端归一化兜底”的摘要,而不是另一套独立状态。

4. 只允许在 plan 模式创建或重写完整计划

runtime 现在只会在 plan 模式下消费结构化 plan_spec + summary_candidate,并创建或重写 CurrentPlan

build 模式下即使模型输出了类似 planning JSON 的内容,也不会改写 CurrentPlan,而是按普通输出处理。

5. 补齐 draft / approved / completed 生命周期

本次把计划状态机补成正式闭环:

  • draft:当前计划存在,但用户尚未确认当前 revision
  • approved:用户已确认当前 revision
  • completed:当前 revision 对应任务已完成

并补充这些规则:

  • plan 模式创建或重写计划时,状态统一落为 draft
  • 通过显式后端接口 ApproveCurrentPlan(...),可将 draft -> approved
  • draftapproved 都允许在完成条件满足时进入 completed
  • 计划正文一旦变化,无论原状态是什么,都会生成新 revision 并回到 draft

6. 用 runtime 状态控制完整计划注入

默认情况下,执行阶段优先注入 SummaryView,避免每轮都发送完整计划。

只有在以下状态下,runtime 才会升级为 full plan 注入:

  • SummaryView 不可用
  • CurrentPlan.Revision > LastFullPlanRevision
  • PlanApprovalPendingFullAlign == true
  • PlanCompletionPendingFullReview == true
  • PlanContextDirty == true
  • PlanRestorePendingAlign == true

同时补齐了两类环境触发:

  • compact 成功应用后,标记 PlanContextDirty
  • 会话恢复后的首个相关回合,标记 PlanRestorePendingAlign

7. 审批和完成后都强制做一次完整对齐

为了让“批准”和“完成”真正影响执行上下文,本次新增两种一次性全文对齐:

  • draft -> approved 后,下一轮强制注入一次 full plan
  • 首次进入 completed 后,下一轮也强制注入一次 full plan 做完成确认

对齐完成后,这些一次性标记会被清理,后续回到摘要优先。

8. 收紧 plan/build 提示词

为了避免模型随意改计划,本次同步收紧了两套模板:

  • plan 模式:
    • 可以分析、调研、回答问题
    • 只有在明确创建或重写完整计划时才输出 planning JSON
  • build 模式:
    • 只执行,不创建、不重写完整计划
    • 若认为当前计划失准,只能解释偏差或建议切回 plan
    • 计划完成时通过结构化完成信号回传,而不是自然语言猜测

具体修改范围

session

涉及文件:

  • internal/session/plan.go
  • internal/session/plan_test.go
  • internal/session/store.go
  • internal/session/sqlite_store.go
  • internal/session/store_test.go

本次新增或调整:

  • AgentMode
  • CurrentPlan
  • PlanArtifact / PlanSpec / SummaryView / PlanStatus
  • LastFullPlanRevision
  • PlanApprovalPendingFullAlign
  • PlanCompletionPendingFullReview
  • PlanContextDirty
  • PlanRestorePendingAlign
  • 计划相关的 SQLite 持久化与 schema migration

runtime

涉及文件:

  • internal/runtime/planning.go
  • internal/runtime/planning_test.go
  • internal/runtime/run.go
  • internal/runtime/runtime.go
  • internal/runtime/plan_approval.go
  • internal/runtime/runtime_test.go
  • internal/runtime/session_scheduler.go
  • internal/runtime/compact.go
  • internal/runtime/input_prepare.go
  • internal/runtime/permission.go
  • internal/runtime/session_mutation.go
  • internal/runtime/state.go
  • internal/runtime/budget_models.go

本次新增或调整:

  • plan/build 运行阶段判定
  • 只读 planning 边界
  • 结构化计划解析
  • 结构化完成信号解析
  • CurrentPlan 的创建、重写、审批、完成推进
  • full plan 注入判定
  • compact 后计划上下文重新对齐
  • 恢复后计划上下文重新对齐
  • 显式后端审批接口 ApproveCurrentPlan(...)

context

涉及文件:

  • internal/context/builder.go
  • internal/context/builder_test.go
  • internal/context/source_plan_mode.go
  • internal/context/types.go

本次新增或调整:

  • plan/build context source 注册
  • BuildInput 中的 planning 相关字段
  • Plan ModeCurrent Plan 的 prompt 投影
  • 按需注入 full_plan_view

promptasset

涉及文件:

  • internal/promptasset/assets.go
  • internal/promptasset/assets_test.go
  • internal/promptasset/templates/context/plan_mode_plan.md
  • internal/promptasset/templates/context/plan_mode_build_execute.md

本次新增或调整:

  • plan/build 模式模板入口
  • 规划态提示词约束
  • 执行态禁止改写计划的提示词约束
  • 结构化完成信号提示

预期收益

用户角度

1. 规划和执行第一次被正式区分

用户后续可以明确地进入“先规划,再执行”或“直接执行”的不同工作流,而不是把规划内容混在普通消息里。

2. 当前计划可以稳定保存和复用

一旦计划形成,用户后续可以围绕同一份 CurrentPlan 持续执行、查看摘要、审批 revision、确认完成,而不是每次都重新描述目标。

3. 执行态上下文更稳

默认走摘要注入,只有在审批、完成确认、compact 或恢复等需要重新对齐的时候才升级为 full plan,能减少上下文噪音,也更符合长任务执行体验。

4. 计划状态对用户可解释

draft / approved / completed 给后续交互提供了明确语义,用户可以理解当前计划是“未确认”“已确认”还是“已完成”,而不是只看到一堆隐式历史消息。

开发者角度

1. planning 语义第一次成为正式后端模型

plan/buildCurrentPlanSummaryView 和相关状态位都已经进入 session/runtime/context 的正式结构里,planning 不再依赖零散消息约定。

2. 摘要和全文有了统一后端规则

SummaryView 现在由 summary_candidateBuildSummaryView(...) 两层机制保证;其中后者是对 PlanSpec 的确定性字段投影,开发侧不需要再假设模型每次都能自己稳定写出可用摘要。

3. 全文注入条件可测试、可扩展

full plan 是否注入现在由明确状态驱动,compact/恢复/审批/完成这些行为也都有固定触发点,后续演进不需要再靠自然语言猜测。

4. 为上层接入提供稳定后端锚点

即使当前不修改 TUI/gateway,后端已经具备承载模式切换、计划展示、审批、完成态展示和全文查看的正式基础。


TUI / Gateway 后续可接入内容

本次不要求上层立即接入,但后端已经为后续接入预留了清晰能力:

1. 模式切换

上层后续可以显式传递:

  • plan
  • build

从而驱动不同的 runtime 语义。

2. 当前计划展示

上层后续可以展示 CurrentPlan.Summary,包括:

  • 当前目标
  • 关键步骤
  • 验证标准
  • 活跃待办关联

3. 计划审批

后端已经暴露显式接口:

  • ApproveCurrentPlan(sessionID, planID, revision)

上层后续只需要在合适的交互点调用,不必再定义新的后端状态机。

4. 完整计划查看

当前已经有 SummaryView / full_plan_view 双层机制,上层后续可以基于这些字段提供“查看摘要”和“查看完整计划”的界面能力。

5. 完成态展示

后续可以根据 PlanStatus 展示:

  • draft
  • approved
  • completed

并在执行结束后反映当前计划是否已经完成收口。


非目标

本次不处理:

  • TUI / gateway 的实际协议和 UI 改造
  • 更复杂的计划历史管理
  • 按 step 级别强绑定执行
  • 基于执行失配的全文注入触发

#511

@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.

Completed 4-pass review (code quality, performance, security, documentation).

Noteworthy findings:

  1. A strict JSON extraction path can fail the whole run when assistant output contains braces or a "task_completion" mention but no valid JSON object.
  2. Compaction detection now scans and renders the entire transcript on every session load, which can become expensive for long histories.

No additional security or documentation-accuracy issues were identified beyond the inline comments.

Comment thread internal/runtime/planning.go Outdated
Comment thread internal/runtime/session_scheduler.go Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

@phantom5099
Copy link
Copy Markdown
Collaborator Author

/code 提高测试覆盖率,并提交PR到fork仓库

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 30, 2026

完成情况

已按你的要求提升测试覆盖率并推送到 fork。

本次改动

  • 新增 internal/context/builder_test.go 用例:覆盖 NewBuilderWithMemoAndSummarizers(...) 构造路径。
  • 新增 internal/runtime/planning_test.go 用例:覆盖计划状态边界/错误分支,包括:
    • markCurrentPlanRestorePending / markCurrentPlanContextDirty 的空计划、幂等、completed 状态分支
    • applyCurrentPlanRevision 的 nil guard
    • approveCurrentPlan 的校验失败分支(无计划、ID 不匹配、revision 不匹配、状态不允许)
  • 新增 internal/runtime/runtime_test.go 用例:覆盖 Service.ApproveCurrentPlan(...) 的上下文取消分支与 SessionID trim 分支。

验证

  • 执行:go test ./internal/context ./internal/runtime ./internal/session ./internal/tools(通过)
  • 覆盖率复测:
    • internal/runtime 91.9%
    • internal/context 93.9%
    • internal/session 85.2%
    • internal/tools 91.9%

提交与推送

View job run

xgopilot and others added 2 commits April 30, 2026 04:05
Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: phantom5099 <245659304+phantom5099@users.noreply.github.com>
test: improve coverage for plan/build runtime changes
@pionxe pionxe merged commit b42d4ac into 1024XEngineer:main May 1, 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.

3 participants