feat(kimi-code): NotifyUser tool and mid-turn update panel - #3524
feat(kimi-code): NotifyUser tool and mid-turn update panel#3524RealKai42 wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: c193fbd 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.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6df9bcb981
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "@moonshot-ai/kimi-code": patch | ||
| --- | ||
|
|
||
| Collapse finished tool calls in the transcript to a single line; a Bash card now carries the command in its header, and successful output, Grep/Glob path samples, and the per-file list of a Read group only appear after `Ctrl+O`. Failed calls keep their output preview, and Edit/Write previews are unchanged. |
There was a problem hiding this comment.
Reduce each changeset to one short sentence
This changeset contains two sentences, and .changeset/notify-user-panel.md contains three, although the repository requires each changeset to be one short user-facing sentence. Condense each entry before release tooling turns them into changelog text.
AGENTS.md reference: AGENTS.md:L86-L86
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c52eb7d550
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // never hidden behind a bare header. | ||
| export const renderTruncated: ResultRenderer = (_toolCall, result, ctx) => { | ||
| if (!result.output) return []; | ||
| if (!ctx.expanded && result.is_error !== true) return []; |
There was a problem hiding this comment.
Preserve output for cards that Ctrl-O cannot expand
With the default TRANSCRIPT_EXPAND_TURNS=3, toggleToolOutputExpansion only expands cards in the three newest turns; older retained cards are deliberately left collapsed. Returning no body here therefore makes successful fallback/MCP outputs in those turns impossible to inspect, rather than merely hidden until Ctrl-O (and setting KIMI_CODE_TUI_EXPAND_TURNS=0 makes every successful output inaccessible). The same new early-return pattern affects Bash and summary renderers, so non-expandable cards need a preview or must remain eligible for expansion.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d53c13bfb8
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@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: 988971dae3
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@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: 90efdba79b
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@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: ac182d6663
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| notifyUserActive: | ||
| notifyUserAvailable(this.flags, this.bootstrap) && | ||
| this.scopeContext.agentId === MAIN_AGENT_ID && | ||
| this.isToolActiveForProfile(profile, NOTIFY_USER_TOOL_NAME), |
There was a problem hiding this comment.
Recompute guidance after per-prompt tool overrides
When an SDK caller submits a prompt with disabledTools: ['NotifyUser'], PromptService.submit updates the session denylist after the profile has already bound and stored its system prompt, while LLMRequesterService continues reusing profile.getSystemPrompt(). Fresh evidence beyond the earlier fix is that this one-time check therefore leaves the NotifyUser guidance in subsequent requests even though shapeTools removes the tool, encouraging calls to an unavailable tool; regenerate or overlay this guidance when the per-prompt denylist changes.
Useful? React with 👍 / 👎.
| // A new turn closes the previous turn's update panel; the first | ||
| // NotifyUser call of this turn reopens it. | ||
| this.host.streamingUI.clearNotifyPanel(); |
There was a problem hiding this comment.
Clear updates when a local shell turn starts
After a turn ends with updates visible, submitting a local ! command goes through runShellCommandFromInput, which appends a new user turn boundary but emits no turn.started event, so this is never called and the previous turn's panel remains above the input throughout the shell command despite saying the next message clears it. Replay does clear the panel for the same shell_command input via advanceTurn, so the live and resumed views also disagree; clear it when the local shell command begins.
Useful? React with 👍 / 👎.
| for (const [index, entry] of this.entries.entries()) { | ||
| const newest = index === this.entries.length - 1; | ||
| const marker = newest ? chalk.hex(c.primary)('◆') : chalk.hex(c.textDim)('◇'); | ||
| const body = new Markdown( | ||
| entry.text.trim(), |
There was a problem hiding this comment.
Bound or cache off-screen update rendering
In a long turn with many updates, every TUI paint recreates a Markdown component and renders every accumulated entry before slicing the result down to the eight visible rows. Because neither the schema nor this panel caps retained message size/count, a verbose or repeatedly updating model can make spinner-driven paints repeatedly process a large, entirely off-screen history, causing avoidable CPU usage and UI lag; cap retained updates or cache rendered rows and only invalidate changed entries.
Useful? React with 👍 / 👎.
Add an experimental NotifyUser tool (flag notify_user, off by default) that agent-core-v2 offers only when the host declares the update_panel UI capability at bootstrap; the TUI declares it through the SDK harness options. The system prompt's guidance to send updates is injected only when the tool is active for the agent. The TUI renders the turn's updates in a panel above the editor (stacked, 8-row window, Ctrl+N pages back) that the next turn clears, and keeps a one-line card in the transcript.
ac182d6 to
c193fbd
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c193fbd80d
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| state.notifyPanel.clear(); | ||
| this._notifyPanelTurnId = toolCall.turnId; | ||
| } | ||
| state.notifyPanel.upsert(toolCall.id, message); |
There was a problem hiding this comment.
Wait for authorization before showing updates
When a user configures an ask or deny permission rule for NotifyUser, streaming argument deltas reach this method before the engine evaluates that rule, so upsert displays the message before the approval is granted or the call is rejected. Removing the entry after an error result cannot undo that disclosure. Fresh evidence beyond the prior removal fix is that flushToolCallPreview still invokes this path for tool.call.delta events, whereas authorization precedes only tool.call.started; mount the update only after that authorized event (or otherwise gate the streaming preview on authorization).
Useful? React with 👍 / 👎.
Related Issue
No linked issue; internal UX change, the problem is described below.
Stacked on #3539 (two-line collapsed tool cards); the base switches to
mainonce that merges.Problem
While a long turn runs, the user has no reliable way to know what the agent is doing. The v2 system prompt told the model that text between tool calls may not be shown, so it rarely narrated, and the transcript is dominated by tool cards the user seldom reads. What the user actually wants to know mid-turn is: did it understand me, where is it, how long will this take, is there anything I should know, and is it stuck.
What changed
NotifyUsertool (agent-core-v2)notifyfeature contributes the tool. Singlemessageparameter (light Markdown in the user's language); the result is a one-line acknowledgement. Main agent only (mainAgentOnlyExecution), auto-approved,accesses: none()so it never serializes a tool batch.notify_userflag (KIMI_CODE_EXPERIMENTAL_NOTIFY_USER, or[experimental] notify_user = true) defaults to off, and even when on the tool is offered only when the host declared theupdate_panelUI capability at bootstrap (BootstrapInput.args.uiCapabilities, passed by the TUI through the SDK harness options). Print mode, kap-server and other hosts never expose it. The gate is evaluated in-process when the tool table is built and nothing is persisted, so flipping the flag or switching hosts leaves no trace in the session; the system prompt paragraph that encourages updates is injected through the same gate, and only when the tool is effectively active for the agent (main agent, profile allowlist, denylists).Update panel (TUI)
◆/◇markers), rendered as Markdown; an 8-row window follows the tail;Ctrl+Npages back through earlier rows and wraps; a new update snaps the view back to the tail. The message streams into the panel while the tool arguments are still arriving./clear; a finished turn, and a resumed session's replay, only dim the title, and the dimmed title says so (turn ended · next message clears).max_tokensis removed from the panel again; the last case's card readsUpdate cut off.Sent you an update (…)card;Ctrl+Oexpands the full message.Why this shape
Docs and changesets: tools reference and keyboard reference updated in both locales; one
minorchangeset.Tests: new unit tests for the tool (execution, subagent guard, flag default, auto-approve), the availability gate and prompt injection, the panel (stacking, paging, tail-follow, ended state, width), the streaming controller (panel feed including streaming arguments, turn replacement, dropped entries) and the event handler and replay (turn lifecycle); the v1/v2 parity test projects the v2-only tool out; the tool-roster and compaction snapshots in agent-core-v2 are unchanged with the flag off. Full suites for agent-core-v2, kap-server, node-sdk, klient, acp-server and the CLI app pass; lint and typecheck pass.
Checklist
/approve). Internal change, no issue.gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.History
This PR originally also carried the collapsed tool-card change; that part now lives in #3539 and this branch was rebuilt on top of it as a single commit. Earlier review threads refer to the previous commits.