@tanstack/ai 0.41.0 → 0.43.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 (272) hide show
  1. package/README.md +15 -1
  2. package/dist/esm/activities/chat/adapter.js +23 -16
  3. package/dist/esm/activities/chat/adapter.js.map +1 -1
  4. package/dist/esm/activities/chat/agent-loop-strategies.d.ts +10 -4
  5. package/dist/esm/activities/chat/agent-loop-strategies.js +75 -17
  6. package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -1
  7. package/dist/esm/activities/chat/cancel.d.ts +40 -0
  8. package/dist/esm/activities/chat/cancel.js +54 -0
  9. package/dist/esm/activities/chat/cancel.js.map +1 -0
  10. package/dist/esm/activities/chat/index.d.ts +28 -16
  11. package/dist/esm/activities/chat/index.js +2100 -1744
  12. package/dist/esm/activities/chat/index.js.map +1 -1
  13. package/dist/esm/activities/chat/mcp/manager.d.ts +2 -2
  14. package/dist/esm/activities/chat/mcp/manager.js +90 -77
  15. package/dist/esm/activities/chat/mcp/manager.js.map +1 -1
  16. package/dist/esm/activities/chat/mcp/types.d.ts +2 -2
  17. package/dist/esm/activities/chat/messages.js +397 -346
  18. package/dist/esm/activities/chat/messages.js.map +1 -1
  19. package/dist/esm/activities/chat/middleware/builder.js +17 -15
  20. package/dist/esm/activities/chat/middleware/builder.js.map +1 -1
  21. package/dist/esm/activities/chat/middleware/capabilities.js +78 -43
  22. package/dist/esm/activities/chat/middleware/capabilities.js.map +1 -1
  23. package/dist/esm/activities/chat/middleware/compose.d.ts +94 -1
  24. package/dist/esm/activities/chat/middleware/compose.js +623 -531
  25. package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
  26. package/dist/esm/activities/chat/middleware/define.js +12 -5
  27. package/dist/esm/activities/chat/middleware/define.js.map +1 -1
  28. package/dist/esm/activities/chat/middleware/index.d.ts +5 -1
  29. package/dist/esm/activities/chat/middleware/locks.d.ts +50 -0
  30. package/dist/esm/activities/chat/middleware/locks.js +71 -0
  31. package/dist/esm/activities/chat/middleware/locks.js.map +1 -0
  32. package/dist/esm/activities/chat/middleware/pending-turn.d.ts +15 -0
  33. package/dist/esm/activities/chat/middleware/pending-turn.js +35 -0
  34. package/dist/esm/activities/chat/middleware/pending-turn.js.map +1 -0
  35. package/dist/esm/activities/chat/middleware/run-disconnect.d.ts +23 -0
  36. package/dist/esm/activities/chat/middleware/run-disconnect.js +42 -0
  37. package/dist/esm/activities/chat/middleware/run-disconnect.js.map +1 -0
  38. package/dist/esm/activities/chat/middleware/run-store.d.ts +283 -0
  39. package/dist/esm/activities/chat/middleware/run-store.js +176 -0
  40. package/dist/esm/activities/chat/middleware/run-store.js.map +1 -0
  41. package/dist/esm/activities/chat/middleware/sandbox-runtime.js +14 -8
  42. package/dist/esm/activities/chat/middleware/sandbox-runtime.js.map +1 -1
  43. package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +79 -70
  44. package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -1
  45. package/dist/esm/activities/chat/middleware/types.d.ts +59 -2
  46. package/dist/esm/activities/chat/middleware/validate.js +23 -28
  47. package/dist/esm/activities/chat/middleware/validate.js.map +1 -1
  48. package/dist/esm/activities/chat/stream/json-parser.js +39 -25
  49. package/dist/esm/activities/chat/stream/json-parser.js.map +1 -1
  50. package/dist/esm/activities/chat/stream/message-updaters.js +275 -234
  51. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
  52. package/dist/esm/activities/chat/stream/processor.d.ts +24 -4
  53. package/dist/esm/activities/chat/stream/processor.js +1341 -1542
  54. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  55. package/dist/esm/activities/chat/stream/strategies.js +69 -53
  56. package/dist/esm/activities/chat/stream/strategies.js.map +1 -1
  57. package/dist/esm/activities/chat/tools/approval-schema.d.ts +19 -0
  58. package/dist/esm/activities/chat/tools/approval-schema.js +117 -0
  59. package/dist/esm/activities/chat/tools/approval-schema.js.map +1 -0
  60. package/dist/esm/activities/chat/tools/lazy-tool-manager.js +164 -191
  61. package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -1
  62. package/dist/esm/activities/chat/tools/lazy-tools.js +24 -12
  63. package/dist/esm/activities/chat/tools/lazy-tools.js.map +1 -1
  64. package/dist/esm/activities/chat/tools/schema-converter.js +293 -146
  65. package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
  66. package/dist/esm/activities/chat/tools/tool-calls.d.ts +18 -2
  67. package/dist/esm/activities/chat/tools/tool-calls.js +522 -531
  68. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  69. package/dist/esm/activities/chat/tools/tool-definition.d.ts +75 -16
  70. package/dist/esm/activities/chat/tools/tool-definition.js +95 -23
  71. package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
  72. package/dist/esm/activities/error-payload.js +85 -47
  73. package/dist/esm/activities/error-payload.js.map +1 -1
  74. package/dist/esm/activities/generateAudio/adapter.js +22 -15
  75. package/dist/esm/activities/generateAudio/adapter.js.map +1 -1
  76. package/dist/esm/activities/generateAudio/index.d.ts +4 -0
  77. package/dist/esm/activities/generateAudio/index.js +141 -105
  78. package/dist/esm/activities/generateAudio/index.js.map +1 -1
  79. package/dist/esm/activities/generateImage/adapter.js +22 -15
  80. package/dist/esm/activities/generateImage/adapter.js.map +1 -1
  81. package/dist/esm/activities/generateImage/index.d.ts +4 -0
  82. package/dist/esm/activities/generateImage/index.js +155 -111
  83. package/dist/esm/activities/generateImage/index.js.map +1 -1
  84. package/dist/esm/activities/generateSpeech/adapter.js +22 -15
  85. package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
  86. package/dist/esm/activities/generateSpeech/index.d.ts +4 -0
  87. package/dist/esm/activities/generateSpeech/index.js +159 -110
  88. package/dist/esm/activities/generateSpeech/index.js.map +1 -1
  89. package/dist/esm/activities/generateTranscription/adapter.js +22 -15
  90. package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
  91. package/dist/esm/activities/generateTranscription/index.d.ts +4 -0
  92. package/dist/esm/activities/generateTranscription/index.js +159 -100
  93. package/dist/esm/activities/generateTranscription/index.js.map +1 -1
  94. package/dist/esm/activities/generateVideo/adapter.js +36 -29
  95. package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
  96. package/dist/esm/activities/generateVideo/index.d.ts +143 -19
  97. package/dist/esm/activities/generateVideo/index.js +456 -279
  98. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  99. package/dist/esm/activities/generateVideo/snap.js +60 -48
  100. package/dist/esm/activities/generateVideo/snap.js.map +1 -1
  101. package/dist/esm/activities/index.js +8 -34
  102. package/dist/esm/activities/middleware/index.d.ts +1 -1
  103. package/dist/esm/activities/middleware/run.d.ts +10 -0
  104. package/dist/esm/activities/middleware/run.js +53 -29
  105. package/dist/esm/activities/middleware/run.js.map +1 -1
  106. package/dist/esm/activities/middleware/types.d.ts +44 -6
  107. package/dist/esm/activities/stream-generation-result.d.ts +4 -1
  108. package/dist/esm/activities/stream-generation-result.js +79 -44
  109. package/dist/esm/activities/stream-generation-result.js.map +1 -1
  110. package/dist/esm/activities/summarize/adapter.js +22 -15
  111. package/dist/esm/activities/summarize/adapter.js.map +1 -1
  112. package/dist/esm/activities/summarize/chat-stream-summarize.js +252 -202
  113. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
  114. package/dist/esm/activities/summarize/index.d.ts +27 -0
  115. package/dist/esm/activities/summarize/index.js +268 -102
  116. package/dist/esm/activities/summarize/index.js.map +1 -1
  117. package/dist/esm/adapter-internals.d.ts +2 -1
  118. package/dist/esm/adapter-internals.js +4 -11
  119. package/dist/esm/client.d.ts +25 -3
  120. package/dist/esm/client.js +131 -64
  121. package/dist/esm/client.js.map +1 -1
  122. package/dist/esm/custom-events.d.ts +76 -0
  123. package/dist/esm/custom-events.js +37 -0
  124. package/dist/esm/custom-events.js.map +1 -0
  125. package/dist/esm/delivery-detach.d.ts +50 -0
  126. package/dist/esm/delivery-detach.js +71 -0
  127. package/dist/esm/delivery-detach.js.map +1 -0
  128. package/dist/esm/delivery-disconnect.d.ts +62 -0
  129. package/dist/esm/delivery-disconnect.js +81 -0
  130. package/dist/esm/delivery-disconnect.js.map +1 -0
  131. package/dist/esm/extend-adapter.js +19 -17
  132. package/dist/esm/extend-adapter.js.map +1 -1
  133. package/dist/esm/index.d.ts +23 -5
  134. package/dist/esm/index.js +30 -97
  135. package/dist/esm/interrupt-resume.d.ts +71 -0
  136. package/dist/esm/interrupt-resume.js +438 -0
  137. package/dist/esm/interrupt-resume.js.map +1 -0
  138. package/dist/esm/interrupt-serialization.d.ts +12 -0
  139. package/dist/esm/interrupt-serialization.js +178 -0
  140. package/dist/esm/interrupt-serialization.js.map +1 -0
  141. package/dist/esm/interrupts.d.ts +84 -0
  142. package/dist/esm/interrupts.js +31 -0
  143. package/dist/esm/interrupts.js.map +1 -0
  144. package/dist/esm/locks.d.ts +10 -0
  145. package/dist/esm/locks.js +2 -0
  146. package/dist/esm/logger/console-logger.js +101 -78
  147. package/dist/esm/logger/console-logger.js.map +1 -1
  148. package/dist/esm/logger/internal-logger.js +104 -89
  149. package/dist/esm/logger/internal-logger.js.map +1 -1
  150. package/dist/esm/logger/resolve.js +54 -49
  151. package/dist/esm/logger/resolve.js.map +1 -1
  152. package/dist/esm/logger/types.d.ts +1 -1
  153. package/dist/esm/middlewares/content-guard.js +142 -148
  154. package/dist/esm/middlewares/content-guard.js.map +1 -1
  155. package/dist/esm/middlewares/index.js +2 -6
  156. package/dist/esm/middlewares/otel.js +598 -732
  157. package/dist/esm/middlewares/otel.js.map +1 -1
  158. package/dist/esm/middlewares/usage-attributes.js +47 -40
  159. package/dist/esm/middlewares/usage-attributes.js.map +1 -1
  160. package/dist/esm/realtime/event-emitter.js +24 -25
  161. package/dist/esm/realtime/event-emitter.js.map +1 -1
  162. package/dist/esm/realtime/index.d.ts +5 -9
  163. package/dist/esm/realtime/index.js +29 -6
  164. package/dist/esm/realtime/index.js.map +1 -1
  165. package/dist/esm/scope.d.ts +47 -0
  166. package/dist/esm/stream-durability.d.ts +171 -0
  167. package/dist/esm/stream-durability.js +295 -0
  168. package/dist/esm/stream-durability.js.map +1 -0
  169. package/dist/esm/stream-to-response.d.ts +178 -13
  170. package/dist/esm/stream-to-response.js +663 -115
  171. package/dist/esm/stream-to-response.js.map +1 -1
  172. package/dist/esm/strip-to-spec-middleware.js +30 -16
  173. package/dist/esm/strip-to-spec-middleware.js.map +1 -1
  174. package/dist/esm/system-prompts.js +27 -21
  175. package/dist/esm/system-prompts.js.map +1 -1
  176. package/dist/esm/tool-registry.js +72 -45
  177. package/dist/esm/tool-registry.js.map +1 -1
  178. package/dist/esm/tools/provider-tool.js +14 -5
  179. package/dist/esm/tools/provider-tool.js.map +1 -1
  180. package/dist/esm/types.d.ts +332 -21
  181. package/dist/esm/types.js +2 -0
  182. package/dist/esm/utilities/ag-ui-wire.js +79 -93
  183. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  184. package/dist/esm/utilities/chat-params.d.ts +26 -4
  185. package/dist/esm/utilities/chat-params.js +218 -92
  186. package/dist/esm/utilities/chat-params.js.map +1 -1
  187. package/dist/esm/utilities/errors.js +28 -18
  188. package/dist/esm/utilities/errors.js.map +1 -1
  189. package/dist/esm/utilities/media-prompt.js +46 -41
  190. package/dist/esm/utilities/media-prompt.js.map +1 -1
  191. package/dist/esm/utilities/numbers.js +13 -10
  192. package/dist/esm/utilities/numbers.js.map +1 -1
  193. package/dist/esm/utilities/provider-executed.js +20 -11
  194. package/dist/esm/utilities/provider-executed.js.map +1 -1
  195. package/dist/esm/utilities/sampling-keys.js +31 -19
  196. package/dist/esm/utilities/sampling-keys.js.map +1 -1
  197. package/dist/esm/utilities/tool-result.js +42 -30
  198. package/dist/esm/utilities/tool-result.js.map +1 -1
  199. package/dist/esm/utilities/usage.js +27 -9
  200. package/dist/esm/utilities/usage.js.map +1 -1
  201. package/dist/esm/utils.js +26 -18
  202. package/dist/esm/utils.js.map +1 -1
  203. package/package.json +10 -6
  204. package/skills/ai-core/SKILL.md +69 -18
  205. package/skills/ai-core/adapter-configuration/SKILL.md +44 -21
  206. package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +1 -3
  207. package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +148 -0
  208. package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +2 -6
  209. package/skills/ai-core/adapter-configuration/references/groq-adapter.md +2 -6
  210. package/skills/ai-core/adapter-configuration/references/openai-adapter.md +1 -3
  211. package/skills/ai-core/ag-ui-protocol/SKILL.md +1 -1
  212. package/skills/ai-core/chat-experience/SKILL.md +156 -11
  213. package/skills/ai-core/client-persistence/SKILL.md +277 -0
  214. package/skills/ai-core/custom-backend-integration/SKILL.md +1 -1
  215. package/skills/ai-core/debug-logging/SKILL.md +1 -1
  216. package/skills/ai-core/locks/SKILL.md +143 -0
  217. package/skills/ai-core/media-generation/SKILL.md +144 -12
  218. package/skills/ai-core/middleware/SKILL.md +258 -33
  219. package/skills/ai-core/structured-outputs/SKILL.md +1 -1
  220. package/skills/ai-core/tool-calling/SKILL.md +54 -59
  221. package/src/activities/chat/agent-loop-strategies.ts +10 -4
  222. package/src/activities/chat/cancel.ts +81 -0
  223. package/src/activities/chat/index.ts +1152 -153
  224. package/src/activities/chat/mcp/manager.ts +4 -4
  225. package/src/activities/chat/mcp/types.ts +2 -2
  226. package/src/activities/chat/messages.ts +5 -3
  227. package/src/activities/chat/middleware/builder.ts +1 -1
  228. package/src/activities/chat/middleware/compose.ts +186 -9
  229. package/src/activities/chat/middleware/index.ts +26 -0
  230. package/src/activities/chat/middleware/locks.ts +102 -0
  231. package/src/activities/chat/middleware/pending-turn.ts +47 -0
  232. package/src/activities/chat/middleware/run-disconnect.ts +62 -0
  233. package/src/activities/chat/middleware/run-store.ts +412 -0
  234. package/src/activities/chat/middleware/types.ts +62 -1
  235. package/src/activities/chat/stream/processor.ts +189 -5
  236. package/src/activities/chat/tools/approval-schema.ts +205 -0
  237. package/src/activities/chat/tools/tool-calls.ts +106 -13
  238. package/src/activities/chat/tools/tool-definition.ts +210 -39
  239. package/src/activities/generateAudio/index.ts +20 -3
  240. package/src/activities/generateImage/index.ts +20 -3
  241. package/src/activities/generateSpeech/index.ts +25 -3
  242. package/src/activities/generateTranscription/index.ts +26 -3
  243. package/src/activities/generateVideo/index.ts +345 -82
  244. package/src/activities/middleware/index.ts +2 -0
  245. package/src/activities/middleware/run.ts +31 -0
  246. package/src/activities/middleware/types.ts +49 -5
  247. package/src/activities/stream-generation-result.ts +30 -2
  248. package/src/activities/summarize/chat-stream-summarize.ts +5 -0
  249. package/src/activities/summarize/index.ts +200 -10
  250. package/src/adapter-internals.ts +10 -1
  251. package/src/client.ts +244 -0
  252. package/src/custom-events.ts +107 -0
  253. package/src/delivery-detach.ts +72 -0
  254. package/src/delivery-disconnect.ts +84 -0
  255. package/src/index.ts +138 -0
  256. package/src/interrupt-resume.ts +824 -0
  257. package/src/interrupt-serialization.ts +183 -0
  258. package/src/interrupts.ts +146 -0
  259. package/src/locks.ts +17 -0
  260. package/src/logger/types.ts +1 -1
  261. package/src/middlewares/otel.ts +1 -0
  262. package/src/realtime/index.ts +5 -9
  263. package/src/scope.ts +47 -0
  264. package/src/stream-durability.ts +598 -0
  265. package/src/stream-to-response.ts +1051 -95
  266. package/src/strip-to-spec-middleware.ts +3 -3
  267. package/src/types.ts +416 -24
  268. package/src/utilities/chat-params.ts +245 -55
  269. package/dist/esm/activities/index.js.map +0 -1
  270. package/dist/esm/adapter-internals.js.map +0 -1
  271. package/dist/esm/index.js.map +0 -1
  272. package/dist/esm/middlewares/index.js.map +0 -1
