@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
@@ -1,54 +1,128 @@
1
1
  /**
2
2
  * Shared constants used by both codec and transport layers.
3
3
  *
4
- * Header constants define the `x-ably-*` wire protocol. Message and event
5
- * name constants define the transport lifecycle signals on the channel.
4
+ * Header constants define the transport wire header names. Message and event
5
+ * name constants define the session lifecycle signals on the channel.
6
6
  *
7
7
  * These live at the top level (not in codec/ or transport/) because both
8
8
  * layers need them — the codec core reads/writes stream and status headers,
9
- * while the transport layer reads/writes turn, cancel, and role headers.
9
+ * while the transport layer reads/writes run, cancel, and role headers.
10
10
  */
11
11
  /** Header: whether this Ably message uses streaming (message appends) or is discrete. Always "true" or "false". */
12
- export declare const HEADER_STREAM = "x-ably-stream";
13
- /** Header: lifecycle status of a streamed message. Only set when x-ably-stream is "true". */
14
- export declare const HEADER_STATUS = "x-ably-status";
12
+ export declare const HEADER_STREAM = "stream";
13
+ /** Header: lifecycle status of a streamed message. Only set when stream is "true". One of "streaming", "complete", or "cancelled". */
14
+ export declare const HEADER_STATUS = "status";
15
15
  /** Header: stream identity. Set by the encoder on every streamed message; read by the decoder to correlate streams. */
16
- export declare const HEADER_STREAM_ID = "x-ably-stream-id";
16
+ export declare const HEADER_STREAM_ID = "stream-id";
17
17
  /** Header: marks a message as a discrete message part (from writeMessages). Set by publishDiscreteBatch; not set on lifecycle events from publishDiscrete. */
18
- export declare const HEADER_DISCRETE = "x-ably-discrete";
19
- /** Header: turn correlation ID. Set on every message in a turn. */
20
- export declare const HEADER_TURN_ID = "x-ably-turn-id";
18
+ export declare const HEADER_DISCRETE = "discrete";
19
+ /** Header: run correlation ID. Set on every agent-published message and on continuation client inputs, but omitted from the originating fresh client input (the agent mints the run-id at run-start). */
20
+ export declare const HEADER_RUN_ID = "run-id";
21
+ /** Header: invocation correlation ID; identifies a specific invocation under a run. Agent-minted and stamped by the agent on every event it publishes for the invocation — run lifecycle (run-start/resume/suspend/end) and assistant outputs. Never set by the client on its input. */
22
+ export declare const HEADER_INVOCATION_ID = "invocation-id";
23
+ /**
24
+ * Header: per-event identifier stamped by the client on every
25
+ * client-published event in a send — user-message events AND amend
26
+ * events (tool-approval responses, client tool outputs). Distinct from
27
+ * `codec-message-id` so it survives edits/retries that reuse the same
28
+ * codec-message-id, and so amend events that target an existing message can
29
+ * carry their own per-send identity. The invocation body lists every
30
+ * inputEventId the agent must observe on the channel before starting LLM
31
+ * work — see `Run.start()`'s input-event lookup.
32
+ */
33
+ export declare const HEADER_EVENT_ID = "event-id";
21
34
  /** Header: message identity. Assigned per message (user or assistant). Used for optimistic reconciliation on the client. */
22
- export declare const HEADER_MSG_ID = "x-ably-msg-id";
23
- /** Header: clientId of the user who initiated the turn. Set by the server on stream messages. */
24
- export declare const HEADER_TURN_CLIENT_ID = "x-ably-turn-client-id";
35
+ export declare const HEADER_CODEC_MESSAGE_ID = "codec-message-id";
36
+ /** Header: clientId of the user who initiated the run. Stamped by the client on its user input and re-stamped by the agent on the run's lifecycle and stream messages. */
37
+ export declare const HEADER_RUN_CLIENT_ID = "run-client-id";
38
+ /**
39
+ * Header: clientId of the input event (the `ai-input`) that drove the
40
+ * current invocation. The agent reads the publisher's Ably-level `clientId`
41
+ * from the triggering input event on the channel and re-stamps it as
42
+ * `input-client-id` on every event it publishes for that invocation
43
+ * (run lifecycle and assistant outputs). May differ from
44
+ * `run-client-id` on continuation invocations driven by an input
45
+ * from a non-owner (e.g. a tool-result publish from a different client).
46
+ * Not stamped on `ai-input` events themselves — the wire publisher's
47
+ * Ably `clientId` already conveys that.
48
+ */
49
+ export declare const HEADER_INPUT_CLIENT_ID = "input-client-id";
25
50
  /** Header: message role (e.g. "user", "assistant"). */
