summaryrefslogtreecommitdiffhomepage
path: root/packages/transport-contract/src
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-06 19:53:51 +0900
committerAdam Malczewski <[email protected]>2026-06-06 19:53:51 +0900
commit61b6e24c7abb4eebf94da0a0498a68a1bb8ba92e (patch)
tree47f8a60a0c4c51c1fa8beee2cb90fd54abf91c68 /packages/transport-contract/src
parent44e27177892a48a51c440676ff3f6613deef5164 (diff)
downloaddispatch-61b6e24c7abb4eebf94da0a0498a68a1bb8ba92e.tar.gz
dispatch-61b6e24c7abb4eebf94da0a0498a68a1bb8ba92e.zip
feat(transport-http): GET /conversations/:id?sinceSeq= read-side history endpoint
Incremental rehydration endpoint for long-lived clients. Returns ConversationHistoryResponse { chunks: StoredChunk[], latestSeq } — the RAW, append-order, seq-filtered slice from conversation-store.loadSince, NOT reconciled (reconcile conflicts with the per-chunk seq cursor, so it stays on the turn path; the read path is a pure sync primitive). - transport-contract: add ConversationHistoryResponse + StoredChunk re-export. - transport-http: GET /conversations/:id route reaching the log directly via conversationStoreHandle (dependsOn conversation-store); pure parseSinceSeq (absent->0, invalid->400). - build wiring: conversation-store dep + project ref. FE Slice 2 backend prereq (read-side). typecheck clean, 481 vitest, biome clean.
Diffstat (limited to 'packages/transport-contract/src')
-rw-r--r--packages/transport-contract/src/index.ts30
1 files changed, 29 insertions, 1 deletions
diff --git a/packages/transport-contract/src/index.ts b/packages/transport-contract/src/index.ts
index 7d3996a..9d8f6f4 100644
--- a/packages/transport-contract/src/index.ts
+++ b/packages/transport-contract/src/index.ts
@@ -12,7 +12,9 @@
* union, re-exported here so a client has one import for the whole wire.
*/
-export type { AgentEvent } from "@dispatch/wire";
+import type { StoredChunk } from "@dispatch/wire";
+
+export type { AgentEvent, StoredChunk } from "@dispatch/wire";
/**
* Request body for `POST /chat` (sent as JSON).
@@ -55,3 +57,29 @@ export interface ChatRequest {
export interface ModelsResponse {
readonly models: readonly string[];
}
+
+/**
+ * Response body for `GET /conversations/:id?sinceSeq=<n>` — the incremental
+ * read-side history endpoint a long-lived client uses to (re)hydrate a
+ * conversation cheaply.
+ *
+ * `chunks` is the RAW, append-order, seq-ordered slice of the conversation log
+ * with `seq > sinceSeq` (or the whole log when `sinceSeq` is omitted/0). It is
+ * NOT reconciled: a dangling tool-call is returned as-is (rendered as an
+ * interrupted call). Reconciliation is a turn-path concern — the server repairs
+ * history only when it feeds a provider, never on this read path — which is what
+ * preserves the per-chunk `seq` cursor invariant (a synthesized repair chunk
+ * would have no seq).
+ *
+ * `latestSeq` is the `seq` of the LAST chunk in this response, or — when the
+ * slice is empty (the client is already caught up) — the requested `sinceSeq`
+ * (0 for a full read of an empty conversation). So after applying the response a
+ * client's new cursor is always `latestSeq`, and an empty `chunks` means
+ * "nothing new past your cursor". (A true server-side high-water mark
+ * independent of the filter is deferred until a consumer needs it — it would
+ * require widening the store contract.)
+ */
+export interface ConversationHistoryResponse {
+ readonly chunks: readonly StoredChunk[];
+ readonly latestSeq: number;
+}