kimi-code/packages/transcript/src
7Sageer 1f3f5dadaa
feat(agent-core-v2): interruption reminder for user-cancelled turns (#2400)
* feat(agent-core-v2): interruption reminder for user-cancelled turns

When the user interrupts a turn with Esc, append a durable
<system-reminder> (origin: injection/interruption) to the agent context
via a new loop aspect watching turn.ended, so the model learns the
previous turn was deliberately cut off. The marker persists to the
wire, replays on resume, stays hidden from transcripts, skips non-user
aborts and steer, and does not stack on repeated cancels.

Two supporting fixes:

- An aborted LLM stream now persists its accumulated partial
  text/thinking as content.part loop events instead of dropping every
  produced token; gated on the turn signal so retried or
  step-cancelled attempts keep their partial output out of the record.
- The turn.cancel wire op carries an optional reason
  ('user_cancelled' | 'aborted') so cold readers can tell deliberate
  interrupts from programmatic aborts. Goal-lifecycle cancels now pass
  an explicit programmatic reason to keep that field honest.

* feat(transcript): mark user-cancelled turns with an interruption marker

Project the deliberate user interrupt onto the transcript timeline: the
live projector emits an 'interruption' marker when a turn ends with
interruptReason 'user_cancelled', and the cold fold consumes the
persisted turn.cancel reason into the same marker. Programmatic aborts
keep surfacing through their own outlets (errors, goal/task state), and
queued cancels that left no visible residue are skipped.

* fix(agent-core-v2): make user-turn cancellation idempotent and reconcile interruption reminders on restore

* fix(transcript): dedupe user-cancelled interruption markers by turn in the cold fold

* chore(agent-core-v2): regenerate state manifest after merging main

* refactor(agent-core-v2): split interruptionReminder out of the loop domain

The loop domain owns turn execution mechanics; whether an interrupted turn
should produce a model-visible reminder is a model-context policy. Move it
into its own L4 domain with its own wire model that cross-reduces the
loop's turn.cancel fact, and rename the op to interruptionReminder.recorded.

---------

Signed-off-by: Haozhe <yanghaozhe@moonshot.ai>
Co-authored-by: Haozhe <yanghaozhe@moonshot.ai>
2026-07-31 18:17:14 +08:00
..
contract feat(kap-server): global session work status, transcript subscribe_v2, and plan endpoint (#2094) 2026-07-23 18:48:25 +08:00
granularity feat(kap-server): global session work status, transcript subscribe_v2, and plan endpoint (#2094) 2026-07-23 18:48:25 +08:00
history feat(agent-core-v2): interruption reminder for user-cancelled turns (#2400) 2026-07-31 18:17:14 +08:00
model feat: agent-core-v2 permission/workspace refactors and transcript durability (#2021) 2026-07-22 19:21:56 +08:00
ops feat: agent-core-v2 permission/workspace refactors and transcript durability (#2021) 2026-07-22 19:21:56 +08:00
pagination feat(transcript): add unified transcript layer, drop the /api/v2 RPC surface (#1888) 2026-07-20 15:33:05 +08:00
store feat: agent-core-v2 permission/workspace refactors and transcript durability (#2021) 2026-07-22 19:21:56 +08:00
view feat(transcript): add unified transcript layer, drop the /api/v2 RPC surface (#1888) 2026-07-20 15:33:05 +08:00
index.ts feat: agent-core-v2 permission/workspace refactors and transcript durability (#2021) 2026-07-22 19:21:56 +08:00