@ably/ai-transport 0.0.1 → 0.2.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.
Files changed (167) hide show
  1. package/README.md +114 -116
  2. package/dist/ably-ai-transport.js +1743 -961
  3. package/dist/ably-ai-transport.js.map +1 -1
  4. package/dist/ably-ai-transport.umd.cjs +1 -1
  5. package/dist/ably-ai-transport.umd.cjs.map +1 -1
  6. package/dist/constants.d.ts +117 -39
  7. package/dist/core/agent.d.ts +29 -0
  8. package/dist/core/codec/decoder.d.ts +20 -23
  9. package/dist/core/codec/encoder.d.ts +11 -8
  10. package/dist/core/codec/index.d.ts +1 -2
  11. package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
  12. package/dist/core/codec/types.d.ts +410 -101
  13. package/dist/core/transport/agent-session.d.ts +10 -0
  14. package/dist/core/transport/branch-chain.d.ts +43 -0
  15. package/dist/core/transport/client-session.d.ts +13 -0
  16. package/dist/core/transport/decode-fold.d.ts +47 -0
  17. package/dist/core/transport/headers.d.ts +97 -17
  18. package/dist/core/transport/index.d.ts +5 -3
  19. package/dist/core/transport/internal/bounded-map.d.ts +20 -0
  20. package/dist/core/transport/invocation.d.ts +74 -0
  21. package/dist/core/transport/load-conversation.d.ts +128 -0
  22. package/dist/core/transport/load-history.d.ts +39 -0
  23. package/dist/core/transport/pipe-stream.d.ts +9 -8
  24. package/dist/core/transport/run-manager.d.ts +78 -0
  25. package/dist/core/transport/tree.d.ts +435 -0
  26. package/dist/core/transport/types/agent.d.ts +353 -0
  27. package/dist/core/transport/types/client.d.ts +168 -0
  28. package/dist/core/transport/types/shared.d.ts +24 -0
  29. package/dist/core/transport/types/tree.d.ts +315 -0
  30. package/dist/core/transport/types/view.d.ts +222 -0
  31. package/dist/core/transport/types.d.ts +13 -402
  32. package/dist/core/transport/view.d.ts +354 -0
  33. package/dist/errors.d.ts +37 -9
  34. package/dist/index.d.ts +6 -6
  35. package/dist/logger.d.ts +12 -0
  36. package/dist/react/ably-ai-transport-react.js +1164 -645
  37. package/dist/react/ably-ai-transport-react.js.map +1 -1
  38. package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
  39. package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
  40. package/dist/react/contexts/client-session-context.d.ts +36 -0
  41. package/dist/react/contexts/client-session-provider.d.ts +53 -0
  42. package/dist/react/create-session-hooks.d.ts +116 -0
  43. package/dist/react/index.d.ts +16 -10
  44. package/dist/react/internal/use-resolved-session.d.ts +36 -0
  45. package/dist/react/use-ably-messages.d.ts +20 -11
  46. package/dist/react/use-client-session.d.ts +81 -0
  47. package/dist/react/use-create-view.d.ts +23 -0
  48. package/dist/react/use-tree.d.ts +35 -0
  49. package/dist/react/use-view.d.ts +110 -0
  50. package/dist/utils.d.ts +32 -23
  51. package/dist/vercel/ably-ai-transport-vercel.js +2748 -1625
  52. package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
  53. package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
  54. package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
  55. package/dist/vercel/codec/decoder.d.ts +5 -18
  56. package/dist/vercel/codec/encoder.d.ts +6 -36
  57. package/dist/vercel/codec/events.d.ts +51 -0
  58. package/dist/vercel/codec/index.d.ts +24 -12
  59. package/dist/vercel/codec/reducer.d.ts +144 -0
  60. package/dist/vercel/codec/tool-transitions.d.ts +50 -0
  61. package/dist/vercel/index.d.ts +4 -2
  62. package/dist/vercel/react/ably-ai-transport-vercel-react.js +10298 -1410
  63. package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
  64. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +70 -1
  65. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
  66. package/dist/vercel/react/contexts/chat-transport-context.d.ts +33 -0
  67. package/dist/vercel/react/contexts/chat-transport-provider.d.ts +96 -0
  68. package/dist/vercel/react/index.d.ts +4 -0
  69. package/dist/vercel/react/use-chat-transport.d.ts +66 -21
  70. package/dist/vercel/react/use-message-sync.d.ts +31 -12
  71. package/dist/vercel/run-end-reason.d.ts +29 -0
  72. package/dist/vercel/transport/chat-transport.d.ts +71 -30
  73. package/dist/vercel/transport/index.d.ts +25 -18
  74. package/dist/vercel/transport/run-output-stream.d.ts +56 -0
  75. package/dist/version.d.ts +2 -0
  76. package/package.json +47 -34
  77. package/src/constants.ts +126 -47
  78. package/src/core/agent.ts +68 -0
  79. package/src/core/codec/decoder.ts +71 -98
  80. package/src/core/codec/encoder.ts +115 -58
  81. package/src/core/codec/index.ts +13 -6
  82. package/src/core/codec/lifecycle-tracker.ts +10 -9
  83. package/src/core/codec/types.ts +438 -106
  84. package/src/core/transport/agent-session.ts +1344 -0
  85. package/src/core/transport/branch-chain.ts +58 -0
  86. package/src/core/transport/client-session.ts +775 -0
  87. package/src/core/transport/decode-fold.ts +91 -0
  88. package/src/core/transport/headers.ts +182 -19
  89. package/src/core/transport/index.ts +29 -22
  90. package/src/core/transport/internal/bounded-map.ts +27 -0
  91. package/src/core/transport/invocation.ts +98 -0
  92. package/src/core/transport/load-conversation.ts +355 -0
  93. package/src/core/transport/load-history.ts +269 -0
  94. package/src/core/transport/pipe-stream.ts +58 -40
  95. package/src/core/transport/run-manager.ts +249 -0
  96. package/src/core/transport/tree.ts +1167 -0
  97. package/src/core/transport/types/agent.ts +407 -0
  98. package/src/core/transport/types/client.ts +211 -0
  99. package/src/core/transport/types/shared.ts +27 -0
  100. package/src/core/transport/types/tree.ts +344 -0
  101. package/src/core/transport/types/view.ts +259 -0
  102. package/src/core/transport/types.ts +13 -527
  103. package/src/core/transport/view.ts +1271 -0
  104. package/src/errors.ts +42 -9
  105. package/src/event-emitter.ts +3 -2
  106. package/src/index.ts +55 -39
  107. package/src/logger.ts +14 -1
  108. package/src/react/contexts/client-session-context.ts +41 -0
  109. package/src/react/contexts/client-session-provider.tsx +186 -0
  110. package/src/react/create-session-hooks.ts +141 -0
  111. package/src/react/index.ts +27 -10
  112. package/src/react/internal/use-resolved-session.ts +63 -0
  113. package/src/react/use-ably-messages.ts +47 -19
  114. package/src/react/use-client-session.ts +201 -0
  115. package/src/react/use-create-view.ts +72 -0
  116. package/src/react/use-tree.ts +84 -0
  117. package/src/react/use-view.ts +275 -0
  118. package/src/react/vite.config.ts +4 -1
  119. package/src/utils.ts +63 -45
  120. package/src/vercel/codec/decoder.ts +336 -255
  121. package/src/vercel/codec/encoder.ts +348 -196
  122. package/src/vercel/codec/events.ts +87 -0
  123. package/src/vercel/codec/index.ts +59 -14
  124. package/src/vercel/codec/reducer.ts +977 -0
  125. package/src/vercel/codec/tool-transitions.ts +122 -0
  126. package/src/vercel/index.ts +7 -3
  127. package/src/vercel/react/contexts/chat-transport-context.ts +41 -0
  128. package/src/vercel/react/contexts/chat-transport-provider.tsx +150 -0
  129. package/src/vercel/react/index.ts +13 -1
  130. package/src/vercel/react/use-chat-transport.ts +162 -42
  131. package/src/vercel/react/use-message-sync.ts +121 -22
  132. package/src/vercel/react/vite.config.ts +4 -2
  133. package/src/vercel/run-end-reason.ts +78 -0
  134. package/src/vercel/transport/chat-transport.ts +553 -113
  135. package/src/vercel/transport/index.ts +40 -28
  136. package/src/vercel/transport/run-output-stream.ts +170 -0
  137. package/src/version.ts +2 -0
  138. package/dist/core/transport/client-transport.d.ts +0 -10
  139. package/dist/core/transport/conversation-tree.d.ts +0 -9
  140. package/dist/core/transport/decode-history.d.ts +0 -41
  141. package/dist/core/transport/server-transport.d.ts +0 -7
  142. package/dist/core/transport/stream-router.d.ts +0 -19
  143. package/dist/core/transport/turn-manager.d.ts +0 -34
  144. package/dist/react/use-active-turns.d.ts +0 -8
  145. package/dist/react/use-client-transport.d.ts +0 -7
  146. package/dist/react/use-conversation-tree.d.ts +0 -20
  147. package/dist/react/use-edit.d.ts +0 -7
  148. package/dist/react/use-history.d.ts +0 -19
  149. package/dist/react/use-messages.d.ts +0 -7
  150. package/dist/react/use-regenerate.d.ts +0 -7
  151. package/dist/react/use-send.d.ts +0 -7
  152. package/dist/vercel/codec/accumulator.d.ts +0 -21
  153. package/src/core/transport/client-transport.ts +0 -959
  154. package/src/core/transport/conversation-tree.ts +0 -434
  155. package/src/core/transport/decode-history.ts +0 -337
  156. package/src/core/transport/server-transport.ts +0 -458
  157. package/src/core/transport/stream-router.ts +0 -118
  158. package/src/core/transport/turn-manager.ts +0 -147
  159. package/src/react/use-active-turns.ts +0 -61
  160. package/src/react/use-client-transport.ts +0 -37
  161. package/src/react/use-conversation-tree.ts +0 -71
  162. package/src/react/use-edit.ts +0 -24
  163. package/src/react/use-history.ts +0 -111
  164. package/src/react/use-messages.ts +0 -32
  165. package/src/react/use-regenerate.ts +0 -24
  166. package/src/react/use-send.ts +0 -25
  167. package/src/vercel/codec/accumulator.ts +0 -603
