diff options
| author | Adam Malczewski <[email protected]> | 2026-06-22 01:09:26 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-22 01:09:26 +0900 |
| commit | 5af664777bd64cddd168679d6369cd188212201a (patch) | |
| tree | 8e72022183b8d72eccdb568de5776d74cd91f1aa /packages/transport-http/src | |
| parent | 28154825fb47248be21a0d64fc36492fb01c9a42 (diff) | |
| download | dispatch-5af664777bd64cddd168679d6369cd188212201a.tar.gz dispatch-5af664777bd64cddd168679d6369cd188212201a.zip | |
feat: non-destructive compaction — fork history to archive before replacing
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: <original>', compactedFrom=<originalId>.
2. Replaces the original conversation's history with [system: summary]
+ recent N messages (same as before).
3. Sets compactedFrom=<archiveId> 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
Diffstat (limited to 'packages/transport-http/src')
| -rw-r--r-- | packages/transport-http/src/app.test.ts | 10 | ||||
| -rw-r--r-- | packages/transport-http/src/app.ts | 1 | ||||
| -rw-r--r-- | packages/transport-http/src/server.bun.test.ts | 2 |
3 files changed, 13 insertions, 0 deletions
diff --git a/packages/transport-http/src/app.test.ts b/packages/transport-http/src/app.test.ts index 51f791f..b265f5e 100644 --- a/packages/transport-http/src/app.test.ts +++ b/packages/transport-http/src/app.test.ts @@ -143,6 +143,8 @@ function createFakeConversationStore( return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; } @@ -869,6 +871,8 @@ describe("GET /conversations/:id", () => { return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; const app = createApp({ conversationStore: store, @@ -942,6 +946,8 @@ describe("GET /conversations/:id", () => { return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; const app = createApp({ conversationStore: store, @@ -1084,6 +1090,8 @@ describe("GET /conversations/:id/metrics", () => { return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; const app = createApp({ conversationStore: brokenStore, @@ -2059,6 +2067,8 @@ describe("PUT /conversations/:id/reasoning-effort", () => { return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; const app = createApp({ conversationStore: store, diff --git a/packages/transport-http/src/app.ts b/packages/transport-http/src/app.ts index fd78f3e..233e30e 100644 --- a/packages/transport-http/src/app.ts +++ b/packages/transport-http/src/app.ts @@ -725,6 +725,7 @@ export function createApp(opts: CreateServerOptions): Hono { const response: CompactResponse = { conversationId, + archiveId: result.archiveId, messagesSummarized: result.messagesSummarized, messagesKept: result.messagesKept, }; diff --git a/packages/transport-http/src/server.bun.test.ts b/packages/transport-http/src/server.bun.test.ts index e770867..3b7700e 100644 --- a/packages/transport-http/src/server.bun.test.ts +++ b/packages/transport-http/src/server.bun.test.ts @@ -70,6 +70,8 @@ function fakeConversationStore(): ConversationStore { return null; }, async setCompactThreshold() {}, + async forkHistory() {}, + async setCompactedFrom() {}, }; } |
