@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.
Files changed (221) hide show
  1. package/README.md +93 -111
  2. package/dist/ably-ai-transport.js +2401 -1387
  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 +116 -42
  7. package/dist/core/agent.d.ts +44 -0
  8. package/dist/core/channel-options.d.ts +57 -0
  9. package/dist/core/codec/codec-event.d.ts +9 -0
  10. package/dist/core/codec/decoder.d.ts +24 -24
  11. package/dist/core/codec/define-codec.d.ts +100 -0
  12. package/dist/core/codec/encoder.d.ts +10 -12
  13. package/dist/core/codec/field-bag.d.ts +85 -0
  14. package/dist/core/codec/fields.d.ts +141 -0
  15. package/dist/core/codec/index.d.ts +8 -2
  16. package/dist/core/codec/input-descriptor-decoder.d.ts +19 -0
  17. package/dist/core/codec/input-descriptor-encoder.d.ts +22 -0
  18. package/dist/core/codec/input-descriptors.d.ts +281 -0
  19. package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
  20. package/dist/core/codec/output-descriptor-decoder.d.ts +29 -0
  21. package/dist/core/codec/output-descriptor-encoder.d.ts +31 -0
  22. package/dist/core/codec/output-descriptors.d.ts +237 -0
  23. package/dist/core/codec/types.d.ts +470 -119
  24. package/dist/core/codec/well-known-inputs.d.ts +52 -0
  25. package/dist/core/transport/agent-session.d.ts +10 -0
  26. package/dist/core/transport/agent-view.d.ts +296 -0
  27. package/dist/core/transport/client-session.d.ts +13 -0
  28. package/dist/core/transport/decode-fold.d.ts +55 -0
  29. package/dist/core/transport/headers.d.ts +121 -14
  30. package/dist/core/transport/index.d.ts +5 -6
  31. package/dist/core/transport/internal/bounded-map.d.ts +20 -0
  32. package/dist/core/transport/invocation.d.ts +74 -0
  33. package/dist/core/transport/load-history-pages.d.ts +71 -0
  34. package/dist/core/transport/load-history.d.ts +44 -0
  35. package/dist/core/transport/pipe-stream.d.ts +9 -9
  36. package/dist/core/transport/run-manager.d.ts +76 -0
  37. package/dist/core/transport/session-support.d.ts +55 -0
  38. package/dist/core/transport/tree.d.ts +523 -109
  39. package/dist/core/transport/types/agent.d.ts +375 -0
  40. package/dist/core/transport/types/client.d.ts +201 -0
  41. package/dist/core/transport/types/shared.d.ts +24 -0
  42. package/dist/core/transport/types/tree.d.ts +357 -0
  43. package/dist/core/transport/types/view.d.ts +249 -0
  44. package/dist/core/transport/types.d.ts +13 -553
  45. package/dist/core/transport/view.d.ts +390 -84
  46. package/dist/core/transport/wire-log.d.ts +102 -0
  47. package/dist/errors.d.ts +27 -10
  48. package/dist/index.d.ts +8 -9
  49. package/dist/logger.d.ts +12 -0
  50. package/dist/react/ably-ai-transport-react.js +1365 -1010
  51. package/dist/react/ably-ai-transport-react.js.map +1 -1
  52. package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
  53. package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
  54. package/dist/react/contexts/client-session-context.d.ts +37 -0
  55. package/dist/react/contexts/client-session-provider.d.ts +56 -0
  56. package/dist/react/create-session-hooks.d.ts +116 -0
  57. package/dist/react/index.d.ts +13 -12
  58. package/dist/react/internal/skipped-session.d.ts +8 -0
  59. package/dist/react/internal/use-resolved-session.d.ts +36 -0
  60. package/dist/react/use-ably-messages.d.ts +17 -14
  61. package/dist/react/use-client-session.d.ts +81 -0
  62. package/dist/react/use-create-view.d.ts +14 -13
  63. package/dist/react/use-tree.d.ts +30 -15
  64. package/dist/react/use-view.d.ts +81 -50
  65. package/dist/utils.d.ts +48 -71
  66. package/dist/vercel/ably-ai-transport-vercel.js +3257 -2499
  67. package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
  68. package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
  69. package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
  70. package/dist/vercel/codec/decode-lifecycle.d.ts +9 -0
  71. package/dist/vercel/codec/events.d.ts +50 -0
  72. package/dist/vercel/codec/fields.d.ts +44 -0
  73. package/dist/vercel/codec/fold-content.d.ts +16 -0
  74. package/dist/vercel/codec/fold-data.d.ts +16 -0
  75. package/dist/vercel/codec/fold-input.d.ts +67 -0
  76. package/dist/vercel/codec/fold-lifecycle.d.ts +16 -0
  77. package/dist/vercel/codec/fold-text.d.ts +16 -0
  78. package/dist/vercel/codec/fold-tool-input.d.ts +17 -0
  79. package/dist/vercel/codec/fold-tool-output.d.ts +16 -0
  80. package/dist/vercel/codec/index.d.ts +7 -20
  81. package/dist/vercel/codec/inputs.d.ts +11 -0
  82. package/dist/vercel/codec/outputs.d.ts +11 -0
  83. package/dist/vercel/codec/reducer-state.d.ts +121 -0
  84. package/dist/vercel/codec/reducer.d.ts +62 -0
  85. package/dist/vercel/codec/tool-transitions.d.ts +2 -8
  86. package/dist/vercel/codec/wire-data.d.ts +34 -0
  87. package/dist/vercel/index.d.ts +5 -5
  88. package/dist/vercel/react/ably-ai-transport-vercel-react.js +2859 -9705
  89. package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
  90. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +1 -45
  91. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
  92. package/dist/vercel/react/contexts/chat-transport-context.d.ts +9 -7
  93. package/dist/vercel/react/contexts/chat-transport-provider.d.ts +53 -41
  94. package/dist/vercel/react/index.d.ts +1 -2
  95. package/dist/vercel/react/use-chat-transport.d.ts +30 -26
  96. package/dist/vercel/react/use-message-sync.d.ts +17 -30
  97. package/dist/vercel/run-end-reason.d.ts +84 -0
  98. package/dist/vercel/tool-part.d.ts +21 -0
  99. package/dist/vercel/transport/chat-transport.d.ts +41 -24
  100. package/dist/vercel/transport/index.d.ts +24 -20
  101. package/dist/vercel/transport/run-output-stream.d.ts +54 -0
  102. package/dist/version.d.ts +2 -0
  103. package/package.json +31 -24
  104. package/src/constants.ts +124 -51
  105. package/src/core/agent.ts +92 -0
  106. package/src/core/channel-options.ts +89 -0
  107. package/src/core/codec/codec-event.ts +27 -0
  108. package/src/core/codec/decoder.ts +202 -105
  109. package/src/core/codec/define-codec.ts +432 -0
  110. package/src/core/codec/encoder.ts +114 -107
  111. package/src/core/codec/field-bag.ts +142 -0
  112. package/src/core/codec/fields.ts +193 -0
  113. package/src/core/codec/index.ts +56 -6
  114. package/src/core/codec/input-descriptor-decoder.ts +97 -0
  115. package/src/core/codec/input-descriptor-encoder.ts +150 -0
  116. package/src/core/codec/input-descriptors.ts +373 -0
  117. package/src/core/codec/lifecycle-tracker.ts +10 -9
  118. package/src/core/codec/output-descriptor-decoder.ts +139 -0
  119. package/src/core/codec/output-descriptor-encoder.ts +101 -0
  120. package/src/core/codec/output-descriptors.ts +307 -0
  121. package/src/core/codec/types.ts +505 -126
  122. package/src/core/codec/well-known-inputs.ts +96 -0
  123. package/src/core/transport/agent-session.ts +1085 -0
  124. package/src/core/transport/agent-view.ts +738 -0
  125. package/src/core/transport/client-session.ts +780 -0
  126. package/src/core/transport/decode-fold.ts +101 -0
  127. package/src/core/transport/headers.ts +234 -22
  128. package/src/core/transport/index.ts +27 -27
  129. package/src/core/transport/internal/bounded-map.ts +27 -0
  130. package/src/core/transport/invocation.ts +98 -0
  131. package/src/core/transport/load-history-pages.ts +220 -0
  132. package/src/core/transport/load-history.ts +271 -0
  133. package/src/core/transport/pipe-stream.ts +63 -39
  134. package/src/core/transport/run-manager.ts +243 -0
  135. package/src/core/transport/session-support.ts +96 -0
  136. package/src/core/transport/tree.ts +1293 -308
  137. package/src/core/transport/types/agent.ts +434 -0
  138. package/src/core/transport/types/client.ts +247 -0
  139. package/src/core/transport/types/shared.ts +27 -0
  140. package/src/core/transport/types/tree.ts +393 -0
  141. package/src/core/transport/types/view.ts +288 -0
  142. package/src/core/transport/types.ts +13 -706
  143. package/src/core/transport/view.ts +1229 -450
  144. package/src/core/transport/wire-log.ts +189 -0
  145. package/src/errors.ts +29 -9
  146. package/src/event-emitter.ts +3 -2
  147. package/src/index.ts +86 -42
  148. package/src/logger.ts +14 -1
  149. package/src/react/contexts/client-session-context.ts +41 -0
  150. package/src/react/contexts/client-session-provider.tsx +222 -0
  151. package/src/react/create-session-hooks.ts +141 -0
  152. package/src/react/index.ts +24 -13
  153. package/src/react/internal/skipped-session.ts +62 -0
  154. package/src/react/internal/use-resolved-session.ts +63 -0
  155. package/src/react/use-ably-messages.ts +32 -22
  156. package/src/react/use-client-session.ts +178 -0
  157. package/src/react/use-create-view.ts +33 -29
  158. package/src/react/use-tree.ts +61 -30
  159. package/src/react/use-view.ts +138 -96
  160. package/src/utils.ts +83 -131
  161. package/src/vercel/codec/decode-lifecycle.ts +70 -0
  162. package/src/vercel/codec/events.ts +85 -0
  163. package/src/vercel/codec/fields.ts +58 -0
  164. package/src/vercel/codec/fold-content.ts +54 -0
  165. package/src/vercel/codec/fold-data.ts +46 -0
  166. package/src/vercel/codec/fold-input.ts +255 -0
  167. package/src/vercel/codec/fold-lifecycle.ts +85 -0
  168. package/src/vercel/codec/fold-text.ts +55 -0
  169. package/src/vercel/codec/fold-tool-input.ts +86 -0
  170. package/src/vercel/codec/fold-tool-output.ts +79 -0
  171. package/src/vercel/codec/index.ts +28 -21
  172. package/src/vercel/codec/inputs.ts +116 -0
  173. package/src/vercel/codec/outputs.ts +207 -0
  174. package/src/vercel/codec/reducer-state.ts +169 -0
  175. package/src/vercel/codec/reducer.ts +191 -0
  176. package/src/vercel/codec/tool-transitions.ts +3 -14
  177. package/src/vercel/codec/wire-data.ts +64 -0
  178. package/src/vercel/index.ts +7 -19
  179. package/src/vercel/react/contexts/chat-transport-context.ts +8 -7
  180. package/src/vercel/react/contexts/chat-transport-provider.tsx +87 -59
  181. package/src/vercel/react/index.ts +3 -5
  182. package/src/vercel/react/use-chat-transport.ts +44 -66
  183. package/src/vercel/react/use-message-sync.ts +75 -39
  184. package/src/vercel/run-end-reason.ts +157 -0
  185. package/src/vercel/tool-part.ts +25 -0
  186. package/src/vercel/transport/chat-transport.ts +380 -98
  187. package/src/vercel/transport/index.ts +38 -37
  188. package/src/vercel/transport/run-output-stream.ts +169 -0
  189. package/src/version.ts +2 -0
  190. package/dist/core/transport/client-transport.d.ts +0 -10
  191. package/dist/core/transport/decode-history.d.ts +0 -43
  192. package/dist/core/transport/server-transport.d.ts +0 -7
  193. package/dist/core/transport/stream-router.d.ts +0 -29
  194. package/dist/core/transport/turn-manager.d.ts +0 -37
  195. package/dist/react/contexts/transport-context.d.ts +0 -31
  196. package/dist/react/contexts/transport-provider.d.ts +0 -49
  197. package/dist/react/create-transport-hooks.d.ts +0 -124
  198. package/dist/react/use-active-turns.d.ts +0 -12
  199. package/dist/react/use-client-transport.d.ts +0 -80
  200. package/dist/vercel/codec/accumulator.d.ts +0 -21
  201. package/dist/vercel/codec/decoder.d.ts +0 -22
  202. package/dist/vercel/codec/encoder.d.ts +0 -41
  203. package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +0 -30
  204. package/dist/vercel/tool-approvals.d.ts +0 -124
  205. package/dist/vercel/tool-events.d.ts +0 -26
  206. package/src/core/transport/client-transport.ts +0 -977
  207. package/src/core/transport/decode-history.ts +0 -485
  208. package/src/core/transport/server-transport.ts +0 -612
  209. package/src/core/transport/stream-router.ts +0 -136
  210. package/src/core/transport/turn-manager.ts +0 -165
  211. package/src/react/contexts/transport-context.ts +0 -37
  212. package/src/react/contexts/transport-provider.tsx +0 -164
  213. package/src/react/create-transport-hooks.ts +0 -144
  214. package/src/react/use-active-turns.ts +0 -72
  215. package/src/react/use-client-transport.ts +0 -197
  216. package/src/vercel/codec/accumulator.ts +0 -588
  217. package/src/vercel/codec/decoder.ts +0 -618
  218. package/src/vercel/codec/encoder.ts +0 -410
  219. package/src/vercel/react/use-staged-add-tool-approval-response.ts +0 -87
  220. package/src/vercel/tool-approvals.ts +0 -380
  221. package/src/vercel/tool-events.ts +0 -53
