Skip to content

Commit 8dca0fd

Browse files
authored
fix(desktop): show unknown context usage after compaction (#5548)
Treat measurements taken before a successful compaction as stale until a newer request settles. Update the composer display, localized tooltip, tests, and changelog. Generated-by: Codex fix(ui): keep post-compaction anchor over stale snapshot Preserve the selected request anchor timestamp so the context usage resolver can order it against a retained diagnostics snapshot. Cover the post-compaction sequence in resolver tests. Generated-by: Codex fix(ui): order context usage anchors by request settlement Persist the provider request completion time on usage anchors so a later transcript write cannot displace the same request snapshot and its metered window. Preserve legacy anchors and bump the runtime-host compatibility epoch for the new field. Generated-by: Codex docs(changelog): describe the post-compaction gauge fallback The stale reading keeps the gauge chip on its localized Usage label with the compacted-context tooltip; it never rendered a question mark. Align the entry with the shipped ContextUsageAction. Generated-by: Codex docs(ui): explain context usage reading resolution Describe what resolveContextUsage consumes (live Turn snapshot and durable transcript anchors/notes) and the ordering rule it applies after a compaction. Generated-by: Codex fix(ui): order usage anchors against the compaction apply time Record context_compaction_applied when a compaction lands so the boundary carries the apply time rather than the turn's settlement time, and persist completedAt on the settlement usage anchor even without provider telemetry. A send that compacts mid-turn and never completes its retry settles the usage row after the compaction notes while the anchor still describes the pre-compaction request, so readers arbitrate the newest anchored row against a boundary found behind it by event time. The applied row is hidden from the user-facing notes; context_compacted stays the display row. Refs #5547 Generated-by: Codex test(ui): assert context usage tooltips for stale and unavailable readings The share-resolution test only checked the visible label, so a stale reading and an unavailable reading were indistinguishable. Resolve the button aria-describedby to its tooltip element and assert the copy for the stale, measured, and unavailable states so the tooltip follows the reading across transitions in the same mounted control. Generated-by: Codex docs(runtime-host): cover the compaction note kind in the epoch-206 note Generated-by: Codex docs(changelog): name the compaction apply-time boundary row The gauge entry credited context_compacted alone, but the mid-turn boundary is the context_compaction_applied row recorded when a compaction lands; context_compacted stays the settlement-time display note. Refs #5547 Generated-by: Codex fix(runtime): forward compaction boundaries while a turn is running A mid-turn compaction only reached the composer gauge once the turn settled and the transcript refreshed, so the pre-compaction figure stayed on screen for the rest of a long turn. The runtime now emits a context_compaction_applied event when a compaction lands, persists it as the hidden boundary note, and the Runtime Host forwards it over the session subscription. The live context usage tracker holds the gauge on the compacted reading until a measurement that settled after the boundary arrives. Live and transcript readings share one ContextUsageSnapshot union, and the measured reading's window is renamed to contextWindow. Refs #5547 Generated-by: Codex test(ui): align context usage assertions with shortened tooltips Preserve the upstream measured and unavailable tooltip copy in the post-compaction component assertions. The branch compatibility bump was already reconciled while replaying the protocol changes: epoch 214 is ahead of main at 212 and the 213 claims in open PRs #5394 and #5969. Generated-by: Codex
1 parent f757428 commit 8dca0fd

44 files changed

Lines changed: 1785 additions & 196 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@
4040

4141
### Fixed
4242

43+
- The composer's context gauge now falls back to its localized `Usage` label
44+
instead of holding the pre-compaction figure after a compaction: no provider
45+
has tokenized the replacement prompt yet, so the last real count is stale.
46+
A `context_compaction_applied` boundary is persisted and forwarded over the
47+
session subscription the moment a compaction lands, so a mid-turn fold
48+
clears the figure while that turn is still running — the `context_compacted`
49+
note stays the settlement-time display row — and only a measurement that
50+
completed after the boundary restores it. A failed-open compaction is not a
51+
boundary: that request went out with its full raw history.
4352
- Fixed a renderer crash dialog reporting React error #185 ("Maximum update depth
4453
exceeded") coming from the composer's prompt-history inline completion (#4117): the
4554
offer engine the 0.1.11 composer fed could flip-flop its announcement state on

‎apps/desktop/src/main/__tests__/conversation-owner.test.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import type { DesktopSessionSummary } from '../../shared/desktop-session-project
2727
import { createSessionCatalogController, SessionCatalogContext } from '../../renderer/application/contracts/session-catalog/session-catalog-state.js';
2828
import { ConversationProvider, ConversationServicesProvider, ConversationLifecycle, ConversationTranscriptRegion, ConversationComposerRegion, useAppShellSessionUiState, type ConversationObservationServices, type ConversationServices } from '../../renderer/features/conversation/index.js';
2929
import { renderConversationMarkdown, stubComposerGateInputs, stubConversationServices, useConversationOwner } from '../../renderer/features/conversation/testing.js';
30+
import type { LatestRequestUsage } from '../../renderer/application/contracts/session-inspector/latest-request-usage.js';
3031
import { cleanupFakeDom, installReactRenderer } from './fake-dom.js';
3132
import { withComposerSubmission } from './composer-submission-fixture.js';
3233

@@ -97,7 +98,7 @@ function harness(options: {
9798
let setVisible!: (visible: boolean) => void;
9899
let setCovered!: (covered: boolean) => void;
99100
function Transcript(props: NonNullable<typeof transcript>) { transcript = props; transcriptRenders += 1; return null; }
100-
function Composer(_props: { processing: boolean; pendingMessages?: readonly TransientUserMessageProjection[]; latestRequestUsageTokens?: number }) {
101+
function Composer(_props: { processing: boolean; pendingMessages?: readonly TransientUserMessageProjection[]; latestRequestUsage?: LatestRequestUsage }) {
101102
composerRenders += 1;
102103
useEffect(() => { composerMounts += 1; return () => { composerUnmounts += 1; }; }, []);
103104
return null;

0 commit comments

Comments
 (0)