@@ -0,0 +1,354 @@
1
+ import { Logger } from '../../logger.js';
2
+ import { Codec, CodecInputEvent, CodecMessage, CodecOutputEvent } from '../codec/types.js';
3
+ import { TreeInternal } from './tree.js';
4
+ import { ActiveRun, BranchSelection, RunInfo, RunLifecycleEvent, SendOptions, View } from './types.js';
5
+ /**
6
+ * DefaultView — a paginated, branch-aware projection over the Tree.
7
+ *
8
+ * Wraps a Tree (RunNode-keyed) and manages a pagination window that controls
9
+ * which Runs are visible to the UI. New live Runs appear immediately; older
10
+ * Runs are revealed progressively via `loadOlder()`.
11
+ *
12
+ * `getMessages()` reads the Tree's visible node chain (input nodes + reply
13
+ * runs, with sibling selection applied) and concatenates each node's
14
+ * `codec.getMessages(node.projection)` to produce the flat
15
+ * `CodecMessage<TMessage>[]` the UI renders.
16
+ *
17
+ * Each View owns its own branch selection state and pagination window,
18
+ * allowing multiple independent Views over the same Tree.
19
+ *
20
+ * Events are scoped to the visible window — 'update' only fires when the
21
+ * visible output changes, 'ably-message' only for messages corresponding to
22
+ * visible Runs, and 'run' only for runs with visible content.
23
+ */
24
+ import * as Ably from 'ably';
25
+ /**
26
+ * Internal delegate function provided by the session for executing sends.
27
+ * The View pre-computes the visible branch's flat message list and the
28
+ * codec-message-id of its tail (for auto-parent routing) before calling
29
+ * the delegate, so the delegate has no back-reference to the View.
30
+ *
31
+ * Each TInput carries its own routing metadata (`parent` / `target` /
32
+ * `codecMessageId`) via the {@link CodecInputEvent} base; the delegate
33
+ * reads those fields directly without runtime classification.
34
+ *
35
+ * `parentCodecMessageId` is the codec-message-id of the last message in
36
+ * the visible branch (extracted from the tail Run's projection per codec
37
+ * convention), or `undefined` for an empty conversation. The session
38
+ * uses it as the auto-parent for fresh user messages.
39
+ */
40
+ export type SendDelegate<TInput extends CodecInputEvent> = (input: TInput[], options: SendOptions | undefined, parentCodecMessageId: string | undefined) => Promise<ActiveRun>;
41
+ /** Options for creating a View. */
42
+ export interface ViewOptions<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> {
43
+ /** The tree to project. */
44
+ tree: TreeInternal<TInput, TOutput, TProjection>;
45
+ /** The Ably channel to load history from. */
46
+ channel: Ably.RealtimeChannel;
47
+ /** The codec used to project messages, mint regenerate inputs, and decode history. */
48
+ codec: Codec<TInput, TOutput, TProjection, TMessage>;
49
+ /** Delegate for executing sends through the session. */
50
+ sendDelegate: SendDelegate<TInput>;
51
+ /** Logger for diagnostic output. */
52
+ logger: Logger;
53
+ /** Called when the view is closed, allowing the owner to clean up references. */
54
+ onClose?: () => void;
55
+ }
56
+ export declare class DefaultView<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> implements View<TInput, TMessage> {
57
+ private readonly _tree;
58
+ private readonly _channel;
59
+ private readonly _codec;
60
+ private readonly _sendDelegate;
61
+ private readonly _logger;
62
+ private readonly _emitter;
63
+ private readonly _onClose?;
64
+ /**
65
+ * View-local branch selections: group-root runId → selection intent.
66
+ * Fork points not present here default to the latest sibling.
67
+ */
68
+ private readonly _branchSelections;
69
+ /**
70
+ * View-local regenerate-group selections: anchor codec-message-id (the assistant
71
+ * codec-message-id being regenerated) → selection intent. Distinct from
72
+ * {@link _branchSelections} because a regenerate group is a set of
73
+ * same-parent reply runs — message-level alternatives at a single
74
+ * conversation slot, not edit forks of the prompt. Groups not present here default to the latest
75
+ * member (the most recent regenerator, or the original if no regen has
76
+ * landed).
77
+ */
78
+ private readonly _regenSelections;
79
+ /** Spec: AIT-CT11c — runIds loaded from history but not yet revealed to the UI. */
80
+ private readonly _withheldRunIds;
81
+ /** Snapshot of visible node keys — used to detect structural changes and for selection pinning. */
82
+ private _lastVisibleNodeKeys;
83
+ /**
84
+ * Snapshot of visible projection references — used to detect in-place
85
+ * projection updates (streaming). One entry per visible Run.
86
+ */
87
+ private _lastVisibleProjections;
88
+ /**
89
+ * Snapshot of the visible flat message chain with codec-message-ids —
90
+ * exposed verbatim via `getMessages()` and the internal correlation
91
+ * source for parent/branch routing.
92
+ */
93
+ private _lastVisibleMessagePairs;
94
+ /** Cached visible node-key Set — for O(1) lookup in event scoping. */
95
+ private _lastVisibleNodeKeySet;
96
+ /** Whether there are more history pages to fetch from the channel. */
97
+ private _hasMoreHistory;
98
+ /** Internal state for continuing history pagination. */
99
+ private _lastHistoryPage;
100
+ /** Buffer of withheld nodes (input + reply), drained newest-first by successive loadOlder() calls. */
101
+ private readonly _withheldBuffer;
102
+ /** Unsubscribe functions for tree event subscriptions. */
103
+ private readonly _unsubs;
104
+ /**
105
+ * Cached result of the last flat-nodes computation. Drives the visible
106
+ * message snapshot exposed via `getMessages()`; refreshed by
107
+ * `_computeFlatNodes()` on structural changes, selection changes,
108
+ * and history reveal.
109
+ */
110
+ private _cachedNodes;
111
+ private _loadingOlder;
112
+ private _processingHistory;
113
+ private _closed;
114
+ constructor(options: ViewOptions<TInput, TOutput, TProjection, TMessage>);
115
+ /**
116
+ * Handle decoded outputs folded into a Run (streaming delta). If the run
117
+ * is on the visible chain, recompute the flat message list and emit
118
+ * `update`.
119
+ * @param event - The output event from the Tree.
120
+ */
121
+ private _onTreeOutput;
122
+ getMessages(): CodecMessage<TMessage>[];
123
+ runs(): RunInfo[];
124
+ /**
125
+ * Compute the fresh visible node chain. The Tree's `visibleNodes` already
126
+ * applies kind-blind reachability and sibling selection (edit versions /
127
+ * regenerate runs collapse to the selected member), so the View only layers
128
+ * its pagination window on top: drop nodes whose key is currently withheld.
129
+ * @returns A fresh array of visible nodes (inputs + reply runs).
130
+ */
131
+ private _computeFlatNodes;
132
+ /**
133
+ * Recompute the visible node chain, refresh the cache + snapshot, and emit
134
+ * `update` unconditionally. Use after a mutation that always changes the
135
+ * visible output (e.g. an explicit selection or a withheld-batch reveal).
136
+ */
137
+ private _recomputeAndEmit;
138
+ /**
139
+ * Recompute the visible node chain and, only if it differs from the current
140
+ * snapshot, refresh the cache + snapshot and emit `update`. Use after a
141
+ * mutation that may or may not move the visible window (e.g. a structural
142
+ * tree update, or a deferred regenerate promotion that may already match).
143
+ */
144
+ private _recomputeAndEmitIfChanged;
145
+ /**
146
+ * Resolve the reply Run that owns a codec-message-id, narrowing the Tree's
147
+ * node union to a {@link RunNode}. A user-input codec-message-id resolves to
148
+ * an input node and yields `undefined` here — callers that must handle input
149
+ * nodes use {@link _tree.getNodeByCodecMessageId} directly.
150
+ * @param codecMessageId - The codec-message-id to resolve.
151
+ * @returns The owning RunNode, or undefined if absent or not a reply Run.
152
+ */
153
+ private _runByCodecMessageId;
154
+ /**
155
+ * Extract the flat TMessage[] from a visible node chain.
156
+ *
157
+ * In the two-node model the Tree's `visibleNodes` has already selected one
158
+ * member per sibling group (the chosen edit version, the chosen regenerate
159
+ * run), so a regenerate is just a sibling reply run that appears in place of
160
+ * the original. Each visible node contributes its own messages in projection
161
+ * order; the flat list is their concatenation.
162
+ *
163
+ * Deferred caveat: a mid-reply regenerate that replaces a non-head message
164
+ * inside a multi-message reply run is not expressible as a sibling run in
165
+ * this model and is not handled here (see the `regenerate-of-multi-message`
166
+ * golden test).
167
+ * @param nodes - The visible nodes (inputs + reply runs) in chronological order.
168
+ * @returns The flat message list, each message paired with its codec-message-id.
169
+ */
170
+ private _extractMessages;
171
+ hasOlder(): boolean;
172
+ /**
173
+ * Reveal up to `limit` older Runs in this view.
174
+ *
175
+ * The pagination unit is the **Run**, not the message. A single Run
176
+ * typically materialises into multiple messages (e.g. user + assistant
177
+ * pair) so revealing `limit` Runs may add several messages to the flat
178
+ * list returned by {@link getMessages}. Channel pages don't align to
179
+ * Run boundaries, so {@link _loadUntilVisible} keeps fetching channel
180
+ * pages until at least `limit` Runs are buffered (or the channel is
181
+ * exhausted).
182
+ * @param limit - Maximum number of older Runs to reveal. Defaults to 100.
183
+ */
184
+ loadOlder(limit?: number): Promise<void>;
185
+ runOf(codecMessageId: string): RunInfo | undefined;
186
+ /**
187
+ * Resolve the reply run currently selected for an input node, honouring the
188
+ * View's regenerate selection. Falls back to the latest reply run when no
189
+ * selection has been recorded; undefined when no reply run has started.
190
+ * @param inputCodecMessageId - The input node's codec-message-id.
191
+ * @returns The selected reply RunNode, or undefined.
192
+ */
193
+ private _selectedReplyRun;
194
+ run(runId: string): RunInfo | undefined;
195
+ branchSelection(codecMessageId: string): BranchSelection<TMessage>;
196
+ selectSibling(codecMessageId: string, index: number): void;
197
+ /**
198
+ * Resolve the currently selected sibling's index inside a branch group.
199
+ * Pending selections fall back to the latest sibling. The caller clamps
200
+ * the returned index against any post-extraction filtering.
201
+ * @param branch - Resolved branch-point descriptor from `_resolveMessageBranchPoint`.
202
+ * @returns The selected sibling's index within `branch.siblings`.
203
+ */
204
+ private _resolveSelectedIndex;
205
+ /**
206
+ * Resolve the branch point anchored at `codecMessageId`, if any.
207
+ *
208
+ * Returns the resolved group `kind` along with the sibling list so the
209
+ * caller can update the correct selection map without re-entering the
210
+ * runId-based `select()` dispatch (which biases to fork-of first and
211
+ * would mis-route a regen-anchor codec-message-id when the owning Run is in
212
+ * BOTH groups — e.g. R1 owns both a user prompt that got edited and
213
+ * an assistant that got regenerated).
214
+ *
215
+ * Two anchor cases:
216
+ * - **fork-of** — `codecMessageId` is the first message of a Run in a fork-of
217
+ * sibling group (edit-style branch point anchored at the user prompt).
218
+ * - **regen** — `codecMessageId` is the regen-anchor itself (in the owner Run)
219
+ * or content of a regenerator Run (regen-style branch point anchored
220
+ * at the assistant slot).
221
+ * @param codecMessageId - The codec-message-id to look up.
222
+ * @returns The kind + sibling list + group key (runId for fork-of,
223
+ * anchor codec-message-id for regen), or undefined when `codecMessageId` is not an
224
+ * anchor in either group type.
225
+ */
226
+ private _resolveMessageBranchPoint;
227
+ send(input: TInput | TInput[], options?: SendOptions): Promise<ActiveRun>;
228
+ /**
229
+ * Auto-select / pin branch selections after a forking send.
230
+ * @param result - The ActiveRun returned by the delegate.
231
+ * @param options - The SendOptions passed by the caller.
232
+ */
233
+ private _applyForkAutoSelect;
234
+ /**
235
+ * Auto-select / pin the regenerate group anchored at `anchorCodecMessageId` so
236
+ * the new Run's content appears as soon as the agent's run-start lands.
237
+ *
238
+ * `View.regenerate()` calls this with the assistant codec-message-id being
239
+ * regenerated. The Run doesn't exist yet on the channel (the regenerate
240
+ * wire is wire-only); the selection is recorded as `pending` and
241
+ * promoted to `auto` by `_pinRegenSelections` once the corresponding
242
+ * Run is created in the tree.
243
+ * @param result - The ActiveRun returned by the delegate (run-id is the new regenerator's).
244
+ * @param anchorCodecMessageId - The codec-message-id of the assistant being regenerated.
245
+ */
246
+ private _applyRegenerateAutoSelect;
247
+ regenerate(messageId: string, options?: SendOptions): Promise<ActiveRun>;
248
+ edit(messageId: string, inputs: TInput | TInput[], options?: SendOptions): Promise<ActiveRun>;
249
+ /**
250
+ * Find the codec-message-id of the message immediately preceding `targetMsgId` in
251
+ * the visible conversation.
252
+ *
253
+ * Consults the View's visible message chain first so message-level
254
+ * replacements (regenerate) are respected: regenerating an
255
+ * already-regenerated assistant lands the predecessor on the user
256
+ * prompt the regen is responding to, NOT on the hidden original
257
+ * assistant that occupies the same conversation slot. Falls back to a
258
+ * projection-walk for the rare case where `targetMsgId` isn't on the
259
+ * visible chain (e.g. caller is operating on a Run that's selection-
260
+ * hidden by the current branch).
261
+ * @param targetNode - The node (input node or reply run) that owns `targetMsgId`.
262
+ * @param targetMsgId - The codec-message-id to find the parent of.
263
+ * @returns The parent codec-message-id, or undefined if no predecessor exists.
264
+ */
265
+ private _findParentMsgId;
266
+ on(event: 'update', handler: () => void): () => void;
267
+ on(event: 'ably-message', handler: (msg: Ably.InboundMessage) => void): () => void;
268
+ on(event: 'run', handler: (event: RunLifecycleEvent) => void): () => void;
269
+ close(): void;
270
+ private _loadFirstPage;
271
+ /**
272
+ * Walk channel history from `page` until at least `limit` new Runs are
273
+ * observed (or the channel is exhausted), then reveal the newest batch and
274
+ * withhold the rest. Snapshots the already-visible nodes up front so only
275
+ * newly-observed Runs count toward `limit`. No-op if the view closed during
276
+ * the page walk.
277
+ * @param page - The decoded history page to start from.
278
+ * @param limit - Max Runs to reveal in this batch.
279
+ */
280
+ private _revealFromPage;
281
+ /**
282
+ * Reveal the newest `limit` Runs from `newVisible` and withhold the rest
283
+ * so subsequent `loadOlder` calls can drain them. Called by
284
+ * {@link _revealFromPage} to enforce the Run-unit pagination contract.
285
+ * @param newVisible - Newly observed Runs from the history fetch.
286
+ * @param limit - Max Runs to reveal in this batch.
287
+ */
288
+ private _splitReveal;
289
+ /**
290
+ * Replay a history page's raw messages into the Tree. Dispatches by Ably
291
+ * message name to run-lifecycle vs. regular wire messages, mirroring the
292
+ * live `client-session._handleMessage` decode loop. Uses a fresh decoder
293
+ * since the session's live decoder maintains its own stream-tracker state.
294
+ * @param page - The history page returned by `loadHistory`.
295
+ */
296
+ private _processHistoryPage;
297
+ private _loadUntilVisible;
298
+ private _releaseWithheld;
299
+ private _updateVisibleSnapshot;
300
+ private _onTreeUpdate;
301
+ /**
302
+ * Build the unified selection map the Tree's `visibleNodes` consumes:
303
+ * `groupRootKey -> selectedKey`, covering both edit forks (input-node groups,
304
+ * keyed by the input group root) and regenerate groups (reply-run groups,
305
+ * keyed by the original reply's group root). Pending entries (no chosen
306
+ * member yet) are omitted so the Tree falls back to the latest sibling.
307
+ * @returns The merged group-root → selected-key map.
308
+ */
309
+ private _resolveSelections;
310
+ /**
311
+ * The Tree's visible node chain under this view's current selections — the
312
+ * reachable, sibling-resolved nodes before the View's pagination window is
313
+ * applied.
314
+ * @returns The selection-resolved visible node chain.
315
+ */
316
+ private _treeVisibleNodes;
317
+ /**
318
+ * For each previously-visible Run that now has siblings but no explicit
319
+ * selection, pin the selection to that Run's runId. This preserves the
320
+ * current branch when new forks appear from other views or external
321
+ * sources.
322
+ *
323
+ * Exception: if the fork was initiated by this view (tracked as a
324
+ * `pending` BranchSelection), select the newest sibling (the awaited Run)
325
+ * instead of pinning the old one.
326
+ */
327
+ private _pinBranchSelections;
328
+ /**
329
+ * Roll `pending` and `auto` regenerate selections forward to the newest
330
+ * group member. A regenerate slot defaults to the latest member, so each
331
+ * new regenerator (this view's awaited run, or an external one) auto-rolls
332
+ * the slot forward — UNLESS the user explicitly selected an earlier member
333
+ * (`user`), which pins and is left untouched. The agent mints the run-id, so
334
+ * we can't match the awaited run by id — once the group grows we adopt the
335
+ * newest as the selected member.
336
+ */
337
+ private _resolvePendingRegenSelections;
338
+ private _onTreeAblyMessage;
339
+ private _onTreeRun;
340
+ /**
341
+ * Predict whether a run-start's messages will be visible on this view's
342
+ * branch using the parent/forkOf metadata from the event.
343
+ * @param event - The run-start lifecycle event.
344
+ * @returns True if the run is expected to be visible on this view's branch.
345
+ */
346
+ private _isRunStartVisible;
347
+ private _visibleChanged;
348
+ }
349
+ /**
350
+ * Create a View that projects a paginated window over a Tree.
351
+ * @param options - The tree, channel, codec, and logger to use.
352
+ * @returns A new {@link DefaultView} instance.
353
+ */
354
+ export declare const createView: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>(options: ViewOptions<TInput, TOutput, TProjection, TMessage>) => DefaultView<TInput, TOutput, TProjection, TMessage>;
package/dist/errors.d.ts CHANGED
@@ -12,30 +12,58 @@ export declare enum ErrorCode {
12
12
  */
13
13
  InvalidArgument = 40003,
14
14
  /**
15
- * Encoder recovery failed after flush one or more updateMessage calls
15
+ * Operation not permitted with the provided capability (Ably 40160).
16
+ * Used when the Ably channel rejects a publish for a capability reason.
17
+ */
18
+ InsufficientCapability = 40160,
19
+ /**
20
+ * Encoder recovery failed during flush — one or more updateMessage calls
16
21
  * could not recover a failed append pipeline.
17
22
  */
18
23
  EncoderRecoveryFailed = 104000,
19
24
  /**
20
- * A transport-level channel subscription callback threw unexpectedly.
25
+ * A session-level channel subscription callback threw unexpectedly.
21
26
  */
22
- TransportSubscriptionError = 104001,
27
+ SessionSubscriptionError = 104001,
23
28
  /**
24
29
  * Cancel listener or onCancel hook threw while processing a cancel message.
25
30
  */
26
31
  CancelListenerError = 104002,
27
32
  /**
28
- * A turn lifecycle event (turn-start or turn-end) failed to publish.
33
+ * A publish within a run failed (lifecycle event, message, or event).
34
+ */
35
+ RunLifecycleError = 104003,
36
+ /**
37
+ * An operation was attempted on a session that has already been closed.
38
+ */
39
+ SessionClosed = 104004,
40
+ /**
41
+ * The HTTP POST to the agent endpoint failed (network error or non-2xx response).
42
+ */
43
+ SessionSendFailed = 104005,
44
+ /**
45
+ * The Ably channel lost message continuity — the channel entered FAILED,
46
+ * SUSPENDED, or DETACHED, or re-attached with `resumed: false`. Active
47
+ * streams can no longer be guaranteed to receive all events.
48
+ */
49
+ ChannelContinuityLost = 104006,
50
+ /**
51
+ * An operation was attempted but the channel is not in a usable state
52
+ * (not ATTACHED or ATTACHING).
29
53
  */
30
- TurnLifecycleError = 104003,
54
+ ChannelNotReady = 104007,
31
55
  /**
32
- * An operation was attempted on a transport that has already been closed.
56
+ * An error occurred while piping a response stream to the channel — either
57
+ * the source event stream threw (e.g. LLM provider rate limit, model error,
58
+ * network failure) or an underlying publish failed mid-stream.
33
59
  */
34
- TransportClosed = 104004,
60
+ StreamError = 104008,
35
61
  /**
36
- * The HTTP POST to the server endpoint failed (network error or non-2xx response).
62
+ * The agent attached to the channel and waited for the input event(s) the
63
+ * invocation points at (rewind + live wait) but `inputEventLookupTimeoutMs`
64
+ * lapsed without seeing them.
37
65
  */
38
- TransportSendFailed = 104005
66
+ InputEventNotFound = 104010
39
67
  }
