Catch-Up Card
A pinned four-line summary that appears above a session's transcript while that session is waiting on you, so you can pick the conversation back up without rereading it. Covers what each line is, when the card appears and disappears, how it collapses, what each regeneration costs, and the fact that it is currently switched off for everyone.
What it is
A pinned, four-line summary that sits at the top of a session's transcript while the session is waiting on you. It tells you, at a glance, what you originally asked, what the agent has been doing, and what it's currently asking you for — so you can context-switch back into a session without rereading the whole conversation.
Catch-Up Card is an opt-in feature that watches each session's status. The first time a session flips into Needs You (the agent stopped and is waiting on a human reply), Omniscio composes a summary card pinned above the message list. The card has two distinct modes controlled by a separate sub-toggle:
- Default mode (no agent summary) —
OriginallyandLast askedalways render. The agent'sDidandAskslines are hidden. Default cost: one Originally AI call once per session lifetime + one Last-asked AI call per regeneration. Cheapest mode that still gives you the user's question at a glance. - Agent-summary mode (
continuousSummaryShowAgentSummary: true) — adds aDidline and anAsksline summarizing what the agent did and what it's now blocking on, AND adds the prior-Didrows inside the inline prior-turn history. The prior-Askedrows are visible in either mode. This is the full four-piece view that costs +1 AI call per regeneration on top of the default.
The card renders pieces from up to three independent AI calls — each one is independently gated:
- Originally is a 10–30 word plain-English summary of the user's first message in the session — the "what is this session even about" anchor. Omniscio asks the AI to summarize the first user message exactly once per session lifetime, then reuses the result verbatim on every later regeneration. If the AI call fails or returns an empty summary, Omniscio falls back to a verbatim slice of the first message (capped at
continuousSummaryOriginallyLengthCapcharacters, default 1000) and flips the row'spartialFailureflag so the UI can offer a retry. Originally always regenerates regardless of the agent-summary toggle. - Last asked is a small AI rewrite of the user's most recent message before the session blocked. Independent of the agent-summary toggle — always runs and always renders, except when suppressed by the single-message-turn rule (the user has only sent one message — rephrasing it would just duplicate Originally).
- Did + Asks are produced by a second AI call that summarizes what the agent did since the user's last message and what it's now blocking on. Skipped entirely when agent-summary mode is off — no AI call, no rows.
The Originally summary is the reason a verbatim 1000-char slice was never enough: when the user's first message is a 10K-line log dump, the verbatim slice fills the whole card with noise. The AI summary distills it into a single sentence the operator can scan in one second.
Once the Originally is set, every later regeneration reuses it without another AI call — Originally is "sticky." The Last-asked and Agent (Did + Asks) calls are incremental: each one sees only the previous result plus what's new, so cost stays low even on long looping sessions.
The card sits inside a normal CARD_BASE panel above the transcript, scrolls with the conversation, and disappears entirely the moment the session is no longer in Needs You (e.g., the agent starts running again, or you archive/pause the session).
Status: temporarily disabled (2026-04-30)
The feature is currently force-disabled for all users while we evaluate whether to remove it entirely. Behaviorally:
- The Settings → AI Provider section that exposed the master toggle and the per-section prompt editors has been unwired — it no longer renders in Settings, and the global settings search will not surface its rows.
- The Settings → AI Provider section that exposed the toggle is unwired, so the only way
continuousSummaryEnabledbecomestrueis if a user toggled it on before the UI was unwired and the value has been sitting in theirconfig.jsonever since. Default for fresh installs isfalse. The visibility gate (status === 'needs_you'×continuousSummaryEnabled === true×isVisible) therefore stays closed for everyone except that historical-toggle-on cohort — for them, the persisted value is honored as-is (no force-coercion at read-time;getSettings()is a pure pass-through per the global pure-read contract). If the feature is fully removed, the field itself should be dropped from the schema rather than re-introducing a read-time override. - The implementation is preserved on disk — the
ContinuousSummarySettings.tsxeditor, theContinuousSummaryPanel.tsxrenderer, thecontinuous-summary-service.tsbackend, the IPC handlers, the renderer store, the search-index entries, the database table (migration v115; v114 was taken by the cron self-healing schema at merge time), and the prompt templates all remain intact. Restoring the feature is a three-line revert: re-add the<ContinuousSummarySettings>mount insideAiProviderSettings.tsx, restore itspendingSettingIdprop, and passpendingSettingIdfromSettings.tsxinto the AI Provider call site again. NogetSettings()change is required — the read path is already pure.
2026-06-20 update: The references below to
AiProviderSettings.tsx(the Catch-Up Card's former settings mount/host) are now historical — that file was deleted when the AI Provider settings panel was removed. A future restore would need a new mount home (e.g. its own Settings section), not the old panel.
The rest of this page describes the feature as it was designed and as the code still implements. Treat it as a frozen reference until the call to remove or re-enable is made.
Where it appears
- Top of
SessionPanel, immediately above the message list, only when all three of the following are true:continuousSummaryEnabledistruein Settings (default:false— opt-in).- The session's status is
needs_you. - The
SessionPanelis the visible session (it's gated by the keep-aliveisVisibleflag, so hidden panels in the keep-alive pool don't render or fetch).
- It is not present in the transcript when the session is
running,starting,ended,error,paused,archived, etc. Omniscio has noidlestatus —needs_youis the canonical "agent stopped, waiting on operator" state. - The settings UI also reuses the same panel as the live UI to render back-test results in-place — see Settings below.
The lines
The card always shows the Originally and Last asked lines. The agent's Did and Asks lines (plus the prior-Did rows in the inline history) only appear when continuousSummaryShowAgentSummary is on.
Always-on:
- Originally (accent dot, label inline with body, line-clamped to 3 lines by default) — a 10–30 word AI-summarized anchor of what the session is about, derived from the user's first message on the very first regeneration and then reused verbatim across every later round. The label
Originallyand the body sit on the same line inside a single line-clamp container — clicking the row removes the clamp to reveal the full text. The model is instructed to keep the summary ≤400 characters and to mirror the user's intent without paraphrasing it into jargon. If the AI call fails (network error, parser miss, emptyoriginallyfield), Omniscio falls back to the verbatim first user message truncated tocontinuousSummaryOriginallyLengthCapcharacters (default 1000) and the row'spartialFailureflag flips so the panel can offer a retry. - Last asked (accent dot, indented
↳) — a ≤50-word / ≤3-sentence rewrite of the user's most recent message before the session blocked. Hidden when the row'slastAskedfield is empty (e.g., suppressed for single-message turns where rephrasing would just duplicate Originally). If the user's most recent message is justcontinue/go on/yes/ similar, the prompt is instructed to reuse the previous Last asked verbatim instead of trying to rewrite a content-free turn. Independent ofcontinuousSummaryShowAgentSummary. - Inline prior
Askedrows (faded accent dot, indented↳) — theq(question) half of each prior pair fromsummary.hiddenPairs. These render between Originally and the current turn even when agent-summary mode is off, because they're the user's prior asks — same family as Last asked.
Gated by continuousSummaryShowAgentSummary (default OFF):
- Inline prior
Didrows (faded green dot, indented↳) — thea(answer) half of each prior pair fromsummary.hiddenPairs. Hidden when the toggle is off. The prior-Askedrow above each prior-Didstill renders, so when the toggle is off you see a list of prior user questions with no corresponding agent activity. - Did (green dot, indented
↳) — a ≤50-word / ≤3-sentence summary of the most recent substantive agent activity (tools used, files touched, the gist of what it did) since the user's last message. Hidden whendidis empty. - Asks (amber dot, indented
↳) — a ≤50-word / ≤3-sentence rewrite of the question or blocking ask the agent is currently waiting on. This is the "what do I need to decide right now" line, and it's the same amber-* token used for the Needs You status pill across the rest of Omniscio. Hidden whenasksis empty.
The number of prior pairs surfaced is continuousSummaryRecentTurnsVisible − 1 (the current turn counts as the Nth, so N=1 shows 0 prior pairs, N=3 shows the 2 most recent prior pairs, etc.). hiddenPairs is the running record of compressed previous turns: each round, when at least one of lastAsked / did advances and previous values are non-empty, the previous pair is appended. Because the array grows monotonically and only the tail (slice(-N)) renders, the inline prior-pairs list reflects the most recent N−1 turns and silently drops older ones from view.
Where to find it
When it is on, there is nothing to open — the card pins itself above the message list of a session that has stopped and is waiting on you, and it disappears again as soon as that session is no longer waiting. Its own settings lived on the AI Provider settings page, and that part of the page has since been unwired, so no control for it is reachable in Settings today.
How it behaves
Card behavior (header, viewport cap, collapse, line-clamp)
The card has a thin header strip with the label SUMMARY on the left. The whole-panel collapse control is not in the header — it's a small ▴ / ▾ button that floats at the bottom-center of the card, hover-revealed via Tailwind group + group-hover:opacity-100 (it lives outside the card's visible chrome via absolute -bottom-2.5 and is invisible until the user mouses over the card). Click it to collapse all rows down to the header strip; click again to expand. This is the viewport-saving toggle for sessions where the agent's running output below the card is what you actually want to read.
The expanded body has a viewport cap: max-h-[40vh] overflow-y-auto on the inner body div (the one carrying data-role="summary-body"). On a tall viewport with recentTurnsVisible = 5 and many prior pairs, the body scrolls internally instead of pushing the transcript out of view. The cap is on the inner body — the always-visible header strip and the bottom hover-reveal collapse button stay accessible no matter how many rows are inside. Users who want to reclaim the whole 40% can still click the bottom collapse button.
Collapse state is per-session and keyed to the current summary's generatedAt timestamp — so if you collapse the panel and then a new agent turn lands, producing a new summary row with a later generatedAt, the card auto-expands. You only have to manually re-expand if you keep the same summary row but want to see it again. The implementation is in the renderer store: a Map<sessionId, generatedAt> records the timestamp at which a session was collapsed, and isPanelCollapsed(sessionId, currentGeneratedAt) returns true only when those values match exactly. Any later generatedAt makes the stored entry stale → returns false → expanded.
The Originally label and body are rendered as siblings inside a single line-clamp parent so they share the same line box — Originally followed by the body text on the same line, with the clamp applied to the wrapper rather than the body span. Click anywhere on the row to remove the clamp and show the full original prompt; click again to re-clamp. This toggle is per-session and is independent of the whole-panel collapse.
Body text uses text-surface-700 (theme-aware: near-white in dark mode, dark-grey in light mode) for high contrast against the card surface — not text-surface-300, which inverts to near-black in dark mode and used to render the body unreadable.
How it regenerates
There are exactly two triggers that ask the AI to refresh the summary:
enter-needs-you— fires when a session transitions fromrunning→needs_you. The agent has stopped and surfaced a question; Omniscio takes that as the cue to refresh the four lines for the user.after-reply— fires when the operator just sent a reply and the session is nowrunning(the agent is working on the answer). This pre-warms the next regeneration so the card is fresh by the time the agent stops again.
Terminal statuses (ended / error / archived / paused) never trigger — there's no point summarizing a dead session. Same-status transitions are also no-ops, matching the rest of Omniscio's updateStatus early-return convention.
The summarization is incremental at three levels, and only the agent (Did + Asks) call is gated by the toggle:
- Originally is summarized by the AI once on the session's first regeneration (a single short call against the user's first message, capped at 12 KB of input regardless of how long that first message actually was) and then preserved verbatim across every later run — the previous summary's value is reused without ever asking the AI again. AI failure or an empty
originallyfield falls back to the verbatim first user message slice (capped atcontinuousSummaryOriginallyLengthCap, default 1000 chars). Originally always regenerates regardless ofcontinuousSummaryShowAgentSummary. - Last asked is its own AI call per regeneration whenever the user's last message id has advanced. The call is small: it gets the previous result as a
<context>slot and only the latest user message as the<new>slot. Independent ofcontinuousSummaryShowAgentSummary— always runs unless suppressed by the single-message-turn rule (the user has only sent one message, so the AI rephrasing would just duplicate Originally; backtests bypass the suppression so the prompt-eval harness sees the full pipeline output). - Agent (did + asks) is its own AI call per regeneration whenever the agent's last message id has advanced AND
continuousSummaryShowAgentSummaryis on. Same<context>+<new>shape as Last asked. When the toggle is off, this call is skipped entirely — the row'sdid/asksfields fall back to the previous values (or empty), so flipping the toggle on later doesn't lose anything: the next regen produces fresh values from the current cursor.
Whenever lastAsked / did advance in a round, the previous pair is folded into the hiddenPairs array so the inline prior-pairs view (controlled by continuousSummaryRecentTurnsVisible) can render the most recent N−1 turns. With agent-summary off, the prior-q (Asked) halves still render in the inline history; the prior-a (Did) halves are hidden by the panel.
The user can also manually trigger a regeneration from the Settings back-test (see below). That call goes through a separate IPC path (CONTINUOUS_SUMMARY_RUN_BACKTEST) that does not affect live summaries — it writes a trigger: 'backtest' row that the live UI ignores, and renders the result inline in the settings panel for review.
When a regeneration finishes, the main process emits a CONTINUOUS_SUMMARY_UPDATED push event scoped to the session. The visible SessionPanel listens for that channel (filtered by sessionId, gated by isVisible) and refetches the latest row.
Settings
The settings UI lives at the bottom of the AI Provider settings page (Settings → AI Provider, scroll past the email-prescreen note). It is composed of a master toggle that always shows, plus a nested block that only appears when the feature is enabled. All controls follow the parent-injection pattern (settings, onSettingChange props) — no direct store mutation.
- Master toggle (
continuousSummaryEnabled, defaultfalse): turn the feature on or off globally. When off, no panels render anywhere and no AI calls happen on status transitions. - Show agent summary toggle (
continuousSummaryShowAgentSummary, defaultfalse): adds theDidandAsksrows (what the agent did and what it's now waiting on), plus the prior-Didhalves of the inline history. TheOriginallyandLast askedrows always render either way — this toggle only gates the agent's reply summary and the agent half of prior pairs. When off, the agent AI call is skipped entirely. Surfaces as aSETTING_TOGGLE_ROWdirectly under the master toggle. - Recent turns visible (
continuousSummaryRecentTurnsVisible, integer 1–5, default1): how many "turns" the card surfaces in the inline prior-pairs history. The current turn counts as the Nth, so N=1 shows 0 prior pairs, N=3 shows the 2 most recent prior pairs fromhiddenPairs, N=5 caps at 4 prior pairs. Older history beyond that is silently dropped from view (it stays inhiddenPairsfor forward survival but is not rendered). Each prior pair contributes anAskedrow (always rendered) and, when the agent-summary toggle is on, aDidrow (gated). Surfaces as a number input next to the agent-summary toggle. - Model override (
continuousSummaryModel, defaultnull): a free-text model identifier. Empty = use the user's default LLM (governed by the AI Provider section above). Set this if you want Catch-Up Card to use a specific model regardless of the app-wide default. - Three collapsible per-section editors, one per summary line:
- Originally — a monospace textarea seeded with the built-in default prompt for
continuousSummaryOriginallyPromptTemplate. Available variable shown as an accent badge above the textarea:{originally}(interpolated with the user's first message, capped at 12 KB). Staged: typing into the textarea does not persist anything — you must click Save prompt to commit the draft. Reset to default clears both the local draft and the override (sendsnullto settings). Below the prompt editor sits a number input forcontinuousSummaryOriginallyLengthCap(default1000) — this is the fallback verbatim-slice cap used only when the AI call fails or returns empty; it does not bound the AI summary length (the prompt rules cap that at 400 chars). - Last asked — a monospace textarea seeded with the built-in default prompt for
continuousSummaryLastAskedPromptTemplate. Available variables shown as accent badges above the textarea:{originally},{previous_last_asked},{current_user_message}. Staged: typing into the textarea does not persist anything — you must click Save prompt to commit the draft. Reset to default clears both the local draft and the override (sendsnullto settings, so the next regen uses the built-in template). - Agent — same shape as Last asked but for
continuousSummaryAgentPromptTemplate. Available variables:{originally},{last_asked},{current_user_message},{agent_final_text}. The default template asks the model to output strict JSON{ "did": "...", "asks": "..." }.
- Originally — a monospace textarea seeded with the built-in default prompt for
- Back-test against a session: enter any session ID (including ended or archived sessions) and click Run back-test. The current draft templates + model override are sent to the back-test IPC, the AI returns parsed results, and the same
<ContinuousSummaryPanel>component renders the result in-place — the same four lines, the same chevron, the same colors as the live UI. Live summaries are never affected. This is the safe way to iterate on a custom prompt before saving.
Settings search & auto-expand
Each section has a kebab-case data-setting-id (continuous-summary-show-agent-summary, continuous-summary-recent-turns-visible, continuous-summary-originally-prompt-template, continuous-summary-originally-length-cap, continuous-summary-last-asked, continuous-summary-agent) and a matching entry in settings-search-index.ts. When the user searches the global settings search and clicks a hit on one of these settings, the parent threads pendingSettingId through Settings.tsx → AiProviderSettings.tsx → ContinuousSummarySettings.tsx, which auto-expands the matching collapsed section before the scroll-to-setting animation runs. Without that auto-expand, the row would scroll into view but the textarea would be hidden behind a collapsed disclosure — see the settings-search-scroll postmortem for why this matters.
Off-by-default + cost note
The feature is off by default because it spends money on every status transition. The cost depends on the agent-summary toggle:
Default mode (agent-summary off — continuousSummaryShowAgentSummary: false):
- First regeneration on a brand-new session — agent stops and asks the first clarifying question (transition:
running→needs_you) → +2 small AI calls (Originally + Last asked). Originally is sticky for the lifetime of the session; Last asked re-runs whenever the user's last message id advances. - Every subsequent regeneration — agent stops again, or you reply and the agent resumes → +1 small AI call (Last asked, when the user's last message id has advanced). Originally is reused from the previous summary row without any AI call. If only the agent's last message advanced (no new user message), there are 0 calls in this mode.
- Repeat per round-trip.
This is the cheaper mode: the agent AI call is skipped entirely. The card shows what the user asked but not what the agent did or is waiting on.
Agent-summary mode (continuousSummaryShowAgentSummary: true):
- First regeneration on a brand-new session — agent stops and asks the first clarifying question (transition:
running→needs_you) → +3 small AI calls (Originally + Last asked + Agent did/asks). Originally fires only on this first round; it's then sticky for the lifetime of the session. - Every subsequent regeneration — agent stops again, or you reply and the agent resumes → +1 to +2 small AI calls (Last asked when the user's last message id has advanced, plus Agent did/asks when the agent's last message id has advanced). Originally is reused from the previous summary row without any AI call.
- Repeat per round-trip.
Each call is cheap because the prompt is incremental (previous result + only the latest user message / agent response), but it's not free. Users with many concurrent sessions or long looping sessions can keep the agent-summary mode off for the cheaper behavior, override the model to a smaller / cheaper one via the Model override field, or keep the master toggle off entirely.
The default model is Claude Sonnet (the value of MODEL_SONNET_LATEST in src/shared/model-latest.ts — currently claude-sonnet-4-5-20250929). Sonnet is the canonical default because the prompts were tuned and back-tested on Sonnet in the tools/summary-tester/ harness; cheaper Anthropic models produced noticeably more rule violations (preamble, jargon mirroring, workflow plumbing) on the same threads. The Model override field lets users swap in a cheaper model knowing they'll trade a measurable amount of summary quality for the cost reduction.
The settings UI does not currently surface a per-call cost estimate; if cost becomes a concern, switch the model to a smaller one and watch your provider's usage dashboard.
For agents
Prompt tuning + the back-test harness
The default prompts in src/main/services/continuous-summary-prompts/ (originally.ts, lastAsked.ts, and agent.ts) are the descendants of multiple iteration rounds run through the tools/summary-tester/ harness — a small Node + browser tool that runs each candidate prompt against a curated set of real session threads, parses the JSON, and runs an automated rule-violation evaluator (jargon, preamble, workflow plumbing, process metadata, empty intensifiers, scaffolding verbs at start of did, URL/email leakage, hallucinated names). The 3-piece architecture (originallyPrompt AI + lastAskedPrompt AI + agentPrompt AI) inherits the full rule set tuned across those iteration rounds. The Originally prompt was added once it became clear that a verbatim 1000-char slice was unusable for sessions whose first message was a multi-thousand-line log dump — the AI summary distills the user's first message into a single short sentence regardless of input size, with a verbatim slice fallback when the AI call fails.
When changing a default prompt, run the harness against the same threads to verify rule compliance hasn't regressed. The harness expects a local prompts.json populated from prompts-source.js via node sync-prompts.js, then node evaluate.js for the rule-violation tally. See the harness README.md for setup.
Code references
- UI panel (live + back-test render):
src/renderer/src/features/sessions/ContinuousSummaryPanel.tsx - Visibility gate (status × enabled × visible):
src/renderer/src/features/sessions/continuous-summary-visibility.ts - SessionPanel mount + push listener:
src/renderer/src/features/sessions/SessionPanel.tsx - Renderer store (cache + chevron state + actions):
src/renderer/src/stores/continuous-summary-store.ts - Settings UI (three-section editor, collapse, draft sync, auto-expand):
src/renderer/src/features/settings/sections/continuous-summary/ContinuousSummarySettings.tsx - Settings mount point +
pendingSettingIdthreading:src/renderer/src/features/settings/AiProviderSettings.tsx(deleted — former mount host; see the 2026-06-20 note above) - Backend service (trigger logic, parallel AI calls, hidden-pairs append):
src/main/services/continuous-summary-service.ts - Default prompts + variable interpolation + JSON parsers:
src/main/services/continuous-summary-prompts/index.ts - IPC handlers:
src/main/ipc/continuous-summary-handlers.ts - IPC channels:
CONTINUOUS_SUMMARY_GET_LATEST,CONTINUOUS_SUMMARY_LIST_HISTORY,CONTINUOUS_SUMMARY_REGENERATE_NOW,CONTINUOUS_SUMMARY_RUN_BACKTEST, push:CONTINUOUS_SUMMARY_UPDATED(src/shared/ipc-channels/index.ts) - DB queries:
src/main/db/queries-sessions/session-summaries.ts(table added in migration v115) - Settings fields:
continuousSummaryEnabled,continuousSummaryShowAgentSummary(gates ONLY the agent'sDid/Asksrows AND the agent AI call; theOriginallyandLast askedrows + the user'sLast askedAI call are independent of this toggle; defaultfalse),continuousSummaryRecentTurnsVisible(integer 1–5 inclusive, default1; controls how many turns render in the inline prior-pairs history — the prior-Askedrows render in both modes, the prior-Didrows are gated bycontinuousSummaryShowAgentSummary),continuousSummaryModel,continuousSummaryOriginallyPromptTemplate,continuousSummaryOriginallyLengthCap(fallback verbatim cap only — the AI summary length is constrained by the prompt rules),continuousSummaryLastAskedPromptTemplate,continuousSummaryAgentPromptTemplateinsrc/shared/types.tsand matching Zod fields insrc/shared/ipc-schemas.ts.
Related
The other place Omniscio writes a summary of a session for you is the compaction summary page. What "waiting on you" means for a session, and where those sessions are gathered, is described on inbox overview.
Last verified 2026-10-06