@@ -0,0 +1,288 @@
1
+ /** View types: history pagination, branch selection, run info, and the windowed View contract. */
2
+
3
+ import type * as Ably from 'ably';
4
+
5
+ import type { CodecInputEvent, CodecMessage } from '../../codec/types.js';
6
+ import type { ActiveRun, SendOptions } from './client.js';
7
+ import type { RunEndReason } from './shared.js';
8
+ import type { RunLifecycleEvent } from './tree.js';
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // History / pagination
12
+ // ---------------------------------------------------------------------------
13
+
14
+ /** A page of raw history wires from the channel. Internal to View/decodeHistory. */
15
+ export interface HistoryPage {
16
+ /** Raw Ably messages that produced this page, in chronological order (oldest first). */
17
+ rawMessages: Ably.InboundMessage[];
18
+ /** Whether there are older pages available. */
19
+ hasNext(): boolean;
20
+ /** Fetch the next (older) page. Returns undefined if no more pages. */
21
+ next(): Promise<HistoryPage | undefined>;
22
+ }
23
+
24
+ /** Options for loading channel history. */
25
+ export interface LoadHistoryOptions {
26
+ /** Max messages per page. Default: 100. */
27
+ limit?: number;
28
+ }
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // View — windowed projection over the tree
32
+ // ---------------------------------------------------------------------------
33
+
34
+ /** Fields common to every {@link RunInfo} arm. */
35
+ interface RunInfoBase {
36
+ /** The Run's unique identifier. */
37
+ runId: string;
38
+ /**
39
+ * Identity of the Ably client that started this Run. Empty string
40
+ * when the wire didn't carry an owner client id.
41
+ */
42
+ clientId: string;
43
+ /**
44
+ * The agent-minted `invocationId` observed for this Run, adopted from the
45
+ * wire `ai-run-start`. Stable across the Run's lifecycle once observed.
46
+ * Empty string until run-start arrives (the agent mints it, so an
47
+ * optimistic Run carries none) or when the wire didn't carry an
48
+ * invocation-id.
49
+ */
50
+ invocationId: string;
51
+ }
52
+
53
+ /**
54
+ * Projection-free, View-facing snapshot of a Run.
55
+ *
56
+ * Exposes the Run facts a UI consumer needs (`runId`, owner `clientId`,
57
+ * lifecycle `status`, `invocationId`, and — only when it failed — the terminal
58
+ * `error`) without leaking the codec's opaque per-Run projection or the Tree's
59
+ * structural fields. Callers that need the full Run record (parent / fork
60
+ * relationships, serials, projection) reach `session.tree.getRunNode(runId)`
61
+ * directly.
62
+ *
63
+ * Discriminated on `status`: a Run with `status: 'error'` carries the terminal
64
+ * `error`; every other status has no `error`. So `info.error` is defined
65
+ * exactly when `info.status === 'error'`.
66
+ */
67
+ export type RunInfo =
68
+ | (RunInfoBase & {
69
+ /**
70
+ * Run lifecycle status. `'active'` while the Run is streaming;
71
+ * `'suspended'` while it is paused awaiting input (still live, a
72
+ * continuation re-activates it); otherwise the non-error terminal
73
+ * {@link RunEndReason} (`'complete'` or `'cancelled'`). Literal lifecycle
74
+ * vocabulary — UIs that want `'streaming'` rendering language translate
75
+ * at the component boundary. The `'error'` terminal status lives on the
76
+ * other arm of this union, where it is paired with the terminal `error`.
77
+ */
78
+ status: 'active' | 'suspended' | Exclude<RunEndReason, 'error'>;
79
+ /** Never present for a non-error status. */
80
+ error?: never;
81
+ })
82
+ | (RunInfoBase & {
83
+ /** Terminal error status — the Run ended with {@link RunEndReason} `'error'`, carrying the terminal `error` below. */
84
+ status: 'error';
85
+ /**
86
+ * The terminal error. Carries the agent-stamped `error-code` /
87
+ * `error-message` detail (or a generic fallback when the run ended in
88
+ * error without detail), so a UI can show *why* a run failed alongside
89
+ * its `'error'` status. Mirrors the `Ably.ErrorInfo` delivered via
90
+ * `ClientSession.on('error')`.
91
+ */
92
+ error: Ably.ErrorInfo;
93
+ });
94
+
95
+ /**
96
+ * Bundle returned by {@link View.branchSelection} describing the
97
+ * sibling group anchored at a given codec-message-id.
98
+ *
99
+ * Total / always-defined — `view.branchSelection(id)` is safe to call
100
+ * for any message:
101
+ *
102
+ * - **Branch anchor (N ≥ 2 siblings)**: `siblings` carries every
103
+ * sibling Run's view of the anchor slot, `index` is the selected
104
+ * sibling's position, `selected === siblings[index]`,
105
+ * `hasSiblings: true`.
106
+ * - **Known non-anchor message**: `siblings = [thisMessage]`,
107
+ * `index: 0`, `selected: thisMessage`, `hasSiblings: false`.
108
+ * - **Unknown codec-message-id**: `siblings: []`, `index: 0`,
109
+ * `selected: undefined`, `hasSiblings: false`.
110
+ *
111
+ * Because `siblings` always contains the currently rendered message
112
+ * (for known ids), `siblings.length` is `1` for a plain bubble (not
113
+ * `0`) and the indexing space matches between read and write —
114
+ * passing `branch.index` back into {@link View.selectSibling} is a
115
+ * round-trip no-op.
116
+ */
117
+ export interface BranchSelection<TMessage> {
118
+ /** True when the codec-message-id is a branch anchor with more than one sibling. Equivalent to `siblings.length > 1`. */
119
+ hasSiblings: boolean;
120
+ /**
121
+ * The selected sibling and any alternatives, in tree-order (oldest
122
+ * first). Always contains the currently rendered message itself for
123
+ * known codec-message-ids; empty only when the id is unknown to the
124
+ * view.
125
+ */
126
+ siblings: TMessage[];
127
+ /** Index of the selected sibling within `siblings`. `0` when there is no real branching or the id is unknown. */
128
+ index: number;
129
+ /** Convenience reference to `siblings[index]`. `undefined` only when `siblings` is empty. */
130
+ selected: TMessage | undefined;
131
+ }
132
+
133
+ /**
134
+ * A paginated, branch-aware projection of the conversation tree.
135
+ *
136
+ * Returns only the visible portion of the selected branch. New live messages
137
+ * appear immediately; older messages are revealed progressively via
138
+ * `loadOlder()`. Events are scoped to the visible window — subscribers
139
+ * are only notified when the visible output changes.
140
+ */
141
+ export interface View<TInput extends CodecInputEvent, TMessage> {
142
+ /**
143
+ * The visible messages along the selected branch, each paired with its
144
+ * codec-message-id (see {@link CodecMessage}). Computed by walking the
145
+ * visible Run chain (newest to root) and concatenating each Run's
146
+ * `codec.getMessages(projection)` in chronological order.
147
+ *
148
+ * Correlate a message back to the transport — routing a continuation
149
+ * input, resolving a regenerate/edit target, looking up the owning Run —
150
+ * via its `codecMessageId`, which the SDK assigns and tracks
151
+ * independently of any identity the domain `message` may carry. Read the
152
+ * domain object from each entry's `message` field.
153
+ */
154
+ getMessages(): CodecMessage<TMessage>[];
155
+
156
+ /**
157
+ * Snapshot of the visible Runs along the selected branch, in
158
+ * chronological order — already filtered by this view's pagination
159
+ * window, branch selection, and regenerate substitution. The
160
+ * companion to {@link getMessages}: same scope, exposed as
161
+ * projection-free {@link RunInfo} so consumers can iterate Run
162
+ * identity (runId, clientId, status, invocationId) without touching
163
+ * the Tree.
164
+ */
165
+ runs(): RunInfo[];
166
+
167
+ /** Whether there are older messages that can be loaded or revealed. */
168
+ hasOlder(): boolean;
169
+
170
+ /**
171
+ * Reveal exactly `limit` older codecMessages — fewer only when channel history
172
+ * is exhausted. Loads from channel history when the tree doesn't already hold
173
+ * `limit` hidden messages, then advances the pagination window. Emits 'update'
174
+ * when the visible list changes.
175
+ *
176
+ * The pagination unit is the **codecMessage**. A node (a user prompt, or a
177
+ * reply Run) contributes 1..N messages to the flat list returned by
178
+ * {@link View.getMessages}; the window counts those messages, so a node
179
+ * straddling the boundary is **partially revealed** — only its newest messages
180
+ * enter the window — and the page lands exactly on `limit` rather than on a
181
+ * node boundary. Such a partially-revealed run still appears in
182
+ * {@link View.runs} and is event-scoped.
183
+ * @param limit - Number of older codecMessages to reveal. Defaults to 10.
184
+ */
185
+ loadOlder(limit?: number): Promise<void>;
186
+
187
+ // --- Run lookup ---
188
+
189
+ /**
190
+ * Look up the {@link RunInfo} for the Run that owns `codecMessageId`.
191
+ * For a user input node's codec-message-id, resolves to its
192
+ * currently-selected reply run. Returns `undefined` when the
193
+ * codec-message-id hasn't been observed by the view, or when it names
194
+ * an input node that has no reply run yet.
195
+ * @param codecMessageId - The codec-message-id to look up.
196
+ */
197
+ runOf(codecMessageId: string): RunInfo | undefined;
198
+
199
+ /**
200
+ * Direct lookup by Run id. Kept for symmetry with {@link runOf} so
201
+ * callers that hold a `runId` (e.g. cancel handlers) get a one-step
202
+ * lookup. Returns `undefined` when the Run hasn't been observed.
203
+ * @param runId - The Run id to look up.
204
+ */
205
+ run(runId: string): RunInfo | undefined;
206
+
207
+ // --- Branch navigation ---
208
+
209
+ /**
210
+ * Resolve the {@link BranchSelection} bundle anchored at
211
+ * `codecMessageId`. Always returns a safe object — see
212
+ * {@link BranchSelection} for the per-case shape.
213
+ *
214
+ * Per AITRFC-014, branch points are message-anchored: edit forks
215
+ * point at the user prompt's codec-message-id, regenerate forks
216
+ * point at the assistant message's codec-message-id.
217
+ * @param codecMessageId - The codec-message-id of the bubble being rendered.
218
+ */
219
+ branchSelection(codecMessageId: string): BranchSelection<TMessage>;
220
+
221
+ /**
222
+ * Select a sibling at the branch point anchored at
223
+ * `codecMessageId`. `index` is clamped to
224
+ * `[0, siblings.length - 1]`. Silent no-op when `codecMessageId`
225
+ * is not a branch anchor. Emits 'update' when the visible output
226
+ * changes.
227
+ * @param codecMessageId - The codec-message-id of the bubble being rendered.
228
+ * @param index - The index of the sibling to select.
229
+ */
230
+ selectSibling(codecMessageId: string, index: number): void;
231
+
232
+ // --- Write operations ---
233
+
234
+ /**
235
+ * Send one or more TInputs on the channel and fire a POST. Each TInput
236
+ * carries its own routing metadata (`parent` / `target` / `codecMessageId`)
237
+ * via the {@link CodecInputEvent} base; the SDK reads those fields
238
+ * directly without runtime classification.
239
+ *
240
+ * To send a fresh user message, wrap the domain message with
241
+ * {@link Codec.createUserMessage} and pass the result here, e.g.
242
+ * `view.send(codec.createUserMessage(message))`.
243
+ *
244
+ * Convention: a send containing at least one `UserMessage` is a
245
+ * fresh send (mints a new `runId`). A send containing only
246
+ * tool-resolution inputs is a continuation — pair with
247
+ * `options.runId` to extend a suspended run.
248
+ *
249
+ * The parent is auto-computed from this view's selected branch unless
250
+ * overridden. The HTTP POST is fire-and-forget — the returned stream is
251
+ * available immediately. If the POST fails, the error is surfaced via
252
+ * the session's `on("error")` and the stream is errored.
253
+ */
254
+ send(events: TInput | TInput[], options?: SendOptions): Promise<ActiveRun>;
255
+
256
+ /**
257
+ * Regenerate an assistant message. Mints a codec `Regenerate` input
258
+ * carrying `target` (the assistant codec-message-id being regenerated)
259
+ * and `parent` (the preceding user prompt's codec-message-id), both
260
+ * auto-computed from this view's branch — there are no new user inputs.
261
+ * The new reply run is not a `forkOf` fork; it continues the
262
+ * regenerated message's run, and the message-level replacement (the new
263
+ * assistant superseding the original) happens at projection-extraction
264
+ * time.
265
+ */
266
+ regenerate(messageId: string, options?: SendOptions): Promise<ActiveRun>;
267
+
268
+ /**
269
+ * Edit a user message. Creates a new run that forks the target message
270
+ * with replacement content. Automatically computes `forkOf` (the edited
271
+ * message) and `parent` from this view's branch.
272
+ */
273
+ edit(messageId: string, inputs: TInput | TInput[], options?: SendOptions): Promise<ActiveRun>;
274
+
275
+ // --- Observation ---
276
+
277
+ /** The visible message list changed (new visible node, branch switch, window shift). */
278
+ on(event: 'update', handler: () => void): () => void;
279
+
280
+ /** A raw Ably message arrived that corresponds to a visible node. */
281
+ on(event: 'ably-message', handler: (msg: Ably.InboundMessage) => void): () => void;
282
+
283
+ /** A run event occurred for a run with visible messages in the window. */
284
+ on(event: 'run', handler: (event: RunLifecycleEvent) => void): () => void;
285
+
286
+ /** Tear down the view — unsubscribe from tree events and clear internal state. */
287
+ close(): void;
288
+ }