From 2cfb78fc36744ee20615876fbb40bd56514eb241 Mon Sep 17 00:00:00 2001 From: Nikita Ashikhmin Date: Thu, 13 Aug 2026 01:20:31 +0400 Subject: [PATCH] feat: add versioned context compaction metadata Expose compaction through the shared provider-neutral ACP tool lifecycle so clients can recognize it without relying on adapter-specific text. --- src/CodexToolCallMapper.ts | 13 +++++---- src/ContextCompactionMeta.ts | 29 +++++++++++++++++++ .../data/context-compaction-lifecycle.json | 14 +++++---- .../data/load-session-history.json | 8 +++-- 4 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 src/ContextCompactionMeta.ts diff --git a/src/CodexToolCallMapper.ts b/src/CodexToolCallMapper.ts index 3402cfc0..fe139bac 100644 --- a/src/CodexToolCallMapper.ts +++ b/src/CodexToolCallMapper.ts @@ -32,6 +32,7 @@ import { createTerminalOutputMeta, type TerminalOutputMode, } from "./TerminalOutputMode"; +import {createContextCompactionMeta} from "./ContextCompactionMeta"; type CodexItemStatus = CommandExecutionStatus | PatchApplyStatus | McpToolCallStatus | DynamicToolCallStatus | CollabAgentToolCallStatus; type AcpToolCallStatus = "pending" | "in_progress" | "completed" | "failed"; @@ -45,7 +46,7 @@ type CommandExecutionItem = ThreadItem & { type: "commandExecution" }; type ContextCompactionItem = ThreadItem & { type: "contextCompaction" }; type AcpToolCallEvent = Extract; -const CONTEXT_COMPACTION_META = { contextCompaction: true }; +const CONTEXT_COMPACTION_META = createContextCompactionMeta(); function toAcpStatus(status: CodexItemStatus): AcpToolCallStatus { switch (status) { @@ -230,8 +231,8 @@ export function createContextCompactionStartUpdate( return { sessionUpdate: "tool_call", toolCallId: item.id, - kind: "other", - title: "Context compacting", + kind: "think", + title: "Compact conversation", status: "in_progress", _meta: CONTEXT_COMPACTION_META, }; @@ -243,7 +244,7 @@ export function createContextCompactionCompleteUpdate( return { sessionUpdate: "tool_call_update", toolCallId: item.id, - title: "Context compacted", + title: "Compact conversation", status: "completed", _meta: CONTEXT_COMPACTION_META, }; @@ -255,8 +256,8 @@ export function createCompletedContextCompactionUpdate( return { sessionUpdate: "tool_call", toolCallId: item.id, - kind: "other", - title: "Context compacted", + kind: "think", + title: "Compact conversation", status: "completed", _meta: CONTEXT_COMPACTION_META, }; diff --git a/src/ContextCompactionMeta.ts b/src/ContextCompactionMeta.ts new file mode 100644 index 00000000..dbffc7d2 --- /dev/null +++ b/src/ContextCompactionMeta.ts @@ -0,0 +1,29 @@ +export const CONTEXT_COMPACTION_META_KEY = "contextCompaction"; +export const CONTEXT_COMPACTION_META_VERSION = 1; + +export type ContextCompactionTrigger = "manual" | "automatic"; + +export interface ContextCompactionMetadata { + version: typeof CONTEXT_COMPACTION_META_VERSION; + trigger?: ContextCompactionTrigger; + preTokens?: number; + postTokens?: number; + durationMs?: number; + error?: string; +} + +/** + * Provider-neutral metadata for a synthetic ACP context-compaction tool call. + * The standard toolCallId and status fields own lifecycle identity and phase; + * this extension carries only compaction-specific facts. + */ +export function createContextCompactionMeta( + metadata: Omit = {}, +): Record { + return { + [CONTEXT_COMPACTION_META_KEY]: { + version: CONTEXT_COMPACTION_META_VERSION, + ...metadata, + }, + }; +} diff --git a/src/__tests__/CodexACPAgent/data/context-compaction-lifecycle.json b/src/__tests__/CodexACPAgent/data/context-compaction-lifecycle.json index bbc4a32d..53d145ba 100644 --- a/src/__tests__/CodexACPAgent/data/context-compaction-lifecycle.json +++ b/src/__tests__/CodexACPAgent/data/context-compaction-lifecycle.json @@ -6,11 +6,13 @@ "update": { "sessionUpdate": "tool_call", "toolCallId": "context-compaction-id", - "kind": "other", - "title": "Context compacting", + "kind": "think", + "title": "Compact conversation", "status": "in_progress", "_meta": { - "contextCompaction": true + "contextCompaction": { + "version": 1 + } } } } @@ -24,10 +26,12 @@ "update": { "sessionUpdate": "tool_call_update", "toolCallId": "context-compaction-id", - "title": "Context compacted", + "title": "Compact conversation", "status": "completed", "_meta": { - "contextCompaction": true + "contextCompaction": { + "version": 1 + } } } } diff --git a/src/__tests__/CodexACPAgent/data/load-session-history.json b/src/__tests__/CodexACPAgent/data/load-session-history.json index 16a14532..8d758b67 100644 --- a/src/__tests__/CodexACPAgent/data/load-session-history.json +++ b/src/__tests__/CodexACPAgent/data/load-session-history.json @@ -391,11 +391,13 @@ "update": { "sessionUpdate": "tool_call", "toolCallId": "item-context-compaction-1", - "kind": "other", - "title": "Context compacted", + "kind": "think", + "title": "Compact conversation", "status": "completed", "_meta": { - "contextCompaction": true + "contextCompaction": { + "version": 1 + } } } }