diff options
| author | Adam Malczewski <[email protected]> | 2026-06-22 01:22:21 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-22 01:22:21 +0900 |
| commit | ae8f61cefd383417bc0f80447d7ab1bfdfe0726d (patch) | |
| tree | ddb6ccb08a4338aa2c6ccb397696074d8c2c22c5 /packages/conversation-store | |
| parent | 54613fc2bd4869a95ffda34230006da6d9dfc8c3 (diff) | |
| download | dispatch-ae8f61cefd383417bc0f80447d7ab1bfdfe0726d.tar.gz dispatch-ae8f61cefd383417bc0f80447d7ab1bfdfe0726d.zip | |
fix: compaction keeps original ID, forks old history to archive, chains via compactedFrom
Reworked compaction to match the confirmed design:
- The compacted conversation KEEPS its original ID (messaging between
agents is unaffected — the ID never changes)
- The old full history is forked to a new archive conversation (new UUID)
- The archive inherits the source's compactedFrom, creating a chain:
A → Y → X (walk compactedFrom backward)
- A's history is replaced with [summary + recent N]
- A.compactedFrom = archive ID
forkHistory: inherit compactedFrom from source (not set to sourceId),
so archives chain backward to previous archives.
FE: no tab switching needed — the ID doesn't change. Just reload history.
Diffstat (limited to 'packages/conversation-store')
| -rw-r--r-- | packages/conversation-store/src/store.ts | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/packages/conversation-store/src/store.ts b/packages/conversation-store/src/store.ts index d713de3..700be1e 100644 --- a/packages/conversation-store/src/store.ts +++ b/packages/conversation-store/src/store.ts @@ -113,7 +113,7 @@ export interface ConversationStore { * Set the `compactedFrom` field on a conversation's metadata, pointing to * the archive conversation that holds the pre-compaction history. */ - readonly setCompactedFrom: (conversationId: string, archiveId: string) => Promise<void>; + readonly setCompactedFrom: (conversationId: string, newConversationId: string) => Promise<void>; } export const conversationStoreHandle = defineService<ConversationStore>("conversation-store/store"); @@ -592,7 +592,9 @@ export function createConversationStore( } await storage.set(seqKey(targetId), String(Math.max(seq - 1, 0))); - // Copy metadata with archive title + closed status + compactedFrom. + // Copy metadata with archive title + closed status. + // Inherit compactedFrom from the source so archives chain: + // A → Y → X (each archive points to the previous one). const metaRaw = await storage.get(metaKey(sourceId)); if (metaRaw !== null) { const existing = parseMetaRow(metaRaw); @@ -602,7 +604,9 @@ export function createConversationStore( lastActivityAt: existing.lastActivityAt, title: `Archive: ${existing.title}`, status: "closed", - compactedFrom: sourceId, + ...(existing.compactedFrom !== undefined + ? { compactedFrom: existing.compactedFrom } + : {}), }; await storage.set(metaKey(targetId), JSON.stringify(row)); } @@ -630,7 +634,7 @@ export function createConversationStore( } }, - async setCompactedFrom(conversationId, archiveId) { + async setCompactedFrom(conversationId, newConversationId) { const raw = await storage.get(metaKey(conversationId)); const existing = raw !== null ? parseMetaRow(raw) : null; const ts = now(); @@ -642,7 +646,7 @@ export function createConversationStore( }; await storage.set( metaKey(conversationId), - JSON.stringify({ ...row, compactedFrom: archiveId }), + JSON.stringify({ ...row, compactedFrom: newConversationId }), ); }, }; |