26
- export declare const HEADER_ROLE = "x-ably-role";
27
- /** Header: the msg-id of the existing message this Ably message amends. Present on cross-turn amendment events. */
28
- export declare const HEADER_AMEND = "x-ably-amend";
29
- /** Header: cancel a specific turn by ID. */
30
- export declare const HEADER_CANCEL_TURN_ID = "x-ably-cancel-turn-id";
31
- /** Header: cancel all turns belonging to the sender's clientId. */
32
- export declare const HEADER_CANCEL_OWN = "x-ably-cancel-own";
33
- /** Header: cancel all turns on the channel. */
34
- export declare const HEADER_CANCEL_ALL = "x-ably-cancel-all";
35
- /** Header: cancel all turns belonging to a specific clientId. */
36
- export declare const HEADER_CANCEL_CLIENT_ID = "x-ably-cancel-client-id";
37
- /** Header: the msg-id of the immediately preceding message in this branch. */
38
- export declare const HEADER_PARENT = "x-ably-parent";
39
- /** Header: the msg-id of the message this one replaces (creates a fork). */
40
- export declare const HEADER_FORK_OF = "x-ably-fork-of";
41
- /** Header: reason a turn ended (on x-ably-turn-end messages). */
42
- export declare const HEADER_TURN_REASON = "x-ably-turn-reason";
43
- /** Message name: client->server cancel signal. */
44
- export declare const EVENT_CANCEL = "x-ably-cancel";
45
- /** Message name: server publishes this to signal a turn has started. */
46
- export declare const EVENT_TURN_START = "x-ably-turn-start";
47
- /** Message name: server publishes this to signal a turn has ended. */
48
- export declare const EVENT_TURN_END = "x-ably-turn-end";
49
- /** Message name: transport-level abort signal (stream cancelled). */
50
- export declare const EVENT_ABORT = "x-ably-abort";
51
- /** Message name: transport-level error signal. */
52
- export declare const EVENT_ERROR = "x-ably-error";
53
- /** Prefix for domain-specific headers. Distinguishes codec-layer headers from transport `x-ably-*` headers. */
54
- export declare const DOMAIN_HEADER_PREFIX = "x-domain-";
51
+ export declare const HEADER_ROLE = "role";
52
+ /** Header: the codec-message-id of the immediately preceding message in this branch. */
53
+ export declare const HEADER_PARENT = "parent";
54
+ /** Header: the codec-message-id of the message this one replaces (creates a fork). */
55
+ export declare const HEADER_FORK_OF = "fork-of";
56
+ /**
57
+ * Header: the codec-message-id of the assistant message this run regenerates.
58
+ *
59
+ * Stamped on the regenerate wire (and echoed on `run-start`) when the
60
+ * client requested a regeneration. A regenerate run parents at the SAME input
61
+ * node as the reply it regenerates, so it joins that input's reply runs as a
62
+ * same-parent sibling (no fork-of). The View consults this header to resolve
63
+ * the message-level sibling group and to drop the regenerated message from
64
+ * earlier Runs in the visible chain (Spec: AIT-CT13d).
65
+ */
66
+ export declare const HEADER_MSG_REGENERATE = "msg-regenerate";
67
+ /** Header: reason a run ended (on ai-run-end messages). */
68
+ export declare const HEADER_RUN_REASON = "run-reason";
69
+ /**
70
+ * Header: the `codec-message-id` of the input event that triggered the run.
71
+ * The triggering input is the one whose `event-id` matches the invocation's
72
+ * `inputEventId` (the last input of the originating send). The agent
73
+ * re-stamps it on every event it publishes for the invocation (run
74
+ * lifecycle + assistant outputs), mirroring `input-client-id`. This is the
75
+ * codec-message-id the client owns at send time, so it lets the client
76
+ * correlate any of those events back to the originating input without
77
+ * depending on a client-minted run-id or invocation-id.
78
+ */
79
+ export declare const HEADER_INPUT_CODEC_MESSAGE_ID = "input-codec-message-id";
80
+ /** Header: numeric error code accompanying an `ai-run-end` with reason `error`. */
81
+ export declare const HEADER_ERROR_CODE = "error-code";
82
+ /** Header: human-readable error message accompanying an `ai-run-end` with reason `error`. */
83
+ export declare const HEADER_ERROR_MESSAGE = "error-message";
84
+ /**
85
+ * Message name: client->agent cancel intent. Targets a run by `run-id` (a
86
+ * continuation, whose run-id the client already knows) and/or by
87
+ * `input-codec-message-id` (a fresh send, whose run-id the agent mints at
88
+ * run-start — so the client can only key the cancel by the triggering input's
89
+ * codec-message-id it owns at send time). The agent resolves whichever is
90
+ * present to the registered run; a cancel that arrives before the run is known
91
+ * (the input-event lookup hasn't resolved the input id to a run yet) is
92
+ * buffered by `input-codec-message-id` and honoured when the run resolves it.
93
+ * Also carries an `event-id` so channel rewind redelivers it to a per-request /
94
+ * serverless agent that attaches after the cancel was published.
95
+ */
96
+ export declare const EVENT_CANCEL = "ai-cancel";
97
+ /** Message name: server publishes this to signal a run has started. */
98
+ export declare const EVENT_RUN_START = "ai-run-start";
99
+ /**
100
+ * Message name: server publishes this to signal a run has suspended — paused
101
+ * awaiting participant input (e.g. a client tool result or approval) without
102
+ * ending. The run stays live and may be resumed under the same `runId`.
103
+ * Distinct from `ai-run-end`, which is terminal.
104
+ */
105
+ export declare const EVENT_RUN_SUSPEND = "ai-run-suspend";
106
+ /**
107
+ * Message name: server publishes this when a subsequent invocation re-enters an
108
+ * already-started run (e.g. a tool-result follow-up under the same `runId`).
109
+ * A pure re-entry signal: unlike `ai-run-start` it carries no `parent` / `fork-of`
110
+ * (the original `ai-run-start` already established the run's structure).
111
+ */
112
+ export declare const EVENT_RUN_RESUME = "ai-run-resume";
113
+ /** Message name: server publishes this to signal a run has ended. */
114
+ export declare const EVENT_RUN_END = "ai-run-end";
115
+ /**
116
+ * Message name: every agent-published codec event (text, reasoning, tool calls,
117
+ * tool outputs, lifecycle helpers, file / source parts, data-* chunks) rides
118
+ * this single wire name. The codec event's own `type` is carried in the
119
+ * SDK-controlled codec-level `kind` header so the decoder can dispatch.
120
+ */
121
+ export declare const EVENT_AI_OUTPUT = "ai-output";
122
+ /**
123
+ * Message name: every client-published codec event (user-message parts,
124
+ * tool-approval responses, regenerate signals) rides this single wire
125
+ * name. The codec event's own kind is carried in the codec-level `kind`
126
+ * header so the decoder can dispatch.
127
+ */
128
+ export declare const EVENT_AI_INPUT = "ai-input";
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Wraps the two paths chat-js uses (see ChatClient._addAgent): the
3
+ * `options.agents` mutation (read by ably-js when opening the initial
4
+ * WebSocket) and the `params.agent` channel option (sent on ATTACH so
5
+ * an already-open connection still carries the identifier).
6
+ *
7
+ * `options.agents` is a private API on the Realtime client — no public
8
+ * typed accessor exists in the `ably` package — so this module casts to a
9
+ * `RealtimeWithOptions` shape to write it.
10
+ */
11
+ import type * as Ably from 'ably';
12
+ /**
13
+ * The space-separated `params.agent` string this SDK stamps on channel ATTACH —
14
+ * `ai-transport-js/<version>` plus the codec's adapter tag when present. Pure:
15
+ * unlike {@link registerAgent} it does not mutate the client. Use it to seed a
16
+ * `<ChannelProvider options>` so ably-js's React hooks append their own agent
17
+ * additively (`channelOptionsForReactHooks`) rather than overwriting this SDK's.
18
+ * @param codec - The codec instance whose optional identifier opts into registration.
19
+ * @param codec.adapterTag - The optional Ably-Agent identifier; registered as an agent when present.
20
+ * @returns The channel `params.agent` string.
21
+ */
22
+ export declare const channelAgent: (codec?: {
23
+ readonly adapterTag?: string;
24
+ }) => string;
25
+ /**
26
+ * Register this SDK (and optionally a codec) on the supplied Realtime client
27
+ * and return the channel options the caller should pass to
28
+ * `client.channels.get(...)` so the agent is also carried on channel ATTACH.
29
+ * Sets `options.agents['ai-transport-js'] = VERSION`. When the codec carries an
30
+ * `adapterTag`, also sets `options.agents[adapterTag] = VERSION`.
31
+ * Idempotent — repeated calls with the same client and codec produce the same keys/values.
32
+ * Spec: AIT-CT1a, AIT-CT1a2, AIT-CT1a3, AIT-ST1a, AIT-ST1a2, AIT-ST1a3.
33
+ * @param client - The Ably Realtime client to register on.
34
+ * @param codec - The codec instance whose optional identifier opts into registration.
35
+ * @param codec.adapterTag - The optional Ably-Agent identifier; registered as an agent when present.
36
+ * @returns Channel options containing `params.agent` for `channels.get`.
37
+ */
38
+ export declare const registerAgent: (client: Ably.Realtime, codec?: {
39
+ readonly adapterTag?: string;
40
+ }) => {
41
+ params: {
42
+ agent: string;
43
+ };
44
+ };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Channel-mode resolution shared by the sessions and the React provider.
3
+ *
4
+ * Presence, pub/sub, and annotation publishing are all part of the server's
5
+ * default channel-mode set, so a channel attached with no mode flags is granted
6
+ * them automatically. LiveObjects is different: object operations require the
7
+ * `object_subscribe` / `object_publish` modes, which are NOT in the default
8
+ * set, so the channel must be attached with explicit modes to use them.
9
+ *
10
+ * Setting `modes` on the wire is a full replacement, not additive: the moment
11
+ * an ATTACH carries any mode flag the server takes that bitfield verbatim and
12
+ * never falls back to its default set. So requesting object modes means also
13
+ * requesting everything the default set would grant, plus the object modes.
14
+ * {@link AIT_BASE_MODES} is exactly the server default, so opting into extra
15
+ * modes adds the extras and changes nothing else.
16
+ *
17
+ * Every place that resolves the session's channel options — both session
18
+ * constructors and the React `<ChannelProvider>` — must funnel through
19
+ * {@link resolveChannelModes} so they all request the SAME modes in the SAME
20
+ * order. ably-js compares modes order- and duplicate-sensitively when deciding
21
+ * whether a `setOptions` call needs a reattach; identical arrays compare equal,
22
+ * so consistent resolution avoids both spurious reattaches and silent mode
23
+ * reversion when one writer omits modes another set.
24
+ */
25
+ import type * as Ably from 'ably';
26
+ /**
27
+ * The modes AI Transport always needs — byte-for-byte the server's default
28
+ * channel-mode set (`PUBLISH | SUBSCRIBE | PRESENCE | PRESENCE_SUBSCRIBE |
29
+ * ANNOTATION_PUBLISH`). Because this equals the default, requesting it plus
30
+ * extra modes (e.g. {@link OBJECT_MODES}) grants the same access as the default
31
+ * set plus those extras.
32
+ */
33
+ export declare const AIT_BASE_MODES: readonly Ably.ChannelMode[];
34
+ /**
35
+ * The channel modes required to read and write Ably LiveObjects. Pass as the
36
+ * session's `channelModes` option (`channelModes: OBJECT_MODES`) to enable the
37
+ * `object` accessor on a session and the LiveObjects channel hooks under a
38
+ * `<ClientSessionProvider>`.
39
+ */
40
+ export declare const OBJECT_MODES: readonly Ably.ChannelMode[];
41
+ /**
42
+ * Resolve the channel modes AI Transport should request on its channel.
43
+ *
44
+ * Returns `undefined` when the caller asks for no extra modes, so the channel
45
+ * attaches with no mode flags and the server applies its default set. When
46
+ * extra modes are supplied (e.g. {@link OBJECT_MODES}),
47
+ * returns {@link AIT_BASE_MODES} unioned with them, de-duplicated and in a
48
+ * fixed canonical order so repeated resolutions compare equal.
49
+ *
50
+ * Modes outside {@link MODE_ORDER} (which should not occur for a valid
51
+ * {@link Ably.ChannelMode}, but is possible with the type's lowercase aliases)
52
+ * are appended after the canonical modes, sorted alphabetically, so the result
53
+ * is still deterministic.
54
+ * @param extraModes - Additional modes to request on top of {@link AIT_BASE_MODES}. Omit or pass an empty array to request no modes at all.
55
+ * @returns The canonically-ordered, de-duplicated mode set, or `undefined` when no extra modes were requested.
56
+ */
57
+ export declare const resolveChannelModes: (extraModes?: readonly Ably.ChannelMode[]) => Ably.ChannelMode[] | undefined;
@@ -0,0 +1,9 @@
1
+ import { CodecEvent, CodecInputEvent, CodecOutputEvent, DecodedMessage } from './types.js';
2
+ /**
3
+ * Tag a decoded message's events with their wire direction.
4
+ * @template TInput - The codec's input union.
5
+ * @template TOutput - The codec's output union.
6
+ * @param decoded - The decoder's input/output split for one inbound message.
7
+ * @returns The events as a direction-tagged {@link CodecEvent} list, inputs first.
8
+ */
9
+ export declare const toCodecEvents: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent>(decoded: DecodedMessage<TInput, TOutput>) => CodecEvent<TInput, TOutput>[];
@@ -1,22 +1,22 @@
1
1
  import { Logger } from '../../logger.js';
