Skip to content

feat: promote beta agent runtime, core extraction, and CLI hardening - #237

Merged
im10furry merged 108 commits into
mainfrom
beta
Aug 17, 2026
Merged

feat: promote beta agent runtime, core extraction, and CLI hardening#237
im10furry merged 108 commits into
mainfrom
beta

Conversation

@im10furry

@im10furry im10furry commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

概览

本 PR 将 beta 的 105 个提交推广到 main。相对 main,共涉及 809 个文件(47,457 行新增、5,860 行删除;207 新增、451 修改、8 删除、143 重命名)。这不是一次机械合并:它同时完成 core 拆包阶段、可恢复的 Agent/Goal 工作流、模型与语音能力、CLI/桌面交互稳定性、工具安全边界,以及 CI/性能门禁的收敛。

功能实现总览

领域 本次实现 实际使用价值
语音会话 新增 /voice、F10 快捷入口、MiMo ASR/TTS、转写确认与播放控制 在终端中以语音发起和继续对话,且不会跳过既有审批链路
Goal 与任务 Goal 持久化生命周期、调度、租约与恢复;TaskBatch 图执行 长任务可管理、可恢复;可验证的只读工作可并发,写操作保持串行
Agent 协作 后台任务编排、运行引导、工作区租约、跨会话消息 将协作状态和消息从临时 UI 状态收敛为可追踪的本地持久化记录
模型与登录 可复用 OAuth 运行时、Codex/Copilot/Grok 登录、MiMo 文件工具流式调用 降低登录和模型切换中的竞态,扩展模型接入路径
CLI/TUI 外部编辑器、补全、权限批量确认、快捷键、状态行和任务面板 改善日常终端操作,在 Windows 与长流式输出场景更稳定
网络与工具 多提供方 WebSearch 自动回退、WebFetch 与归档/权限/沙箱加固 提高检索可用性,并收紧网络和文件处理的失败路径

语音会话:从录音到受控执行

  • 新增实验性、macOS-first 的语音对话能力。通过 KODE_EXPERIMENTAL_VOICE=1 kode 显式开启,避免在未确认麦克风、网络和模型成本前默认暴露设备能力;CLI 同时提供 /voice 与 F10 入口。
  • /voice 采用明确的 push-to-talk 流程:本地录制短 WAV(私有临时目录)→ MiMo ASR SSE 渐进转写 → 可编辑的 Review 页面 → 用户明确 Send 后才作为普通 REPL 消息提交。录音、转写和 Review 阶段均可取消;音频请求结束或失败后不保留。
  • 回复可通过 MiMo TTS 的 SSE PCM16 流异步播放;播放不影响已完成的文本结果,新输入或 /voice stop 可以中断当前播放。对不保留 SSE 的兼容 API 仍有有界 WAV 回退。
  • 语音配置由 /voice config 管理,API Key 仅允许粘贴到 owner-only 凭据存储;环境变量(例如 MIMO_API_KEY)可供托管/CI 场景优先使用,密钥不接受命令参数,也不会写入普通配置或 shell 历史。
  • 语音文本不是隐式命令:转写必须先经用户确认,之后仍走普通 REPL、模型工具与权限确认。若语义尚不明确,Agent 先澄清;只有形成规范化 intent brief 后,才允许委派任务。
  • 面向语音委派新增受控 TaskBatch 路径:独立且验证为只读的子任务可在有界并发组中运行;带 shell、编辑、未知能力或写权限的任务保持串行。Task 子代理不能再递归调用 TaskBatch,避免并行写入与失控扇出。
  • /voice guide 可向运行中的 Agent 提交经确认的指导;/voice message 可将经确认的转写交给跨会话消息中心。二者不改变原有权限、消息持久化和投递语义。

Goal、任务与 Agent 协作

  • Goal 从命令层能力扩展为持久化生命周期:支持创建、调度、立即运行、暂停、恢复、取消和状态收敛。CLI、daemon 与 Web 控制面共享状态和租约语义,旧 run 在恢复、回收或并发切换后不能继续覆盖最新状态。
  • Agent 与后台任务新增更清晰的前后台生命周期、执行编排、工作区 lease、任务监控和运行时引导;任务持久化与协调逻辑覆盖恢复、收尾和并发场景。
  • 新增 durable cross-session messaging。/session-message/sm)提供会话发现、发送、回复、收件箱、历史/全文检索、未读状态、发送前取消和状态查询;消息按同一 canonical Git workspace 隔离并持久化,使不同时在线的本地会话也可协作。
  • 消息投递以稳定 message/thread ID、pending 文件与 receipt 驱动:失败回收、崩溃 claim 过期、恢复期去重均有处理。Agent 侧的 SessionMessage 工具继续使用正常权限流,Task 子代理不能使用它,避免隐藏消息扇出。
  • runtime 统一 Agent 编排与 session controls;engine 补充外部工具桥接、工具队列、read mode、完成证据、变更收据和工作区指纹验证。任务完成不再只依赖模型文本标记,还能附带可审计的变更证据。

