Skip to content

fix(kimi-code): keep the previous turn's answer visible when a task-notification turn ends - #3799

Merged
Grapedge merged 5 commits into
MoonshotAI:mainfrom
kimi-agent-bot:fix/task-notification-fold-boundary
Oct 14, 2026
Merged

Grapedge merged 5 commits into
MoonshotAI:mainfrom
kimi-agent-bot:fix/task-notification-fold-boundary

Conversation

@kimi-agent-bot

@kimi-agent-bot kimi-agent-bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

Related Issue

Follow-up to #3154 (same root-cause family; no separate issue filed).

Problem

The TUI folds completed-turn assistant messages beyond a keep cap into a step summary, grouped by "fold segments" delimited by turn-boundary components. A turn started by a background task completion notification (detached subagent / background bash / process task injecting an origin: { kind: 'task' } user message while the agent is idle) mounts no fold-segment boundary of its own: the injected message is never rendered, and the task's terminal status card is mounted asynchronously at termination time, decoupled from the turn it belongs to. When such a notification turn ends, its output shares the previous user turn's fold segment, so the fold cap folds the previous turn's final answer into the step summary — the answer disappears from the transcript and cannot be expanded.

This is the same root cause as #3154 (cron-fired turns), which fixed the cron variant by treating the cron card as a fold-segment boundary.

What changed

Minimal, precedent-following fix (a turnId-ownership-based boundary rework is intentionally left for a future, unified discussion). Three logical pieces:

  • Terminal task cards count as fold-segment boundaries. tui/kimi-tui.ts — isFoldSegmentBoundaryComponent now also accepts a BackgroundAgentStatusComponent whose phase is terminal (anything but started; started-phase cards are excluded so merely starting a background task does not fragment the active turn's fold segment). tui/components/messages/background-agent-status.ts exposes the card's phase for the check.
  • The boundary is anchored to the notification turn itself. tui/controllers/session-event-handler.ts — on turn.started with a task origin, anchorTaskNotificationTurn moves the task's already-mounted terminal card to the turn start (moveTranscriptEntryToEnd, so each notification turn begins with its own boundary), falling back to mounting a card when none exists (e.g. an agent that terminated without a lifecycle card). Cards are tracked in a backgroundTaskTerminalEntries map populated at every mount path — the terminated branch (process/question, behavior unchanged from main) and the subagent lifecycle handler (agent completed/failed/killed).
  • Card registration is robust to task-sync timing and shared agent ids.
    • BackgroundAgentMetadata now carries the optional taskId from subagent.spawned (filled by the Agent tool at registration), so an agent that completes before background.task.started syncs the task map still registers its card immediately instead of relying on the not-yet-synced lookup.
    • BackgroundAgentStatusData carries the agentId, and the anchor resolves the turn's taskId to its agentId via the (by then synced) task map and reuses an existing orphaned terminal card — covering Tower spawns, which omit taskId at spawn time. Cards already registered to a different taskId are skipped, so a resumed background agent (which intentionally shares its predecessor's agentId) never inherits the previous run's card.

Deliberately not changed: the background.task.terminated branch keeps main's behavior (agent-kind tasks still mount nothing there) — making all kinds mount a card turned out to be an out-of-scope UX change and a source of duplicate-card races. Replay needed no changes: it already mounts the notification card at the notification's position, matching the anchored live behavior.

Trade-off, same as #3154 accepted for mid-turn cron fires: a task that terminates while a turn is still running inserts a segment boundary mid-turn, so that turn's earlier steps may stay expanded instead of being folded. Correctness (never folding away an answer) takes precedence over compactness.

Out of scope, tracked as follow-up: trimTranscriptWindow eviction still only recognizes user-turn boundaries, so a long autonomous run of task-notification turns is not window-trimmed (pre-existing on main; fixing it touches undo/replay/fold interactions and belongs in its own change).

Tests

New regression tests (each fails before its respective fix, passes after):

  • test/tui/kimi-tui-message-flow.test.ts — the previous turn's final answer stays mounted when a task-notification turn completes (background bash and tower/worker paths), and when another task terminates mid notification turn (anchor scenario).
  • test/tui/message-replay.test.ts — same guarantee on the replay path.
  • test/tui/controllers/session-event-handler-background-task.test.ts — completion-before-task-sync registers exactly one card; Tower-style spawn without taskId reuses the orphaned card; a resumed agent sharing an agentId never steals the previous run's card; an agent that terminates with no lifecycle card gets one mounted at anchor time.