2
- import { DecoderOutput, MessagePayload, StreamTrackerState } from './types.js';
2
+ import { MessagePayload, StreamTrackerState } from './types.js';
3
3
  /**
4
4
  * Decoder core — action dispatch and serial tracking machinery.
5
5
  *
6
6
  * Handles the Ably message action patterns (create, append, update, delete)
7
7
  * and delegates to domain-specific hooks for event building and discrete
8
- * event decoding.
8
+ * event decoding. Stream trackers are version-guarded: a delivery whose
9
+ * `Message.version.serial` the tracker has already incorporated decodes to
10
+ * nothing, so the same decoder instance can serve both the live
11
+ * subscription and history hydration without double-decoding.
9
12
  *
10
13
  * Domain decoders call `createDecoderCore(hooks, options)` and provide hooks
11
- * for stream classification, event building, and discrete decoding.
14
+ * for stream classification, event building, and discrete decoding. Hooks
15
+ * return a flat `TEvent[]` — no event-vs-message union. Per-message routing
16
+ * concerns (`codec-message-id`) are handled by the SDK via `ReducerMeta`, not
17
+ * here.
12
18
  */
13
19
  import type * as Ably from 'ably';
14
- /**
15
- * Wrap a domain event as a single-element decoder output array.
16
- * @param event - The domain event to wrap.
17
- * @returns A single-element array containing the event as a decoder output.
18
- */
19
- export declare const eventOutput: <TEvent, TMessage>(event: TEvent) => DecoderOutput<TEvent, TMessage>[];
20
20
  /** Options for creating a decoder core. */
