@tanstack/ai 0.36.0 → 0.37.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 (205) hide show
  1. package/dist/esm/activities/chat/adapter.d.ts +163 -0
  2. package/dist/esm/activities/chat/adapter.js +17 -0
  3. package/dist/esm/activities/chat/adapter.js.map +1 -0
  4. package/dist/esm/activities/chat/agent-loop-strategies.d.ts +59 -0
  5. package/dist/esm/activities/chat/agent-loop-strategies.js +23 -0
  6. package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -0
  7. package/dist/esm/activities/chat/index.d.ts +270 -0
  8. package/dist/esm/activities/chat/index.js +1724 -0
  9. package/dist/esm/activities/chat/index.js.map +1 -0
  10. package/dist/esm/activities/chat/mcp/manager.d.ts +25 -0
  11. package/dist/esm/activities/chat/mcp/manager.js +71 -0
  12. package/dist/esm/activities/chat/mcp/manager.js.map +1 -0
  13. package/dist/esm/activities/chat/mcp/types.d.ts +56 -0
  14. package/dist/esm/activities/chat/messages.d.ts +78 -0
  15. package/dist/esm/activities/chat/messages.js +374 -0
  16. package/dist/esm/activities/chat/messages.js.map +1 -0
  17. package/dist/esm/activities/chat/middleware/builder.d.ts +46 -0
  18. package/dist/esm/activities/chat/middleware/builder.js +17 -0
  19. package/dist/esm/activities/chat/middleware/builder.js.map +1 -0
  20. package/dist/esm/activities/chat/middleware/capabilities.d.ts +93 -0
  21. package/dist/esm/activities/chat/middleware/capabilities.js +45 -0
  22. package/dist/esm/activities/chat/middleware/capabilities.js.map +1 -0
  23. package/dist/esm/activities/chat/middleware/compose.d.ts +87 -0
  24. package/dist/esm/activities/chat/middleware/compose.js +510 -0
  25. package/dist/esm/activities/chat/middleware/compose.js.map +1 -0
  26. package/dist/esm/activities/chat/middleware/define.d.ts +20 -0
  27. package/dist/esm/activities/chat/middleware/define.js +7 -0
  28. package/dist/esm/activities/chat/middleware/define.js.map +1 -0
  29. package/dist/esm/activities/chat/middleware/index.d.ts +10 -0
  30. package/dist/esm/activities/chat/middleware/tool-cache-middleware.d.ts +89 -0
  31. package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +76 -0
  32. package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -0
  33. package/dist/esm/activities/chat/middleware/types.d.ts +405 -0
  34. package/dist/esm/activities/chat/middleware/validate.d.ts +19 -0
  35. package/dist/esm/activities/chat/middleware/validate.js +30 -0
  36. package/dist/esm/activities/chat/middleware/validate.js.map +1 -0
  37. package/dist/esm/activities/chat/runtime-context-types.d.ts +43 -0
  38. package/dist/esm/activities/chat/stream/index.d.ts +11 -0
  39. package/dist/esm/activities/chat/stream/json-parser.d.ts +38 -0
  40. package/dist/esm/activities/chat/stream/json-parser.js +28 -0
  41. package/dist/esm/activities/chat/stream/json-parser.js.map +1 -0
  42. package/dist/esm/activities/chat/stream/message-updaters.d.ts +81 -0
  43. package/dist/esm/activities/chat/stream/message-updaters.js +253 -0
  44. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -0
  45. package/dist/esm/activities/chat/stream/processor.d.ts +439 -0
  46. package/dist/esm/activities/chat/stream/processor.js +1426 -0
  47. package/dist/esm/activities/chat/stream/processor.js.map +1 -0
  48. package/dist/esm/activities/chat/stream/strategies.d.ts +43 -0
  49. package/dist/esm/activities/chat/stream/strategies.js +54 -0
  50. package/dist/esm/activities/chat/stream/strategies.js.map +1 -0
  51. package/dist/esm/activities/chat/stream/types.d.ts +90 -0
  52. package/dist/esm/activities/chat/tools/lazy-tool-manager.d.ts +82 -0
  53. package/dist/esm/activities/chat/tools/lazy-tool-manager.js +194 -0
  54. package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -0
  55. package/dist/esm/activities/chat/tools/lazy-tools.d.ts +15 -0
  56. package/dist/esm/activities/chat/tools/lazy-tools.js +16 -0
  57. package/dist/esm/activities/chat/tools/lazy-tools.js.map +1 -0
  58. package/dist/esm/activities/chat/tools/schema-converter.d.ts +140 -0
  59. package/dist/esm/activities/chat/tools/schema-converter.js +167 -0
  60. package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -0
  61. package/dist/esm/activities/chat/tools/tool-calls.d.ts +140 -0
  62. package/dist/esm/activities/chat/tools/tool-calls.js +512 -0
  63. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -0
  64. package/dist/esm/activities/chat/tools/tool-definition.d.ts +135 -0
  65. package/dist/esm/activities/chat/tools/tool-definition.js +25 -0
  66. package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -0
  67. package/dist/esm/activities/error-payload.d.ts +30 -0
  68. package/dist/esm/activities/error-payload.js +54 -0
  69. package/dist/esm/activities/error-payload.js.map +1 -0
  70. package/dist/esm/activities/generateAudio/adapter.d.ts +62 -0
  71. package/dist/esm/activities/generateAudio/adapter.js +16 -0
  72. package/dist/esm/activities/generateAudio/adapter.js.map +1 -0
  73. package/dist/esm/activities/generateAudio/index.d.ts +85 -0
  74. package/dist/esm/activities/generateAudio/index.js +114 -0
  75. package/dist/esm/activities/generateAudio/index.js.map +1 -0
  76. package/dist/esm/activities/generateImage/adapter.d.ts +78 -0
  77. package/dist/esm/activities/generateImage/adapter.js +16 -0
  78. package/dist/esm/activities/generateImage/adapter.js.map +1 -0
  79. package/dist/esm/activities/generateImage/index.d.ts +134 -0
  80. package/dist/esm/activities/generateImage/index.js +121 -0
  81. package/dist/esm/activities/generateImage/index.js.map +1 -0
  82. package/dist/esm/activities/generateSpeech/adapter.d.ts +62 -0
  83. package/dist/esm/activities/generateSpeech/adapter.js +16 -0
  84. package/dist/esm/activities/generateSpeech/adapter.js.map +1 -0
  85. package/dist/esm/activities/generateSpeech/index.d.ts +96 -0
  86. package/dist/esm/activities/generateSpeech/index.js +119 -0
  87. package/dist/esm/activities/generateSpeech/index.js.map +1 -0
  88. package/dist/esm/activities/generateTranscription/adapter.d.ts +62 -0
  89. package/dist/esm/activities/generateTranscription/adapter.js +16 -0
  90. package/dist/esm/activities/generateTranscription/adapter.js.map +1 -0
  91. package/dist/esm/activities/generateTranscription/index.d.ts +109 -0
  92. package/dist/esm/activities/generateTranscription/index.js +109 -0
  93. package/dist/esm/activities/generateTranscription/index.js.map +1 -0
  94. package/dist/esm/activities/generateVideo/adapter.d.ts +145 -0
  95. package/dist/esm/activities/generateVideo/adapter.js +30 -0
  96. package/dist/esm/activities/generateVideo/adapter.js.map +1 -0
  97. package/dist/esm/activities/generateVideo/index.d.ts +223 -0
  98. package/dist/esm/activities/generateVideo/index.js +295 -0
  99. package/dist/esm/activities/generateVideo/index.js.map +1 -0
  100. package/dist/esm/activities/generateVideo/snap.d.ts +14 -0
  101. package/dist/esm/activities/generateVideo/snap.js +54 -0
  102. package/dist/esm/activities/generateVideo/snap.js.map +1 -0
  103. package/dist/esm/activities/index.d.ts +27 -0
  104. package/dist/esm/activities/index.js +43 -0
  105. package/dist/esm/activities/index.js.map +1 -0
  106. package/dist/esm/activities/middleware/index.d.ts +2 -0
  107. package/dist/esm/activities/middleware/run.d.ts +20 -0
  108. package/dist/esm/activities/middleware/run.js +42 -0
  109. package/dist/esm/activities/middleware/run.js.map +1 -0
  110. package/dist/esm/activities/middleware/types.d.ts +118 -0
  111. package/dist/esm/activities/stream-generation-result.d.ts +15 -0
  112. package/dist/esm/activities/stream-generation-result.js +49 -0
  113. package/dist/esm/activities/stream-generation-result.js.map +1 -0
  114. package/dist/esm/activities/summarize/adapter.d.ts +74 -0
  115. package/dist/esm/activities/summarize/adapter.js +16 -0
  116. package/dist/esm/activities/summarize/adapter.js.map +1 -0
  117. package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +45 -0
  118. package/dist/esm/activities/summarize/chat-stream-summarize.js +212 -0
  119. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -0
  120. package/dist/esm/activities/summarize/index.d.ts +108 -0
  121. package/dist/esm/activities/summarize/index.js +113 -0
  122. package/dist/esm/activities/summarize/index.js.map +1 -0
  123. package/dist/esm/adapter-internals.d.ts +5 -0
  124. package/dist/esm/adapter-internals.js +10 -0
  125. package/dist/esm/adapter-internals.js.map +1 -0
  126. package/dist/esm/client.d.ts +44 -0
  127. package/dist/esm/client.js +67 -0
  128. package/dist/esm/client.js.map +1 -0
  129. package/dist/esm/extend-adapter.d.ts +152 -0
  130. package/dist/esm/extend-adapter.js +21 -0
  131. package/dist/esm/extend-adapter.js.map +1 -0
  132. package/dist/esm/index.d.ts +45 -0
  133. package/dist/esm/index.js +109 -0
  134. package/dist/esm/index.js.map +1 -0
  135. package/dist/esm/logger/console-logger.d.ts +29 -0
  136. package/dist/esm/logger/console-logger.js +83 -0
  137. package/dist/esm/logger/console-logger.js.map +1 -0
  138. package/dist/esm/logger/internal-logger.d.ts +41 -0
  139. package/dist/esm/logger/internal-logger.js +86 -0
  140. package/dist/esm/logger/internal-logger.js.map +1 -0
  141. package/dist/esm/logger/resolve.d.ts +14 -0
  142. package/dist/esm/logger/resolve.js +54 -0
  143. package/dist/esm/logger/resolve.js.map +1 -0
  144. package/dist/esm/logger/types.d.ts +75 -0
  145. package/dist/esm/middlewares/content-guard.d.ts +77 -0
  146. package/dist/esm/middlewares/content-guard.js +156 -0
  147. package/dist/esm/middlewares/content-guard.js.map +1 -0
  148. package/dist/esm/middlewares/index.d.ts +2 -0
  149. package/dist/esm/middlewares/index.js +7 -0
  150. package/dist/esm/middlewares/index.js.map +1 -0
  151. package/dist/esm/middlewares/otel.d.ts +81 -0
  152. package/dist/esm/middlewares/otel.js +745 -0
  153. package/dist/esm/middlewares/otel.js.map +1 -0
  154. package/dist/esm/middlewares/tool-cache.d.ts +1 -0
  155. package/dist/esm/middlewares/usage-attributes.d.ts +24 -0
  156. package/dist/esm/middlewares/usage-attributes.js +43 -0
  157. package/dist/esm/middlewares/usage-attributes.js.map +1 -0
  158. package/dist/esm/realtime/index.d.ts +28 -0
  159. package/dist/esm/realtime/index.js +8 -0
  160. package/dist/esm/realtime/index.js.map +1 -0
  161. package/dist/esm/realtime/types.d.ts +282 -0
  162. package/dist/esm/stream-to-response.d.ts +102 -0
  163. package/dist/esm/stream-to-response.js +121 -0
  164. package/dist/esm/stream-to-response.js.map +1 -0
  165. package/dist/esm/strip-to-spec-middleware.d.ts +18 -0
  166. package/dist/esm/strip-to-spec-middleware.js +20 -0
  167. package/dist/esm/strip-to-spec-middleware.js.map +1 -0
  168. package/dist/esm/system-prompts.d.ts +66 -0
  169. package/dist/esm/system-prompts.js +23 -0
  170. package/dist/esm/system-prompts.js.map +1 -0
  171. package/dist/esm/tool-registry.d.ts +81 -0
  172. package/dist/esm/tool-registry.js +49 -0
  173. package/dist/esm/tool-registry.js.map +1 -0
  174. package/dist/esm/tools/provider-tool.d.ts +30 -0
  175. package/dist/esm/tools/provider-tool.js +7 -0
  176. package/dist/esm/tools/provider-tool.js.map +1 -0
  177. package/dist/esm/types.d.ts +1594 -0
  178. package/dist/esm/utilities/ag-ui-wire.d.ts +44 -0
  179. package/dist/esm/utilities/ag-ui-wire.js +107 -0
  180. package/dist/esm/utilities/ag-ui-wire.js.map +1 -0
  181. package/dist/esm/utilities/chat-params.d.ts +85 -0
  182. package/dist/esm/utilities/chat-params.js +100 -0
  183. package/dist/esm/utilities/chat-params.js.map +1 -0
  184. package/dist/esm/utilities/errors.d.ts +13 -0
  185. package/dist/esm/utilities/errors.js +22 -0
  186. package/dist/esm/utilities/errors.js.map +1 -0
  187. package/dist/esm/utilities/media-prompt.d.ts +35 -0
  188. package/dist/esm/utilities/media-prompt.js +43 -0
  189. package/dist/esm/utilities/media-prompt.js.map +1 -0
  190. package/dist/esm/utilities/numbers.d.ts +8 -0
  191. package/dist/esm/utilities/numbers.js +12 -0
  192. package/dist/esm/utilities/numbers.js.map +1 -0
  193. package/dist/esm/utilities/sampling-keys.d.ts +20 -0
  194. package/dist/esm/utilities/sampling-keys.js +20 -0
  195. package/dist/esm/utilities/sampling-keys.js.map +1 -0
  196. package/dist/esm/utilities/tool-result.d.ts +21 -0
  197. package/dist/esm/utilities/tool-result.js +37 -0
  198. package/dist/esm/utilities/tool-result.js.map +1 -0
  199. package/dist/esm/utilities/usage.d.ts +31 -0
  200. package/dist/esm/utilities/usage.js +11 -0
  201. package/dist/esm/utilities/usage.js.map +1 -0
  202. package/dist/esm/utils.d.ts +17 -0
  203. package/dist/esm/utils.js +20 -0
  204. package/dist/esm/utils.js.map +1 -0
  205. package/package.json +3 -3
