Expand description
How an interrupted turn is recorded in conversation history.
When a turn is cancelled, the engine publishes the REAL partial history —
the assistant’s partial message (text / signed thinking / completed tool
calls), every completed tool round, and a canceled tool_result for any
call that did not finish. The frontend adopts that history verbatim and
then appends ONE short, factual user message: the interruption marker.
This replaces the old “ABORT CONTEXT” recap, which re-described the model’s own reasoning and tool calls as text inside the NEXT user message. A user turn that impersonates the model’s output reads as a prompt injection, and current models refuse it. The marker carries no instructions and claims nothing about what the model did — the history already says that, in the provider’s own message format.
Prompt caching: the marker is only ever APPENDED after the adopted history, never folded into or edited onto an existing message, so every byte the provider already cached stays identical.
Enums§
- Interrupt
Reason - Why a turn was interrupted. Selects the marker text only.
Functions§
- append_
marker - Append the marker for
reasonunless the history already ends with a marker (a second interruption with no turn in between records nothing new). Returns whether a message was appended. - interruption_
label "[Request interrupted by user]"→"Request interrupted by user", for display.Nonefor anything that is not a marker.- is_
interruption_ marker - True iff
textis EXACTLY one of the interruption markers. Clients use this to render the marker as an “interrupted” line instead of a user bubble (the daemon’sDisplayItemhas no dedicated variant: adding one would break older clients, whoseDisplayItemhas no#[serde(other)]). Exact, not a prefix: a user message that merely starts like a marker is the user’s, and is shown (and deduplicated) as such. - is_
tool_ in_ flight_ note - A user-role history message whose string content is exactly a tool-in-flight note.
- migrate_
legacy_ abort_ context - Load-time migration for sessions saved before this change. A non-
Noneabort_contextmeans the saved history ends at the interrupted turn and the recap was waiting to be prepended to the next user message. The recap is DISCARDED (it is exactly the injection-shaped text this module replaces) and the marker is appended in its place. - recover_
crashed_ turn - Fold an in-flight turn draft left by a process that died mid-turn
(
agent_core::core::session_draft) into the loaded history. - tool_
in_ flight_ note - The note a cancel records when the engine never reported back on a tool
call the interrupted response made (
session::actorkeep_streamed_partial): the engine’s canceled-tool_resultwording, hedged to “may have already started” because the actor can’t tell whether the call began. A plain user-role message, recognised by its exact text like the interruption marker (never by a host key a rolled-back 0.10.2 would take for an archive marker); the generator and the matcher live inagent_core::core::host_note, which archive projection (agent-core) uses too. - tool_
in_ flight_ note_ label textwithout its brackets iff it is exactly a notetool_in_flight_note_textgenerates: a single line, a known phrase, one or more names that are each a backticked plausible tool name orUNRECOGNISED_TOOL, and nothing else. Checked by regenerating the note from the names it contains, so there is no free-form part.Nonefor anything else.- tool_
in_ flight_ note_ message - The note as a history message.