fix(kimi-code): keep the previous turn's answer visible when a task-notification turn ends - #3799
kimi-agent-bot wants to merge 3 commits into
Conversation
…otification turn ends
🦋 Changeset detectedLatest commit: e6bd3d7 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 |
commit: |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
@codex review |
There was a problem hiding this comment.
💡 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".
A terminal background-task card mounts when the task terminates, which is decoupled from turn boundaries: a task that finishes mid-turn lands its card inside the live turn's output. When the notification for that card later missed the turn drain and opened its own turn, that turn had no boundary of its own, so its end-of-turn fold segment started at the stray card and the completed-turn assistant cap folded the previous notification turn's final answer into the step summary. Give every task-notification turn (turn.started with a task origin) its own boundary at turn start: re-anchor the task's mounted terminal card to the turn, or mount one when none is mounted. Terminal cards stay in the fold-segment boundary whitelist as a fallback for cards that never get a notification turn (resumed sessions, replay).
|
@codex review |
There was a problem hiding this comment.
💡 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".
| const mounted = this.backgroundTaskTerminalEntries.get(taskId); | ||
| if (mounted !== undefined && this.host.moveTranscriptEntryToEnd(mounted)) return; | ||
| const task = this.backgroundTasks.get(taskId); | ||
| if (task === undefined) return; | ||
| const entry = this.appendBackgroundTaskEntry({ ...task, status }); |
There was a problem hiding this comment.
Reuse the terminal card emitted by the subagent handler
When a detached agent completes, SubAgentEventHandler.handleSubagentCompleted can append its terminal card first and mark backgroundTaskTranscriptedTerminal; the later background.task.terminated event then skips its append, so backgroundTaskTerminalEntries is never populated. When the task-notification turn starts, this fallback appends a second terminal card even though the first remains mounted. Record the entry created through the subagent path, or locate/reuse that existing entry, to avoid duplicate completion cards for normal background-agent notifications.
Useful? React with 👍 / 👎.
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 boundary component: the injected message is never rendered, and forkind: 'agent'tasks not even a terminal status card is mounted (the termination handler only updates the original tool card in place). 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):
tui/kimi-tui.ts—isFoldSegmentBoundaryComponentnow also accepts aBackgroundAgentStatusComponentwhose phase is terminal (completed/failed).started-phase cards are excluded so merely starting a background task does not fragment the active turn's fold segment. Live view and replay both mount these cards for task notifications, so the boundary exists on both paths.tui/controllers/session-event-handler.ts— onbackground.task.terminated, mount the terminal status card foragent-kind tasks too (previously onlyprocess/questiongot one). This closes the tower/worker path, where no card was mounted at all, and matches what replay already renders for agent-task notifications.tui/components/messages/background-agent-status.ts— expose the card'sphasefor the boundary check.subagent.faileddoes not add a contradictory one.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.
Known limitation: a notification whose terminal event this TUI session never saw (e.g. restored after an engine restart) still mounts no card and gets no boundary; replay of such history is covered because replay mounts the card from the notification record itself.
Tests
New regression tests (all fail before the fix, pass after):
test/tui/kimi-tui-message-flow.test.ts— "keeps the previous turn's final answer mounted when a task-notification turn completes" (background bash) and "...when a background-agent notification turn completes" (tower/worker path).test/tui/message-replay.test.ts— "keeps the previous turn's final answer visible when a task-notification turn follows in replay".Full
test/tuisuite green (one pre-existing, environment-dependent failure intest/tui/commands/registry.test.ts— it reads$HOMEand fails identically on a clean checkout).tsc --noEmitclean;oxlint --type-aware0 errors.Checklist
gen-changesetsskill (patch changeset included).gen-docsskill, or this PR needs no doc update.