From 5af664777bd64cddd168679d6369cd188212201a Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 22 Jun 2026 01:09:26 +0900 Subject: feat: non-destructive compaction — fork history to archive before replacing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compaction now preserves the full pre-compaction history: 1. Forks the conversation to a new archive ID (complete copy: chunks, metadata, cwd, reasoning-effort). Archive gets status=closed, title='Archive: ', compactedFrom=. 2. Replaces the original conversation's history with [system: summary] + recent N messages (same as before). 3. Sets compactedFrom= on the original conversation's metadata. The original history is never destroyed. The archive is accessible via GET /conversations/:id using the archive ID. Wire/contract changes: - ConversationMeta: add compactedFrom?: string - CompactionResult: add archiveId: string - ConversationCompactedMessage: add archiveId - CompactResponse: add archiveId Conversation store: - forkHistory(sourceId, targetId): copies all chunks + metadata to a new conversation ID - setCompactedFrom(conversationId, archiveId): marks the conversation --- packages/wire/src/index.ts | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'packages/wire/src') diff --git a/packages/wire/src/index.ts b/packages/wire/src/index.ts index 69f35f0..8c85f89 100644 --- a/packages/wire/src/index.ts +++ b/packages/wire/src/index.ts @@ -521,6 +521,12 @@ export interface ConversationMeta { readonly lastActivityAt: number; readonly title: string; readonly status: ConversationStatus; + /** + * Set on a compacted conversation: points to the archive conversation ID + * that holds the full pre-compaction history. Absent on conversations + * that have never been compacted. + */ + readonly compactedFrom?: string; } // ─── Compaction ────────────────────────────────────────────────────────────── @@ -529,9 +535,12 @@ export interface ConversationMeta { * Result of a compaction operation. `summary` is the text the model produced; * `messagesKept` is how many recent messages were retained after the summary; * `messagesSummarized` is how many old messages were replaced by the summary. + * `archiveId` is the ID of the new conversation that holds the full + * pre-compaction history (non-destructive — the original history is preserved). */ export interface CompactionResult { readonly summary: string; + readonly archiveId: string; readonly messagesSummarized: number; readonly messagesKept: number; } -- cgit v1.2.3