模型、认证与交互体验

  • 提供可复用 OAuth 模型运行时,覆盖 Codex / ChatGPT OAuth、GitHub Copilot OAuth 与 Grok Build OAuth 的接入和模型 profile 绑定;Codex 登录增加推荐设置引导,推理强度设置与连接状态在 CLI 中可见。
  • 登录激活、OAuth 取消、连接测试和 session 恢复均加入过期结果防护,旧请求的完成结果不会回写覆盖当前选择。MiMo 模型恢复带文件工具时的流式调用,避免文件工具使响应退化为非流式。
  • CLI/TUI 修复并强化外部编辑器的单实例启动、失败恢复与生命周期守卫,覆盖 console、文件、通知、转录、task 与 plan 编辑器;Windows 下无 HOME 或 Windows 路径形式的场景可正确解析编辑器路径和恢复终端状态。
  • 补全和交互新增模糊匹配、批量权限批准、单键快捷操作;同时改善状态行、流式思考/转录展示、任务面板、会话恢复与 stale selector fork 的体验,降低长会话下的误操作和视觉跳动。

工具、安全与协议能力

  • WebSearch 支持多提供方自动回退,单一提供方异常时仍可继续返回检索结果;WebFetch 的代理 fake-IP 场景与 SSRF 防护规则协同处理,避免把合法代理路径误判为可访问内网。
  • 归档解包、项目学习存储、权限拒绝处理、沙箱和 Windows 自动化策略补齐校验与回归覆盖,限制异常输入、失败恢复和跨平台环境差异带来的错误状态。
  • protocol 与 session 层补齐 ACP JSON-RPC、流式会话导入、session messaging 和控制面类型;server、CLI、Web 继续通过共享 protocol/client 边界协作。
  • MCP Sampling 作为独立实验能力门控,避免连接到 MCP server 后隐式消耗模型配额或引入外部成本。

