Skip to main content

Module digest

Module digest 

Source
Expand description

What a model is shown of a pane’s recent conversation: a bounded digest read from the block’s output file, with hidden memory-reinjection turns removed.

Structs§

RecentActivity
A block’s recent activity: the digest text, and how it ends.

Enums§

TurnEnding
How the newest exchange in a block’s recent activity ends. Decided in code, from the same entries the digest is built from, so a call that could only decline is never made.

Constants§

ASKS_USER_TOOLS 🔒
Tools that end a turn by asking the user something.
DIGEST_ENTRY_MAX_CHARS 🔒
DIGEST_MAX_CHARS 🔒
DIGEST_MAX_ENTRIES 🔒
Entries kept, per-entry and total character caps for a digest. The old digest was “the last 30 raw lines”, which on a streaming session is mostly deltas.

Statics§

HIDDEN_REINJECTION_BLOCKS 🔒
Global registry of blocks currently inside a hidden-memory-reinjection window — authoritative and set at RPC-dispatch time (COMMAND_AGENT_INPUT’s handler, agent_handlers/input.rs), NOT reconstructed by scanning transcript bytes. reagentx P0, SEVENTH review round, PR #3502: extract_digest_text’s marker-text suppression can only see what’s inside read_recent_activity_digest’s own 96 KB tail window. Personal memory content is expected to grow (§3.4) — the PR’s own measurements record real bodies of 61,725 and 76,164 bytes on this machine, both already past that window on their own, before the model’s reply is even appended. Once the reinjection marker line scrolls out of the window (which large memory content does routinely, not as an edge case), a LATER call — next_prompt_suggestion after the turn ends, or activity_watcher.rs’s independent periodic sweep during it — starts its own fresh extract_digest_text scan with hiding = false and no marker line in view, and forwards the model’s suppressed-turn reply anyway. This registry closes that: it isn’t reconstructed from a byte window at all, so it can’t be scrolled past. extract_digest_text’s own marker-based suppression stays in place as defense-in-depth (e.g. a server restart mid-hidden-turn drops this in-memory registry, but a marker line still inside the window at that point is still caught).

Functions§

activity_from_entries
The recent activity a pane sent with its request: entries in the digest’s own form ([user] …, [assistant] …, [tool] Name, [error] …), oldest first, from the document it has already translated for its provider. Kept to the same caps and judged the same way as one read from the output file, and refused the same way while a hidden memory reinjection is in progress.
activity_of 🔒
clip_entry 🔒
Keeps the END of an over-long entry: the tail of a message (its question, its conclusion) is what predicts the next one.
ends_a_question 🔒
Whether any question mark in line ends a sentence: only closing formatting (**, _, quotes, brackets, a code span’s backtick) stands between it and the end of the line or the next space. Not a ? inside code (`?`, `result?`), a URL’s query, or a?.b.
ends_in_question 🔒
Whether a message’s last paragraph asks something: one of its sentences ends in a question mark. The whole paragraph, not only its end, because a question is often followed by a line of courtesy (“Which do you prefer? Let me know and I’ll proceed.”). A question earlier in the message, which it went on to answer, is not in the last paragraph.
extract_digest_parts 🔒
[extract_digest_text]’s entries, one per message/tool/error, so a caller can budget by entry instead of by raw line.
finalize_digest 🔒
Turns extracted entries into the text sent to the model, or None when there is no conversation in them. Only [user] and [assistant] entries count as substance: a window of tool names and errors says what ran, not what the work is, and the model answers “I have no context” to it.
is_digest_entry 🔒
Whether entry is in the digest’s form. An entry the pane sent in any other shape is dropped rather than shown to the model as if it were one.
is_hidden_reinjection_active 🔒
is_hidden_reinjection_text 🔒
True for a <system-reminder>...Your memory was reinjected because your working context was just reset... message — a hidden memory-reinjection turn (frontend/app/view/agent/memory-reinjection.ts’s composeReinjectionMessage). Mirrors that module’s isMemoryReinjectionMessage exactly, including the exact signature string — kept as a literal duplicate rather than a shared constant (Rust and TypeScript can’t share one across the language boundary without extra plumbing this one string doesn’t justify), so a future change to the frontend’s wording must update this function too.
read_recent_activity
read_recent_activity_digest’s digest, with how the newest exchange ends.
read_recent_activity_digest
Read the last 96 KB of a block’s FileStore output, extract digest entries from all of it, and keep the newest few (finalize_digest). Used directly by next_prompt_suggestion; activity_summary now only falls back to this when the caller didn’t supply user_message (see docs/specs/SPEC_AMBIENT_PANE_TITLE_OVERALL_GOAL_TRACKING_2026_08_17.md) — the common case passes the literal just-submitted text instead. Returns None when there’s nothing usable — callers should return an empty ambient result in that case without invoking the CLI.
reads_output_format
Whether a block’s output can be read as a digest: Claude Code’s stream-json shape, which Qwen’s stream also has. Any other provider’s file reads as no conversation at all, so a caller that has only the file skips such a block instead of reading 96 KB of it to find nothing. A pane sends its own translated activity instead (activity_from_entries). agentOutputFormat is empty on blocks created before it was recorded, which were all Claude.
set_hidden_reinjection_active 🔒
Called once, at the moment an AgentInputCommand is dispatched for a block — hidden: true starts (or extends) that block’s suppression window; hidden: false (any ordinary user turn) ends it. The tool_result continuation frames a hidden turn’s own tool-using reply produces never go through this path (they’re the CLI’s own stdout, not a fresh RPC), so they can’t accidentally clear it either — the same class of bug finding #7 fixed for the byte-scanning heuristic doesn’t exist here by construction.
turn_ending 🔒
How parts (oldest first) end. See TurnEnding.