summaryrefslogtreecommitdiffhomepage
path: root/frontend-compaction-handoff.md
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-30 01:30:06 +0900
committerAdam Malczewski <[email protected]>2026-06-30 01:30:06 +0900
commitbf74aeab143a49005c380706ae9847cf064fd2f2 (patch)
treec9e93dc0ebe818e7c0d0aafeba8387afd161da3f /frontend-compaction-handoff.md
parent6dd9ea9b935e5011c16faed6c869c976cf5ff172 (diff)
downloaddispatch-main.tar.gz
dispatch-main.zip
chore: remove old handoff docs, plans, review reports, and task lists from rootHEADmaindev
Removed 40+ markdown files that were cluttering the repo root: - frontend-*-handoff.md (28 files) — historical API contract handoffs, features all implemented - backend-to-fe-handoff.md, backend-to-fe-handoff-2.md — old handoff docs - broken-chat-repair-handoff.md — old repair handoff - PLAN-mcp.md, PLAN-per-edit-diagnostics.md — old planning docs - ai-review-report.md, crash-review-report.md — one-time review reports - tasks.md, HANDOFF.md — outdated status docs (git log is the source of truth) Kept: AGENTS.md, GLOSSARY.md, ORCHESTRATOR.md, README.md Also: gitignored ai-review-report.md so future Gemini reviews don't commit it
Diffstat (limited to 'frontend-compaction-handoff.md')
-rw-r--r--frontend-compaction-handoff.md167
1 files changed, 0 insertions, 167 deletions
diff --git a/frontend-compaction-handoff.md b/frontend-compaction-handoff.md
deleted file mode 100644
index 195bc1e..0000000
--- a/frontend-compaction-handoff.md
+++ /dev/null
@@ -1,167 +0,0 @@
-# FE handoff — conversation compacting
-
-Courier this to `../frontend`. All changes are ADDITIVE.
-
-## What shipped (backend)
-
-Conversation compaction: summarize old history into a summary + recent N,
-preserving the full pre-compaction history in a separate archive conversation.
-Creates a linked chain of archives you can walk backward.
-
-Two modes:
-- **Manual**: `POST /conversations/:id/compact` — triggers immediately.
-- **Automatic**: after each turn settles, the backend checks if the last turn's
- input tokens exceeded the per-conversation `compactThreshold` (default 85).
- If so, compaction runs automatically (fire-and-forget, non-blocking).
-
-## How compaction works — non-destructive, chained
-
-The compacted conversation **keeps its original ID** (so messaging between
-agents still works). The old full history is **forked** to a new archive
-conversation (new UUID). The archive inherits the source's `compactedFrom`,
-creating a chain:
-
-```
-Compaction 1: A (ID "abc") — full history forked to X (new ID).
- A's history replaced with [summary + recent N].
- A.compactedFrom = X
-
-Compaction 2: A (ID "abc") — current history forked to Y (new ID).
- A's history replaced with [new summary + recent N].
- A.compactedFrom = Y
- Y.compactedFrom = X (inherited from A's pre-compaction state)
-
-Chain: A → Y → X (walk compactedFrom backward)
-```
-
-Each archive is an **immutable snapshot** — a complete copy of the conversation
-at the time of that compaction. History is never destroyed.
-
-The FE **does not switch tabs** — the conversation ID doesn't change. Just
-reload the history.
-
-## Bump pinned deps
-- `@dispatch/wire` → `0.11.0`
-- `@dispatch/transport-contract` → `0.15.0`
-
-## New types
-
-```ts
-// @dispatch/wire — ConversationMeta now has compactedFrom
-export interface ConversationMeta {
- readonly id: string;
- readonly createdAt: number;
- readonly lastActivityAt: number;
- readonly title: string;
- readonly status: ConversationStatus; // "active" | "idle" | "closed"
- /** Points to the archive conversation with full pre-compaction history. */
- readonly compactedFrom?: string;
-}
-
-// @dispatch/wire
-export interface CompactionResult {
- readonly summary: string;
- readonly newConversationId: string; // ID of the archive (old full history)
- readonly messagesSummarized: number;
- readonly messagesKept: number;
-}
-
-// @dispatch/transport-contract — WS message (server → client)
-export interface ConversationCompactedMessage {
- readonly type: "conversation.compacted";
- readonly conversationId: string; // the conversation (ID unchanged)
- readonly newConversationId: string; // the archive ID (old full history)
- readonly messagesSummarized: number;
- readonly messagesKept: number;
-}
-// Added to WsServerMessage union.
-
-// @dispatch/transport-contract — HTTP response types
-export interface CompactResponse {
- readonly conversationId: string; // the conversation (ID unchanged)
- readonly newConversationId: string; // the archive ID (old full history)
- readonly messagesSummarized: number;
- readonly messagesKept: number;
-}
-
-export interface CompactPercentResponse {
- readonly conversationId: string;
- readonly percent: number; // 0 = manual only; null = default 85
-}
-
-export interface SetCompactPercentRequest {
- readonly percent: number;
-}
-```
-
-## `POST /conversations/:id/compact` — manual compaction
-
-Triggers compaction on demand. Optional JSON body:
-```json
-{ "keepLastN": 10, "modelName": "umans/umans-glm-5.2" }
-```
-- `keepLastN` (default 10): how many recent messages to retain.
-- `modelName`: override the model used for summarization.
-
-200 response: `CompactResponse` — includes `newConversationId` (the archive ID).
-The conversation ID in the response is the same as the request — the ID doesn't
-change. The FE should reload the conversation history.
-
-409: `{ error: string }` — conversation is generating, too short, percent not exceeded, etc.
-503: compaction service not available.
-
-## `GET /conversations/:id/compact-percent` — read percent
-
-200: `CompactPercentResponse { conversationId, percent }`
-- `percent: 0` — auto-compact explicitly disabled (manual only).
-- `percent: null` (not stored) — **default: 85** (85% tokens). The FE
- should display 85 as the default value in the settings UI.
-- Any positive number — auto-compact triggers when the last turn's input tokens
- exceed this value.
-
-## `PUT /conversations/:id/compact-percent` — set percent
-
-Body: `SetCompactPercentRequest { percent: number }`
-- `0` explicitly disables auto-compact.
-- Any positive number sets the trigger percent.
-- To "reset to default", set it to 85.
-
-## `conversation.compacted` WS message
-
-Broadcast to all connected WS clients when compaction completes. The FE should
-**reload the conversation history** via `GET /conversations/:id` (the
-conversation ID hasn't changed — just reload the same ID). The first message
-will now be a system summary.
-
-No tab switching needed — the ID is the same.
-
-## What the FE needs to do
-
-1. **Compact button** in the conversation toolbar → `POST /conversations/:id/compact`.
- Show a loading indicator while waiting. On success, reload the conversation
- history (same ID — just re-fetch).
-
-2. **Settings UI** for compact percent: `PUT /conversations/:id/compact-percent`
- with `{ percent: number }`. A number input (0 = manual only, default 85).
- Read the current value via `GET /conversations/:id/compact-percent`.
-
-3. **Handle `conversation.compacted` WS messages**: reload the conversation
- history via `GET /conversations/:id` (same ID, no tab switch).
-
-4. **"View predecessor" link**: when `ConversationMeta.compactedFrom` is present,
- show a link that opens the archive conversation in a read-only view (or a new
- tab). Load it via `GET /conversations/:compactedFrom`. The archive has
- `status: "closed"` and title `"Archive: <original>"`. Each archive may also
- have its own `compactedFrom` — walk the chain backward to see every snapshot.
-
-5. **Archives in conversation list**: archives appear in
- `GET /conversations?status=closed`. They have `compactedFrom` chaining to
- the previous archive (if any). The FE can show them in a history view.
-
-6. **Visual indicator**: show a badge on conversations that have a
- `compactedFrom` (they've been compacted). E.g. "Compacted" badge or chain icon.
-
-## CLI
-
-`dispatch compact <conversationId>` — triggers manual compaction. Resolves
-short IDs like other commands. The response includes the archive ID.