@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
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Core codec interfaces
|
|
2
|
+
* Core codec interfaces for the event-sourced model.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The codec describes the wire as a flat stream of TEvent values. A reducer
|
|
5
|
+
* folds events into an opaque TProjection. The SDK extracts TMessage[] from
|
|
6
|
+
* the projection to populate the conversation Tree.
|
|
7
|
+
*
|
|
8
|
+
* All types are framework-agnostic. Domain codecs (e.g. the Vercel codec)
|
|
9
|
+
* choose concrete shapes for TEvent / TProjection / TMessage.
|
|
6
10
|
*/
|
|
7
11
|
import type * as Ably from 'ably';
|
|
8
12
|
/**
|
|
@@ -18,188 +22,535 @@ export interface ChannelWriter {
|
|
|
18
22
|
/** Replace the data of an existing message identified by its serial. */
|
|
19
23
|
updateMessage(message: Ably.Message, operation?: Ably.MessageOperation, options?: Ably.PublishOptions): Promise<Ably.UpdateDeleteResult>;
|
|
20
24
|
}
|
|
21
|
-
/** Shape of the extras
|
|
25
|
+
/** Shape of the extras config passed through WriteOptions and EncoderOptions. */
|
|
22
26
|
export interface Extras {
|
|
23
|
-
/**
|
|
27
|
+
/** Transport-tier headers to attach to the message's `extras.ai.transport` namespace. */
|
|
24
28
|
headers?: Record<string, string>;
|
|
25
29
|
}
|
|
26
30
|
/** Per-write overrides for encoder operations. */
|
|
27
31
|
export interface WriteOptions {
|
|
28
|
-
/** Override the default clientId for this write. */
|
|
29
|
-
clientId?: string;
|
|
30
32
|
/** Override the default extras for this write. */
|
|
31
33
|
extras?: Extras;
|
|
32
|
-
/** Message identity for
|
|
34
|
+
/** Message identity for projection routing. Stamped as `codec-message-id`. */
|
|
33
35
|
messageId?: string;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* A codec-agnostic description of a discrete Ably message. Used on both sides:
|
|
37
39
|
* - **Encode:** the domain encoder describes what to publish; the encoder core
|
|
38
|
-
* handles header merging
|
|
39
|
-
* - **Decode:** the decoder core extracts these fields from an
|
|
40
|
-
* before calling domain hooks, keeping hooks free of
|
|
40
|
+
* handles header merging and the actual publish.
|
|
41
|
+
* - **Decode:** the decoder core extracts these fields from an
|
|
42
|
+
* `Ably.InboundMessage` before calling domain hooks, keeping hooks free of
|
|
43
|
+
* Ably SDK types.
|
|
41
44
|
*
|
|
42
45
|
* Data is `unknown` because discrete messages can carry arbitrary payloads
|
|
43
46
|
* (strings, objects, etc.) — Ably handles serialization natively.
|
|
44
47
|
*/
|
|
45
48
|
export interface MessagePayload {
|
|
46
|
-
/** Ably message name (
|
|
49
|
+
/** Ably message name — the wire direction (`ai-output` / `ai-input`). */
|
|
47
50
|
name: string;
|
|
48
51
|
/** Message data. Ably handles serialization — strings, objects, and arrays are all valid. */
|
|
49
52
|
data: unknown;
|
|
50
|
-
/**
|
|
51
|
-
|
|
53
|
+
/** Codec-tier headers — the codec's own fields, carried under `extras.ai.codec`. */
|
|
54
|
+
codecHeaders?: Record<string, string>;
|
|
55
|
+
/**
|
|
56
|
+
* Transport-tier headers a codec needs to stamp directly (e.g. `role`,
|
|
57
|
+
* `status`), carried under `extras.ai.transport`. Most codec payloads leave
|
|
58
|
+
* this unset and let the transport layer supply transport headers via config.
|
|
59
|
+
*/
|
|
60
|
+
transportHeaders?: Record<string, string>;
|
|
52
61
|
/** Mark this message as ephemeral (not persisted in channel history). Only meaningful on encode. */
|
|
53
62
|
ephemeral?: boolean;
|
|
54
63
|
}
|
|
55
64
|
/**
|
|
56
|
-
* Payload for streamed messages. Data must be a string because
|
|
57
|
-
*
|
|
58
|
-
*
|
|
65
|
+
* Payload for streamed messages. Data must be a string because the message
|
|
66
|
+
* append lifecycle uses text append/accumulate semantics — deltas are
|
|
67
|
+
* concatenated for recovery and prefix-matching on the decoder.
|
|
59
68
|
*/
|
|
60
69
|
export interface StreamPayload {
|
|
61
|
-
/** Ably message name (
|
|
70
|
+
/** Ably message name — `ai-output` (only outputs stream); not the codec `kind` / stream family. */
|
|
62
71
|
name: string;
|
|
63
72
|
/** Initial or closing data for the stream. Must be a string for append/accumulate semantics. */
|
|
64
73
|
data: string;
|
|
65
|
-
/**
|
|
66
|
-
|
|
74
|
+
/** Codec-tier headers — the codec's own fields, carried under `extras.ai.codec`. */
|
|
75
|
+
codecHeaders?: Record<string, string>;
|
|
76
|
+
/**
|
|
77
|
+
* Transport-tier headers a codec needs to stamp directly (e.g. `role`,
|
|
78
|
+
* `status`), carried under `extras.ai.transport`.
|
|
79
|
+
*/
|
|
80
|
+
transportHeaders?: Record<string, string>;
|
|
67
81
|
}
|
|
68
82
|
/**
|
|
69
83
|
* Running state of a streamed message tracked by the decoder core.
|
|
70
84
|
* Accumulates text across appends and tracks lifecycle (open/closed).
|
|
71
85
|
*/
|
|
72
86
|
export interface StreamTrackerState {
|
|
73
|
-
/** Ably message name (
|
|
87
|
+
/** Ably message name — `ai-output` (only outputs stream); not the codec `kind` / stream family. */
|
|
74
88
|
name: string;
|
|
75
89
|
/** Stream identifier (e.g. chunk.id for text, toolCallId for tool-input). */
|
|
76
90
|
streamId: string;
|
|
77
91
|
/** Full accumulated text so far. */
|
|
78
92
|
accumulated: string;
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Current codec-tier headers (`extras.ai.codec`) for this stream. Initially
|
|
95
|
+
* set from the first publish, but may be replaced on update.
|
|
96
|
+
*/
|
|
97
|
+
codecHeaders: Record<string, string>;
|
|
98
|
+
/**
|
|
99
|
+
* Current transport-tier headers (`extras.ai.transport`) for this stream.
|
|
100
|
+
* Initially set from the first publish, but may be replaced on update.
|
|
101
|
+
*/
|
|
102
|
+
transportHeaders: Record<string, string>;
|
|
103
|
+
/**
|
|
104
|
+
* Highest `Message.version.serial` incorporated into this tracker.
|
|
105
|
+
* Versions are lexicographically comparable within one message serial, so
|
|
106
|
+
* a delivery carrying a version at or below this value is already
|
|
107
|
+
* incorporated and decodes to nothing. Stamped at first contact (a
|
|
108
|
+
* never-mutated message's version serial equals the message serial, which
|
|
109
|
+
* is also the fallback when the version carries no serial) and advanced by
|
|
110
|
+
* each version-bearing delivery.
|
|
111
|
+
*/
|
|
112
|
+
version: string;
|
|
113
|
+
/** Whether this stream has been closed (complete or cancelled). */
|
|
82
114
|
closed: boolean;
|
|
83
115
|
}
|
|
84
116
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* any streaming lifecycle (no trackers, no pending appends, no close).
|
|
88
|
-
*
|
|
89
|
-
* The server transport calls `writeMessages` to publish user messages to the
|
|
90
|
-
* channel. All messages in a single call are published atomically and share
|
|
91
|
-
* a single `x-ably-msg-id`, forming one node in the conversation tree.
|
|
92
|
-
* `writeEvent` is a public API for consumers to publish standalone discrete
|
|
93
|
-
* events outside the streaming flow — it is not called by the transport internally.
|
|
117
|
+
* Transport-derived metadata passed alongside each TEvent into `fold`. Read
|
|
118
|
+
* by the SDK from the inbound Ably message and stamped before each fold call.
|
|
94
119
|
*/
|
|
95
|
-
export interface
|
|
120
|
+
export interface ReducerMeta {
|
|
96
121
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
122
|
+
* Ably channel serial of the wire message that produced this event, or `''`
|
|
123
|
+
* for a not-yet-sequenced optimistic (local) fold. Ordering context only:
|
|
124
|
+
* the transport invokes `fold` in canonical serial order and exactly once
|
|
125
|
+
* per event, so the reducer must not treat a same-or-lower serial as a
|
|
126
|
+
* replay to skip — ordering and dedup are the transport's job, not the
|
|
127
|
+
* reducer's.
|
|
101
128
|
*/
|
|
102
|
-
|
|
129
|
+
serial: string;
|
|
103
130
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* within a stream (e.g. text deltas).
|
|
131
|
+
* Optional `codec-message-id` from the inbound Ably message. Reducers use this
|
|
132
|
+
* to route an event to a target message within the projection (e.g. to
|
|
133
|
+
* amend an existing assistant message addressed by its codec-message-id).
|
|
108
134
|
*/
|
|
109
|
-
|
|
135
|
+
messageId?: string;
|
|
110
136
|
}
|
|
111
137
|
/**
|
|
112
|
-
*
|
|
113
|
-
* `
|
|
114
|
-
*
|
|
138
|
+
* Pure, stateless reducer contract. A reducer folds TEvents into an opaque
|
|
139
|
+
* TProjection. The same `(state, event, meta)` triple must produce the same
|
|
140
|
+
* result every time — `fold` is a pure function and the reducer holds no
|
|
141
|
+
* instance state.
|
|
142
|
+
*
|
|
143
|
+
* Ordering, deduplication, and replay are the transport's responsibility, not
|
|
144
|
+
* the reducer's. The transport invokes `fold` exactly once per event, in
|
|
145
|
+
* canonical order — wire messages ascending by serial, events within a wire in
|
|
146
|
+
* decode order — refolding a node from a fresh `init` when a late wire would
|
|
147
|
+
* otherwise land out of order. The reducer therefore folds unconditionally: it
|
|
148
|
+
* must not keep a serial high-water-mark or skip "already-seen" events.
|
|
149
|
+
* Last-writer-wins for events competing over the same state falls out of fold
|
|
150
|
+
* order, since the highest-serial event folds last.
|
|
151
|
+
*
|
|
152
|
+
* Mutation: `fold` is allowed to mutate the projection passed in and return
|
|
153
|
+
* it. The caller treats the projection as single-owner and never retains a
|
|
154
|
+
* reference to an old state.
|
|
115
155
|
*/
|
|
116
|
-
export interface
|
|
117
|
-
/** Encode and append a streaming domain event to an in-progress stream (delta semantics). */
|
|
118
|
-
appendEvent(event: TEvent, options?: WriteOptions): Promise<void>;
|
|
156
|
+
export interface Reducer<TEvent, TProjection> {
|
|
119
157
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* @param reason - Optional reason string for the abort (e.g. 'cancelled').
|
|
158
|
+
* Build an empty initial projection. Called once per conversation node — a
|
|
159
|
+
* Run node or a run-less input node — before any of that node's events are
|
|
160
|
+
* folded, and again on every refold of that node.
|
|
124
161
|
*/
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
|
|
162
|
+
init(): TProjection;
|
|
163
|
+
/**
|
|
164
|
+
* Fold one TEvent into the projection and return the updated projection.
|
|
165
|
+
* Invoked exactly once per event, in canonical order; the reducer may mutate
|
|
166
|
+
* `state` in place.
|
|
167
|
+
*/
|
|
168
|
+
fold(state: TProjection, event: TEvent, meta: ReducerMeta): TProjection;
|
|
128
169
|
}
|
|
129
170
|
/**
|
|
130
|
-
* A
|
|
131
|
-
*
|
|
132
|
-
*
|
|
171
|
+
* A decoded event tagged with the wire direction it arrived on. The reducer
|
|
172
|
+
* folds this union (not a bare `TInput | TOutput`) so it can dispatch on
|
|
173
|
+
* `direction` rather than inspecting the event's shape. Direction is derived
|
|
174
|
+
* once, from the Ably message name, at decode time (see `toCodecEvents`) — the
|
|
175
|
+
* authoritative signal, since a single message is either `ai-input` or
|
|
176
|
+
* `ai-output` but never both.
|
|
177
|
+
* @template TInput - The codec's input union.
|
|
178
|
+
* @template TOutput - The codec's output union.
|
|
133
179
|
*/
|
|
134
|
-
export type
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
180
|
+
export type CodecEvent<TInput, TOutput> = {
|
|
181
|
+
/** The event arrived on the `ai-input` wire. */
|
|
182
|
+
readonly direction: 'input';
|
|
183
|
+
/** The decoded input event. */
|
|
184
|
+
readonly event: TInput;
|
|
138
185
|
} | {
|
|
139
|
-
|
|
140
|
-
|
|
186
|
+
/** The event arrived on the `ai-output` wire. */
|
|
187
|
+
readonly direction: 'output';
|
|
188
|
+
/** The decoded output event. */
|
|
189
|
+
readonly event: TOutput;
|
|
141
190
|
};
|
|
142
|
-
/**
|
|
143
|
-
export interface StreamDecoder<TEvent, TMessage> {
|
|
144
|
-
/** Decode a single Ably message into zero or more domain outputs. */
|
|
145
|
-
decode(message: Ably.InboundMessage): DecoderOutput<TEvent, TMessage>[];
|
|
146
|
-
}
|
|
147
|
-
/** Accumulates decoder outputs into a list of domain messages, tracking active streams. */
|
|
148
|
-
export interface MessageAccumulator<TEvent, TMessage> {
|
|
149
|
-
/** Process a batch of decoder outputs, updating internal message state. */
|
|
150
|
-
processOutputs(outputs: DecoderOutput<TEvent, TMessage>[]): void;
|
|
151
|
-
/** Apply an external update to a message (e.g. from an update callback). */
|
|
152
|
-
updateMessage(message: TMessage): void;
|
|
153
|
-
/**
|
|
154
|
-
* Ensure the accumulator is ready to process events for the given message.
|
|
155
|
-
* If not already active, creates internal tracking state from the message.
|
|
156
|
-
* If already active, syncs internal state with the provided message
|
|
157
|
-
* (picking up external changes like cross-turn amendments).
|
|
158
|
-
* Idempotent — safe to call before every processOutputs.
|
|
159
|
-
*/
|
|
160
|
-
initMessage(messageId: string, message: TMessage): void;
|
|
161
|
-
/**
|
|
162
|
-
* Mark a message as completed. Removes it from active tracking so it
|
|
163
|
-
* appears in {@link completedMessages}. No-op if not active.
|
|
164
|
-
*/
|
|
165
|
-
completeMessage(messageId: string): void;
|
|
166
|
-
/** All messages accumulated so far (in-progress and completed). */
|
|
167
|
-
readonly messages: TMessage[];
|
|
168
|
-
/** Only messages whose streams have finished. */
|
|
169
|
-
readonly completedMessages: TMessage[];
|
|
170
|
-
/** Whether any stream is still actively receiving data. */
|
|
171
|
-
readonly hasActiveStream: boolean;
|
|
172
|
-
}
|
|
173
|
-
/** Options passed to a codec's `createEncoder` factory to configure default identity and message hooks. */
|
|
191
|
+
/** Options passed to a codec's `createEncoder` factory. */
|
|
174
192
|
export interface EncoderOptions {
|
|
175
|
-
/** Default clientId for all writes. */
|
|
176
|
-
clientId?: string;
|
|
177
193
|
/** Default extras (e.g. headers) merged into every Ably message. */
|
|
178
194
|
extras?: Extras;
|
|
179
|
-
/** Hook called before each Ably message is published. Mutate the message in place to add transport-level headers. */
|
|
195
|
+
/** Hook called before each Ably message is published. Mutate the message in place to add transport-level headers under `extras.ai`. */
|
|
180
196
|
onMessage?: (message: Ably.Message) => void;
|
|
181
197
|
/**
|
|
182
|
-
*
|
|
183
|
-
* messageId
|
|
184
|
-
*
|
|
198
|
+
* Fallback domain message id surfaced to output escape hatches as
|
|
199
|
+
* `ctx.messageId` (e.g. the Vercel `start` hatch injects it when a chunk
|
|
200
|
+
* carries no `messageId` of its own). Unrelated to the wire
|
|
201
|
+
* codec-message-id transport header, which `WriteOptions.messageId` stamps.
|
|
185
202
|
*/
|
|
186
203
|
messageId?: string;
|
|
187
204
|
}
|
|
188
205
|
/**
|
|
189
|
-
*
|
|
206
|
+
* Stateful encoder for a single channel. Two publish methods enforce
|
|
207
|
+
* direction at the call site — `publishInput` for client-published events
|
|
208
|
+
* (`ai-input` wire) and `publishOutput` for agent-published events
|
|
209
|
+
* (`ai-output` wire). Stream-tracker state lives inside the encoder and
|
|
210
|
+
* is shared across both directions.
|
|
211
|
+
*/
|
|
212
|
+
export interface Encoder<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent> {
|
|
213
|
+
/**
|
|
214
|
+
* Encode and publish a single client input on the `ai-input` wire.
|
|
215
|
+
* Rejects if the codec cannot encode the given input
|
|
216
|
+
* variant.
|
|
217
|
+
*/
|
|
218
|
+
publishInput(input: TInput, options?: WriteOptions): Promise<void>;
|
|
219
|
+
/**
|
|
220
|
+
* Encode and publish a single agent output on the `ai-output` wire.
|
|
221
|
+
* Rejects if the codec cannot encode the given output
|
|
222
|
+
* variant.
|
|
223
|
+
*/
|
|
224
|
+
publishOutput(output: TOutput, options?: WriteOptions): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Close all in-progress streamed messages as cancelled (status:cancelled) and
|
|
227
|
+
* flush pending appends. Pure transport mechanics — emits no codec output.
|
|
228
|
+
* Idempotent: streams already cancelled are not re-appended. Must not be
|
|
229
|
+
* called after `close`; doing so throws because the encoder is already closed.
|
|
230
|
+
* Run termination is signalled separately by the transport `ai-run-end` event.
|
|
231
|
+
*/
|
|
232
|
+
cancelStreams(): Promise<void>;
|
|
233
|
+
/** Flush pending appends and release encoder resources. */
|
|
234
|
+
close(): Promise<void>;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Tagged result of decoding one inbound Ably message — the codec routes
|
|
238
|
+
* by the wire `name` and returns inputs and outputs separately so the
|
|
239
|
+
* SDK never has to introspect direction.
|
|
240
|
+
*/
|
|
241
|
+
export interface DecodedMessage<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent> {
|
|
242
|
+
/** Inputs decoded from the inbound message (only populated when the wire `name` is `ai-input`). */
|
|
243
|
+
inputs: TInput[];
|
|
244
|
+
/** Outputs decoded from the inbound message (only populated when the wire `name` is `ai-output`). */
|
|
245
|
+
outputs: TOutput[];
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Stateful decoder for a single channel subscription. Maintains internal
|
|
249
|
+
* stream-tracker state across messages so that mid-stream join (history
|
|
250
|
+
* compaction, partial-history page boundary, rewind miss) synthesizes any
|
|
251
|
+
* missing start events before deltas reach the SDK — the reducer always
|
|
252
|
+
* sees a clean `(start, delta*, end)` sequence.
|
|
253
|
+
*
|
|
254
|
+
* Trackers are version-guarded: a delivery whose `Message.version.serial`
|
|
255
|
+
* is at or below the version already incorporated decodes to nothing. One
|
|
256
|
+
* decoder instance can therefore be shared by the live subscription and
|
|
257
|
+
* history hydration — whichever route delivers a message's content first
|
|
258
|
+
* wins, and the other route's covered deliveries are no-ops.
|
|
259
|
+
*/
|
|
260
|
+
export interface Decoder<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent> {
|
|
261
|
+
/** Decode one Ably inbound message into the input/output halves. */
|
|
262
|
+
decode(message: Ably.InboundMessage): DecodedMessage<TInput, TOutput>;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Structural base every codec input variant must satisfy. Codec authors
|
|
266
|
+
* compose their `TInput` union from variants extending this type; the
|
|
267
|
+
* transport reads the routing fields directly off the variant to stamp
|
|
268
|
+
* wire headers, so no runtime classification step is needed.
|
|
190
269
|
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*/
|
|
196
|
-
export interface
|
|
197
|
-
/**
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
270
|
+
* The `kind` discriminator is required on every variant so the codec's
|
|
271
|
+
* reducer can switch on it. Codec authors pick the literal value per
|
|
272
|
+
* variant; the SDK ships well-known literals (`'user-message'`,
|
|
273
|
+
* `'regenerate'`) — see {@link UserMessage}, {@link Regenerate}.
|
|
274
|
+
*/
|
|
275
|
+
export interface CodecInputEvent {
|
|
276
|
+
/**
|
|
277
|
+
* Discriminator. Codec authors pick the literal value per variant. The
|
|
278
|
+
* SDK reserves the literals used by well-known variants
|
|
279
|
+
* ({@link UserMessage}, {@link Regenerate}); codec-specific variants pick
|
|
280
|
+
* any other literal.
|
|
281
|
+
*/
|
|
282
|
+
kind: string;
|
|
283
|
+
/**
|
|
284
|
+
* Sets the wire `parent` header — the codec-message-id of the
|
|
285
|
+
* preceding codec-message on this branch. When omitted, the SDK
|
|
286
|
+
* auto-computes the parent from the visible branch tail at send time.
|
|
287
|
+
*/
|
|
288
|
+
parent?: string;
|
|
289
|
+
/**
|
|
290
|
+
* Pointer to another codec-message this input references. The semantic
|
|
291
|
+
* depends on `kind` — for `regenerate`, the assistant codec-message to
|
|
292
|
+
* regenerate; codec-specific `kind`s may give it other meanings. The
|
|
293
|
+
* input event itself does not create a fork — it requests one: the
|
|
294
|
+
* transport reads `target` off the input (e.g. the client session maps a
|
|
295
|
+
* regenerate's target into its transport headers) and the fork
|
|
296
|
+
* relationship is established on the agent's response (and on
|
|
297
|
+
* `ai-run-start`).
|
|
298
|
+
*/
|
|
299
|
+
target?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Targets an existing codec-message-id instead of minting a fresh one.
|
|
302
|
+
* Used by continuation inputs (tool results, approval responses) that
|
|
303
|
+
* amend an existing assistant message rather than creating a new one;
|
|
304
|
+
* the wire's `codec-message-id` is stamped with this value so
|
|
305
|
+
* the reducer's direct-fold path matches by codec-message-id.
|
|
306
|
+
*/
|
|
307
|
+
codecMessageId?: string;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Well-known input variant: a new user message in the codec's domain
|
|
311
|
+
* representation. Pinned `kind: 'user-message'`. Produced by the SDK's
|
|
312
|
+
* `Codec.createUserMessage` factory and published via `View.send`
|
|
313
|
+
* (e.g. `view.send(codec.createUserMessage(message))`).
|
|
314
|
+
* @template TMessage - The codec's per-message domain type.
|
|
315
|
+
*/
|
|
316
|
+
export interface UserMessage<TMessage> extends CodecInputEvent {
|
|
317
|
+
/** Discriminator. */
|
|
318
|
+
kind: 'user-message';
|
|
319
|
+
/** The user's message in the codec's domain representation. */
|
|
320
|
+
message: TMessage;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Well-known input variant: request that an existing assistant
|
|
324
|
+
* codec-message be regenerated. Pinned `kind: 'regenerate'`. This event
|
|
325
|
+
* is a signal, not itself a fork — `target` names the assistant message
|
|
326
|
+
* to regenerate, and `parent` names the user message the new assistant
|
|
327
|
+
* threads under. Both are required; the codec cannot regenerate without
|
|
328
|
+
* both. Produced by the SDK's `Codec.createRegenerate` factory and
|
|
329
|
+
* surfaced via `View.regenerate`.
|
|
330
|
+
*/
|
|
331
|
+
export interface Regenerate extends CodecInputEvent {
|
|
332
|
+
/** Discriminator. */
|
|
333
|
+
kind: 'regenerate';
|
|
334
|
+
/** The codec-message-id of the assistant to regenerate. Required. */
|
|
335
|
+
target: string;
|
|
336
|
+
/** The codec-message-id of the parent user message the new assistant threads under. Required. */
|
|
337
|
+
parent: string;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Well-known input variant: client-published tool result (success). The
|
|
341
|
+
* tool ran and produced output. Mutates the assistant codec-message
|
|
342
|
+
* addressed by `codecMessageId` — the codec's reducer applies the result
|
|
343
|
+
* onto the existing tool-call state of the referenced assistant.
|
|
344
|
+
*
|
|
345
|
+
* The core is domain-independent: it knows only that this input amends the
|
|
346
|
+
* assistant at `codecMessageId` and carries a codec-defined `payload`. The
|
|
347
|
+
* shape of `payload` (e.g. the tool-call id and output value) is supplied
|
|
348
|
+
* by the codec via `TPayload` (e.g. a tool-call id and output value).
|
|
349
|
+
*
|
|
350
|
+
* Codecs opt in to client-side tool resolution by including this variant
|
|
351
|
+
* in their `TInput` union. Codecs whose domain model doesn't natively
|
|
352
|
+
* distinguish client-side tool results as a top-level event type (e.g.
|
|
353
|
+
* Anthropic Messages, where tool results are normally embedded in a
|
|
354
|
+
* user-role message) can still use this variant — the codec's reducer
|
|
355
|
+
* translates the wire-level update into the codec's domain representation.
|
|
356
|
+
* @template TPayload - The codec's domain payload for a tool result.
|
|
357
|
+
*/
|
|
358
|
+
export interface ToolResult<TPayload> extends CodecInputEvent {
|
|
359
|
+
/** Discriminator. */
|
|
360
|
+
kind: 'tool-result';
|
|
361
|
+
/** The assistant codec-message containing the tool call. Required. */
|
|
362
|
+
codecMessageId: string;
|
|
363
|
+
/** The codec's domain payload describing the tool result. */
|
|
364
|
+
payload: TPayload;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Well-known input variant: client-published tool result (failure). The
|
|
368
|
+
* tool ran and failed. Mutates the assistant codec-message addressed by
|
|
369
|
+
* `codecMessageId`. The failure detail (e.g. tool-call id and error text)
|
|
370
|
+
* is the codec's domain `payload`.
|
|
371
|
+
* @template TPayload - The codec's domain payload for a tool-result failure.
|
|
372
|
+
*/
|
|
373
|
+
export interface ToolResultError<TPayload> extends CodecInputEvent {
|
|
374
|
+
/** Discriminator. */
|
|
375
|
+
kind: 'tool-result-error';
|
|
376
|
+
/** The assistant codec-message containing the tool call. Required. */
|
|
377
|
+
codecMessageId: string;
|
|
378
|
+
/** The codec's domain payload describing the failure. */
|
|
379
|
+
payload: TPayload;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Well-known input variant: client-published response to an
|
|
383
|
+
* agent-emitted tool-approval request. Mutates the assistant
|
|
384
|
+
* codec-message addressed by `codecMessageId` — flipping the targeted
|
|
385
|
+
* tool call from pending-approval to approved or denied. The decision
|
|
386
|
+
* detail (e.g. tool-call id, approved flag, reason) is the codec's domain
|
|
387
|
+
* `payload`.
|
|
388
|
+
*
|
|
389
|
+
* Codecs may layer approval semantics on top of domain models that don't
|
|
390
|
+
* natively support gating tool execution behind an approval — the codec
|
|
391
|
+
* is responsible for mapping the decision into its own representation.
|
|
392
|
+
* @template TPayload - The codec's domain payload for an approval response.
|
|
393
|
+
*/
|
|
394
|
+
export interface ToolApprovalResponse<TPayload> extends CodecInputEvent {
|
|
395
|
+
/** Discriminator. */
|
|
396
|
+
kind: 'tool-approval-response';
|
|
397
|
+
/** The assistant codec-message containing the tool call. Required. */
|
|
398
|
+
codecMessageId: string;
|
|
399
|
+
/** The codec's domain payload describing the approval decision. */
|
|
400
|
+
payload: TPayload;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Extract the domain `payload` type of a codec's {@link ToolResult} member
|
|
404
|
+
* from its `TInput` union, or `never` if the codec has no tool-result
|
|
405
|
+
* variant. Used to type {@link Codec.createToolResult} without adding a
|
|
406
|
+
* standalone type parameter to the codec.
|
|
407
|
+
* @template TInput - The codec's input union.
|
|
408
|
+
*/
|
|
409
|
+
export type ToolResultPayloadOf<TInput> = TInput extends ToolResult<infer P> ? P : never;
|
|
410
|
+
/**
|
|
411
|
+
* Extract the domain `payload` type of a codec's {@link ToolResultError}
|
|
412
|
+
* member from its `TInput` union, or `never` if absent.
|
|
413
|
+
* @template TInput - The codec's input union.
|
|
414
|
+
*/
|
|
415
|
+
export type ToolResultErrorPayloadOf<TInput> = TInput extends ToolResultError<infer P> ? P : never;
|
|
416
|
+
/**
|
|
417
|
+
* Extract the domain `payload` type of a codec's {@link ToolApprovalResponse}
|
|
418
|
+
* member from its `TInput` union, or `never` if absent.
|
|
419
|
+
* @template TInput - The codec's input union.
|
|
420
|
+
*/
|
|
421
|
+
export type ToolApprovalResponsePayloadOf<TInput> = TInput extends ToolApprovalResponse<infer P> ? P : never;
|
|
422
|
+
/**
|
|
423
|
+
* Extract the domain message type (`TMessage`) carried by a codec's
|
|
424
|
+
* {@link UserMessage} member from its `TInput` union, or `never` if the codec
|
|
425
|
+
* has no user-message variant. Lets the core well-known input factories type
|
|
426
|
+
* `createUserMessage` from `TInput` alone, without a separate message type
|
|
427
|
+
* parameter.
|
|
428
|
+
* @template TInput - The codec's input union.
|
|
429
|
+
*/
|
|
430
|
+
export type UserMessageOf<TInput> = TInput extends UserMessage<infer M> ? M : never;
|
|
431
|
+
/**
|
|
432
|
+
* Structural base every codec output variant must satisfy. The output
|
|
433
|
+
* counterpart of {@link CodecInputEvent}: pins a `type` discriminator so
|
|
434
|
+
* the SDK can reliably narrow `TInput | TOutput` (inputs carry `kind`,
|
|
435
|
+
* outputs carry `type`) and reserves a contract for future routing
|
|
436
|
+
* fields on outputs without a breaking generic-arity change.
|
|
437
|
+
*
|
|
438
|
+
* The `type` discriminator is required on every variant so the codec's
|
|
439
|
+
* reducer can switch on it — any domain union whose members carry a `type`
|
|
440
|
+
* string literal satisfies it structurally.
|
|
441
|
+
*
|
|
442
|
+
* No routing fields today: outputs carry no per-event `codecMessageId` /
|
|
443
|
+
* `parent` / `forkOf` overrides. Those move onto this base when a concrete
|
|
444
|
+
* output needs to carry them.
|
|
445
|
+
*/
|
|
446
|
+
export interface CodecOutputEvent {
|
|
447
|
+
/** Discriminator. Codec authors pick the literal value per variant. */
|
|
448
|
+
type: string;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* A single domain message paired with the codec-message-id that identifies
|
|
452
|
+
* it on the wire. Returned from {@link Codec.getMessages}.
|
|
453
|
+
*
|
|
454
|
+
* The two fields are deliberately separate: `message` is reconstructed to
|
|
455
|
+
* faithfully reproduce the values the source produced (e.g. the id the AI
|
|
456
|
+
* SDK stream assigned) and is surfaced to the application as-is; the SDK
|
|
457
|
+
* never inspects `message` for identity. All internal correlation —
|
|
458
|
+
* Tree indexing, parent/fork/regenerate routing, branch grouping — keys on
|
|
459
|
+
* `codecMessageId`, the SDK's own client-minted identifier. The two need
|
|
460
|
+
* not be equal.
|
|
461
|
+
* @template TMessage - The codec's per-message domain type.
|
|
462
|
+
*/
|
|
463
|
+
export interface CodecMessage<TMessage> {
|
|
464
|
+
/** The SDK's codec-message-id for this message — the correlation key. */
|
|
465
|
+
codecMessageId: string;
|
|
466
|
+
/** The domain message, reconstructed verbatim from the source values. */
|
|
467
|
+
message: TMessage;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* The codec describes the wire and folds events into a per-node projection.
|
|
471
|
+
*
|
|
472
|
+
* Type parameters:
|
|
473
|
+
* - `TInput` — the union of input variants the client publishes on the
|
|
474
|
+
* `ai-input` wire. Every variant extends {@link CodecInputEvent}.
|
|
475
|
+
* - `TOutput` — the union of output variants the agent publishes on the
|
|
476
|
+
* `ai-output` wire. Every variant extends {@link CodecOutputEvent}.
|
|
477
|
+
* - `TProjection` — the opaque per-node state the reducer folds events into
|
|
478
|
+
* (one projection per node, whether a RunNode or a run-less input node).
|
|
479
|
+
* The SDK never inspects it directly; use {@link Codec.getMessages} to
|
|
480
|
+
* extract messages for the conversation Tree.
|
|
481
|
+
* - `TMessage` — the per-message shape consumed by the Tree. Returned from
|
|
482
|
+
* {@link Codec.getMessages}.
|
|
483
|
+
*/
|
|
484
|
+
export interface Codec<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> extends Reducer<CodecEvent<TInput, TOutput>, TProjection> {
|
|
485
|
+
/**
|
|
486
|
+
* Optional Ably-Agent identifier. When present, the agent-registration path
|
|
487
|
+
* registers it on the channel (so traffic is attributed to this codec); when
|
|
488
|
+
* absent, the codec opts out of registration. Read directly by `registerAgent`.
|
|
489
|
+
*/
|
|
490
|
+
readonly adapterTag?: string;
|
|
491
|
+
/** Create a stateful encoder bound to the given channel. */
|
|
492
|
+
createEncoder(channel: ChannelWriter, options?: EncoderOptions): Encoder<TInput, TOutput>;
|
|
493
|
+
/** Create a stateful decoder for converting Ably inbound messages into typed inputs and outputs. */
|
|
494
|
+
createDecoder(): Decoder<TInput, TOutput>;
|
|
495
|
+
/**
|
|
496
|
+
* Extract the per-message list from a projection, each message paired
|
|
497
|
+
* with its codec-message-id (see {@link CodecMessage}). The SDK uses the
|
|
498
|
+
* `codecMessageId` to correlate messages — it never reads identity from
|
|
499
|
+
* the message itself — and surfaces `message` to the application
|
|
500
|
+
* unchanged.
|
|
501
|
+
*/
|
|
502
|
+
getMessages(projection: TProjection): CodecMessage<TMessage>[];
|
|
503
|
+
/**
|
|
504
|
+
* Wrap a TMessage as the codec's well-known {@link UserMessage} variant,
|
|
505
|
+
* returned as a `TInput` ready to publish on the `ai-input` wire. This is
|
|
506
|
+
* the public way to turn a caller-provided TMessage into an input for
|
|
507
|
+
* `View.send`; the client session's seed-message path uses it too. The
|
|
508
|
+
* returned value is a `UserMessage<TMessage>` member of the codec's
|
|
509
|
+
* `TInput` union — typed as `TInput` so callers need no cast.
|
|
510
|
+
* @param message - The user's message in the codec's domain representation.
|
|
511
|
+
* @returns A `TInput` (the codec's {@link UserMessage} variant).
|
|
512
|
+
*/
|
|
513
|
+
createUserMessage(message: TMessage): TInput;
|
|
514
|
+
/**
|
|
515
|
+
* Build a {@link Regenerate} for the codec, returned as a `TInput`. The
|
|
516
|
+
* View calls this from `regenerate(messageId)`; the input event is a
|
|
517
|
+
* signal (not itself a fork) that targets the assistant codec-message to
|
|
518
|
+
* be regenerated.
|
|
519
|
+
*
|
|
520
|
+
* The new Run is a CONTINUATION of the regenerated message's Run, not a
|
|
521
|
+
* fork at the Run level. The message-level replacement (the new
|
|
522
|
+
* assistant supersedes the original) happens at the View's
|
|
523
|
+
* projection-extraction step (Spec: AIT-CT13d).
|
|
524
|
+
* @param target - The codec-message-id of the assistant being regenerated.
|
|
525
|
+
* @param parent - The codec-message-id of the parent user message the new assistant threads under.
|
|
526
|
+
* @returns A `TInput` (the codec's {@link Regenerate} variant).
|
|
527
|
+
*/
|
|
528
|
+
createRegenerate(target: string, parent: string): TInput;
|
|
529
|
+
/**
|
|
530
|
+
* Build a {@link ToolResult} for the codec, returned as a `TInput`.
|
|
531
|
+
* Amends the assistant at `codecMessageId` with the codec's domain
|
|
532
|
+
* `payload`. Optional — only codecs whose `TInput` includes the
|
|
533
|
+
* {@link ToolResult} variant implement it.
|
|
534
|
+
* @param codecMessageId - The assistant codec-message the result amends.
|
|
535
|
+
* @param payload - The codec's domain tool-result payload.
|
|
536
|
+
* @returns A `TInput` (the codec's {@link ToolResult} variant).
|
|
537
|
+
*/
|
|
538
|
+
createToolResult?(codecMessageId: string, payload: ToolResultPayloadOf<TInput>): TInput;
|
|
539
|
+
/**
|
|
540
|
+
* Build a {@link ToolResultError} for the codec, returned as a `TInput`.
|
|
541
|
+
* Optional — only codecs whose `TInput` includes the variant implement it.
|
|
542
|
+
* @param codecMessageId - The assistant codec-message the error amends.
|
|
543
|
+
* @param payload - The codec's domain tool-result-failure payload.
|
|
544
|
+
* @returns A `TInput` (the codec's {@link ToolResultError} variant).
|
|
545
|
+
*/
|
|
546
|
+
createToolResultError?(codecMessageId: string, payload: ToolResultErrorPayloadOf<TInput>): TInput;
|
|
547
|
+
/**
|
|
548
|
+
* Build a {@link ToolApprovalResponse} for the codec, returned as a
|
|
549
|
+
* `TInput`. Optional — only codecs whose `TInput` includes the variant
|
|
550
|
+
* implement it.
|
|
551
|
+
* @param codecMessageId - The assistant codec-message the response amends.
|
|
552
|
+
* @param payload - The codec's domain approval-decision payload.
|
|
553
|
+
* @returns A `TInput` (the codec's {@link ToolApprovalResponse} variant).
|
|
554
|
+
*/
|
|
555
|
+
createToolApprovalResponse?(codecMessageId: string, payload: ToolApprovalResponsePayloadOf<TInput>): TInput;
|
|
205
556
|
}
|