21
21
  export interface DecoderCoreOptions {
22
22
  /** Called when a tracked stream is replaced (non-prefix update). Receives the tracker with updated state. */
@@ -27,31 +27,31 @@ export interface DecoderCoreOptions {
27
27
  logger?: Logger;
28
28
  }
29
29
  /** Hooks that a domain codec provides to the decoder core for stream classification and event building. */
30
- export interface DecoderCoreHooks<TEvent, TMessage> {
30
+ export interface DecoderCoreHooks<TEvent> {
31
31
  /**
32
32
  * Build domain events emitted when a new stream starts. May return multiple
33
33
  * events (e.g. a start event and a start-step event).
34
34
  */
35
- buildStartEvents(tracker: StreamTrackerState): DecoderOutput<TEvent, TMessage>[];
35
+ buildStartEvents(tracker: StreamTrackerState): TEvent[];
36
36
  /** Build domain events for a text delta received on a stream. */
37
- buildDeltaEvents(tracker: StreamTrackerState, delta: string): DecoderOutput<TEvent, TMessage>[];
37
+ buildDeltaEvents(tracker: StreamTrackerState, delta: string): TEvent[];
38
38
  /**
39
- * Build domain events emitted when a stream finishes (x-ably-status:finished).
40
- * Not called for aborted streams. The closing headers may differ from
41
- * tracker.headers if the closing append carried updated headers.
39
+ * Build domain events emitted when a stream completes (status:complete).
40
+ * Not called for cancelled streams. The closing codec headers may differ
41
+ * from tracker.codecHeaders if the closing append carried updated headers.
42
42
  */
43
- buildEndEvents(tracker: StreamTrackerState, closingHeaders: Record<string, string>): DecoderOutput<TEvent, TMessage>[];
43
+ buildEndEvents(tracker: StreamTrackerState, closingCodecHeaders: Record<string, string>): TEvent[];
44
44
  /**
45
- * Decode a discrete message (message.create where x-ably-stream is "false",
46
- * or a non-streamable first-contact update). Handles user messages, lifecycle
47
- * events, tool lifecycle, data-*, etc.
45
+ * Decode a discrete message (a `message.create` whose stream header is not
46
+ * "true", or a non-streamable first-contact update). Handles user messages,
47
+ * tool lifecycle, data-*, etc.
48
48
  */
49
- decodeDiscrete(input: MessagePayload): DecoderOutput<TEvent, TMessage>[];
49
+ decodeDiscrete(input: MessagePayload): TEvent[];
50
50
  }
51
51
  /** The decoder core returned by {@link createDecoderCore}. */
52
- export interface DecoderCore<TEvent, TMessage> {
53
- /** Decode a single Ably message into zero or more domain outputs. */
54
- decode(message: Ably.InboundMessage): DecoderOutput<TEvent, TMessage>[];
52
+ export interface DecoderCore<TEvent> {
53
+ /** Decode a single Ably message into zero or more domain TEvents. */
54
+ decode(message: Ably.InboundMessage): TEvent[];
55
55
  }
56
56
  /**
57
57
  * Create a decoder core with the given domain hooks.
@@ -59,4 +59,4 @@ export interface DecoderCore<TEvent, TMessage> {
59
59
  * @param options - Decoder configuration (callbacks, logger).
60
60
  * @returns A new {@link DecoderCore} instance.
61
61
  */
62
- export declare const createDecoderCore: <TEvent, TMessage>(hooks: DecoderCoreHooks<TEvent, TMessage>, options?: DecoderCoreOptions) => DecoderCore<TEvent, TMessage>;
62
+ export declare const createDecoderCore: <TEvent>(hooks: DecoderCoreHooks<TEvent>, options?: DecoderCoreOptions) => DecoderCore<TEvent>;
@@ -0,0 +1,100 @@
1
+ import { InputBuilder, InputDescriptor } from './input-descriptors.js';
2
+ import { OutputBuilder, OutputDescriptor } from './output-descriptors.js';
3
+ import { Codec, CodecEvent, CodecInputEvent, CodecMessage, CodecOutputEvent, ReducerMeta, StreamTrackerState } from './types.js';
4
+ import { WellKnownInputFactories } from './well-known-inputs.js';
5
+ export type { InputBuilder } from './input-descriptors.js';
6
+ export type { OutputBuilder } from './output-descriptors.js';
7
+ /** Context passed to a {@link LifecyclePolicy} `onDiscrete` repair function. */
8
+ export interface LifecycleDiscreteContext {
9
+ /** The inbound codec-tier headers (e.g. to recover a stream's message id). */
10
+ codecHeaders: Record<string, string>;
11
+ }
12
+ /**
13
+ * Declarative decode-time lifecycle repair, applied when joining a stream
14
+ * mid-flight (history compaction, rewind miss, partial page). Each function
15
+ * performs its side effect on the codec's lifecycle tracker (captured by the
16
+ * factory that builds the policy) and RETURNS lead-in events to PREPEND; the
17
+ * generic decoder ALWAYS runs the descriptor driver after and appends its
18
+ * output, so the policy never replaces a decode. A codec with no repair
19
+ * supplies no policy.
20
+ * @template TOutput - The codec's output union.
21
+ */
22
+ export interface LifecyclePolicy<TOutput> {
23
+ /**
24
+ * Keyed on the discrete codec `kind`. Returns lead-in events to prepend
25
+ * (empty array = none) after applying any tracker side effect.
26
+ */
27
+ onDiscrete?: Record<string, (runId: string, ctx: LifecycleDiscreteContext) => TOutput[]>;
28
+ /** Lead-in prepended to a stream's start events (mid-stream-join pre-roll). */
29
+ onStreamStart?: (runId: string, tracker: StreamTrackerState) => TOutput[];
30
+ }
31
+ /**
32
+ * The reducer parts a codec supplies. `TProjection` and `TMessage` infer from
33
+ * these, so `defineCodec` callers need not spell them out.
34
+ * @template TInput - The codec's input union.
35
+ * @template TOutput - The codec's output union.
36
+ * @template TProjection - The per-node projection the reducer folds into.
37
+ * @template TMessage - The per-message domain type.
38
+ */
39
+ export interface CodecReducer<TInput, TOutput, TProjection, TMessage> {
40
+ /** Build an empty projection for a node. */
41
+ init: () => TProjection;
42
+ /** Fold one direction-tagged input or output event into the projection. */
43
+ fold: (state: TProjection, event: CodecEvent<TInput, TOutput>, meta: ReducerMeta) => TProjection;
44
+ /** Extract the per-message list (each paired with its codec-message-id). */
45
+ getMessages: (projection: TProjection) => CodecMessage<TMessage>[];
46
+ }
47
+ /**
48
+ * The parts a codec supplies to {@link defineCodec}.
49
+ * @template TInput - The codec's input union.
50
+ * @template TOutput - The codec's output union.
51
+ * @template TProjection - The per-node projection the reducer folds into.
52
+ * @template TMessage - The per-message domain type.
53
+ */
54
+ export interface DefineCodecConfig<TInput extends {
55
+ kind: string;
56
+ }, TOutput extends {
57
+ type: string;
58
+ }, TProjection, TMessage> {
59
+ /** Optional Ably-Agent identifier registered on the channel; omit to opt out. */
60
+ adapterTag?: string;
61
+ /** Reducer parts; `TProjection` / `TMessage` infer from here. */
62
+ reducer: CodecReducer<TInput, TOutput, TProjection, TMessage>;
63
+ /**
64
+ * The declarative output (`ai-output`) descriptor table, returned from the
65
+ * injected `{ event, stream }` builder (both curried on `TOutput`).
66
+ */
67
+ output: (b: OutputBuilder<TOutput>) => readonly OutputDescriptor<TOutput>[];
68
+ /**
69
+ * The declarative input (`ai-input`) descriptor table, returned from the
70
+ * injected `{ event, batch }` builder (both curried on `TInput`).
71
+ */
72
+ input: (b: InputBuilder<TInput>) => readonly InputDescriptor<TInput>[];
73
+ /**
74
+ * Factory for a fresh decode lifecycle policy per decoder instance (the
75
+ * policy's closures capture a fresh, per-decoder lifecycle tracker). Omit
76
+ * for a codec with no mid-stream-join repair.
77
+ */
78
+ decodeLifecycle?: () => LifecyclePolicy<TOutput>;
79
+ }
80
+ /**
81
+ * A codec assembled by {@link defineCodec}: a conforming {@link Codec} whose
82
+ * well-known input factories are typed concretely by {@link WellKnownInputFactories}
83
+ * (so `createToolResult` etc. are callable without a guard). The factory methods
84
+ * are sourced from `WellKnownInputFactories` rather than `Codec` because the
85
+ * former types them against `UserMessageOf<TInput>` / `ToolResultPayloadOf<TInput>`
86
+ * — equal to the codec's `TMessage` / payloads for every real codec, but not
87
+ * provably so to the generic type system. At a concrete call site a
88
+ * `DefinedCodec` is assignable to the corresponding `Codec`.
89
+ */
90
+ export type DefinedCodec<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> = Omit<Codec<TInput, TOutput, TProjection, TMessage>, keyof WellKnownInputFactories<TInput>> & WellKnownInputFactories<TInput>;
91
+ /**
92
+ * Assemble a fully-formed {@link Codec} from a codec's parts. Curried on the
93
+ * input/output unions so `TProjection` / `TMessage` infer from `config.reducer`
94
+ * — a caller writes `defineCodec<TInput, TOutput>()({ ... })` and never spells
95
+ * out the projection or message types.
96
+ * @template TInput - The codec's input union.
97
+ * @template TOutput - The codec's output union.
98
+ * @returns A function taking the codec's parts and returning the assembled codec.
99
+ */
100
+ export declare const defineCodec: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent>() => <TProjection, TMessage>(config: DefineCodecConfig<TInput, TOutput, TProjection, TMessage>) => DefinedCodec<TInput, TOutput, TProjection, TMessage>;
@@ -3,7 +3,7 @@ import { ChannelWriter, EncoderOptions, MessagePayload, StreamPayload, WriteOpti
3
3
  /**
4
4
  * Encoder core — message append lifecycle machinery.
5
5
  *
6
- * Provides Ably primitives (publish, append, close, abort, flush) that
6
+ * Provides Ably primitives (publish, append, close, cancel, flush) that
7
7
  * domain-specific encoders wire their event types to.
8
8
  *
9
9
  * Domain encoders call `createEncoderCore(writer, options)` and use the
@@ -22,35 +22,33 @@ export interface EncoderCore {
22
22
  publishDiscrete(payload: MessagePayload, opts?: WriteOptions): Promise<Ably.PublishResult>;
23
23
  /** Publish multiple discrete messages atomically in a single channel publish. */
24
24
  publishDiscreteBatch(payloads: MessagePayload[], opts?: WriteOptions): Promise<Ably.PublishResult>;
25
- /** Start a streamed message with x-ably-status:streaming. */
25
+ /** Start a streamed message with status:streaming. */
26
26
  startStream(streamId: string, payload: StreamPayload, opts?: WriteOptions): Promise<void>;
27
27
  /**
28
28
  * Append data to an in-flight streamed message. Fire-and-forget: errors are
29
- * collected internally and surfaced by {@link closeStream} or {@link close}.
29
+ * collected internally and surfaced by {@link closeStream},
30
+ * {@link cancelAllStreams} or {@link close}.
31
+ * @throws {Ably.ErrorInfo} InvalidArgument if there is no active stream for `streamId` or the core is closed.
30
32
  */
31
33
  appendStream(streamId: string, data: string): void;
32
34
  /**
33
- * Close a streamed message with x-ably-status:finished. Flushes all pending
35
+ * Close a streamed message with status:complete. Flushes all pending
34
36
  * appends for recovery before returning. Repeats persistent and payload headers.
37
+ * @throws {Ably.ErrorInfo} InvalidArgument if there is no active stream for `streamId`, or the encoder has been closed; EncoderRecoveryFailed if a failed append cannot be recovered during the flush.
35
38
  */
36
39
  closeStream(streamId: string, payload: StreamPayload): Promise<void>;
37
40
  /**
38
- * Abort a single in-progress stream (x-ably-status:aborted) and flush all
41
+ * Cancel all in-progress streams (status:cancelled) and flush all
39
42
  * pending appends for recovery before returning.
40
43
  */
41
- abortStream(streamId: string, opts?: WriteOptions): Promise<void>;
42
- /**
43
- * Abort all in-progress streams (x-ably-status:aborted) and flush all
44
- * pending appends for recovery before returning.
45
- */
46
- abortAllStreams(opts?: WriteOptions): Promise<void>;
44
+ cancelAllStreams(opts?: WriteOptions): Promise<void>;
47
45
  /** Flush + clear trackers. Idempotent. */
48
46
  close(): Promise<void>;
49
47
  }
50
48
  /**
51
49
  * Create an encoder core bound to the given channel writer.
52
50
  * @param writer - The channel writer to publish messages through.
53
- * @param options - Encoder configuration (clientId, extras, hooks, logger).
51
+ * @param options - Encoder configuration (extras, hooks, logger).
54
52
  * @returns A new {@link EncoderCore} instance.
55
53
  */
56
54
  export declare const createEncoderCore: (writer: ChannelWriter, options?: EncoderCoreOptions) => EncoderCore;
@@ -0,0 +1,85 @@
1
+ import { HeaderField } from './fields.js';
2
+ import { OutputDescriptor, OutputEventDescriptor } from './output-descriptors.js';
3
+ /** The codec header carrying the SDK-controlled dispatch kind / stream family id. */
4
+ export declare const KIND_HEADER = "kind";
5
+ /**
6
+ * Derive a wildcard dispatch predicate from a descriptor literal: a literal
7
+ * ending in `-*` matches any value sharing its prefix, so the literal and its
8
+ * predicate can never disagree. Returns `undefined` for an exact literal.
9
+ * Shared by the output event builder and the input part builder so the `-*`
10
+ * sentinel rule lives in one place, next to the {@link partFor} that consumes it.
11
+ * @param literal - The declared descriptor literal (`type` / `partType`).
12
+ * @returns A prefix-match predicate for a wildcard literal, else `undefined`.
13
+ */
14
+ export declare const wildcardMatcher: (literal: string) => ((value: string) => boolean) | undefined;
15
+ /**
16
+ * The codec header carrying a batch part's sub-discriminator. A batch stamps it
17
+ * on every exploded part on encode; the decoder reads it back to resolve the
18
+ * matching part descriptor. Centralised so the key has one home across the
19
+ * input encode and decode drivers and cannot drift between them.
20
+ */
21
+ export declare const PART_TYPE_HEADER = "partType";
22
+ /**
23
+ * Read the value at a declared field key off a source object.
24
+ * @param source - The object to index (a chunk, or a lensed sub-object such as a payload).
25
+ * @param key - The declared field key.
26
+ * @returns The value at `key`, typed `unknown`.
27
+ */
28
+ export declare const prop: (source: object, key: string) => unknown;
29
+ /**
30
+ * Build a codec-headers record from a source object through declared fields,
31
+ * seeded with the dispatch `kind`. Each field writes the value at its key on
32
+ * `source`; an optional `keys` subset restricts which fields are written.
33
+ * @param fields - The declared header fields.
34
+ * @param kindValue - The dispatch kind / stream family id to seed under {@link KIND_HEADER}.
35
+ * @param source - The object to read field values from (a chunk, or a lensed payload).
36
+ * @param keys - Optional subset of field keys to write; omit to write all.
37
+ * @returns The codec-headers record.
38
+ */
39
+ export declare const writeFields: (fields: readonly HeaderField<unknown>[], kindValue: string, source: object, keys?: readonly string[]) => Record<string, string>;
40
+ /**
41
+ * Read declared fields out of a codec-headers record into a bag keyed by field key.
42
+ * A field that reads `undefined` (absent, with no default) contributes no key — the
43
+ * bag carries only the values that are actually present.
44
+ * @param fields - The declared header fields.
45
+ * @param headers - The inbound codec-tier headers.
46
+ * @returns A bag of the present field values, keyed by each field's key.
47
+ */
48
+ /** The structural slice of a part descriptor {@link partFor} dispatches on. */
49
+ interface PartDispatch {
50
+ /** The exact `partType` literal, or the `-*` wildcard literal for a family. */
51
+ partType: string;
52
+ /** Wildcard dispatch predicate; absent for an exact part. */
53
+ match?: (partType: string) => boolean;
54
+ }
55
+ /**
56
+ * Resolve the part descriptor for a `partType`: an exact non-wildcard match,
57
+ * else a wildcard whose derived predicate accepts it. Wildcards are excluded
58
+ * from the exact pass — only their predicate may route to them. Shared by the
59
+ * input encode and decode drivers.
60
+ * @param parts - The batch's part descriptor sub-table.
61
+ * @param partType - The `partType` to resolve (from `partTypeOf` on encode, the wire header on decode).
62
+ * @returns The matching part descriptor, or undefined when none matches.
63
+ */
64
+ export declare const partFor: <P extends PartDispatch>(parts: readonly P[], partType: string) => P | undefined;
65
+ /** An output descriptor set's event descriptors, split for dispatch. */
66
+ export interface OutputEventDispatch<U> {
67
+ /** Exact (non-wildcard) event descriptors, keyed by `type`. */
68
+ discreteByType: Map<string, OutputEventDescriptor<U>>;
69
+ /** Wildcard event descriptors, dispatched by their `match` predicate. */
70
+ wildcards: OutputEventDescriptor<U>[];
71
+ }
72
+ /**
73
+ * Partition an output descriptor set's `event` descriptors into an exact-type
74
+ * map and a wildcard list. Stream descriptors are skipped — each driver indexes
75
+ * those by its own key (phase on encode, kind on decode). Shared by the output
76
+ * encode and decode drivers so the exact-vs-wildcard split has one home.
77
+ * @template U - The codec's event union.
78
+ * @param descriptors - The full descriptor set (events + streamed families).
79
+ * @returns The event descriptors split into {@link OutputEventDispatch}.
80
+ */
81
+ export declare const partitionOutputEvents: <U extends {
82
+ type: string;
83
+ }>(descriptors: readonly OutputDescriptor<U>[]) => OutputEventDispatch<U>;
84
+ export declare const readFields: (fields: readonly HeaderField<unknown>[], headers: Record<string, string>) => Record<string, unknown>;
85
+ export {};