Full test/tui suite green (one pre-existing, environment-dependent failure in test/tui/commands/registry.test.ts — it reads $HOME and fails identically on a clean checkout). tsc --noEmit clean; oxlint --type-aware 0 errors.

Checklist

@changeset-bot

changeset-bot Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9867a50

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 Patch

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

@pkg-pr-new

pkg-pr-new Bot commented Sep 15, 2026 •

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

commit: 9867a50

@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.

@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: c116ccc52e

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/kimi-tui.ts
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: e6bd3d73c0

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/controllers/session-event-handler.ts
@shsaihdsaiudh

Copy link
Copy Markdown

Confirming this exact bug on release 2.1.1 — 100% reproducible. Posting since the PR notes no separate issue was filed.

Environment: kimi-code 2.1.1, macOS, Warp terminal (TERM_PROGRAM=WarpTerminal).

Repro (every time):

  1. In a session, have the agent launch a long-running background bash task (e.g. a large git clone via run_in_background)
  2. Keep chatting while it runs — everything renders normally
  3. The moment the task-completion notification is injected, the conversation content produced after the background task started disappears from the transcript; content from before the task started stays visible

Notes

@kimi-agent-bot
kimi-agent-bot force-pushed the fix/task-notification-fold-boundary branch from e6bd3d7 to c9dbfe5 Compare October 13, 2026 15:11
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 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-10-14T04:28:10.371733Z 9867a50 Manual request
ℹ️ 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.

@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: c9dbfe57a9

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/controllers/session-event-handler.ts Outdated
The previous commit also made background.task.terminated mount a terminal
card for every task kind, which smuggled a behavior change into the bug
fix: agent-kind tasks terminating without a subagent lifecycle event used
to be silent in the transcript and would now gain a status card. It also
raced the subagent lifecycle path — an agent finishing before
background.task.started synced could end up with two terminal cards.

Restore the terminated branch to its main behavior: only process and
question tasks mount a card there (now also registered for anchoring);
agent terminal cards remain owned by the subagent lifecycle path. The
notification-turn anchor keeps its mount-if-missing fallback, which is
the single new product behavior and covers abnormally terminated agents
with no card to anchor — making the reconciliation machinery unnecessary.
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: bedfdcd265

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/controllers/session-event-handler.ts
…s spawn-time task id

A spawn-time background agent whose subagent.completed lands before the
background.task.started sync could not be matched to a task id by
findAgentTaskId, so its terminal card never registered in
backgroundTaskTerminalEntries. When the task-notification turn started,
anchorTaskNotificationTurn found no mounted card and appended a second
terminal card — a duplicate.

The subagent.spawned event already carries the task id (the Agent tool
fills it from the task registration), so keep it on
BackgroundAgentMetadata and prefer it over the task-table lookup in the
completed/failed/cancelled paths; the lookup stays as fallback for
spawn paths that carry no task id.
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: f68694f2ba

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/kimi-tui.ts
Comment thread apps/kimi-code/src/tui/controllers/subagent-event-handler.ts
…the notification turn

Tower's spawnTool emits subagent.spawned without a task id (the task is
registered only after launch() returns), so a tower worker that finishes
before the registration mounts its terminal card with no task id to key
on: the spawn event has no taskId and findAgentTaskId searches an empty
task table. The card never registers in backgroundTaskTerminalEntries,
and when the task-notification turn starts, anchorTaskNotificationTurn
finds no mounted card and appends a second terminal card — a duplicate.

Keep the agentId on the card's BackgroundAgentStatusData and, before
falling back to mounting, resolve the agentId from the now-synced task
table and scan the transcript for that agent's terminal card. When one
is found, register it under the task id and move it to the turn start
like any mapped card; only mount a new card when the agent left none.
Process-kind anchoring is unchanged.
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: 78878bf260

ℹ️ 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".

Comment thread apps/kimi-code/src/tui/controllers/session-event-handler.ts Outdated
A resumed background agent keeps its previous agentId, so the orphaned
terminal-card scan at the notification turn could match the previous
run's card. When the resumed task then terminated without mounting a
card of its own (e.g. timed out), the anchor moved the earlier run's
card to the new turn and returned, so the resumed task's real terminal
status was never shown. Skip candidates already registered in
backgroundTaskTerminalEntries under a different task id and mount the
task's own terminal card instead.
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 9867a50953

ℹ️ 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".

@Grapedge
Grapedge merged commit 7e58f2d into MoonshotAI:main Oct 14, 2026
16 checks passed
@github-actions github-actions Bot mentioned this pull request Oct 14, 2026
@github-actions github-actions Bot mentioned this pull request Oct 20, 2026
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.

3 participants