Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/src/components/ContextUsageInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ export function ContextUsageInspector({
<span>
{t("chat.usageCompaction", { times: compaction.generation })}
</span>
<strong>~{formatCompactTokenCount(compaction.summaryTokens)}</strong>
<strong title={compaction.summarized && !compaction.fallback && compaction.summary?.trim() ? compaction.summary : undefined}>~{formatCompactTokenCount(compaction.summaryTokens)}</strong>
</div>
) : null}
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/features/chat/transcript/AssistantTurn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,14 @@ export const AssistantTurn = memo(function AssistantTurn({
* turn item: a divider that says the earlier turns above it are now a summary.
* It carries no actions — nothing about a persisted checkpoint is undoable.
*/
export function CompactionRow({ mark }: { mark: ContextCompactionMark }) {
export function CompactionRow({ mark }: { mark: ContextCompactionMark & { summary?: string } }) {
const { t } = useTranslation();
return (
<div className="transcript-compaction-row" role="separator">
<span className="transcript-compaction-label">
{t("chat.compactionRow", { times: mark.generation })}
</span>
<span className="transcript-compaction-detail">
<span className="transcript-compaction-detail" title={mark.summarized && !mark.fallback && mark.summary?.trim() ? mark.summary : undefined}>
{mark.fallback
? t("chat.compactionRowSummaryFailed")
: mark.summarized
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/stores/app-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export type AppState = {
/** Latest terminal outcome per session for compact sidebar feedback. */
sessionOutcomes: Record<string, SidebarSessionOutcome>;
/** Every checkpoint a session has installed, oldest first. */
sessionCompactions: Record<string, ContextCompactionMark[]>;
sessionCompactions: Record<string, (ContextCompactionMark & { summary?: string })[]>;
providers: ProviderPublic[];
/** Discovered model lists per provider id (composer model menu). */
providerModels: Record<string, ModelInfo[]>;
Expand Down
10 changes: 6 additions & 4 deletions apps/desktop/src/stores/app-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,12 @@ function persistCurrentSidebar(getState: () => AppState): void {

/** Append a freshly installed checkpoint, or replace a retried one by id. */
function withCompactionMark(
marks: ContextCompactionMark[] | undefined,
mark: ContextCompactionMark,
): ContextCompactionMark[] {
return [...(marks ?? []).filter((existing) => existing.id !== mark.id), mark];
marks: AppState["sessionCompactions"][string] | undefined,
mark: AppState["sessionCompactions"][string][number],
): AppState["sessionCompactions"][string] {
const existing = marks?.find((m) => m.id === mark.id);
const merged = { ...mark, summary: mark.summary ?? existing?.summary };
return [...(marks ?? []).filter((m) => m.id !== mark.id), merged];
}

let storeAccess: StoreAccess | null = null;
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/stores/runtime/session-coordination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export function createSessionCoordination({
const records =
session?.compactions ??
(session?.compaction ? [session.compaction] : []);
const marks = records.map(contextCompactionMark);
const marks = records.map((record) => ({ ...contextCompactionMark(record), summary: record.summary }));
set((state) => ({
sessionCompactions:
marks.length > 0
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/test/context-compaction.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ test("a delegate gets the session's turn-boundary budget protection (ADR 0299)",
// retention rule, and the degradation ladder of decision 4.
assert.match(subagentContext, /prepareCompaction\(/);
assert.match(subagentContext, /generateSummaryWithUsage\(/);
assert.match(subagentContext, /contextBudgetFor\(input\.model/);
assert.match(subagentContext, /contextBudgetFor\(model,/);
assert.match(subagentContext, /delegateRetentionMode/);
assert.match(subagentContext, /\? "active_turn"\s*: "completed_turn"/);
assert.match(subagentContext, /degradedDelegateMessages/);
Expand Down Expand Up @@ -356,7 +356,7 @@ test("the transcript shows one row per compaction, the inspector the newest", ()
assert.match(runtime, /checkpointDetailsWithGeneration/);
assert.match(runtime, /mark: contextCompactionMark\(checkpoint\)/);
// Both the durable records and the live event feed the same per-session list.
assert.match(store, /sessionCompactions: Record<string, ContextCompactionMark\[\]>/);
assert.match(store, /sessionCompactions: Record<string, \(ContextCompactionMark & \{ summary\?: string \}\)\[\]>/);
assert.match(store, /rememberSessionCompactions\(id, detail\.session\)/);
assert.match(store, /event\.type === "compaction_end" && event\.ok && event\.mark/);
assert.match(store, /withCompactionMark\(/);
Expand Down
Loading