Skip to content

feat: Web 端接入思考流展示,修复 checkpoint/verify/文件变更等核心问题#569

Merged
phantom5099 merged 11 commits into1024XEngineer:mainfrom
Yumiue:html_gui_build
May 7, 2026
Merged

feat: Web 端接入思考流展示,修复 checkpoint/verify/文件变更等核心问题#569
phantom5099 merged 11 commits into1024XEngineer:mainfrom
Yumiue:html_gui_build

Conversation

@Yumiue
Copy link
Copy Markdown
Collaborator

@Yumiue Yumiue commented May 7, 2026

主要功能增强

1. Web 端接入思考流展示

  • 新增 ThinkingDelta 事件处理,支持模型思考过程的实时流式展示
  • eventBridge.ts 中添加思考消息的开始、追加、完成逻辑
  • ChatStore 新增 startThinkingMessageappendThinkingChunkfinalizeThinkingMessage 方法
  • 思考消息在 AgentChunk 开始前自动终结,避免与输出消息冲突

2. Checkpoint 体验优化

  • 重构 CheckpointInlineMark.tsx 组件(283 行改动),增强内联标记的交互和渲染
  • 新增 markAllCheckpointsRestoredmarkAllCheckpointsAvailable 方法,支持批量状态更新
  • 优化 checkpoint restore/undo restore 的事件处理流程
  • 修复 checkpoint 警告信息的展示逻辑

重要 Bug 修复

3. Verify 死循环修复

  • 修复 todo_run_boundary.go 中验证最后 todo 时的死循环问题
  • acceptance_service.go 中新增验收服务,完善验证流程
  • 优化 VerificationStarted 事件处理,当 completion_passed=false 时跳过创建验证消息

4. 文件变更去重

  • eventBridge.ts 中新增 normalizeFilePath 函数,统一文件路径格式
  • 修复 ToolStart 占位条目与 ToolDiff 真实条目无法命中同一 dedup key 的问题
  • 支持 Windows 下大小写不敏感比较,处理工作区相对路径

5. 模型错误提示

  • StopReasonDecided 事件中新增 fatal_error 的错误提示 toast
  • 修复模型调用失败时用户无感知的问题

6. Electron 构建修复

  • 修复 electron-builder.config.cjs 构建顺序问题
  • 解决 portable 版本自动更新相关问题

其他改进

7. Todo 重写规则增强

  • 适应上游新更改,增强 todo 重写的规则
  • 优化 todo_run_boundary_test.go 测试覆盖

8. 输出渲染优化

  • 优化 MarkdownContent.tsx 的渲染逻辑(72 行改动)
  • 改进 CodeBlock.tsx 的代码块展示

9. 协议与状态管理

  • protocol.ts 新增事件类型定义
  • useChatStore.ts 新增 105 行状态管理逻辑
  • useSessionStore.ts 优化会话状态处理

改动统计

  • 20 个文件修改
  • 新增 682 行,删除 182 行
  • 主要涉及 internal/runtime/web/src/ 两个核心目录

测试覆盖

  • 修改 todo_run_boundary_test.go,确保验证逻辑的正确性
  • 其他相关测试同步更新

Yumiue and others added 11 commits May 7, 2026 09:18
- 调整 build:electron 脚本顺序:先 vite build 生成 dist 产物,再编译网关,
  保证 webembed 嵌入的是最新前端资源
- 在 setupAutoUpdater() 中检测 PORTABLE_EXECUTABLE_DIR,portable 模式下
  跳过自动更新检查,避免 NSIS 不支持的更新流程误导用户

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

❌ Patch coverage is 54.65116% with 39 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/runtime/acceptance_service.go 0.00% 21 Missing and 2 partials ⚠️
internal/runtime/streaming/accumulator.go 0.00% 8 Missing ⚠️
internal/runtime/checkpoint_restore.go 80.64% 6 Missing ⚠️
internal/runtime/streaming/handler.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

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.

I found 3 noteworthy logic regressions in the changed paths. go test ./internal/runtime/... passes locally, but these cases are not covered by the current tests.

}
// 当存在 required TODO 且全部已终态时,清除 unverified writes 标记。
// required TODO 全部收敛本身就证明工作已完成,无需额外 verification tool 调用。
if !current.HasPendingAgentTodos && hasCompletedRequiredTodos(state.session.Todos) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

HasUnverifiedWrites is being cleared purely because all required todos are terminal. That lets a run complete after a successful write + todo_write set_status=completed even if no verification tool ever ran, which bypasses the existing unverified_write completion gate. Todo convergence is not equivalent to verification, so this reintroduces false-positive acceptance for code changes.