@@ -11,10 +11,10 @@ import type { StreamChunk } from './types'
11
11
  * spec validation or verifyEvents.
12
12
  */
13
13
  export function stripToSpec(chunk: StreamChunk): StreamChunk {
14
- // Only strip the deprecated nested error object from RUN_ERROR
14
+ // Only strip the deprecated nested error object from RUN_ERROR.
15
15
  if (chunk.type === 'RUN_ERROR' && 'error' in chunk) {
16
- const { error: _deprecated, ...rest } = chunk as Record<string, unknown>
17
- return rest as StreamChunk
16
+ const { error: _deprecated, ...rest } = chunk
17
+ return rest
18
18
  }
19
19
  return chunk
20
20
  }
package/src/types.ts CHANGED
@@ -5,6 +5,8 @@ import type {
5
5
  import type { InternalLogger } from './logger/internal-logger'
6
6
  import type { SystemPrompt } from './system-prompts'
7
7
  import type { CapabilityContext } from './activities/chat/middleware/capabilities'
8
+ import type { InterruptSubmissionError } from './interrupts'
9
+ import type { ProviderTool } from './tools/provider-tool'
8
10
  // The canonical usage types live in the leaf `@tanstack/ai-event-client`
9
11
  // package (which `@tanstack/ai` already depends on) so there is a single source
10
12
  // of truth without a dependency cycle. They are re-exported below.
@@ -18,6 +20,7 @@ import type {
18
20
  import type {
19
21
  BaseEvent as AGUIBaseEvent,
20
22
  CustomEvent as AGUICustomEvent,
23
+ Interrupt as AGUIInterrupt,
21
24
  MessagesSnapshotEvent as AGUIMessagesSnapshotEvent,
22
25
  ReasoningEncryptedValueEvent as AGUIReasoningEncryptedValueEvent,
23
26
  ReasoningEndEvent as AGUIReasoningEndEvent,
@@ -25,8 +28,10 @@ import type {
25
28
  ReasoningMessageEndEvent as AGUIReasoningMessageEndEvent,
26
29
  ReasoningMessageStartEvent as AGUIReasoningMessageStartEvent,
27
30
  ReasoningStartEvent as AGUIReasoningStartEvent,
31
+ ResumeEntry as AGUIResumeEntry,
28
32
  RunErrorEvent as AGUIRunErrorEvent,
29
33
  RunFinishedEvent as AGUIRunFinishedEvent,
34
+ RunFinishedOutcome as AGUIRunFinishedOutcome,
30
35
  RunStartedEvent as AGUIRunStartedEvent,
31
36
  StateDeltaEvent as AGUIStateDeltaEvent,
32
37
  StateSnapshotEvent as AGUIStateSnapshotEvent,
@@ -42,6 +47,12 @@ import type {
42
47
  EventType,
43
48
  } from '@ag-ui/core'
44
49
 
50
+ // Re-export ProviderTool so the type is reachable from `@tanstack/ai`'s root
51
+ // entry via `export * from './types'` without forcing the subpath import.
52
+ // The canonical declaration lives in `./tools/provider-tool` alongside its
53
+ // runtime helper `brandProviderTool`.
54
+ export type { ProviderTool } from './tools/provider-tool'
55
+
45
56
  /**
46
57
  * Tool call states - track the lifecycle of a tool call
47
58
  */
@@ -356,6 +367,15 @@ export interface ModelMessage<
356
367
  toolCalls?: Array<ToolCall>
357
368
  toolCallId?: string
358
369
  thinking?: Array<{ content: string; signature?: string }>
370
+ /**
371
+ * Optional stable message id. Providers ignore it; it exists so a persisted
372
+ * transcript can retain the streaming `messageId` and survive the
373
+ * persist → hydrate round-trip. When present, `modelMessagesToUIMessages`
374
+ * reuses it instead of generating a fresh id, so a hydrated message keeps the
375
+ * same identity as its live stream — which is what lets a mid-stream reload
376
+ * resume the SAME message bubble in place (see `@tanstack/ai-persistence`).
377
+ */
378
+ id?: string
359
379
  }
360
380
 
361
381
  /**
@@ -569,8 +589,8 @@ export type ToolExecutionContext<TContext = unknown> =
569
589
  }
570
590
 
571
591
  export type ToolExecuteFunction<
572
- TInput extends SchemaInput = SchemaInput,
573
- TOutput extends SchemaInput = SchemaInput,
592
+ TInput extends SchemaInput | undefined = SchemaInput,
593
+ TOutput extends SchemaInput | undefined = SchemaInput,
574
594
  TContext = unknown,
575
595
  > = undefined extends TContext
576
596
  ? (
@@ -596,8 +616,8 @@ export type ToolExecuteFunction<
596
616
  * @see https://standardschema.dev/json-schema
597
617
  */
598
618
  export interface Tool<
599
- TInput extends SchemaInput = SchemaInput,
600
- TOutput extends SchemaInput = SchemaInput,
619
+ TInput extends SchemaInput | undefined = SchemaInput,
620
+ TOutput extends SchemaInput | undefined = SchemaInput,
601
621
  TName extends string = string,
602
622
  TContext = unknown,
603
623
  > {
@@ -831,12 +851,24 @@ export interface ResponseFormat<TData = any> {
831
851
  * State passed to agent loop strategy for determining whether to continue
832
852
  */
833
853
  export interface AgentLoopState {
834
- /** Current iteration count (0-indexed) */
854
+ /** Current iteration count (0-indexed). One iteration = one model turn. */
835
855
  iterationCount: number
836
856
  /** Current messages array */
837
857
  messages: Array<ModelMessage>
838
858
  /** Finish reason from the last response */
839
859
  finishReason: string | null
860
+ /**
861
+ * Cumulative tool calls counted so far in this run (model-emitted during the
862
+ * agent loop, including ones skipped by middleware, and pending tools from
863
+ * the inbound message list when resumed). Not a recount of full message
864
+ * history; not model turns.
865
+ */
866
+ toolCallCount: number
867
+ /**
868
+ * Tool calls in the most recent batch — a live model turn or a
869
+ * pending/resume batch (0 when the last phase produced no tool calls).
870
+ */
871
+ lastTurnToolCallCount: number
840
872
  }
841
873
 
842
874
  /**
@@ -847,8 +879,10 @@ export interface AgentLoopState {
847
879
  *
848
880
  * @example
849
881
  * ```typescript
850
- * // Continue for up to 5 iterations
882
+ * // Continue for up to 5 iterations (model turns, not tool calls)
851
883
  * const strategy: AgentLoopStrategy = ({ iterationCount }) => iterationCount < 5;
884
+ * // Cap total tool calls across the run (or use middleware onShouldContinue)
885
+ * const byTools: AgentLoopStrategy = ({ toolCallCount }) => toolCallCount < 20;
852
886
  * ```
853
887
  */
854
888
  export type AgentLoopStrategy = (state: AgentLoopState) => boolean
@@ -979,6 +1013,16 @@ export interface TextOptions<
979
1013
  */
980
1014
  parentRunId?: string
981
1015
 
1016
+ /** Application state mirrored in a STATE_SNAPSHOT before an interrupt terminal. */
1017
+ state?: unknown
1018
+
1019
+ /**
1020
+ * AG-UI interrupt resume responses supplied by the client on a follow-up run.
1021
+ * Threaded through request parsing now so later runtime behavior can resolve
1022
+ * upstream-native interrupts.
1023
+ */
1024
+ resume?: Array<RunAgentResumeItem>
1025
+
982
1026
  /**
983
1027
  * Middleware capability context for this run. The engine populates it with
984
1028
  * the live middleware context so harness adapters that declare
@@ -1068,6 +1112,12 @@ export type {
1068
1112
  */
1069
1113
  export type UsageTotals = TokenUsage
1070
1114
 
1115
+ export type Interrupt = AGUIInterrupt
1116
+
1117
+ export type RunFinishedOutcome = AGUIRunFinishedOutcome
1118
+
1119
+ export type RunAgentResumeItem = AGUIResumeEntry
1120
+
1071
1121
  /**
1072
1122
  * Emitted when a run completes successfully.
1073
1123
  *
@@ -1092,6 +1142,8 @@ export interface RunFinishedEvent extends AGUIRunFinishedEvent {
1092
1142
  export interface RunErrorEvent extends AGUIRunErrorEvent {
1093
1143
  /** Model identifier for multi-model support */
1094
1144
  model?: string
1145
+ /** Exhaustive TanStack interrupt submission failures for this run. */
1146
+ 'tanstack:interruptErrors'?: ReadonlyArray<InterruptSubmissionError>
1095
1147
  /**
1096
1148
  * @deprecated Use top-level `message` and `code` fields instead.
1097
1149
  * Kept for backward compatibility.
@@ -1144,15 +1196,32 @@ export interface TextMessageEndEvent extends AGUITextMessageEndEvent {
1144
1196
  *
1145
1197
  * @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId?`
1146
1198
  * TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `metadata?`
1147
- */
1148
- export interface ToolCallStartEvent extends AGUIToolCallStartEvent {
1199
+ *
1200
+ * Field shapes are taken from AG-UI via `Pick` (not `extends`) so Zod
1201
+ * `.passthrough()` index signatures do not pollute the StreamChunk
1202
+ * discriminated union — required for {@link TypedStreamChunk} narrowing.
1203
+ *
1204
+ * @typeParam TToolName - Constrained tool name type. Defaults to `string` (untyped).
1205
+ * When the stream is returned from `chat()` with typed tools, `TypedStreamChunk`
1206
+ * intersects a literal onto `toolCallName` and `toolName` for discrimination.
1207
+ */
1208
+ export interface ToolCallStartEvent<
1209
+ TToolName extends string = string,
1210
+ > extends Pick<
1211
+ AGUIToolCallStartEvent,
1212
+ 'toolCallId' | 'toolCallName' | 'parentMessageId' | 'timestamp' | 'rawEvent'
1213
+ > {
1214
+ type: 'TOOL_CALL_START'
1149
1215
  /** Model identifier for multi-model support */
1150
1216
  model?: string
1151
1217
  /**
1152
1218
  * @deprecated Use `toolCallName` instead (from @ag-ui/core spec).
1153
1219
  * Kept for backward compatibility.
1220
+ *
1221
+ * Carries `TToolName` on the base interface; for `toolCallName` narrowing use
1222
+ * {@link TypedStreamChunk} (distributed variants intersect the AG-UI field).
1154
1223
  */
1155
- toolName: string
1224
+ toolName: TToolName
1156
1225
  /** Index for parallel tool calls */
1157
1226
  index?: number
1158
1227
  /** Provider-specific metadata to carry into the ToolCall.
@@ -1179,21 +1248,39 @@ export interface ToolCallArgsEvent extends AGUIToolCallArgsEvent {
1179
1248
  * Emitted when a tool call completes.
1180
1249
  *
1181
1250
  * @ag-ui/core provides: `toolCallId`
1182
- * TanStack AI adds: `model?`, `toolCallName?`, `toolName?` (deprecated), `input?`, `result?`
1183
- */
1184
- export interface ToolCallEndEvent extends AGUIToolCallEndEvent {
1251
+ * TanStack AI adds: `model?`, `toolCallName?`, `toolName?` (deprecated), `input?`, `output?`, `result?`
1252
+ *
1253
+ * Same `Pick` (not `extends`) rationale as {@link ToolCallStartEvent}.
1254
+ *
1255
+ * @typeParam TToolName - Constrained tool name type. Defaults to `string` (untyped).
1256
+ * @typeParam TInput - Constrained input arguments type. Defaults to `unknown`.
1257
+ * @typeParam TOutput - Constrained output type from the tool's `outputSchema`. Defaults to `unknown`.
1258
+ */
1259
+ export interface ToolCallEndEvent<
1260
+ TToolName extends string = string,
1261
+ TInput = unknown,
1262
+ TOutput = unknown,
1263
+ > extends Pick<AGUIToolCallEndEvent, 'toolCallId' | 'timestamp' | 'rawEvent'> {
1264
+ type: 'TOOL_CALL_END'
1185
1265
  /** Model identifier for multi-model support */
1186
1266
  model?: string
1187
- /** Name of the tool that completed */
1188
- toolCallName?: string
1267
+ /** Name of the tool that completed (AG-UI-compatible optional field) */
1268
+ toolCallName?: TToolName
1189
1269
  /**
1190
1270
  * @deprecated Use `toolCallName` instead.
1191
1271
  * Kept for backward compatibility.
1192
1272
  */
1193
- toolName?: string
1273
+ toolName?: TToolName
1194
1274
  /** Final parsed input arguments (TanStack AI internal) */
1195
- input?: unknown
1196
- /** Tool execution result (TanStack AI internal) */
1275
+ input?: TInput
1276
+ /**
1277
+ * Tool execution output, validated against the tool's `outputSchema` when
1278
+ * one is declared. Prefer this over parsing `result` when present.
1279
+ * Undefined for tools without execute, client tools pending approval, or
1280
+ * when execution throws.
1281
+ */
1282
+ output?: TOutput
1283
+ /** Tool execution result (TanStack AI internal / wire form) */
1197
1284
  result?: string | Array<ContentPart>
1198
1285
  /** Tool execution output state (TanStack AI internal) */
1199
1286
  state?: ToolOutputState
@@ -1301,10 +1388,26 @@ export interface StateDeltaEvent extends AGUIStateDeltaEvent {
1301
1388
  *
1302
1389
  * @ag-ui/core provides: `name`, `value`
1303
1390
  * TanStack AI adds: `model?`
1391
+ *
1392
+ * Uses `Pick` (not `extends`) so the Zod passthrough index signature does not
1393
+ * erase discriminant property access on {@link KnownCustomEvent} /
1394
+ * {@link TypedStreamChunk} unions.
1304
1395
  */
1305
- export interface CustomEvent extends AGUICustomEvent {
1396
+ export interface CustomEvent extends Pick<
1397
+ AGUICustomEvent,
1398
+ 'name' | 'value' | 'timestamp' | 'rawEvent'
1399
+ > {
1400
+ type: 'CUSTOM'
1306
1401
  /** Model identifier for multi-model support */
1307
1402
  model?: string
1403
+ /**
1404
+ * Routing metadata the TanStack engine attaches when emitting CUSTOM
1405
+ * events that need to be correlated with a specific thread/run.
1406
+ * Stripped by `strip-to-spec-middleware` before going on the wire so
1407
+ * the AG-UI consumer never sees them (when that middleware is enabled).
1408
+ */
1409
+ threadId?: string
1410
+ runId?: string
1308
1411
  }
1309
1412
 
1310
1413
  /**
@@ -1352,6 +1455,10 @@ export interface StructuredOutputStartEvent extends CustomEvent {
1352
1455
  * (the agent-loop branch of `runStreamingStructuredOutputImpl` in
1353
1456
  * `activities/chat/index.ts` forwards CUSTOM events from `TextEngine.run()`).
1354
1457
  */
1458
+ /**
1459
+ * @deprecated Native interrupts use RUN_FINISHED interrupt outcomes. This
1460
+ * compatibility event remains readable until 1.0.
1461
+ */
1355
1462
  export interface ApprovalRequestedEvent extends CustomEvent {
1356
1463
  name: 'approval-requested'
1357
1464
  value: {
@@ -1368,6 +1475,10 @@ export interface ApprovalRequestedEvent extends CustomEvent {
1368
1475
  * will not fire for that run. Shape fixed by the agent-loop forwarding in
1369
1476
  * `runStreamingStructuredOutputImpl` in `activities/chat/index.ts`.
1370
1477
  */
1478
+ /**
1479
+ * @deprecated Native interrupts use RUN_FINISHED interrupt outcomes. This
1480
+ * compatibility event remains readable until 1.0.
1481
+ */
1371
1482
  export interface ToolInputAvailableEvent extends CustomEvent {
1372
1483
  name: 'tool-input-available'
1373
1484
  value: {
@@ -1492,11 +1603,15 @@ export type ChatStream = AsyncIterable<
1492
1603
  /**
1493
1604
  * Public type for streams returned by `chat({ outputSchema, stream: true })`.
1494
1605
  *
1495
- * Yields all standard `StreamChunk` lifecycle events plus the three tagged
1496
- * `CUSTOM` events the orchestrator can emit through this path:
1606
+ * Yields all standard `StreamChunk` lifecycle events plus the typed
1607
+ * structured-output `CUSTOM` event emitted through this path:
1497
1608
  * - `structured-output.complete` — terminal event with typed `value.object: T`
1498
- * - `approval-requested` — server tool needs approval (pauses the run)
1499
- * - `tool-input-available` — client tool invocation (pauses the run)
1609
+ *
1610
+ * User-actionable waits, such as tool approval and client tool input, are
1611
+ * represented by `RUN_FINISHED.outcome.type === 'interrupt'` in current core
1612
+ * streams. Legacy `approval-requested` and `tool-input-available` custom
1613
+ * events may still be consumed for replay and backward compatibility, but
1614
+ * they are not the current source of truth for waits.
1500
1615
  *
1501
1616
  * Each variant has a literal `name`, so a single discriminated narrow gives
1502
1617
  * you a typed `value` with no helper or cast:
@@ -1505,8 +1620,6 @@ export type ChatStream = AsyncIterable<
1505
1620
  * for await (const chunk of stream) {
1506
1621
  * if (chunk.type === 'CUSTOM' && chunk.name === 'structured-output.complete') {
1507
1622
  * chunk.value.object // typed as T
1508
- * } else if (chunk.type === 'CUSTOM' && chunk.name === 'approval-requested') {
1509
- * chunk.value.toolCallId // typed as string
1510
1623
  * }
1511
1624
  * }
1512
1625
  * ```
@@ -1634,6 +1747,215 @@ export type AGUIEvent =
1634
1747
  */
1635
1748
  export type StreamChunk = AGUIEvent
1636
1749
 
1750
+ // ============================================================================
1751
+ // Typed Stream Chunks (tool-aware)
1752
+ // ============================================================================
1753
+
1754
+ /**
1755
+ * Detect the `any` type. Returns `true` for `any`, `false` for everything else.
1756
+ * @internal
1757
+ */
1758
+ type IsAny<T> = 0 extends 1 & T ? true : false
1759
+
1760
+ /**
1761
+ * Partition out provider-specific tools from a tools array. `ProviderTool`
1762
+ * carries opaque provider metadata (e.g. `webSearchTool` from
1763
+ * `@tanstack/ai-anthropic`) and intentionally has a generic `string` name —
1764
+ * if we included it in the discriminated union, it would widen `toolName`
1765
+ * back to `string` and defeat the entire typing exercise.
1766
+ *
1767
+ * @internal
1768
+ */
1769
+ type NonProviderTools<TTools extends ReadonlyArray<AnyTool>> = Exclude<
1770
+ TTools[number],
1771
+ ProviderTool<string, string>
1772
+ >
1773
+
1774
+ /**
1775
+ * Check whether the tools array carries typed tool definitions.
1776
+ * Returns `false` for empty arrays or arrays whose only entries are
1777
+ * `ProviderTool`s (which have generic `string` names).
1778
+ *
1779
+ * The partitioning step matters: a user who passes
1780
+ * `[webSearchTool, myTypedTool]` should still get typed narrowing for
1781
+ * `myTypedTool`. Evaluating `string extends TTools[number]['name']` without
1782
+ * filtering provider tools first would always return `false` (because
1783
+ * `ProviderTool`'s `name` is `string`) and silently fall through to the
1784
+ * untyped branch.
1785
+ *
1786
+ * @internal
1787
+ */
1788
+ type HasTypedTools<TTools extends ReadonlyArray<AnyTool>> = [
1789
+ NonProviderTools<TTools>,
1790
+ ] extends [never]
1791
+ ? false
1792
+ : string extends NonProviderTools<TTools>['name']
1793
+ ? false
1794
+ : true
1795
+
1796
+ /**
1797
+ * Safely infer input type for a single tool, guarding against `any` leaks.
1798
+ * Returns `unknown` when the tool has no inputSchema, when the schema
1799
+ * parameter defaults to `undefined` (no-schema tool definitions), or when
1800
+ * InferSchemaType produces `any` (e.g. for plain JSON Schema tools).
1801
+ * @internal
1802
+ */
1803
+ type SafeToolInput<T> = T extends {
1804
+ inputSchema?: infer TInput
1805
+ }
1806
+ ? [TInput] extends [undefined]
1807
+ ? unknown
1808
+ : IsAny<InferSchemaType<NonNullable<TInput>>> extends true
1809
+ ? unknown
1810
+ : InferSchemaType<NonNullable<TInput>>
1811
+ : unknown
1812
+
1813
+ /**
1814
+ * Safely infer output type for a single tool. Mirrors `SafeToolInput`,
1815
+ * picking `outputSchema` instead. Returns `unknown` when the tool has no
1816
+ * `outputSchema` declared, when the schema parameter defaults to `undefined`,
1817
+ * or when `InferSchemaType` produces `any`.
1818
+ * @internal
1819
+ */
1820
+ type SafeToolOutput<T> = T extends {
1821
+ outputSchema?: infer TOutput
1822
+ }
1823
+ ? [TOutput] extends [undefined]
1824
+ ? unknown
1825
+ : IsAny<InferSchemaType<NonNullable<TOutput>>> extends true
1826
+ ? unknown
1827
+ : InferSchemaType<NonNullable<TOutput>>
1828
+ : unknown
1829
+
1830
+ /**
1831
+ * Distribute over each non-provider tool to create a per-tool
1832
+ * `ToolCallStartEvent`.
1833
+ *
1834
+ * This produces a discriminated union — one variant per tool name literal.
1835
+ * We distribute over `NonProviderTools<TTools>` (not `TTools[number]`) so
1836
+ * that provider tools with generic `string` names do not leak into the
1837
+ * union and widen `toolCallName` / `toolName` back to `string`.
1838
+ *
1839
+ * The trailing `& { toolCallName: TName; toolName: TName }` intersection
1840
+ * narrows the base `AGUIToolCallStartEvent['toolCallName']` (declared as
1841
+ * `string`) to the literal name — TypeScript intersects `string & TName`
1842
+ * down to `TName` for literal `TName`.
1843
+ *
1844
+ * The `name` parameter constraint on the inner `extends` picks up any
1845
+ * tool-like shape — including `ServerTool`, `ClientTool`, and the bare
1846
+ * `Tool` definition — because all three expose `name: TName`.
1847
+ * @internal
1848
+ */
1849
+ type DistributedToolCallStart<TTools extends ReadonlyArray<AnyTool>> =
1850
+ NonProviderTools<TTools> extends infer T
1851
+ ? T extends { name: infer TName extends string }
1852
+ ? ToolCallStartEvent<TName> & { toolCallName: TName; toolName: TName }
1853
+ : never
1854
+ : never
1855
+
1856
+ /**
1857
+ * Distribute over each non-provider tool to create a per-tool
1858
+ * `ToolCallEndEvent`.
1859
+ *
1860
+ * Each variant pairs the tool's name literal with its specific input type,
1861
+ * enabling discriminated narrowing: checking `toolName === 'x'` narrows
1862
+ * `input`.
1863
+ *
1864
+ * `toolName`/`toolCallName` are intersected as required in the distributed
1865
+ * variants so that `Extract<..., { toolName: 'x' }>` works for consumers
1866
+ * relying on the discriminated-union pattern, even though the base
1867
+ * interface keeps them optional for compatibility with the broader AG-UI
1868
+ * surface.
1869
+ *
1870
+ * Distribution happens over `NonProviderTools<TTools>` for the same
1871
+ * reason as in `DistributedToolCallStart`.
1872
+ * @internal
1873
+ */
1874
+ type DistributedToolCallEnd<TTools extends ReadonlyArray<AnyTool>> =
1875
+ NonProviderTools<TTools> extends infer T
1876
+ ? T extends { name: infer TName extends string }
1877
+ ? ToolCallEndEvent<TName, SafeToolInput<T>, SafeToolOutput<T>> & {
1878
+ toolCallName: TName
1879
+ toolName: TName
1880
+ }
1881
+ : never
1882
+ : never
1883
+
1884
+ /**
1885
+ * Discriminated union of the orchestrator-tagged `CUSTOM` events. Each variant
1886
+ * has a literal `name`, so a single narrow on `chunk.name` yields a typed
1887
+ * `value` with no helper or cast:
1888
+ *
1889
+ * ```ts
1890
+ * if (chunk.type === 'CUSTOM' && chunk.name === 'approval-requested') {
1891
+ * chunk.value.toolCallId // typed as string
1892
+ * }
1893
+ * ```
1894
+ *
1895
+ * The `StructuredOutputCompleteEvent` value is parameterized by `T`, which
1896
+ * the chat orchestrator narrows to the schema's inferred type after Standard
1897
+ * Schema validation. Adapters always emit it with `T = unknown`.
1898
+ *
1899
+ * Caveat: tools can emit arbitrary user-defined custom events via the
1900
+ * `emitCustomEvent(name, value)` context API. Those flow through the stream
1901
+ * at runtime but are intentionally absent from this union — including a bare
1902
+ * `CustomEvent` (whose `value: any` would poison the union) would collapse
1903
+ * `chunk.value` back to `any` after the narrow. If you rely on
1904
+ * `emitCustomEvent`, branch on `CUSTOM` outside the literal-`name` narrows
1905
+ * or cast the chunk to `StreamChunk` to recover the wider shape.
1906
+ */
1907
+ export type TaggedCustomEvent<T = unknown> =
1908
+ | StructuredOutputStartEvent
1909
+ | StructuredOutputCompleteEvent<T>
1910
+ | ApprovalRequestedEvent
1911
+ | ToolInputAvailableEvent
1912
+
1913
+ /**
1914
+ * Stream chunk type parameterized by the tools array for type-safe tool call events.
1915
+ *
1916
+ * When specific tool types are provided (e.g. from `chat({ tools: [myTool] })`):
1917
+ * - `TOOL_CALL_START` and `TOOL_CALL_END` events form a **discriminated union**
1918
+ * over tool names — checking `toolName === 'x'` narrows `input` to that tool's type.
1919
+ * - `TOOL_CALL_END` events have `input` typed per-tool via Standard Schema inference.
1920
+ *
1921
+ * `CUSTOM` events are narrowed to the discriminated {@link KnownCustomEvent}
1922
+ * union (sandbox, code-mode, structured-output, approvals, UI resources, etc.).
1923
+ * Free-form user-emitted custom events (via `emitCustomEvent`) still flow at
1924
+ * runtime but are excluded from the type to avoid `any` poisoning the union;
1925
+ * cast to `StreamChunk` if you need to read those.
1926
+ *
1927
+ * When tools are untyped or absent, the tool-call events stay as plain
1928
+ * `ToolCallStartEvent` / `ToolCallEndEvent` (no per-tool name narrowing) and
1929
+ * the type is equivalent to the element type of {@link ChatStream}.
1930
+ */
1931
+ /**
1932
+ * Replace tool-call and bare CUSTOM variants; keep every other StreamChunk
1933
+ * arm. Matches on the string-literal `type` discriminant that TanStack tool
1934
+ * events declare (see ToolCallStartEvent / ToolCallEndEvent). AG-UI events
1935
+ * that still use the EventType enum are kept as-is via the final branch.
1936
+ *
1937
+ * Do **not** use `Exclude<StreamChunk, { type: 'TOOL_CALL_*' }>` — under
1938
+ * @ag-ui/core passthrough index signatures that form removes *every* arm.
1939
+ * @internal
1940
+ */
1941
+ type RemapStreamChunkForTools<
1942
+ TChunk,
1943
+ TTools extends ReadonlyArray<AnyTool>,
1944
+ > = TChunk extends { type: 'TOOL_CALL_START' }
1945
+ ? DistributedToolCallStart<TTools>
1946
+ : TChunk extends { type: 'TOOL_CALL_END' }
1947
+ ? DistributedToolCallEnd<TTools>
1948
+ : TChunk extends { type: 'CUSTOM' }
1949
+ ? never
1950
+ : TChunk
1951
+
1952
+ export type TypedStreamChunk<
1953
+ TTools extends ReadonlyArray<AnyTool> = ReadonlyArray<AnyTool>,
1954
+ > =
1955
+ HasTypedTools<TTools> extends true
1956
+ ? RemapStreamChunkForTools<StreamChunk, TTools> | KnownCustomEvent
1957
+ : Exclude<StreamChunk, CustomEvent> | KnownCustomEvent
1958
+
1637
1959
  // Simple streaming format for basic text completions
1638
1960
  // Converted to StreamChunk format by convertTextCompletionStream()
1639
1961
  export interface TextCompletionChunk {
@@ -1655,6 +1977,16 @@ export interface SummarizationOptions<
1655
1977
  focus?: Array<string>
1656
1978
  /** Provider-specific options forwarded by the summarize() activity. */
1657
1979
  modelOptions?: TProviderOptions
1980
+ /**
1981
+ * Run identity forwarded from the summarize() activity. When set, the
1982
+ * streaming adapter stamps it onto the emitted `RUN_STARTED` (via the wrapped
1983
+ * chat), so a delivery-durable route keys the run's log by the same id the
1984
+ * client rejoins with — making a mid-run reload resumable, like the media
1985
+ * activities. Optional and non-breaking: adapters that ignore it just mint
1986
+ * their own.
1987
+ */
1988
+ runId?: string
1989
+ threadId?: string
1658
1990
  /**
1659
1991
  * Internal logger threaded from the summarize() entry point. Adapters must
1660
1992
  * call logger.request() before the SDK call and logger.errors() in catch blocks.
@@ -1817,6 +2149,50 @@ export type GeneratedMediaSource =
1817
2149
  url?: never
1818
2150
  }
1819
2151
 
2152
+ export type PersistedArtifactRole = 'input' | 'output'
2153
+
2154
+ export type PersistedArtifactActivity =
2155
+ | 'image'
2156
+ | 'audio'
2157
+ | 'tts'
2158
+ | 'video'
2159
+ | 'transcription'
2160
+
2161
+ export interface PersistedArtifactRef {
2162
+ role: PersistedArtifactRole
2163
+ artifactId: string
2164
+ threadId: string
2165
+ runId: string
2166
+ name: string
2167
+ mimeType: string
2168
+ size: number
2169
+ createdAt: string
2170
+ /**
2171
+ * Where these bytes were fetched FROM — the provider's original result URL,
2172
+ * or a caller-supplied prompt URL when `allowInputUrl` opted that in. Usually
2173
+ * expiring, and provenance only: serve from {@link PersistedArtifactRef.url}
2174
+ * instead.
2175
+ */
2176
+ sourceUrl?: string
2177
+ /**
2178
+ * Durable app-origin URL that serves this artifact's persisted bytes (your
2179
+ * `GET` route around `retrieveArtifact` / `retrieveBlob`). Stamped by
2180
+ * `withGenerationPersistence`'s `artifactUrl` option, so clients render and
2181
+ * restore durable media from your own origin rather than the provider's
2182
+ * expiring link.
2183
+ */
2184
+ url?: string
2185
+ source: {
2186
+ activity: PersistedArtifactActivity
2187
+ path: string
2188
+ provider: string
2189
+ model: string
2190
+ mediaType?: 'image' | 'audio' | 'video' | 'document' | 'json'
2191
+ jobId?: string
2192
+ expiresAt?: string
2193
+ }
2194
+ }
2195
+
1820
2196
  /**
1821
2197
  * A single generated image
1822
2198
  */
@@ -1837,6 +2213,8 @@ export interface ImageGenerationResult {
1837
2213
  images: Array<GeneratedImage>
1838
2214
  /** Token usage information (if available) */
1839
2215
  usage?: TokenUsage
2216
+ /** Persisted artifact references for generated assets, when available */
2217
+ artifacts?: Array<PersistedArtifactRef>
1840
2218
  }
1841
2219
 
1842
2220
  // ============================================================================
@@ -1888,6 +2266,8 @@ export interface AudioGenerationResult {
1888
2266
  audio: GeneratedAudio
1889
2267
  /** Token usage information (if available) */
1890
2268
  usage?: TokenUsage
2269
+ /** Persisted artifact references for generated assets, when available */
2270
+ artifacts?: Array<PersistedArtifactRef>
1891
2271
  }
1892
2272
 
1893
2273
  // ============================================================================
@@ -1943,6 +2323,12 @@ export interface VideoJobResult {
1943
2323
  jobId: string
1944
2324
  /** Model used for generation */
1945
2325
  model: string
2326
+ /**
2327
+ * Durable artifact references, when generation persistence with an artifact +
2328
+ * blob store is wired. A submission has no video yet, so this only carries
2329
+ * refs for persisted prompt INPUTS (e.g. a start frame).
2330
+ */
2331
+ artifacts?: Array<PersistedArtifactRef>
1946
2332
  }
1947
2333
 
1948
2334
  /**
@@ -1979,6 +2365,8 @@ export interface VideoUrlResult {
1979
2365
  * real billed quantity — so consumers can compute exact cost.
1980
2366
  */
1981
2367
  usage?: TokenUsage
2368
+ /** Persisted artifact references for generated assets, when available */
2369
+ artifacts?: Array<PersistedArtifactRef>
1982
2370
  }
1983
2371
 
1984
2372
  // ============================================================================
@@ -2028,6 +2416,8 @@ export interface TTSResult {
2028
2416
  contentType?: string
2029
2417
  /** Token usage information (if provided by the adapter) */
2030
2418
  usage?: TokenUsage
2419
+ /** Persisted artifact references for generated assets, when available */
2420
+ artifacts?: Array<PersistedArtifactRef>
2031
2421
  }
2032
2422
 
2033
2423
  // ============================================================================
@@ -2118,6 +2508,8 @@ export interface TranscriptionResult {
2118
2508
  words?: Array<TranscriptionWord>
2119
2509
  /** Token usage information (if provided by the adapter) */
2120
2510
  usage?: TokenUsage
2511
+ /** Persisted artifact references for generated assets, when available */
2512
+ artifacts?: Array<PersistedArtifactRef>
2121
2513
  }
2122
2514
 
2123
2515
  /**