Repository navigation
Conversation
🦋 Changeset detectedLatest commit: 634970d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
commit: |
There was a problem hiding this comment.
🔵 Needs a closer look
It reworks core skill-prompt submission, steering, and replay semantics across the SDK contract and four packages, so it needs human sign-off despite its extensive test coverage.
0 open findings
What changed in this PR
This PR unifies the terminal UI's skill-prompt entry points so that leading single-skill commands, inline mentions, and multi-skill inputs all flow through one path (resolveUserInput → Session.promptWithSkills), rather than splitting between the old activateSkill and promptWithSkills routes. It preserves the full user text, highlights activated skill markers instead of rendering separate "user skill" activation cards, and extends Ctrl-S steering to cover combined/skill inputs. A new optional steerIfActive flag is plumbed through the SDK, RPC, klient contract, and the agent-core-v2 engine so a bundled submission can be injected into a running turn.
Changes:
- Add
steerIfActivetopromptWithSkillsend-to-end (node-sdk → rpc → klient schema →AgentSkillService), injecting into the active turn when running and queuing otherwise. - Replace the per-skill activation-card rendering for user-slash skills with a single highlighted user transcript entry (live + replay), tracked via
seenSkillActivationIds; model-tool activations still render cards. - Rewrite TUI queue steering into a serial, group-aware
steerQueuedMessagesIntoRunningTurn(manual)that preserves failed/subsequent items and manages media leases; removesendSkillActivation/steerSkillActivationandQueuedMessage.mode: 'skill'. - Add
inTurnorigin flag so steered in-turn appends are not miscounted as new user turns, and sync EN/ZH skill docs plus a minor changeset.
| File | Description |
|---|---|
packages/node-sdk/src/session.ts / rpc.ts / sdk-rpc-client-v2.ts |
Add optional steerIfActive to the public promptWithSkills contract and RPC input. |
packages/node-sdk/src/replay.ts / context.ts |
Treat inTurn user messages as not starting a new replay turn; add inTurn? to origin types. |
packages/klient/src/contract/agent/schemas.ts |
Accept optional steerIfActive on the wire. |
packages/agent-core-v2/src/features/skill/skillService.ts / skill.ts |
Steer bundled submission into the running turn when requested, else queue. |
apps/kimi-code/src/tui/commands/resolve.ts / dispatch.ts |
Unify input resolution; argument binding only for a single leading mention. |
apps/kimi-code/src/tui/kimi-tui.ts |
Serial queue steering, skill-arg media preparation/leases, failure/recall handling, highlighted user entries. |
apps/kimi-code/src/tui/controllers/editor-keyboard.ts |
Ctrl-S queues the draft then delegates to the coordinator's manual steer. |
apps/kimi-code/src/tui/controllers/session-replay.ts / session-event-handler.ts |
Render user-slash skills as user prompts; rename to seenSkillActivationIds. |
apps/kimi-code/src/tui/components/messages/user-message.ts / sticky-user-message.ts |
Highlight activated skill tokens in the user message and Fullscreen summary. |
apps/kimi-code/src/tui/utils/{message-replay,inline-skill-tokens}.ts, types.ts |
Prompt-text reconstruction, leading namespaced-slash tokenization, queue/steer type updates. |
docs/{en,zh}/customization/skills.md, .changeset/unify-skill-prompts.md |
Document the unified invocation/Ctrl-S behavior and add a minor changeset. |
| Test files (TUI, node-sdk, klient, agent-core-v2) | Extensive coverage of parsing, steering, media, replay, and the new contract option. |
I traced the argument/dedup rules, the serial steering state machine, media-lease handoff on success/failure/recall, the replay dedup via seenSkillActivationIds, and the steerIfActive plumbing against the included tests, and did not find a concrete defect to flag. The change is nonetheless broad and high-risk: it alters the core prompt-submission semantics that every skill user hits, changes a public SDK method contract, and rewrites the steering/replay paths across four packages.
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2bcc7313d7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep them coming! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 95f413f82f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0906abe0df
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e889df4bc0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 634970db73
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| this.imageStore, | ||
| MEDIA_INGESTION_SUBMIT_WAIT_MS, | ||
| ); | ||
| if (ingestionWait !== undefined) await ingestionWait; |
There was a problem hiding this comment.
Guard the media wait against session switches
When a user submits a newly routed leading skill with an uploading video and then runs /new or switches sessions during this added await, the TUI remains idle and permits the switch; after the wait, the code reads the now-current this.session and the reset image store, so the earlier command can be sent to the new session—often with its media placeholder left literal—instead of being cancelled or restored. Capture the originating session and abort/restore if it changes before extraction and dispatch.
AGENTS.md reference: AGENTS.md:L114-L116
Useful? React with 👍 / 👎.
| prepared.skills.push({ name: activation.skillName }); | ||
| continue; | ||
| } | ||
| const rewrite = rewriteMediaPlaceholders(activation.args, this.imageStore, 'plain'); |
There was a problem hiding this comment.
Preserve skill media args across cache-hint session resets
When the cache-expiry dialog intercepts a sole leading skill such as /skill:review [image #1 …] and the user chooses “Start a new session,” createNewSession clears the image store and makeExtractionResendable only rebuilds the prompt parts, clearing the attachment IDs. This newly deferred rewrite therefore cannot resolve the placeholder in the activation arguments, so the model receives the image part but the expanded skill's ARGUMENTS contains the unusable literal placeholder; materialize or preserve the skill-argument media before resetting the session.
AGENTS.md reference: AGENTS.md:L114-L116
Useful? React with 👍 / 👎.
| if (tokens.length === 1 && tokens[0]?.start === 0) { | ||
| return { | ||
| intent, | ||
| activations: [{ skillName: activations[0]!.skillName, args: text.slice(tokens[0].end).trim() }], |
There was a problem hiding this comment.
Preserve literal multiline prompts after leading skill tokens
For an existing input such as /skill:review\nexplain this or /skill:review\texplain this, parseSlashInput previously treated the whole newline/tab-containing name as an unknown command, and the single-token bundle path deliberately fell through to a normal literal message. This new condition instead recognizes the leading token and binds all remaining text as skill arguments, silently expanding a skill for prompts that previously did not activate one, despite the PR declaring the existing argument rules preserved; restrict argument binding to inputs that the leading slash parser actually resolved as a skill.
AGENTS.md reference: AGENTS.md:L98-L100
Useful? React with 👍 / 👎.
| skill_name: leading.skillName, | ||
| }); | ||
| } | ||
| void host.sendInlineSkillUserInput(text, activations); |
There was a problem hiding this comment.
Revalidate queued video references before skill dispatch
A leading skill with pasted video submitted while another turn or compaction is active now enters the shared prompt queue instead of the old path that immediately copied the video to a durable local cache path. If the queue outlives the daemon upload's expiry, dispatch refreshes only image references and reuses the stale video_url, causing the entire skill request to fail even though its local source could still have been materialized; refresh/re-extract videos at dequeue or preserve the old cache copy when enqueueing. Fresh evidence beyond the earlier immediate-upload issue is that this queue-drain path never calls the expiry check in videoPartForAttachment.
AGENTS.md reference: AGENTS.md:L114-L116
Useful? React with 👍 / 👎.
Requirement or Bug
统一终端界面中行首、正文内和多 Skill 输入的提交、Ctrl-S 投递、显示与历史恢复,保留完整原文及现有参数规则。
Bug Reproduction Steps
N/A
Root Cause
N/A
Code Changes
行首单 Skill 原先走
activateSkill,正文内和多 Skill 走promptWithSkills;Ctrl-S 没有贯通组合输入的投递选项。本次统一终端用户输入入口,不删除外部activateSkillAPI。flowchart TD subgraph TUI Input[Enter 或 Ctrl-S] --> Parse[resolveUserInput] Parse --> Payload[完整原文和 Skill 列表] Render[用户原文和 Skill 高亮] end subgraph SDK Payload --> Submit[Session.promptWithSkills] end subgraph klient Submit --> Contract[组合输入和 steerIfActive] end subgraph core Contract --> Prepare[校验并展开全部 Skill] Prepare --> Loop[loop.submit] end Loop --> RendersteerIfActive贯通 SDK、RPC、klient 和 core,依据实际投递结果处理队列。blocked结果转为明确拒绝,复用现有 TUI 失败恢复;覆盖行首单 Skill、正文内、多 Skill 及空闲 Ctrl-S。inTurn,区分正常用户轮与轮内追加输入。skill_activation命令,组合输入会显示展开指令。恢复时按指令 part 的来源标记过滤;没有 part 标记的旧组合记录沿用激活列表所确定的前导指令边界。原文、媒体、旧单 Skill 命令还原、Hook 输出与用户自写 XML 保留,不改保存的数据或模型输入。WaitFor工具说明,区分自动投递与 Ctrl-S 手动投递。Behavior Changes and Affected Users
skill_activation来源,不进入此 Hook;正文内和多 Skill 的blocked结果被 SDK 丢弃user来源,经过 Hook;返回blocked时 SDK 明确拒绝,TUI 恢复空闲并保留输入和附件Session.promptWithSkills的 SDK 用户activateSkill、klient 或 HTTP 结果契约/btw含 Skill 也复用相同准备函数user-slash不生成重复卡;模型自主及嵌套激活卡保持不变inTurn的输入仍归原轮inTurn的旧记录沿用原规则steerIfActive;省略或 false 保持普通提交,true 尝试注入当前轮,否则沿用现有启动或调度逻辑activateSkill、kap-server HTTP 路径、配置与环境变量不变涉及模块及测试覆盖:
resolve.test.ts、editor-keyboard.test.ts、kimi-tui-message-flow.test.ts。user-message.test.ts、sticky-user-message.test.ts、message-replay.test.ts,覆盖旧记录、轮归属、撤销和高亮。replay.test.ts、session-skills.test.ts、RPC 测试、klient facade 和 memory/IPC conformance。真实本地 Hook 返回退出码 2,覆盖三种 Skill 位置/数量及空闲 steer;断言请求拒绝、不启动轮次且下一次提交可接受。TUI 回归覆盖恢复空闲、无成功用户条目、附件召回及编辑后重新提交。activateSkill.test.ts,覆盖整体准备、参数、实际 steer 结果及inTurn;kap-server API surface 检查保留。replay-adapter.test.ts、replay-resume.integration.test.ts、event-adapter.test.ts。回归覆盖带 part 标记和无 part 标记的旧组合记录,包含行首、正文内、多 Skill、重复提及、图片和视频,以及无激活标记的用户自写 XML。验证结果:
根类型检查、CLI/SDK 构建、中英文文档构建通过;lint 为 0 errors,保留既有 warnings。
完整测试套件只运行一次:16,826 passed、51 skipped、3 failed。本次改动涉及的测试均通过。
两个未修改的 native release artifact 测试因本机 PATH 缺少
zstd失败。一个未修改的 foreground subagent 超时测试在当前代码和基准
5b936697的 core 代码快照中均独立复现 30 秒超时。未修改或跳过这些失败用例来获得绿色结果;需要 CI 继续验证。依赖实际服务的 legacy 测试未连接个人服务。
Hook 修复的定向回归:SDK 四个测试文件 103 passed;TUI 消息流与键盘两个文件 348 passed。根类型检查通过,lint 仍为 2803 warnings、0 errors。
早期 CI 的
test (3)曾在 Tower 的两条预期日志顺序断言失败,未修改该测试;提交95f413f82的全部已执行 CI 检查通过,Windows 检查按原设置跳过。VS Code 显示修复先运行失败回归,再修复并通过三个相关测试文件,共 62 passed。根类型检查、VS Code 扩展和 Webview 类型检查、扩展构建、文档构建通过;lint 为 2803 warnings、0 errors。
本轮补漏仅修改 TUI Skill 提交方法和其既有消息流测试:TUI/键盘 356 passed;CLI 类型检查、构建和 lint 通过,lint 保留 2803 warnings、0 errors。原 Changeset 不变。
Goal 使用实际编辑器、真实本地 SDK/引擎和受控模型响应检查。idle 边界中请求已实际提交;引擎接收后保持既有排队,Goal 仍 active。该检查不代表真人能稳定命中边界,也不保证后台准备耗时不会跨轮。
视频覆盖行首、正文内、多 Skill,提前准备成功、2 秒超时、保留新草稿、召回和附件仅释放一次。没有运行真实剪贴板到远程模型的视频端到端测试。
本轮全仓类型检查两次达到命令时间上限,没有报告类型错误但未完整结束;改动所在 CLI 的独立类型检查通过。完整测试套件没有重跑。
原有 VS Code
inTurn分组和 TUI/undo显示裁剪问题分别在普通 steer 与旧单 Skill 路径已存在,留待独立修复。没有新增 Goal 全局优先级、Ctrl-S 媒体等待、加载提示或客户端轮次协议。BTW 修复:先运行图片投递失败测试,再修复;四个相关 TUI 测试文件 391 passed,覆盖图片/视频、行首/正文内/多 Skill、2 秒超时、SDK 拒绝后重试、面板关闭以及主会话和 BTW 相同 turnId 的资源隔离。CLI 类型检查、构建通过,lint 保留 2803 warnings、0 errors。
实际编辑器、真实本地 SDK/引擎与受控模型响应的补充检查确认:最终模型请求中存在图片内容,轮次仍属于 BTW。它不等于真实远程模型的视觉理解测试;没有重跑本机完整测试套件。
Checklist
/approve).gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.