@@ -0,0 +1,30 @@
1
+ function validateCapabilities(middlewares, adapter) {
2
+ const provided = /* @__PURE__ */ new Set();
3
+ for (const mw of middlewares) {
4
+ for (const handle of mw.provides ?? []) provided.add(handle);
5
+ }
6
+ const providedNames = () => {
7
+ const names = [...provided].map((h) => h.capabilityName);
8
+ return names.length ? names.join(", ") : "none";
9
+ };
10
+ for (const handle of adapter.requires ?? []) {
11
+ if (!provided.has(handle)) {
12
+ throw new Error(
13
+ `Adapter "${adapter.name}" requires capability "${handle.capabilityName}". Provided capabilities: ${providedNames()}. Add a middleware that provides "${handle.capabilityName}".`
14
+ );
15
+ }
16
+ }
17
+ for (const mw of middlewares) {
18
+ for (const handle of mw.requires ?? []) {
19
+ if (!provided.has(handle)) {
20
+ throw new Error(
21
+ `Middleware "${mw.name ?? "unnamed"}" requires capability "${handle.capabilityName}". Provided capabilities: ${providedNames()}. Add a middleware that provides "${handle.capabilityName}".`
22
+ );
23
+ }
24
+ }
25
+ }
26
+ }
27
+ export {
28
+ validateCapabilities
29
+ };
30
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sources":["../../../../../src/activities/chat/middleware/validate.ts"],"sourcesContent":["import type { CapabilityHandle } from './capabilities'\nimport type { AnyChatMiddleware } from './types'\n\n/** Minimal adapter shape needed for capability validation. */\ninterface CapabilityRequiringAdapter {\n name: string\n requires?: ReadonlyArray<CapabilityHandle>\n}\n\n/**\n * Runtime validation: every required capability (from middleware `requires` and\n * the adapter's `requires`) must be provided by some middleware's `provides`.\n * `optionalRequires` is never gating. Throws a clear error otherwise.\n *\n * Presence only — ORDER is not validated here (a provider may appear after its\n * consumer in the array and still pass). Use the `createChatMiddleware()`\n * builder for compile-time order enforcement; at runtime, a consumer that reads\n * a not-yet-provided capability during `setup` fails loud via its getter.\n */\nexport function validateCapabilities(\n middlewares: ReadonlyArray<AnyChatMiddleware>,\n adapter: CapabilityRequiringAdapter,\n): void {\n const provided = new Set<CapabilityHandle>()\n for (const mw of middlewares) {\n for (const handle of mw.provides ?? []) provided.add(handle)\n }\n\n const providedNames = (): string => {\n const names = [...provided].map((h) => h.capabilityName)\n return names.length ? names.join(', ') : 'none'\n }\n\n for (const handle of adapter.requires ?? []) {\n if (!provided.has(handle)) {\n throw new Error(\n `Adapter \"${adapter.name}\" requires capability \"${handle.capabilityName}\". ` +\n `Provided capabilities: ${providedNames()}. ` +\n `Add a middleware that provides \"${handle.capabilityName}\".`,\n )\n }\n }\n\n for (const mw of middlewares) {\n for (const handle of mw.requires ?? []) {\n if (!provided.has(handle)) {\n throw new Error(\n `Middleware \"${mw.name ?? 'unnamed'}\" requires capability ` +\n `\"${handle.capabilityName}\". Provided capabilities: ${providedNames()}. ` +\n `Add a middleware that provides \"${handle.capabilityName}\".`,\n )\n }\n }\n }\n}\n"],"names":[],"mappings":"AAmBO,SAAS,qBACd,aACA,SACM;AACN,QAAM,+BAAe,IAAA;AACrB,aAAW,MAAM,aAAa;AAC5B,eAAW,UAAU,GAAG,YAAY,CAAA,EAAI,UAAS,IAAI,MAAM;AAAA,EAC7D;AAEA,QAAM,gBAAgB,MAAc;AAClC,UAAM,QAAQ,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc;AACvD,WAAO,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;AAAA,EAC3C;AAEA,aAAW,UAAU,QAAQ,YAAY,CAAA,GAAI;AAC3C,QAAI,CAAC,SAAS,IAAI,MAAM,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,YAAY,QAAQ,IAAI,0BAA0B,OAAO,cAAc,6BAC3C,cAAA,CAAe,qCACN,OAAO,cAAc;AAAA,MAAA;AAAA,IAE9D;AAAA,EACF;AAEA,aAAW,MAAM,aAAa;AAC5B,eAAW,UAAU,GAAG,YAAY,CAAA,GAAI;AACtC,UAAI,CAAC,SAAS,IAAI,MAAM,GAAG;AACzB,cAAM,IAAI;AAAA,UACR,eAAe,GAAG,QAAQ,SAAS,0BAC7B,OAAO,cAAc,6BAA6B,cAAA,CAAe,qCAClC,OAAO,cAAc;AAAA,QAAA;AAAA,MAE9D;AAAA,IACF;AAAA,EACF;AACF;"}
@@ -0,0 +1,43 @@
1
+ import { ChatMiddleware } from './middleware/types.js';
2
+ /**
3
+ * Shared type-level helpers for inferring the runtime `context` requirement
4
+ * from typed tools and middleware.
5
+ *
6
+ * These primitives are consumed by both the chat activity options
7
+ * (`./index.ts`, which merges tool + middleware requirements) and the tool
8
+ * execution layer (`./tools/tool-calls.ts`, which only sees tools). They live
9
+ * here so the two call sites share one definition instead of maintaining
10
+ * divergent copies.
11
+ */
12
+ /** True only when `T` is exactly `unknown`. */
13
+ type IsUnknown<T> = unknown extends T ? [T] extends [unknown] ? true : false : false;
14
+ /**
15
+ * Drops an `unknown` context requirement to `never` so that untyped tools and
16
+ * middleware (which default `TContext` to `unknown`) contribute no requirement
17
+ * to the merged context.
18
+ */
19
+ type KnownContext<T> = IsUnknown<T> extends true ? never : T;
20
+ /**
21
+ * Merge two inferred context requirements, treating `never` as "no
22
+ * requirement". Using this instead of a raw intersection keeps a `never`
23
+ * (untyped) contributor from collapsing the whole merge to `never`.
24
+ */
25
+ export type MergeContext<TLeft, TRight> = [TLeft] extends [never] ? TRight : [TRight] extends [never] ? TLeft : TLeft & TRight;
26
+ /** Collapse a union of context requirements into their intersection. */
27
+ export type UnionToIntersection<T> = [T] extends [never] ? never : (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
28
+ /** Strip `undefined` from a context requirement. */
29
+ export type DefinedContext<T> = Exclude<T, undefined>;
30
+ /**
31
+ * Extract the `context` requirement declared by a tool execute function's
32
+ * second argument, dropping `unknown` (untyped) contexts to `never`.
33
+ */
34
+ type ContextFromExecute<T> = T extends (...args: any) => any ? NonNullable<Parameters<T>[1]> extends {
35
+ context: infer TUserContext;
36
+ } ? KnownContext<TUserContext> : never : never;
37
+ /** Extract the context requirement declared by a single tool. */
38
+ export type ContextFromTool<T> = T extends {
39
+ execute?: infer TExecute;
40
+ } ? ContextFromExecute<TExecute> : never;
41
+ /** Extract the context requirement declared by a single middleware. */
42
+ export type ContextFromMiddleware<T> = T extends ChatMiddleware<infer TContext> ? KnownContext<TContext> : never;
43
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Stream Processing Module
3
+ *
4
+ * Unified stream processing for both server and client.
5
+ */
6
+ export { StreamProcessor, createReplayStream } from './processor.js';
7
+ export type { StreamProcessorEvents, StreamProcessorOptions } from './processor.js';
8
+ export { ImmediateStrategy, PunctuationStrategy, BatchStrategy, WordBoundaryStrategy, CompositeStrategy, } from './strategies.js';
9
+ export { PartialJSONParser, defaultJSONParser, parsePartialJSON, } from './json-parser.js';
10
+ export type { JSONParser } from './json-parser.js';
11
+ export type { ChunkStrategy, ChunkRecording, InternalToolCallState, ProcessorResult, ProcessorState, ToolCallState, ToolResultState, } from './types.js';
@@ -0,0 +1,38 @@
1
+ /**
2
+ * JSON Parser for partial/incomplete JSON strings
3
+ *
4
+ * Used during streaming to parse tool call arguments that may be incomplete.
5
+ */
6
+ /**
7
+ * JSON Parser interface - allows for custom parser implementations
8
+ */
9
+ export interface JSONParser {
10
+ /**
11
+ * Parse a JSON string (may be incomplete/partial)
12
+ * @param jsonString - The JSON string to parse
13
+ * @returns The parsed object, or undefined if parsing fails
14
+ */
15
+ parse: (jsonString: string) => any;
16
+ }
17
+ /**
18
+ * Partial JSON Parser implementation using the partial-json library
19
+ * This parser can handle incomplete JSON strings during streaming
20
+ */
21
+ export declare class PartialJSONParser implements JSONParser {
22
+ /**
23
+ * Parse a potentially incomplete JSON string
24
+ * @param jsonString - The JSON string to parse (may be incomplete)
25
+ * @returns The parsed object, or undefined if parsing fails
26
+ */
27
+ parse(jsonString: string): any;
28
+ }
29
+ /**
30
+ * Default parser instance
31
+ */
32
+ export declare const defaultJSONParser: PartialJSONParser;
33
+ /**
34
+ * Parse partial JSON string (convenience function)
35
+ * @param jsonString - The JSON string to parse (may be incomplete)
36
+ * @returns The parsed object, or undefined if parsing fails
37
+ */
38
+ export declare function parsePartialJSON(jsonString: string): any;
@@ -0,0 +1,28 @@
1
+ import { parse } from "partial-json";
2
+ class PartialJSONParser {
3
+ /**
4
+ * Parse a potentially incomplete JSON string
5
+ * @param jsonString - The JSON string to parse (may be incomplete)
6
+ * @returns The parsed object, or undefined if parsing fails
7
+ */
8
+ parse(jsonString) {
9
+ if (!jsonString || jsonString.trim() === "") {
10
+ return void 0;
11
+ }
12
+ try {
13
+ return parse(jsonString);
14
+ } catch {
15
+ return void 0;
16
+ }
17
+ }
18
+ }
19
+ const defaultJSONParser = new PartialJSONParser();
20
+ function parsePartialJSON(jsonString) {
21
+ return defaultJSONParser.parse(jsonString);
22
+ }
23
+ export {
24
+ PartialJSONParser,
25
+ defaultJSONParser,
26
+ parsePartialJSON
27
+ };
28
+ //# sourceMappingURL=json-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-parser.js","sources":["../../../../../src/activities/chat/stream/json-parser.ts"],"sourcesContent":["/**\n * JSON Parser for partial/incomplete JSON strings\n *\n * Used during streaming to parse tool call arguments that may be incomplete.\n */\n\nimport { parse as parsePartialJSONLib } from 'partial-json'\n\n/**\n * JSON Parser interface - allows for custom parser implementations\n */\nexport interface JSONParser {\n /**\n * Parse a JSON string (may be incomplete/partial)\n * @param jsonString - The JSON string to parse\n * @returns The parsed object, or undefined if parsing fails\n */\n parse: (jsonString: string) => any\n}\n\n/**\n * Partial JSON Parser implementation using the partial-json library\n * This parser can handle incomplete JSON strings during streaming\n */\nexport class PartialJSONParser implements JSONParser {\n /**\n * Parse a potentially incomplete JSON string\n * @param jsonString - The JSON string to parse (may be incomplete)\n * @returns The parsed object, or undefined if parsing fails\n */\n parse(jsonString: string): any {\n if (!jsonString || jsonString.trim() === '') {\n return undefined\n }\n\n try {\n return parsePartialJSONLib(jsonString)\n } catch {\n // If partial parsing fails, return undefined\n // This is expected during early streaming when we have very little data\n return undefined\n }\n }\n}\n\n/**\n * Default parser instance\n */\nexport const defaultJSONParser = new PartialJSONParser()\n\n/**\n * Parse partial JSON string (convenience function)\n * @param jsonString - The JSON string to parse (may be incomplete)\n * @returns The parsed object, or undefined if parsing fails\n */\nexport function parsePartialJSON(jsonString: string): any {\n return defaultJSONParser.parse(jsonString)\n}\n"],"names":["parsePartialJSONLib"],"mappings":";AAwBO,MAAM,kBAAwC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnD,MAAM,YAAyB;AAC7B,QAAI,CAAC,cAAc,WAAW,KAAA,MAAW,IAAI;AAC3C,aAAO;AAAA,IACT;AAEA,QAAI;AACF,aAAOA,MAAoB,UAAU;AAAA,IACvC,QAAQ;AAGN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,MAAM,oBAAoB,IAAI,kBAAA;AAO9B,SAAS,iBAAiB,YAAyB;AACxD,SAAO,kBAAkB,MAAM,UAAU;AAC3C;"}
@@ -0,0 +1,81 @@
1
+ import { ContentPart, UIMessage } from '../../../types.js';
2
+ import { ToolCallState, ToolResultState } from './types.js';
3
+ /**
4
+ * Update or add a text part to a message.
5
+ *
6
+ * If the last part is a text part, update it (continuing the same text segment).
7
+ * Otherwise, create a new text part (starting a new text segment after tool calls).
8
+ */
9
+ export declare function updateTextPart(messages: Array<UIMessage>, messageId: string, content: string): Array<UIMessage>;
10
+ /**
11
+ * Update or add a tool call part to a message.
12
+ */
13
+ export declare function updateToolCallPart(messages: Array<UIMessage>, messageId: string, toolCall: {
14
+ id: string;
15
+ name: string;
16
+ arguments: string;
17
+ state: ToolCallState;
18
+ metadata?: Record<string, unknown>;
19
+ }): Array<UIMessage>;
20
+ /**
21
+ * Update or add a tool result part to a message.
22
+ */
23
+ export declare function updateToolResultPart(messages: Array<UIMessage>, messageId: string, toolCallId: string, content: string | Array<ContentPart>, state: ToolResultState, error?: string): Array<UIMessage>;
24
+ /**
25
+ * Update a tool call part with approval request metadata.
26
+ */
27
+ export declare function updateToolCallApproval(messages: Array<UIMessage>, messageId: string, toolCallId: string, approvalId: string): Array<UIMessage>;
28
+ /**
29
+ * Update a tool call part's state (e.g., to "input-complete").
30
+ */
31
+ export declare function updateToolCallState(messages: Array<UIMessage>, messageId: string, toolCallId: string, state: ToolCallState): Array<UIMessage>;
32
+ /**
33
+ * Update a tool call part with output.
34
+ * Searches all messages to find the tool call by ID.
35
+ */
36
+ export declare function updateToolCallWithOutput(messages: Array<UIMessage>, toolCallId: string, output: any, state?: ToolCallState, errorText?: string): Array<UIMessage>;
37
+ /**
38
+ * Update a tool call part with approval response.
39
+ * Searches all messages to find the tool call by approval ID.
40
+ */
41
+ export declare function updateToolCallApprovalResponse(messages: Array<UIMessage>, approvalId: string, approved: boolean): Array<UIMessage>;
42
+ /**
43
+ * Append a delta to the structured-output part on `messageId`, or create one
44
+ * if absent. Progressive parse of the accumulated buffer fills `partial`.
45
+ *
46
+ * Callers must only invoke this while the part is still in flight — the
47
+ * helper unconditionally writes `status: 'streaming'`, so feeding it a delta
48
+ * after a `complete`/`error` terminal would regress the part. In practice the
49
+ * processor gates calls via `structuredMessageIds`, which is dropped on
50
+ * terminal events.
51
+ *
52
+ * If the progressive parse returns null/undefined (the buffer is not yet a
53
+ * parseable JSON prefix), the previously-good `partial` is preserved so the
54
+ * UI doesn't flicker back to empty for a single render.
55
+ */
56
+ export declare function appendStructuredOutputDelta(messages: Array<UIMessage>, messageId: string, delta: string): Array<UIMessage>;
57
+ /**
58
+ * Snap the structured-output part on `messageId` to `complete` with the
59
+ * validated `data`. Picks the freshest available `raw` so the wire
60
+ * round-trip stays internally consistent:
61
+ *
62
+ * 1. Caller-supplied `raw` (the original streamed bytes from the model).
63
+ * 2. The existing part's `raw` (deltas accumulated before this terminal).
64
+ * 3. `JSON.stringify(data)` as a defensive fallback for terminal-only
65
+ * completes that never shipped raw — keeps the part self-consistent
66
+ * so downstream consumers never see a complete part with empty raw.
67
+ */
68
+ export declare function completeStructuredOutputPart(messages: Array<UIMessage>, messageId: string, data: unknown, raw: string, reasoning?: string): Array<UIMessage>;
69
+ /**
70
+ * Mark the structured-output part on `messageId` as errored. If no part
71
+ * exists yet — RUN_ERROR fired after `structured-output.start` but before
72
+ * any delta — create an empty errored placeholder so consumers have
73
+ * something renderable. Existing complete parts are left alone (an error
74
+ * after a successful complete should not retroactively un-complete it).
75
+ */
76
+ export declare function errorStructuredOutputPart(messages: Array<UIMessage>, messageId: string, errorMessage: string): Array<UIMessage>;
77
+ /**
78
+ * Update or add a thinking part to a message, keyed by stepId.
79
+ * Each distinct stepId produces its own ThinkingPart.
80
+ */
81
+ export declare function updateThinkingPart(messages: Array<UIMessage>, messageId: string, stepId: string, content: string, signature?: string): Array<UIMessage>;
@@ -0,0 +1,253 @@
1
+ import { parsePartialJSON } from "./json-parser.js";
2
+ function updateTextPart(messages, messageId, content) {
3
+ return messages.map((msg) => {
4
+ if (msg.id !== messageId) {
5
+ return msg;
6
+ }
7
+ const parts = [...msg.parts];
8
+ const lastPart = parts.length > 0 ? parts[parts.length - 1] : null;
9
+ if (lastPart && lastPart.type === "text") {
10
+ parts[parts.length - 1] = { type: "text", content };
11
+ } else {
12
+ parts.push({ type: "text", content });
13
+ }
14
+ return { ...msg, parts };
15
+ });
16
+ }
17
+ function updateToolCallPart(messages, messageId, toolCall) {
18
+ return messages.map((msg) => {
19
+ if (msg.id !== messageId) {
20
+ return msg;
21
+ }
22
+ const parts = [...msg.parts];
23
+ const existing = parts.find(
24
+ (p) => p.type === "tool-call" && p.id === toolCall.id
25
+ );
26
+ const metadata = toolCall.metadata ?? existing?.metadata;
27
+ const toolCallPart = {
28
+ type: "tool-call",
29
+ id: toolCall.id,
30
+ name: toolCall.name,
31
+ arguments: toolCall.arguments,
32
+ state: toolCall.state,
33
+ // Carry forward approval and output from the existing part
34
+ ...existing?.approval && { approval: { ...existing.approval } },
35
+ ...existing?.output !== void 0 && { output: existing.output },
36
+ ...metadata !== void 0 && { metadata }
37
+ };
38
+ if (existing) {
39
+ parts[parts.indexOf(existing)] = toolCallPart;
40
+ } else {
41
+ parts.push(toolCallPart);
42
+ }
43
+ return { ...msg, parts };
44
+ });
45
+ }
46
+ function updateToolResultPart(messages, messageId, toolCallId, content, state, error) {
47
+ return messages.map((msg) => {
48
+ if (msg.id !== messageId) {
49
+ return msg;
50
+ }
51
+ const parts = [...msg.parts];
52
+ const resultPartIndex = parts.findIndex(
53
+ (p) => p.type === "tool-result" && p.toolCallId === toolCallId
54
+ );
55
+ const toolResultPart = {
56
+ type: "tool-result",
57
+ toolCallId,
58
+ content,
59
+ state,
60
+ ...error && { error }
61
+ };
62
+ if (resultPartIndex >= 0) {
63
+ parts[resultPartIndex] = toolResultPart;
64
+ } else {
65
+ parts.push(toolResultPart);
66
+ }
67
+ return { ...msg, parts };
68
+ });
69
+ }
70
+ function updateToolCallApproval(messages, messageId, toolCallId, approvalId) {
71
+ return messages.map((msg) => {
72
+ if (msg.id !== messageId) {
73
+ return msg;
74
+ }
75
+ const parts = [...msg.parts];
76
+ const toolCallPart = parts.find(
77
+ (p) => p.type === "tool-call" && p.id === toolCallId
78
+ );
79
+ if (toolCallPart) {
80
+ const index = parts.indexOf(toolCallPart);
81
+ parts[index] = {
82
+ ...toolCallPart,
83
+ state: "approval-requested",
84
+ approval: {
85
+ id: approvalId,
86
+ needsApproval: true
87
+ }
88
+ };
89
+ }
90
+ return { ...msg, parts };
91
+ });
92
+ }
93
+ function updateToolCallWithOutput(messages, toolCallId, output, state, errorText) {
94
+ return messages.map((msg) => {
95
+ const parts = [...msg.parts];
96
+ const toolCallPart = parts.find(
97
+ (p) => p.type === "tool-call" && p.id === toolCallId
98
+ );
99
+ if (toolCallPart) {
100
+ const index = parts.indexOf(toolCallPart);
101
+ parts[index] = {
102
+ ...toolCallPart,
103
+ output: errorText ? { error: errorText } : output,
104
+ state: state ?? (errorText ? "error" : "complete")
105
+ };
106
+ }
107
+ return { ...msg, parts };
108
+ });
109
+ }
110
+ function updateToolCallApprovalResponse(messages, approvalId, approved) {
111
+ return messages.map((msg) => {
112
+ const parts = [...msg.parts];
113
+ const toolCallPart = parts.find(
114
+ (p) => p.type === "tool-call" && p.approval?.id === approvalId
115
+ );
116
+ if (toolCallPart && toolCallPart.approval) {
117
+ const index = parts.indexOf(toolCallPart);
118
+ parts[index] = {
119
+ ...toolCallPart,
120
+ approval: { ...toolCallPart.approval, approved },
121
+ state: "approval-responded"
122
+ };
123
+ }
124
+ return { ...msg, parts };
125
+ });
126
+ }
127
+ function appendStructuredOutputDelta(messages, messageId, delta) {
128
+ return messages.map((msg) => {
129
+ if (msg.id !== messageId) {
130
+ return msg;
131
+ }
132
+ const parts = [...msg.parts];
133
+ const existingIndex = parts.findIndex(
134
+ (p) => p.type === "structured-output"
135
+ );
136
+ const existing = existingIndex >= 0 ? parts[existingIndex] : null;
137
+ const nextRaw = (existing?.raw ?? "") + delta;
138
+ const progressive = parsePartialJSON(nextRaw);
139
+ const nextPartial = progressive !== void 0 && progressive !== null ? progressive : existing?.partial;
140
+ const nextPart = {
141
+ type: "structured-output",
142
+ status: "streaming",
143
+ raw: nextRaw,
144
+ ...nextPartial !== void 0 ? { partial: nextPartial } : {},
145
+ ...existing?.reasoning !== void 0 ? { reasoning: existing.reasoning } : {}
146
+ };
147
+ if (existingIndex >= 0) {
148
+ parts[existingIndex] = nextPart;
149
+ } else {
150
+ parts.push(nextPart);
151
+ }
152
+ return { ...msg, parts };
153
+ });
154
+ }
155
+ function completeStructuredOutputPart(messages, messageId, data, raw, reasoning) {
156
+ return messages.map((msg) => {
157
+ if (msg.id !== messageId) {
158
+ return msg;
159
+ }
160
+ const parts = [...msg.parts];
161
+ const existingIndex = parts.findIndex(
162
+ (p) => p.type === "structured-output"
163
+ );
164
+ const existingRaw = existingIndex >= 0 ? parts[existingIndex].raw : "";
165
+ let resolvedRaw = raw || existingRaw;
166
+ if (resolvedRaw === "" && data !== void 0) {
167
+ try {
168
+ resolvedRaw = JSON.stringify(data);
169
+ } catch {
170
+ }
171
+ }
172
+ const nextPart = {
173
+ type: "structured-output",
174
+ status: "complete",
175
+ data,
176
+ partial: data,
177
+ raw: resolvedRaw,
178
+ ...reasoning !== void 0 ? { reasoning } : {}
179
+ };
180
+ if (existingIndex >= 0) {
181
+ parts[existingIndex] = nextPart;
182
+ } else {
183
+ parts.push(nextPart);
184
+ }
185
+ return { ...msg, parts };
186
+ });
187
+ }
188
+ function errorStructuredOutputPart(messages, messageId, errorMessage) {
189
+ return messages.map((msg) => {
190
+ if (msg.id !== messageId) {
191
+ return msg;
192
+ }
193
+ const parts = [...msg.parts];
194
+ const existingIndex = parts.findIndex(
195
+ (p) => p.type === "structured-output"
196
+ );
197
+ if (existingIndex < 0) {
198
+ parts.push({
199
+ type: "structured-output",
200
+ status: "error",
201
+ raw: "",
202
+ errorMessage
203
+ });
204
+ return { ...msg, parts };
205
+ }
206
+ const existing = parts[existingIndex];
207
+ if (existing.status === "complete") {
208
+ return msg;
209
+ }
210
+ parts[existingIndex] = {
211
+ ...existing,
212
+ status: "error",
213
+ errorMessage
214
+ };
215
+ return { ...msg, parts };
216
+ });
217
+ }
218
+ function updateThinkingPart(messages, messageId, stepId, content, signature) {
219
+ return messages.map((msg) => {
220
+ if (msg.id !== messageId) {
221
+ return msg;
222
+ }
223
+ const parts = [...msg.parts];
224
+ const thinkingPartIndex = parts.findIndex(
225
+ (p) => p.type === "thinking" && p.stepId === stepId
226
+ );
227
+ const thinkingPart = {
228
+ type: "thinking",
229
+ content,
230
+ stepId,
231
+ ...signature && { signature }
232
+ };
233
+ if (thinkingPartIndex >= 0) {
234
+ parts[thinkingPartIndex] = thinkingPart;
235
+ } else {
236
+ parts.push(thinkingPart);
237
+ }
238
+ return { ...msg, parts };
239
+ });
240
+ }
241
+ export {
242
+ appendStructuredOutputDelta,
243
+ completeStructuredOutputPart,
244
+ errorStructuredOutputPart,
245
+ updateTextPart,
246
+ updateThinkingPart,
247
+ updateToolCallApproval,
248
+ updateToolCallApprovalResponse,
249
+ updateToolCallPart,
250
+ updateToolCallWithOutput,
251
+ updateToolResultPart
252
+ };
253
+ //# sourceMappingURL=message-updaters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-updaters.js","sources":["../../../../../src/activities/chat/stream/message-updaters.ts"],"sourcesContent":["/**\n * Message Updaters (Internal)\n *\n * Internal helper functions for updating UIMessage parts.\n * These are used by StreamProcessor to manage the message array.\n */\n\nimport { parsePartialJSON } from './json-parser'\nimport type {\n ContentPart,\n StructuredOutputPart,\n ThinkingPart,\n ToolCallPart,\n ToolResultPart,\n UIMessage,\n} from '../../../types'\nimport type { ToolCallState, ToolResultState } from './types'\n\n/**\n * Update or add a text part to a message.\n *\n * If the last part is a text part, update it (continuing the same text segment).\n * Otherwise, create a new text part (starting a new text segment after tool calls).\n */\nexport function updateTextPart(\n messages: Array<UIMessage>,\n messageId: string,\n content: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const lastPart = parts.length > 0 ? parts[parts.length - 1] : null\n\n if (lastPart && lastPart.type === 'text') {\n // Update the last text part (continuing same text segment)\n parts[parts.length - 1] = { type: 'text', content }\n } else {\n // Create new text part (starting new text segment after tool calls/results)\n parts.push({ type: 'text', content })\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update or add a tool call part to a message.\n */\nexport function updateToolCallPart(\n messages: Array<UIMessage>,\n messageId: string,\n toolCall: {\n id: string\n name: string\n arguments: string\n state: ToolCallState\n metadata?: Record<string, unknown>\n },\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const existing = parts.find(\n (p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCall.id,\n )\n\n // Carry forward metadata from either the new toolCall or the existing\n // part. Once the adapter has emitted metadata for a tool call (e.g.\n // Gemini's thoughtSignature on TOOL_CALL_START) we must not lose it on\n // subsequent updates that don't re-supply it.\n const metadata = toolCall.metadata ?? existing?.metadata\n\n const toolCallPart: ToolCallPart = {\n type: 'tool-call',\n id: toolCall.id,\n name: toolCall.name,\n arguments: toolCall.arguments,\n state: toolCall.state,\n // Carry forward approval and output from the existing part\n ...(existing?.approval && { approval: { ...existing.approval } }),\n ...(existing?.output !== undefined && { output: existing.output }),\n ...(metadata !== undefined && { metadata }),\n }\n\n if (existing) {\n // Update existing tool call\n parts[parts.indexOf(existing)] = toolCallPart\n } else {\n // Add new tool call at the end (preserve natural streaming order)\n parts.push(toolCallPart)\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update or add a tool result part to a message.\n */\nexport function updateToolResultPart(\n messages: Array<UIMessage>,\n messageId: string,\n toolCallId: string,\n content: string | Array<ContentPart>,\n state: ToolResultState,\n error?: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const resultPartIndex = parts.findIndex(\n (p): p is ToolResultPart =>\n p.type === 'tool-result' && p.toolCallId === toolCallId,\n )\n\n const toolResultPart: ToolResultPart = {\n type: 'tool-result',\n toolCallId,\n content,\n state,\n ...(error && { error }),\n }\n\n if (resultPartIndex >= 0) {\n parts[resultPartIndex] = toolResultPart\n } else {\n parts.push(toolResultPart)\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update a tool call part with approval request metadata.\n */\nexport function updateToolCallApproval(\n messages: Array<UIMessage>,\n messageId: string,\n toolCallId: string,\n approvalId: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const toolCallPart = parts.find(\n (p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCallId,\n )\n\n if (toolCallPart) {\n const index = parts.indexOf(toolCallPart)\n parts[index] = {\n ...toolCallPart,\n state: 'approval-requested',\n approval: {\n id: approvalId,\n needsApproval: true,\n },\n }\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update a tool call part's state (e.g., to \"input-complete\").\n */\nexport function updateToolCallState(\n messages: Array<UIMessage>,\n messageId: string,\n toolCallId: string,\n state: ToolCallState,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const toolCallPart = parts.find(\n (p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCallId,\n )\n\n if (toolCallPart) {\n const index = parts.indexOf(toolCallPart)\n parts[index] = { ...toolCallPart, state }\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update a tool call part with output.\n * Searches all messages to find the tool call by ID.\n */\nexport function updateToolCallWithOutput(\n messages: Array<UIMessage>,\n toolCallId: string,\n output: any,\n state?: ToolCallState,\n errorText?: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n const parts = [...msg.parts]\n const toolCallPart = parts.find(\n (p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCallId,\n )\n\n if (toolCallPart) {\n const index = parts.indexOf(toolCallPart)\n parts[index] = {\n ...toolCallPart,\n output: errorText ? { error: errorText } : output,\n state: state ?? (errorText ? 'error' : 'complete'),\n }\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Update a tool call part with approval response.\n * Searches all messages to find the tool call by approval ID.\n */\nexport function updateToolCallApprovalResponse(\n messages: Array<UIMessage>,\n approvalId: string,\n approved: boolean,\n): Array<UIMessage> {\n return messages.map((msg) => {\n const parts = [...msg.parts]\n const toolCallPart = parts.find(\n (p): p is ToolCallPart =>\n p.type === 'tool-call' && p.approval?.id === approvalId,\n )\n\n if (toolCallPart && toolCallPart.approval) {\n const index = parts.indexOf(toolCallPart)\n parts[index] = {\n ...toolCallPart,\n approval: { ...toolCallPart.approval, approved },\n state: 'approval-responded',\n }\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Append a delta to the structured-output part on `messageId`, or create one\n * if absent. Progressive parse of the accumulated buffer fills `partial`.\n *\n * Callers must only invoke this while the part is still in flight — the\n * helper unconditionally writes `status: 'streaming'`, so feeding it a delta\n * after a `complete`/`error` terminal would regress the part. In practice the\n * processor gates calls via `structuredMessageIds`, which is dropped on\n * terminal events.\n *\n * If the progressive parse returns null/undefined (the buffer is not yet a\n * parseable JSON prefix), the previously-good `partial` is preserved so the\n * UI doesn't flicker back to empty for a single render.\n */\nexport function appendStructuredOutputDelta(\n messages: Array<UIMessage>,\n messageId: string,\n delta: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const existingIndex = parts.findIndex(\n (p): p is StructuredOutputPart => p.type === 'structured-output',\n )\n const existing =\n existingIndex >= 0 ? (parts[existingIndex] as StructuredOutputPart) : null\n\n const nextRaw = (existing?.raw ?? '') + delta\n const progressive = parsePartialJSON(nextRaw)\n const nextPartial =\n progressive !== undefined && progressive !== null\n ? progressive\n : existing?.partial\n\n const nextPart: StructuredOutputPart = {\n type: 'structured-output',\n status: 'streaming',\n raw: nextRaw,\n ...(nextPartial !== undefined ? { partial: nextPartial } : {}),\n ...(existing?.reasoning !== undefined\n ? { reasoning: existing.reasoning }\n : {}),\n }\n\n if (existingIndex >= 0) {\n parts[existingIndex] = nextPart\n } else {\n parts.push(nextPart)\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Snap the structured-output part on `messageId` to `complete` with the\n * validated `data`. Picks the freshest available `raw` so the wire\n * round-trip stays internally consistent:\n *\n * 1. Caller-supplied `raw` (the original streamed bytes from the model).\n * 2. The existing part's `raw` (deltas accumulated before this terminal).\n * 3. `JSON.stringify(data)` as a defensive fallback for terminal-only\n * completes that never shipped raw — keeps the part self-consistent\n * so downstream consumers never see a complete part with empty raw.\n */\nexport function completeStructuredOutputPart(\n messages: Array<UIMessage>,\n messageId: string,\n data: unknown,\n raw: string,\n reasoning?: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const existingIndex = parts.findIndex(\n (p): p is StructuredOutputPart => p.type === 'structured-output',\n )\n\n const existingRaw =\n existingIndex >= 0\n ? (parts[existingIndex] as StructuredOutputPart).raw\n : ''\n let resolvedRaw = raw || existingRaw\n if (resolvedRaw === '' && data !== undefined) {\n try {\n resolvedRaw = JSON.stringify(data)\n } catch {\n // Unserializable (circular, BigInt, throwing toJSON). Leave raw\n // empty. Both downstream paths handle this: `ag-ui-wire.ts`\n // `collectText` skips complete parts with empty raw entirely, and\n // `uiMessageToModelMessages` falls back to a defensive\n // `safeJsonStringify(data)` which itself returns `''` for the same\n // unserializable inputs — so the turn is silently dropped from the\n // next request rather than shipping garbage or crashing the stream.\n }\n }\n\n const nextPart: StructuredOutputPart = {\n type: 'structured-output',\n status: 'complete',\n data,\n partial: data,\n raw: resolvedRaw,\n ...(reasoning !== undefined ? { reasoning } : {}),\n }\n\n if (existingIndex >= 0) {\n parts[existingIndex] = nextPart\n } else {\n parts.push(nextPart)\n }\n\n return { ...msg, parts }\n })\n}\n\n/**\n * Mark the structured-output part on `messageId` as errored. If no part\n * exists yet — RUN_ERROR fired after `structured-output.start` but before\n * any delta — create an empty errored placeholder so consumers have\n * something renderable. Existing complete parts are left alone (an error\n * after a successful complete should not retroactively un-complete it).\n */\nexport function errorStructuredOutputPart(\n messages: Array<UIMessage>,\n messageId: string,\n errorMessage: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const existingIndex = parts.findIndex(\n (p): p is StructuredOutputPart => p.type === 'structured-output',\n )\n\n if (existingIndex < 0) {\n parts.push({\n type: 'structured-output',\n status: 'error',\n raw: '',\n errorMessage,\n })\n return { ...msg, parts }\n }\n\n const existing = parts[existingIndex] as StructuredOutputPart\n if (existing.status === 'complete') {\n return msg\n }\n parts[existingIndex] = {\n ...existing,\n status: 'error',\n errorMessage,\n }\n return { ...msg, parts }\n })\n}\n\n/**\n * Update or add a thinking part to a message, keyed by stepId.\n * Each distinct stepId produces its own ThinkingPart.\n */\nexport function updateThinkingPart(\n messages: Array<UIMessage>,\n messageId: string,\n stepId: string,\n content: string,\n signature?: string,\n): Array<UIMessage> {\n return messages.map((msg) => {\n if (msg.id !== messageId) {\n return msg\n }\n\n const parts = [...msg.parts]\n const thinkingPartIndex = parts.findIndex(\n (p) => p.type === 'thinking' && p.stepId === stepId,\n )\n\n const thinkingPart: ThinkingPart = {\n type: 'thinking',\n content,\n stepId,\n ...(signature && { signature }),\n }\n\n if (thinkingPartIndex >= 0) {\n // Update existing thinking part for this step\n parts[thinkingPartIndex] = thinkingPart\n } else {\n // Add new thinking part at the end (preserve natural streaming order)\n parts.push(thinkingPart)\n }\n\n return { ...msg, parts }\n })\n}\n"],"names":[],"mappings":"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"}