case EventType.CheckpointRestored: {
const payload = eventPayload as CheckpointRestoredPayload | undefined
if (payload) insightStore.addCheckpointEvent(payload)
chatStore.markAllCheckpointsRestored()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This ignores payload.checkpoint_id and marks every available checkpoint in the chat as restored. In a session with multiple checkpoints, restoring one checkpoint will flip unrelated inline marks to 已撤回, and checkpoint_undo_restore later flips all of them back. The update needs to target only the restored checkpoint (and probably the guard checkpoint involved in undo), not the whole message list.

Comment thread internal/runtime/todo_run_boundary.go
@phantom5099
Copy link
Copy Markdown
Collaborator

  1. acceptance_service.go:新增 "verification 全过直接
    accepted" —— 绕过 decider 而非修复它

if input.CompletionPassed && verificationGate.Passed {
output.Status = acceptance.AcceptanceAccepted
...
}

问题:这没有修复 decider 本身的层级冲突和零门槛问题,而是在
decider 之上再套一层 bypass。decider 的 DecisionAccepted
仍然可以被 Completion Gate 降级为
AcceptanceContinue,这个补丁只是说"如果 verifier
通过了,就无视 decider"。

这等于承认 decider
不可信,但选择绕过而非重建。在我们之前的分析中,chat/read-only
零门槛、完成声明不参与决策等根因完全没有被触及。

  1. acceptance_service.go:<stale_todo_reset> 提示 ——
    把系统问题推给模型

if output.Status == acceptance.AcceptanceContinue &&
input.NoProgressStreak >= 2 &&
input.Todos.Summary.RequiredOpen > 0 {
staleHint := buildStaleTodoResetHint(...)
}

问题:不是修复 todo 遗留的根因(Run 终止不清理
todo、shouldResetTodosForUserRun
误判),而是让模型在死循环时自己判断哪些 todo 该取消。

模型不可能准确判断哪些 todo 属于"上一个任务",这会导致:

  • 误取消本应该完成的 todo
  • 或者模型忽略提示继续死循环

这是典型的症状治疗。

  1. todo_run_boundary.go:语义反转 ——
    从"默认清空"变成"默认保留",问题加剧

旧逻辑(当前 main):

  • 默认清空 todo
  • 续做意图("继续/接着")保留

PR 569 新逻辑:

  • 默认保留 todo
  • 只有明确新任务("新任务/换任务")才清空

问题:这是方向性错误。我们之前分析指出
shouldResetTodosForUserRun 的 bug 是空输入/前缀误判导致旧 todo
被保留。这个 PR 把它改成了几乎所有输入都保留旧 todo,使旧
todo 遗留的概率大幅增加。

现在用户说"修复登录 bug"——旧
todo("修改配置")被保留;用户说"看看这段代码"——旧 todo
被保留。然后模型陷入"新任务 + 旧 todo 未完成 =
死循环"的概率会更高。

stale_todo_reset 只是这个错误决策的事后补救。

  1. turn_control.go:todo 全完成时忽略未验证写入 —— 危险的捷径

if !current.HasPendingAgentTodos &&
hasCompletedRequiredTodos(state.session.Todos) {
current.HasUnverifiedWrites = false
}

问题:只要 todo 列表打勾了,未验证的文件写入也视为通过。模型可
能写入代码但编译失败/测试失败,就因为 todo
状态满足就直接通过验收。

@phantom5099
Copy link
Copy Markdown
Collaborator

  1. acceptance_service.go:新增 "verification 全过直接
    accepted" —— 绕过 decider 而非修复它

if input.CompletionPassed && verificationGate.Passed { output.Status = acceptance.AcceptanceAccepted ... }

问题:这没有修复 decider 本身的层级冲突和零门槛问题,而是在 decider 之上再套一层 bypass。decider 的 DecisionAccepted 仍然可以被 Completion Gate 降级为 AcceptanceContinue,这个补丁只是说"如果 verifier 通过了,就无视 decider"。

这等于承认 decider 不可信,但选择绕过而非重建。在我们之前的分析中,chat/read-only 零门槛、完成声明不参与决策等根因完全没有被触及。

  1. acceptance_service.go:<stale_todo_reset> 提示 ——
    把系统问题推给模型

if output.Status == acceptance.AcceptanceContinue && input.NoProgressStreak >= 2 && input.Todos.Summary.RequiredOpen > 0 { staleHint := buildStaleTodoResetHint(...) }

问题:不是修复 todo 遗留的根因(Run 终止不清理 todo、shouldResetTodosForUserRun 误判),而是让模型在死循环时自己判断哪些 todo 该取消。

模型不可能准确判断哪些 todo 属于"上一个任务",这会导致:

  • 误取消本应该完成的 todo
  • 或者模型忽略提示继续死循环

这是典型的症状治疗。

  1. todo_run_boundary.go:语义反转 ——
    从"默认清空"变成"默认保留",问题加剧

旧逻辑(当前 main):

  • 默认清空 todo
  • 续做意图("继续/接着")保留

PR 569 新逻辑:

  • 默认保留 todo
  • 只有明确新任务("新任务/换任务")才清空

问题:这是方向性错误。我们之前分析指出 shouldResetTodosForUserRun 的 bug 是空输入/前缀误判导致旧 todo 被保留。这个 PR 把它改成了几乎所有输入都保留旧 todo,使旧 todo 遗留的概率大幅增加。

现在用户说"修复登录 bug"——旧 todo("修改配置")被保留;用户说"看看这段代码"——旧 todo 被保留。然后模型陷入"新任务 + 旧 todo 未完成 = 死循环"的概率会更高。

stale_todo_reset 只是这个错误决策的事后补救。

  1. turn_control.go:todo 全完成时忽略未验证写入 —— 危险的捷径

if !current.HasPendingAgentTodos && hasCompletedRequiredTodos(state.session.Todos) { current.HasUnverifiedWrites = false }

问题:只要 todo 列表打勾了,未验证的文件写入也视为通过。模型可 能写入代码但编译失败/测试失败,就因为 todo 状态满足就直接通过验收。

这个你看看,要不这个PR我直接合,刚好把这些修了

@phantom5099 phantom5099 merged commit c2964d4 into 1024XEngineer:main May 7, 2026
2 of 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