From 44e27177892a48a51c440676ff3f6613deef5164 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 6 Jun 2026 19:39:05 +0900 Subject: feat(wire,conversation-store): per-chunk seq sync cursor (StoredChunk) Add StoredChunk { seq, role, chunk } to @dispatch/wire (re-exported via the kernel contract shims). Keeps Chunk pure (provider-facing, no cursor); the sync cursor lives only on the envelope. conversation-store: rekey conv::msg: -> conv::chunk:; append explodes messages into role-tagged seq'd chunks (1-based, gap-free, monotonic) with internal boundary metadata so load() round-trips ChatMessage[] losslessly and still reconciles; new loadSince(id, sinceSeq?) raw sync stream. session-orchestrator test fake conforms to the widened interface. FE Slice 2 backend prereq (per-chunk seq). typecheck clean, 469 vitest, biome clean. --- packages/wire/src/index.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'packages/wire/src') diff --git a/packages/wire/src/index.ts b/packages/wire/src/index.ts index d2ea341..82fb3ed 100644 --- a/packages/wire/src/index.ts +++ b/packages/wire/src/index.ts @@ -92,6 +92,22 @@ export interface ChatMessage { readonly chunks: readonly Chunk[]; } +/** + * A persisted chunk plus its sync metadata. The append-only conversation log + * stamps every chunk with a monotonic, gap-free, per-conversation `seq` (the + * sync cursor, assigned in append order) and records the `role` of the message + * it belongs to. This makes a flat seq-ordered stream both incrementally + * syncable ("give me chunks after seq N") and regroupable into messages by the + * client. `chunk` is the pure content unit, unchanged — `Chunk` itself never + * carries storage metadata (it is also passed to/from the provider, which has + * no use for a cursor). + */ +export interface StoredChunk { + readonly seq: number; + readonly role: Role; + readonly chunk: Chunk; +} + // ─── Usage ────────────────────────────────────────────────────────────────── /** -- cgit v1.2.3