Skip to content

feat(kimi-code): NotifyUser tool and mid-turn update panel - #3524

Open
RealKai42 wants to merge 1 commit into
feat/compact-tool-cardsfrom
feat/notify-user-panel
Open

feat(kimi-code): NotifyUser tool and mid-turn update panel#3524
RealKai42 wants to merge 1 commit into
feat/compact-tool-cardsfrom
feat/notify-user-panel

Conversation

@RealKai42

@RealKai42 RealKai42 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

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 main once 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

NotifyUser tool (agent-core-v2)

  • A new notify feature contributes the tool. Single message parameter (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.
  • Experimental and TUI-only: the notify_user flag (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 the update_panel UI 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).
  • The tool description and the system prompt's communication paragraph tell the model to send updates early and often at five moments (plan, phase conclusion, before a long-running step, a finding, when stuck), batched with its next tool calls, and to restate anything the user must keep in the final reply.

Update panel (TUI)

  • A new chrome slot between the Todo panel and the editor. The turn's updates stack chronologically (newest last, / markers), rendered as Markdown; an 8-row window follows the tail; Ctrl+N pages 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.
  • Cleared when the next turn starts (user, cron or task notification), on session reset and /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).
  • A denied or failed call, a call interrupted before its result, or one cut off by max_tokens is removed from the panel again; the last case's card reads Update cut off.
  • The transcript keeps a one-line Sent you an update (…) card; Ctrl+O expands the full message.

Why this shape

  • The panel sits where the user's eyes rest while waiting (the input box), and it is independent of the transcript's folding and expansion rules, so it works without changing how the transcript behaves.
  • The tool is the one mid-turn channel: structured enough to render and measure, cheap when batched, and its description is a stronger trigger than prose in the system prompt.
  • The panel is deliberately not durable (the card in the transcript is the trace), and the final reply must stand on its own, as the existing prompt already requires.

Docs and changesets: tools reference and keyboard reference updated in both locales; one minor changeset.

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

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve). Internal change, no issue.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, 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.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c193fbd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T08:09:01.588606Z c193fbd New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@c193fbd
npx https://pkg.pr.new/@moonshot-ai/kimi-code@c193fbd

commit: c193fbd

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread packages/agent-core-v2/src/features/notify/flag.ts Outdated
Comment thread apps/kimi-code/src/tui/controllers/streaming-ui.ts
Comment thread .changeset/compact-tool-cards.md Outdated
"@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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

Comment thread docs/zh/reference/tools.md Outdated
Comment thread apps/kimi-code/src/tui/components/messages/tool-call.ts
Comment thread apps/kimi-code/src/tui/components/messages/tool-call.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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 [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

Comment thread apps/kimi-code/src/tui/controllers/streaming-ui.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread apps/kimi-code/src/tui/controllers/session-replay.ts
Comment thread apps/kimi-code/src/cli/v2/run-v2-print.ts Outdated
Comment thread apps/kimi-code/src/tui/controllers/session-event-handler.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread packages/agent-core-v2/src/agent/profile/profileService.ts Outdated
Comment thread apps/kimi-code/src/tui/components/messages/tool-call.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread apps/kimi-code/src/constant/app.ts Outdated
Comment thread apps/kimi-code/src/tui/components/messages/read-group.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment on lines +845 to +848
notifyUserActive:
notifyUserAvailable(this.flags, this.bootstrap) &&
this.scopeContext.agentId === MAIN_AGENT_ID &&
this.isToolActiveForProfile(profile, NOTIFY_USER_TOOL_NAME),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

Comment on lines +334 to +336
// A new turn closes the previous turn's update panel; the first
// NotifyUser call of this turn reopens it.
this.host.streamingUI.clearNotifyPanel();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

Comment on lines +148 to +152
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(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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.
@RealKai42
RealKai42 force-pushed the feat/notify-user-panel branch from ac182d6 to c193fbd Compare September 4, 2026 08:00
@RealKai42 RealKai42 changed the title feat(kimi-code): NotifyUser update panel and single-line collapsed tool cards feat(kimi-code): NotifyUser tool and mid-turn update panel Sep 4, 2026
@RealKai42
RealKai42 changed the base branch from main to feat/compact-tool-cards September 4, 2026 08:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

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