@ably/ai-transport 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -111
- package/dist/ably-ai-transport.js +2401 -1387
- package/dist/ably-ai-transport.js.map +1 -1
- package/dist/ably-ai-transport.umd.cjs +1 -1
- package/dist/ably-ai-transport.umd.cjs.map +1 -1
- package/dist/constants.d.ts +116 -42
- package/dist/core/agent.d.ts +44 -0
- package/dist/core/channel-options.d.ts +57 -0
- package/dist/core/codec/codec-event.d.ts +9 -0
- package/dist/core/codec/decoder.d.ts +24 -24
- package/dist/core/codec/define-codec.d.ts +100 -0
- package/dist/core/codec/encoder.d.ts +10 -12
- package/dist/core/codec/field-bag.d.ts +85 -0
- package/dist/core/codec/fields.d.ts +141 -0
- package/dist/core/codec/index.d.ts +8 -2
- package/dist/core/codec/input-descriptor-decoder.d.ts +19 -0
- package/dist/core/codec/input-descriptor-encoder.d.ts +22 -0
- package/dist/core/codec/input-descriptors.d.ts +281 -0
- package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
- package/dist/core/codec/output-descriptor-decoder.d.ts +29 -0
- package/dist/core/codec/output-descriptor-encoder.d.ts +31 -0
- package/dist/core/codec/output-descriptors.d.ts +237 -0
- package/dist/core/codec/types.d.ts +470 -119
- package/dist/core/codec/well-known-inputs.d.ts +52 -0
- package/dist/core/transport/agent-session.d.ts +10 -0
- package/dist/core/transport/agent-view.d.ts +296 -0
- package/dist/core/transport/client-session.d.ts +13 -0
- package/dist/core/transport/decode-fold.d.ts +55 -0
- package/dist/core/transport/headers.d.ts +121 -14
- package/dist/core/transport/index.d.ts +5 -6
- package/dist/core/transport/internal/bounded-map.d.ts +20 -0
- package/dist/core/transport/invocation.d.ts +74 -0
- package/dist/core/transport/load-history-pages.d.ts +71 -0
- package/dist/core/transport/load-history.d.ts +44 -0
- package/dist/core/transport/pipe-stream.d.ts +9 -9
- package/dist/core/transport/run-manager.d.ts +76 -0
- package/dist/core/transport/session-support.d.ts +55 -0
- package/dist/core/transport/tree.d.ts +523 -109
- package/dist/core/transport/types/agent.d.ts +375 -0
- package/dist/core/transport/types/client.d.ts +201 -0
- package/dist/core/transport/types/shared.d.ts +24 -0
- package/dist/core/transport/types/tree.d.ts +357 -0
- package/dist/core/transport/types/view.d.ts +249 -0
- package/dist/core/transport/types.d.ts +13 -553
- package/dist/core/transport/view.d.ts +390 -84
- package/dist/core/transport/wire-log.d.ts +102 -0
- package/dist/errors.d.ts +27 -10
- package/dist/index.d.ts +8 -9
- package/dist/logger.d.ts +12 -0
- package/dist/react/ably-ai-transport-react.js +1365 -1010
- package/dist/react/ably-ai-transport-react.js.map +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
- package/dist/react/contexts/client-session-context.d.ts +37 -0
- package/dist/react/contexts/client-session-provider.d.ts +56 -0
- package/dist/react/create-session-hooks.d.ts +116 -0
- package/dist/react/index.d.ts +13 -12
- package/dist/react/internal/skipped-session.d.ts +8 -0
- package/dist/react/internal/use-resolved-session.d.ts +36 -0
- package/dist/react/use-ably-messages.d.ts +17 -14
- package/dist/react/use-client-session.d.ts +81 -0
- package/dist/react/use-create-view.d.ts +14 -13
- package/dist/react/use-tree.d.ts +30 -15
- package/dist/react/use-view.d.ts +81 -50
- package/dist/utils.d.ts +48 -71
- package/dist/vercel/ably-ai-transport-vercel.js +3257 -2499
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
- package/dist/vercel/codec/decode-lifecycle.d.ts +9 -0
- package/dist/vercel/codec/events.d.ts +50 -0
- package/dist/vercel/codec/fields.d.ts +44 -0
- package/dist/vercel/codec/fold-content.d.ts +16 -0
- package/dist/vercel/codec/fold-data.d.ts +16 -0
- package/dist/vercel/codec/fold-input.d.ts +67 -0
- package/dist/vercel/codec/fold-lifecycle.d.ts +16 -0
- package/dist/vercel/codec/fold-text.d.ts +16 -0
- package/dist/vercel/codec/fold-tool-input.d.ts +17 -0
- package/dist/vercel/codec/fold-tool-output.d.ts +16 -0
- package/dist/vercel/codec/index.d.ts +7 -20
- package/dist/vercel/codec/inputs.d.ts +11 -0
- package/dist/vercel/codec/outputs.d.ts +11 -0
- package/dist/vercel/codec/reducer-state.d.ts +121 -0
- package/dist/vercel/codec/reducer.d.ts +62 -0
- package/dist/vercel/codec/tool-transitions.d.ts +2 -8
- package/dist/vercel/codec/wire-data.d.ts +34 -0
- package/dist/vercel/index.d.ts +5 -5
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +2859 -9705
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +1 -45
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
- package/dist/vercel/react/contexts/chat-transport-context.d.ts +9 -7
- package/dist/vercel/react/contexts/chat-transport-provider.d.ts +53 -41
- package/dist/vercel/react/index.d.ts +1 -2
- package/dist/vercel/react/use-chat-transport.d.ts +30 -26
- package/dist/vercel/react/use-message-sync.d.ts +17 -30
- package/dist/vercel/run-end-reason.d.ts +84 -0
- package/dist/vercel/tool-part.d.ts +21 -0
- package/dist/vercel/transport/chat-transport.d.ts +41 -24
- package/dist/vercel/transport/index.d.ts +24 -20
- package/dist/vercel/transport/run-output-stream.d.ts +54 -0
- package/dist/version.d.ts +2 -0
- package/package.json +31 -24
- package/src/constants.ts +124 -51
- package/src/core/agent.ts +92 -0
- package/src/core/channel-options.ts +89 -0
- package/src/core/codec/codec-event.ts +27 -0
- package/src/core/codec/decoder.ts +202 -105
- package/src/core/codec/define-codec.ts +432 -0
- package/src/core/codec/encoder.ts +114 -107
- package/src/core/codec/field-bag.ts +142 -0
- package/src/core/codec/fields.ts +193 -0
- package/src/core/codec/index.ts +56 -6
- package/src/core/codec/input-descriptor-decoder.ts +97 -0
- package/src/core/codec/input-descriptor-encoder.ts +150 -0
- package/src/core/codec/input-descriptors.ts +373 -0
- package/src/core/codec/lifecycle-tracker.ts +10 -9
- package/src/core/codec/output-descriptor-decoder.ts +139 -0
- package/src/core/codec/output-descriptor-encoder.ts +101 -0
- package/src/core/codec/output-descriptors.ts +307 -0
- package/src/core/codec/types.ts +505 -126
- package/src/core/codec/well-known-inputs.ts +96 -0
- package/src/core/transport/agent-session.ts +1085 -0
- package/src/core/transport/agent-view.ts +738 -0
- package/src/core/transport/client-session.ts +780 -0
- package/src/core/transport/decode-fold.ts +101 -0
- package/src/core/transport/headers.ts +234 -22
- package/src/core/transport/index.ts +27 -27
- package/src/core/transport/internal/bounded-map.ts +27 -0
- package/src/core/transport/invocation.ts +98 -0
- package/src/core/transport/load-history-pages.ts +220 -0
- package/src/core/transport/load-history.ts +271 -0
- package/src/core/transport/pipe-stream.ts +63 -39
- package/src/core/transport/run-manager.ts +243 -0
- package/src/core/transport/session-support.ts +96 -0
- package/src/core/transport/tree.ts +1293 -308
- package/src/core/transport/types/agent.ts +434 -0
- package/src/core/transport/types/client.ts +247 -0
- package/src/core/transport/types/shared.ts +27 -0
- package/src/core/transport/types/tree.ts +393 -0
- package/src/core/transport/types/view.ts +288 -0
- package/src/core/transport/types.ts +13 -706
- package/src/core/transport/view.ts +1229 -450
- package/src/core/transport/wire-log.ts +189 -0
- package/src/errors.ts +29 -9
- package/src/event-emitter.ts +3 -2
- package/src/index.ts +86 -42
- package/src/logger.ts +14 -1
- package/src/react/contexts/client-session-context.ts +41 -0
- package/src/react/contexts/client-session-provider.tsx +222 -0
- package/src/react/create-session-hooks.ts +141 -0
- package/src/react/index.ts +24 -13
- package/src/react/internal/skipped-session.ts +62 -0
- package/src/react/internal/use-resolved-session.ts +63 -0
- package/src/react/use-ably-messages.ts +32 -22
- package/src/react/use-client-session.ts +178 -0
- package/src/react/use-create-view.ts +33 -29
- package/src/react/use-tree.ts +61 -30
- package/src/react/use-view.ts +138 -96
- package/src/utils.ts +83 -131
- package/src/vercel/codec/decode-lifecycle.ts +70 -0
- package/src/vercel/codec/events.ts +85 -0
- package/src/vercel/codec/fields.ts +58 -0
- package/src/vercel/codec/fold-content.ts +54 -0
- package/src/vercel/codec/fold-data.ts +46 -0
- package/src/vercel/codec/fold-input.ts +255 -0
- package/src/vercel/codec/fold-lifecycle.ts +85 -0
- package/src/vercel/codec/fold-text.ts +55 -0
- package/src/vercel/codec/fold-tool-input.ts +86 -0
- package/src/vercel/codec/fold-tool-output.ts +79 -0
- package/src/vercel/codec/index.ts +28 -21
- package/src/vercel/codec/inputs.ts +116 -0
- package/src/vercel/codec/outputs.ts +207 -0
- package/src/vercel/codec/reducer-state.ts +169 -0
- package/src/vercel/codec/reducer.ts +191 -0
- package/src/vercel/codec/tool-transitions.ts +3 -14
- package/src/vercel/codec/wire-data.ts +64 -0
- package/src/vercel/index.ts +7 -19
- package/src/vercel/react/contexts/chat-transport-context.ts +8 -7
- package/src/vercel/react/contexts/chat-transport-provider.tsx +87 -59
- package/src/vercel/react/index.ts +3 -5
- package/src/vercel/react/use-chat-transport.ts +44 -66
- package/src/vercel/react/use-message-sync.ts +75 -39
- package/src/vercel/run-end-reason.ts +157 -0
- package/src/vercel/tool-part.ts +25 -0
- package/src/vercel/transport/chat-transport.ts +380 -98
- package/src/vercel/transport/index.ts +38 -37
- package/src/vercel/transport/run-output-stream.ts +169 -0
- package/src/version.ts +2 -0
- package/dist/core/transport/client-transport.d.ts +0 -10
- package/dist/core/transport/decode-history.d.ts +0 -43
- package/dist/core/transport/server-transport.d.ts +0 -7
- package/dist/core/transport/stream-router.d.ts +0 -29
- package/dist/core/transport/turn-manager.d.ts +0 -37
- package/dist/react/contexts/transport-context.d.ts +0 -31
- package/dist/react/contexts/transport-provider.d.ts +0 -49
- package/dist/react/create-transport-hooks.d.ts +0 -124
- package/dist/react/use-active-turns.d.ts +0 -12
- package/dist/react/use-client-transport.d.ts +0 -80
- package/dist/vercel/codec/accumulator.d.ts +0 -21
- package/dist/vercel/codec/decoder.d.ts +0 -22
- package/dist/vercel/codec/encoder.d.ts +0 -41
- package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +0 -30
- package/dist/vercel/tool-approvals.d.ts +0 -124
- package/dist/vercel/tool-events.d.ts +0 -26
- package/src/core/transport/client-transport.ts +0 -977
- package/src/core/transport/decode-history.ts +0 -485
- package/src/core/transport/server-transport.ts +0 -612
- package/src/core/transport/stream-router.ts +0 -136
- package/src/core/transport/turn-manager.ts +0 -165
- package/src/react/contexts/transport-context.ts +0 -37
- package/src/react/contexts/transport-provider.tsx +0 -164
- package/src/react/create-transport-hooks.ts +0 -144
- package/src/react/use-active-turns.ts +0 -72
- package/src/react/use-client-transport.ts +0 -197
- package/src/vercel/codec/accumulator.ts +0 -588
- package/src/vercel/codec/decoder.ts +0 -618
- package/src/vercel/codec/encoder.ts +0 -410
- package/src/vercel/react/use-staged-add-tool-approval-response.ts +0 -87
- package/src/vercel/tool-approvals.ts +0 -380
- package/src/vercel/tool-events.ts +0 -53
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invocation — value object wrapping the JSON body that a client sends to
|
|
3
|
+
* an agent's HTTP endpoint to start a run.
|
|
4
|
+
*
|
|
5
|
+
* The data shape is the wire contract; the {@link Invocation} class is a
|
|
6
|
+
* runtime view of that data with the same fields. {@link Invocation.fromJSON}
|
|
7
|
+
* is the entry point used by agent handlers:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const data = (await req.json()) as InvocationData;
|
|
11
|
+
* const invocation = Invocation.fromJSON(data);
|
|
12
|
+
* const run = session.createRun(invocation, { signal: req.signal });
|
|
13
|
+
* await run.start();
|
|
14
|
+
* await run.loadConversation(); // walk channel history into the session tree
|
|
15
|
+
* const messages = run.messages;
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The body carries only what the agent needs out-of-band before the channel
|
|
19
|
+
* is observable: the session/channel name and the `inputEventId` that triggered
|
|
20
|
+
* the invocation. The agent mints the `invocationId` itself (one per HTTP
|
|
21
|
+
* request) and returns it on the HTTP response, so it is not a body field. Run
|
|
22
|
+
* identity also lives on the channel: the agent mints the `runId` for a fresh
|
|
23
|
+
* run and reads the existing `runId` off the triggering input event for a
|
|
24
|
+
* continuation — so the body carries no run-id either. Per-message metadata —
|
|
25
|
+
* `clientId`, `parent`, `forkOf`, continuation status — likewise lives on the
|
|
26
|
+
* channel and is resolved by the agent from the triggering input event, not
|
|
27
|
+
* from the body. The `inputClientId` the agent re-stamps on its own publishes
|
|
28
|
+
* comes from the publisher's Ably `clientId` on the matched input event, not
|
|
29
|
+
* from a body field.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Wire shape of a single invocation — the JSON body sent from the client
|
|
33
|
+
* transport's HTTP POST to the agent endpoint.
|
|
34
|
+
*/
|
|
35
|
+
export interface InvocationData {
|
|
36
|
+
/**
|
|
37
|
+
* Identifier for the specific input event on the channel that triggered
|
|
38
|
+
* this invocation. The agent locates the event via the `event-id`
|
|
39
|
+
* header. Its wire headers carry the run-id for a continuation (absent for
|
|
40
|
+
* a fresh run), so run identity is resolved from the channel, not the body.
|
|
41
|
+
*/
|
|
42
|
+
inputEventId: string;
|
|
43
|
+
/** Logical name of the session (chat) — used as the Ably channel name. */
|
|
44
|
+
sessionName: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Runtime view of an {@link InvocationData}. Constructed via
|
|
48
|
+
* {@link Invocation.fromJSON}. Read-only; carries no behaviour beyond
|
|
49
|
+
* exposing its fields.
|
|
50
|
+
*/
|
|
51
|
+
export declare class Invocation {
|
|
52
|
+
/**
|
|
53
|
+
* Identifier for the specific input event on the channel that triggered
|
|
54
|
+
* this invocation. Run identity is resolved from that event's wire headers
|
|
55
|
+
* (or minted), not from the body.
|
|
56
|
+
*/
|
|
57
|
+
readonly inputEventId: string;
|
|
58
|
+
/** Logical name of the session (chat). Used as the Ably channel name. */
|
|
59
|
+
readonly sessionName: string;
|
|
60
|
+
private constructor();
|
|
61
|
+
/**
|
|
62
|
+
* Build an Invocation from its JSON wire shape.
|
|
63
|
+
* @param data - Parsed JSON body matching {@link InvocationData}.
|
|
64
|
+
* @returns A new Invocation exposing the same fields.
|
|
65
|
+
*/
|
|
66
|
+
static fromJSON(data: InvocationData): Invocation;
|
|
67
|
+
/**
|
|
68
|
+
* Serialise this invocation to its JSON wire shape — the body a client
|
|
69
|
+
* POSTs to the agent's endpoint to wake a run. Round-trips through
|
|
70
|
+
* {@link Invocation.fromJSON}.
|
|
71
|
+
* @returns The {@link InvocationData} carrying this invocation's identity.
|
|
72
|
+
*/
|
|
73
|
+
toJSON(): InvocationData;
|
|
74
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Logger } from '../../logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* loadHistoryPages — shared low-level history pagination primitive.
|
|
4
|
+
*
|
|
5
|
+
* Consumed by both client (via `load-history.ts`, which layers a complete-
|
|
6
|
+
* domain-message counter on top) and agent (directly, for input-event lookup
|
|
7
|
+
* and conversation hydration). Returns raw Ably messages; does NOT decode.
|
|
8
|
+
*
|
|
9
|
+
* Behaviour:
|
|
10
|
+
* - Attaches the channel (idempotent) then pages via `channel.history()`,
|
|
11
|
+
* using `untilAttach: true` for gapless continuity with any live subscription.
|
|
12
|
+
* - Exposes the underlying pagination as a cursor with `hasNext()` (cheap,
|
|
13
|
+
* no network) and `next()` (one Ably page per call, newest-first within
|
|
14
|
+
* the page).
|
|
15
|
+
* - Per-page failures are retried with bounded exponential backoff; on
|
|
16
|
+
* exhaustion throws `Ably.ErrorInfo` with code `HistoryFetchFailed`.
|
|
17
|
+
* - `signal.aborted` is checked between pages; rejects with
|
|
18
|
+
* `Ably.ErrorInfo` (InvalidArgument) when aborted.
|
|
19
|
+
*
|
|
20
|
+
* Spec: AIT-CT11 / AIT-ST hydration.
|
|
21
|
+
*/
|
|
22
|
+
import * as Ably from 'ably';
|
|
23
|
+
/** Options for {@link loadHistoryPages}. */
|
|
24
|
+
export interface LoadHistoryPagesOptions {
|
|
25
|
+
/** Wire-message limit per Ably page. */
|
|
26
|
+
pageLimit: number;
|
|
27
|
+
/** Set `untilAttach: true` on the underlying history query for gapless continuity with live subscriptions. Default: true. */
|
|
28
|
+
untilAttach?: boolean;
|
|
29
|
+
/** AbortSignal checked between pages. Rejects with InvalidArgument when aborted. */
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
/** Max retries per `page.next()` / initial `history()` failure. Default: 3. */
|
|
32
|
+
maxRetries?: number;
|
|
33
|
+
/** Initial retry backoff in ms (doubled per attempt). Default: 100. */
|
|
34
|
+
retryBackoffMs?: number;
|
|
35
|
+
/** Logger for diagnostic output. */
|
|
36
|
+
logger?: Logger;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Cursor over the channel's history pages.
|
|
40
|
+
*
|
|
41
|
+
* `hasNext()` is cheap (cursor-only, no network); `next()` issues one Ably
|
|
42
|
+
* page fetch (with retry/backoff) and returns its messages. Once `next()`
|
|
43
|
+
* returns `undefined` the cursor is exhausted.
|
|
44
|
+
*/
|
|
45
|
+
export interface HistoryPagesCursor {
|
|
46
|
+
/** True when another Ably page is available (cheap to check; no network). */
|
|
47
|
+
hasNext(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Fetch the next Ably page's messages (newest-first within the page).
|
|
50
|
+
* Returns `undefined` when no more pages are available or the abort
|
|
51
|
+
* signal has fired.
|
|
52
|
+
*/
|
|
53
|
+
next(): Promise<readonly Ably.InboundMessage[] | undefined>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Page through channel history, returning a cursor over Ably pages.
|
|
57
|
+
*
|
|
58
|
+
* Newest-first within each yielded page (matching Ably's native ordering).
|
|
59
|
+
* Caller drives the cursor — calling `next()` until it returns `undefined`
|
|
60
|
+
* or stopping early when a domain-specific stop condition is met
|
|
61
|
+
* (e.g. complete-message counter satisfied, target codec-message-id found,
|
|
62
|
+
* parent chain walk reaches root).
|
|
63
|
+
*
|
|
64
|
+
* The initial Ably history call is awaited eagerly so the returned cursor
|
|
65
|
+
* already knows whether there are pages available (via `hasNext()`).
|
|
66
|
+
* @param channel - The Ably channel to read history from.
|
|
67
|
+
* @param options - Pagination options.
|
|
68
|
+
* @returns A cursor with `hasNext()` (cheap, cursor-only) and `next()` (fetches one page with retry).
|
|
69
|
+
* @throws {Ably.ErrorInfo} `HistoryFetchFailed` on exhausted retry of the initial fetch, or `InvalidArgument` on signal abort.
|
|
70
|
+
*/
|
|
71
|
+
export declare const loadHistoryPages: (channel: Ably.RealtimeChannel, options: LoadHistoryPagesOptions) => Promise<HistoryPagesCursor>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Logger } from '../../logger.js';
|
|
2
|
+
import { HistoryPage, LoadHistoryOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* loadHistory — load conversation history from an Ably channel and return
|
|
5
|
+
* the raw Ably messages as a paginated HistoryPage result.
|
|
6
|
+
*
|
|
7
|
+
* This does NOT decode: it pages back through Ably history via the shared
|
|
8
|
+
* {@link loadHistoryPages} primitive until `limit` complete messages are
|
|
9
|
+
* present, then hands the raw Ably messages (oldest-first) to the caller.
|
|
10
|
+
* The View re-decodes them into the Tree itself, so load-history only needs
|
|
11
|
+
* a cheap, header-based completion counter to decide when to stop paging.
|
|
12
|
+
*
|
|
13
|
+
* The `limit` option controls the number of complete **messages** per page,
|
|
14
|
+
* not the number of Ably messages fetched. A message is complete when
|
|
15
|
+
* its terminal wire signal — `status: "complete"` / `"cancelled"`, or a
|
|
16
|
+
* `discrete` create — has been seen. Runs that span a page boundary are
|
|
17
|
+
* handled by the counter requiring both a start and a terminal signal
|
|
18
|
+
* before counting a message complete.
|
|
19
|
+
*
|
|
20
|
+
* Because Ably history returns newest-first, each page's `rawMessages` are
|
|
21
|
+
* reversed to chronological (oldest-first) so the caller can fold them in
|
|
22
|
+
* order.
|
|
23
|
+
*
|
|
24
|
+
* Spec: AIT-CT11, AIT-CT11b.
|
|
25
|
+
*/
|
|
26
|
+
import type * as Ably from 'ably';
|
|
27
|
+
/**
|
|
28
|
+
* Load conversation history from a channel and return the raw Ably messages.
|
|
29
|
+
*
|
|
30
|
+
* Drives the shared {@link loadHistoryPages} primitive with
|
|
31
|
+
* `untilAttach: true` (gapless continuity with the live subscription) and a
|
|
32
|
+
* Ably message page limit that overprovisions for the many-Ably-messages-per-domain-message
|
|
33
|
+
* ratio. Each `HistoryPage` returned covers up to `limit` complete domain
|
|
34
|
+
* messages; subsequent pages drain over-collected messages from the buffer
|
|
35
|
+
* before pulling more from the iterator.
|
|
36
|
+
*
|
|
37
|
+
* The `limit` option controls the number of complete messages returned per
|
|
38
|
+
* page, not the number of Ably messages fetched.
|
|
39
|
+
* @param channel - The Ably channel to load history from.
|
|
40
|
+
* @param options - Pagination options.
|
|
41
|
+
* @param logger - Logger for diagnostic output.
|
|
42
|
+
* @returns The first page of raw history messages.
|
|
43
|
+
*/
|
|
44
|
+
export declare const loadHistory: (channel: Ably.RealtimeChannel, options: LoadHistoryOptions | undefined, logger: Logger) => Promise<HistoryPage>;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { Logger } from '../../logger.js';
|
|
2
|
-
import {
|
|
2
|
+
import { CodecInputEvent, CodecOutputEvent, Encoder, WriteOptions } from '../codec/types.js';
|
|
3
3
|
import { StreamResult } from './types.js';
|
|
4
4
|
/**
|
|
5
|
-
* Pipe an
|
|
5
|
+
* Pipe an output stream through an encoder to the channel.
|
|
6
6
|
*
|
|
7
7
|
* Returns when the stream completes, is cancelled (via signal), or errors.
|
|
8
8
|
* The `reason` field of the result indicates which case occurred.
|
|
9
|
-
* @param stream - The
|
|
10
|
-
* @param encoder - The
|
|
11
|
-
* @param signal -
|
|
12
|
-
* @param
|
|
13
|
-
* @param resolveWriteOptions - Optional per-
|
|
9
|
+
* @param stream - The output stream to read from.
|
|
10
|
+
* @param encoder - The encoder to publish outputs through.
|
|
11
|
+
* @param signal - AbortSignal to monitor for cancellation.
|
|
12
|
+
* @param onCancelled - Optional callback invoked when the stream is cancelled, before the stream ends.
|
|
13
|
+
* @param resolveWriteOptions - Optional per-output hook returning {@link WriteOptions} overrides to pass to `encoder.publishOutput`.
|
|
14
14
|
* @param logger - Optional logger for diagnostic output.
|
|
15
|
-
* @returns
|
|
15
|
+
* @returns A {@link StreamResult}: `reason` is why the pipe ended, and `error` holds the caught error when `reason` is `'error'`.
|
|
16
16
|
*/
|
|
17
|
-
export declare const pipeStream: <
|
|
17
|
+
export declare const pipeStream: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent>(stream: ReadableStream<TOutput>, encoder: Encoder<TInput, TOutput>, signal: AbortSignal | undefined, onCancelled?: (write: (output: TOutput) => Promise<void>) => void | Promise<void>, resolveWriteOptions?: (output: TOutput) => WriteOptions | undefined, logger?: Logger) => Promise<StreamResult>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Logger } from '../../logger.js';
|
|
2
|
+
import { RunEndReason } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side run state management and lifecycle event publishing.
|
|
5
|
+
*
|
|
6
|
+
* Owns the authoritative run lifecycle. Tracks active runs with their
|
|
7
|
+
* AbortControllers and clientIds. Publishes run-start, run-resume, run-suspend, and
|
|
8
|
+
* run-end events on the Ably channel so all clients can react to run
|
|
9
|
+
* state changes.
|
|
10
|
+
*/
|
|
11
|
+
import type * as Ably from 'ably';
|
|
12
|
+
/**
|
|
13
|
+
* Per-invocation metadata carried on a run's opening lifecycle event. A
|
|
14
|
+
* continuation (re-entering an existing run) sets `continuation` and omits the
|
|
15
|
+
* structural `parent` / `forkOf` / `regenerates` fields.
|
|
16
|
+
*/
|
|
17
|
+
interface StartRunMetadata {
|
|
18
|
+
/** Structural parent codec-message-id (fresh run-start only). */
|
|
19
|
+
parent?: string;
|
|
20
|
+
/** Forked user-prompt codec-message-id for an edit (fresh run-start only). */
|
|
21
|
+
forkOf?: string;
|
|
22
|
+
/** Regenerated assistant codec-message-id (fresh run-start only). */
|
|
23
|
+
regenerates?: string;
|
|
24
|
+
/** Agent-minted invocation id, carried on the lifecycle event. */
|
|
25
|
+
invocationId?: string;
|
|
26
|
+
/** ClientId of the triggering input event. */
|
|
27
|
+
inputClientId?: string;
|
|
28
|
+
/** Codec-message-id of the triggering input event. */
|
|
29
|
+
inputCodecMessageId?: string;
|
|
30
|
+
/** When true, publish `ai-run-resume` (re-entry) instead of `ai-run-start`. */
|
|
31
|
+
continuation?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Manages active runs and publishes run lifecycle events on the channel. */
|
|
34
|
+
export interface RunManager {
|
|
35
|
+
/**
|
|
36
|
+
* Register a run and publish its opening lifecycle event. Publishes
|
|
37
|
+
* `ai-run-start` for a fresh run, or `ai-run-resume` when `metadata.continuation`
|
|
38
|
+
* is set (a subsequent invocation re-entering an existing run). A resume omits
|
|
39
|
+
* the structural `parent` / `forkOf` / `regenerates` headers — the original
|
|
40
|
+
* run-start owns the run's structure.
|
|
41
|
+
*/
|
|
42
|
+
startRun(runId: string, clientId?: string, controller?: AbortController, metadata?: StartRunMetadata): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Suspend a run. Publishes run-suspend on the channel and drops the run's
|
|
45
|
+
* active-run entry — the agent process terminates on suspend, so there is no
|
|
46
|
+
* live AbortController to retain. A cancel arriving during suspension is a
|
|
47
|
+
* no-op; the resuming invocation re-registers the run via {@link startRun}.
|
|
48
|
+
* Carries the same per-invocation attribution as {@link endRun}
|
|
49
|
+
* (`inputClientId`, `inputCodecMessageId`), since a suspend is the terminal
|
|
50
|
+
* event of the suspending invocation just as run-end is of an ending one.
|
|
51
|
+
*/
|
|
52
|
+
suspendRun(runId: string, invocationId?: string, inputClientId?: string, inputCodecMessageId?: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* End a run. Publishes run-end on the channel (stamping `reason` as the
|
|
55
|
+
* run-reason header) and drops the run's active-run entry. Carries the same
|
|
56
|
+
* per-invocation attribution as {@link suspendRun} (`invocationId`,
|
|
57
|
+
* `inputClientId`, `inputCodecMessageId`), since run-end is the terminal event
|
|
58
|
+
* of the ending invocation. When `reason` is `'error'` and an `error` is
|
|
59
|
+
* supplied, its `code` and `message` are additionally stamped as the
|
|
60
|
+
* `error-code` / `error-message` headers — a codec-agnostic baseline failure
|
|
61
|
+
* detail for consumers; omitting `error` publishes a bare `reason: 'error'`.
|
|
62
|
+
*/
|
|
63
|
+
endRun(runId: string, reason: RunEndReason, invocationId?: string, inputClientId?: string, inputCodecMessageId?: string, error?: Ably.ErrorInfo): Promise<void>;
|
|
64
|
+
/** Get the clientId that owns a run. */
|
|
65
|
+
getClientId(runId: string): string | undefined;
|
|
66
|
+
/** Cancel all active runs and clear state. */
|
|
67
|
+
close(): void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create a run manager bound to the given channel.
|
|
71
|
+
* @param channel - The Ably channel to publish lifecycle events on.
|
|
72
|
+
* @param logger - Optional logger for diagnostic output.
|
|
73
|
+
* @returns A new {@link RunManager} instance.
|
|
74
|
+
*/
|
|
75
|
+
export declare const createRunManager: (channel: Ably.RealtimeChannel, logger?: Logger) => RunManager;
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Logger } from '../../logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared lifecycle plumbing for the client and agent sessions.
|
|
4
|
+
*
|
|
5
|
+
* Both `DefaultClientSession` and `DefaultAgentSession` gate their writes on
|
|
6
|
+
* `connect()` having run, detach their channel best-effort on close, and react
|
|
7
|
+
* to channel continuity loss with the same detection rule and error shape.
|
|
8
|
+
* These helpers own that common machinery so the two sessions cannot drift on
|
|
9
|
+
* the connection guard, the detach-swallow behaviour, or — most importantly —
|
|
10
|
+
* the continuity-loss predicate, which encodes channel protocol semantics
|
|
11
|
+
* (Spec AIT-CT19 / AIT-ST12). Each session keeps its own divergent reaction to
|
|
12
|
+
* continuity loss (the client emits; the agent aborts runs and swaps its Tree).
|
|
13
|
+
*/
|
|
14
|
+
import * as Ably from 'ably';
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a session's connect guard: return the in-flight/settled connect
|
|
17
|
+
* promise, or reject with `InvalidArgument` when `connect()` has not been
|
|
18
|
+
* called. Callers `await` the result before any write.
|
|
19
|
+
* @param connectPromise - The session's connect promise, or `undefined` when not yet connected.
|
|
20
|
+
* @param method - The method name being guarded, for the error message.
|
|
21
|
+
* @returns The connect promise.
|
|
22
|
+
* @throws {Ably.ErrorInfo} `InvalidArgument` when `connectPromise` is `undefined`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const requireConnected: (connectPromise: Promise<void> | undefined, method: string) => Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Detach the session's channel on close, best-effort. `connect()` subscribes
|
|
27
|
+
* (which implicitly attaches), so a detach is only attempted when `connect()`
|
|
28
|
+
* ran. A detach failure (e.g. the channel is already FAILED) must not throw out
|
|
29
|
+
* of `close()`, so it is swallowed and logged at debug.
|
|
30
|
+
* @param channel - The session's channel.
|
|
31
|
+
* @param connectPromise - The session's connect promise; detach is skipped when `undefined`.
|
|
32
|
+
* @param logger - Logger for the swallowed-failure debug line, or `undefined`.
|
|
33
|
+
* @param component - The owning class name, used as the log message prefix.
|
|
34
|
+
*/
|
|
35
|
+
export declare const bestEffortDetach: (channel: Ably.RealtimeChannel, connectPromise: Promise<void> | undefined, logger: Logger | undefined, component: string) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether a channel state change breaks message continuity:
|
|
38
|
+
* - FAILED, SUSPENDED, DETACHED — no more messages expected (or a gap)
|
|
39
|
+
* - ATTACHED with `resumed: false` (an UPDATE) — messages were lost
|
|
40
|
+
*
|
|
41
|
+
* The initial attach (ATTACHED with no prior attach) is the caller's concern
|
|
42
|
+
* and is not handled here.
|
|
43
|
+
* @param stateChange - The channel state change to classify.
|
|
44
|
+
* @returns True when continuity was lost.
|
|
45
|
+
*/
|
|
46
|
+
export declare const isContinuityLost: (stateChange: Ably.ChannelStateChange) => boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Build the `ChannelContinuityLost` error for a continuity-breaking state
|
|
49
|
+
* change, attaching the state change's `reason` as `cause`.
|
|
50
|
+
* @param stateChange - The continuity-breaking state change.
|
|
51
|
+
* @param verb - The operation that can no longer proceed, for the
|
|
52
|
+
* `unable to <verb>; ...` message (e.g. "deliver events", "continue").
|
|
53
|
+
* @returns The continuity-loss error.
|
|
54
|
+
*/
|
|
55
|
+
export declare const continuityLostError: (stateChange: Ably.ChannelStateChange, verb: string) => Ably.ErrorInfo;
|