架构与可维护性

  • Strangler-Fig 拆包将 automation、checkpoints、constants、goals、logging、mcp、memory、message-utils、plan、runs、sandbox、tasks、types、worktrees 等 14 个领域从 core 分离为工作区包,并在 tsconfig 保留兼容别名。core 从约 107,389 行降至约 81,327 行;新增代码优先使用 @kode/* 的领域包入口。
  • runtime 承接 JSONL、request status、通知中心、响应状态和基础工具;sandbox 保持叶子包;goals、tasks、automation、worktrees 与 checkpoints 形成更清楚的持久化、调度和工作区边界。
  • 拆包并非简单移动文件:包 manifest、依赖方向和 import alias 与单元测试共同约束,应用层仍通过 engine、protocol 和 client 使用共享能力,减少对 packages/core 内部路径的直接耦合。

性能与交付质量

  • 12 项 CLI 与 2 项 CLI/Web 性能收敛覆盖完整流式交互路径:限制 live stream preview、节流状态行更新、跳过隐藏 selector 测量、memoize 运行中任务面板、复用空进度状态,并精简转录工具状态。
  • 刷新和补全路径增加后台任务刷新限流、非激活 completion 刷新跳过、文件补全扫描收敛;prompt queue props 稳定化、prompt status 汇总合并、live tool progress 索引化,降低频繁状态更新造成的重渲染。
  • Web 侧同步优化流式转录交互与状态更新,长输出时减少无效组件工作并维持可见进度。
  • 新增性能门禁和基准脚本;CI 的三个 OS job 将独立测试文件限制为 3 个 worker,在不取消“每文件独立 Bun 进程”隔离的前提下缩短关键路径。AgentSupervisor 的 unref 定时器测试加入确定性 watchdog,避免 Windows 上耗尽 120 秒文件超时。
  • unit coverage 改为隔离汇总,避免跨 runner 的 module mock 或可变全局状态被误算为覆盖率。

本地验证

  • bun install --frozen-lockfile
  • bun run format:check
  • bun run lint
  • bun run typecheck
  • CI=true KODE_TEST_CONCURRENCY=3 bun run test:548/548 通过,56.3 秒
  • bun run build

im10furry and others added 28 commits August 12, 2026 23:58
Squashed from PR #217-#230: guard editor/clipboard/notifications/task
launches, ignore stale async results (OAuth, login, discovery,
connection tests, session clipboard), recover prompt preparation and
external editor failures, cancel in-flight requests on unmount, and
stabilize view transitions with e2e coverage.
Squashed perf(cli) and perf(web) work: bound live stream preview
rendering, throttle status line usage updates, skip hidden selector
measurements, memoize running task panel, limit background task
refreshes, streamline completion scans and transcript tool state, and
smooth streamed transcript interaction.
Squashed AI/client fixes: sync OpenAI stream mirror, accept growing
streamed snapshots, bound provider retry delays, and clarify bounded
daemon errors.
Squashed parallel work: secret handling hardening across CLI and
server, quality gate enforcement, lint cleanup, and CI workflow
updates.
Verification gate: only passed checks count as terminal evidence, and
auto-compact no longer discards in-flight mutation receipts. Sync
snapshot deduplication into the ai adapter. Harden WebFetch against
0.0.0.0/8 SSRF, bound zip decompression with a byte budget, log silent
model deactivations, fix lock ownership in project learning and goal
storage, add polling timeouts, LSP module resolution fallbacks, and
external editor fallback with tilde expansion.
Compact the project learning event log and trim context snapshots so
long sessions cannot grow disk usage and replay cost without bound,
treat Skill use as a potential workspace write, and detect
case-only path collisions on case-folding file systems.
Drop the completion gate that required a passed test, typecheck, lint,
build, or check receipt after workspace mutations, along with the
verification recovery prompt, receipt generation, evidence collection,
and goal-level verification enforcement. Behavior now matches standard
agent workflows without forced verification.
# Conflicts:
#	apps/cli/src/ui/components/LoginScreen.tsx
#	apps/cli/src/ui/screens/REPL/AssistantStreamPreview.test.tsx
#	apps/cli/src/ui/screens/REPL/AssistantStreamPreview.tsx
#	apps/cli/src/ui/screens/REPL/useReplController.tsx
#	apps/cli/src/ui/screens/overlays/TasksScreen.tsx
#	packages/ai/src/llm/openai/stream.ts
#	packages/core/src/ai/llm/openai/stream.ts
#	packages/core/src/constants/prompts.ts
#	packages/core/src/goals/goals.test.ts
#	packages/core/src/goals/service.ts
#	packages/core/src/test/e2e/tui-interactions.login.test.tsx
#	packages/core/src/test/e2e/tui-interactions.tasksScreen.test.tsx
#	packages/core/src/test/unit/goal-run-engine.test.ts
#	packages/core/src/test/unit/openai-stream-snapshot-dedupe.test.ts
#	packages/engine/src/message-pipeline.ts
#	packages/engine/src/pipeline/tool-call.ts
#	packages/engine/src/pipeline/tool-call.verification.test.ts
#	packages/engine/src/verification/completion-gate.test.ts
#	packages/engine/src/verification/evidence.test.ts
#	packages/engine/src/verification/evidence.ts
#	packages/engine/src/verification/receipt.test.ts
#	packages/engine/src/verification/receipt.ts
…-key shortcuts

Input efficiency:
- Slash commands: fuzzy abbreviation/subsequence matching (e.g. /aprv -> approved-tools) with prefix priority and single-char guard
- File paths: fuzzy fallback behind prefix matches when typing 2+ chars
- History search (Ctrl+R): substring matches ranked first, fuzzy matches fill in

Permission UX:
- Queue pending permission requests instead of clobbering the single dialog slot (pure transition helper with tests)
- Batch action bar when requests queue up: Ctrl+A allow all, Ctrl+D deny all
- Single-key accelerators in every select-based dialog: y allow once, a always allow, n deny
- Dialog footers document the new shortcuts

All guarded by unit tests (queue transitions, shortcut resolution, fuzzy matching).
Keep the most recent completed messages in the bottom-anchored transient
frame instead of freezing them into the top <Static> scrollback. Long
conversations no longer push finished output above the visible viewport
while new work streams in below; output now grows bottom-up like a chat.
Tiny viewports (<=4 rows) keep the previous all-static behavior.
The completed transient messages kept in the bottom-anchored frame could
consume the whole preview budget, pushing the live streamed output out of
the viewport so the answer appeared only after completion. Reserve the
live preview's own height at the bottom of the frame and give the
completed-message region the remaining budget, with a zero budget when
nothing is streaming.
MiMo + Write/Edit tools forced the whole request to the non-streaming
endpoint, so every reply (even plain chat) appeared at once. Stream is
now always enabled; if the stream degrades mid-flight (MiMo's SSE can
terminate during large tool-call arguments), the retry loop re-issues the
request through the non-streaming endpoint instead, preserving completion
integrity without sacrificing the interactive stream.
DuckDuckGo is unreachable or returns empty in some networks, which made
every web search report zero results. Search now runs DuckDuckGo, Bing,
and Baidu in parallel (6s timeout each), merges de-duplicated hits from
every reachable provider, and reports which providers contributed in the
progress line. Protocol-relative DuckDuckGo redirect links are also
unwrapped to their real destinations.
DNS under Clash/Surge fake-ip returns 198.18.0.0/15 (RFC 2544
benchmarking) addresses for every hostname. The guard rejected that
range, so all web fetches failed with 'non-public network address' even
for legitimate sites. The range is never routed on the public internet
and cannot reach internal networks; proxy stacks forward traffic to the
already-validated hostname, so it is now explicitly allowed.
@im10furry
im10furry merged commit 629eae5 into main Aug 17, 2026
@im10furry
im10furry deleted the beta branch August 17, 2026 09:39
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.

1 participant