blob: ffe2c946aa96ebd296d04fbfba6808d9f79b4474 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import type {
ChatQueueMessage,
ChatSendMessage,
ConversationHistoryResponse,
ConversationMetricsResponse,
} from "@dispatch/transport-contract";
/**
* Injected transport port — sends chat messages to the server. Accepts both
* `chat.send` (start a turn) and `chat.queue` (enqueue a steering message;
* auto-starts a turn if idle).
*/
export interface ChatTransport {
send(msg: ChatSendMessage | ChatQueueMessage): void;
}
/**
* Optional windowing for a history fetch ([email protected], CR-5).
* Both must be POSITIVE integers when present (the server 400s otherwise).
*/
export interface HistoryWindow {
/** Return only the NEWEST `limit` chunks of the selection (still ascending). */
readonly limit?: number;
/** Exclusive upper bound: only chunks with `seq < beforeSeq` (backfill paging). */
readonly beforeSeq?: number;
}
/**
* Injected history-sync port — fetches incremental history from the server
* (`GET /conversations/:id?sinceSeq=&beforeSeq=&limit=`). NOTE the contract
* caveat: on a windowed/backfill read the response's `latestSeq` describes the
* returned window, not the conversation's high-water mark — never regress a
* tail cursor from it (the FE's cursor comes from the cache's max seq, which
* satisfies this naturally).
*/
export type HistorySync = (
conversationId: string,
sinceSeq: number,
window?: HistoryWindow,
) => Promise<ConversationHistoryResponse>;
/** Injected metrics-sync port — fetches persisted per-turn metrics from the server. */
export type MetricsSync = (conversationId: string) => Promise<ConversationMetricsResponse>;
|