40
68
  /**
41
69
  * Returns true if the {@link Ably.ErrorInfo} code matches the provided ErrorCode value.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export type { ActiveTurn, AddMessageOptions, AddMessagesResult, CancelFilter, CancelRequest, ClientTransport, ClientTransportOptions, CloseOptions, ConversationNode, ConversationTree, LoadHistoryOptions, MessageWithHeaders, NewTurnOptions, PaginatedMessages, SendOptions, ServerTransport, ServerTransportOptions, StreamResponseOptions, StreamResult, Turn, TurnEndReason, TurnLifecycleEvent, } from './core/transport/index.js';
2
- export { buildTransportHeaders, createClientTransport, createServerTransport } from './core/transport/index.js';
3
- export type { ChannelWriter, Codec, DecoderCore, DecoderCoreHooks, DecoderCoreOptions, DecoderOutput, DiscreteEncoder, EncoderCore, EncoderCoreOptions, EncoderOptions, Extras, LifecycleTracker, MessageAccumulator, MessagePayload, PhaseConfig, StreamDecoder, StreamEncoder, StreamPayload, StreamTrackerState, WriteOptions, } from './core/codec/index.js';
4
- export { createDecoderCore, createEncoderCore, createLifecycleTracker, eventOutput } from './core/codec/index.js';
5
- export { DOMAIN_HEADER_PREFIX, EVENT_ABORT, EVENT_CANCEL, EVENT_ERROR, EVENT_TURN_END, EVENT_TURN_START, HEADER_CANCEL_ALL, HEADER_CANCEL_CLIENT_ID, HEADER_CANCEL_OWN, HEADER_CANCEL_TURN_ID, HEADER_FORK_OF, HEADER_MSG_ID, HEADER_PARENT, HEADER_ROLE, HEADER_STATUS, HEADER_STREAM, HEADER_STREAM_ID, HEADER_TURN_CLIENT_ID, HEADER_TURN_ID, HEADER_TURN_REASON, } from './constants.js';
1
+ export type { ActiveRun, AgentSession, AgentSessionOptions, BranchSelection, CancelRequest, ClientSession, ClientSessionOptions, ConversationNode, EventsNode, InputNode, InvocationData, LoadConversationOptions, MessageNode, OutputEvent, PipeOptions, Run, RunEndReason, RunInfo, RunLifecycleEvent, RunNode, RunRuntime, RunView, SendOptions, StreamResult, Tree, View, } from './core/transport/index.js';
2
+ export { buildTransportHeaders, createAgentSession, createClientSession, Invocation } from './core/transport/index.js';
3
+ export type { ChannelWriter, Codec, CodecInputEvent, CodecMessage, CodecOutputEvent, DecodedMessage, Decoder, DecoderCore, DecoderCoreHooks, DecoderCoreOptions, Encoder, EncoderCore, EncoderCoreOptions, EncoderOptions, Extras, LifecycleTracker, MessagePayload, PhaseConfig, Reducer, ReducerMeta, Regenerate, StreamPayload, StreamTrackerState, ToolApprovalResponse, ToolResult, ToolResultError, UserMessage, WriteOptions, } from './core/codec/index.js';
4
+ export { createDecoderCore, createEncoderCore, createLifecycleTracker } from './core/codec/index.js';
5
+ export { EVENT_CANCEL, EVENT_RUN_END, EVENT_RUN_START, HEADER_CODEC_MESSAGE_ID, HEADER_ERROR_CODE, HEADER_ERROR_MESSAGE, HEADER_FORK_OF, HEADER_INPUT_CLIENT_ID, HEADER_MSG_REGENERATE, HEADER_PARENT, HEADER_ROLE, HEADER_RUN_CLIENT_ID, HEADER_RUN_ID, HEADER_RUN_REASON, HEADER_STATUS, HEADER_STREAM, HEADER_STREAM_ID, } from './constants.js';
6
6
  export type { DomainHeaderReader, DomainHeaderWriter, Stripped } from './utils.js';
7
- export { getHeaders, headerReader, headerWriter, mergeHeaders, stripUndefined } from './utils.js';
7
+ export { getCodecHeaders, getTransportHeaders, headerReader, headerWriter, mergeHeaders, stripUndefined, } from './utils.js';
8
8
  export { EventEmitter } from './event-emitter.js';
9
9
  export { ErrorCode, errorInfoIs } from './errors.js';
10
10
  export type { LogContext, Logger, LoggerOptions, LogHandler } from './logger.js';
package/dist/logger.d.ts CHANGED
@@ -97,7 +97,19 @@ export declare const consoleLogger: (message: string, level: LogLevel, context?:
97
97
  * Options for creating a logger.
98
98
  */
99
99
  export interface LoggerOptions {
100
+ /**
101
+ * The handler that receives formatted log messages. Defaults to {@link consoleLogger} when omitted.
102
+ */
100
103
  logHandler?: LogHandler;
104
+ /**
105
+ * The minimum level to emit; messages below this level are suppressed. Must be a valid {@link LogLevel}, otherwise logger creation throws.
106
+ */
101
107
  logLevel: LogLevel;
102
108
  }
109
+ /**
110
+ * Creates a {@link Logger} from the given options.
111
+ * @param options The handler and minimum level for the logger.
112
+ * @returns A logger that filters by level and delegates to the handler.
113
+ * @throws {@link Ably.ErrorInfo} with {@link ErrorCode.InvalidArgument} if `options.logLevel` is not a recognised {@link LogLevel}.
114
+ */
103
115
  export declare const makeLogger: (options: LoggerOptions) => Logger;