@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
@@ -9,6 +9,7 @@ import { aiEventClient } from '@tanstack/ai-event-client'
9
9
  import { streamGenerationResult } from '../stream-generation-result.js'
10
10
  import { resolveDebugOption } from '../../logger/resolve'
11
11
  import {
12
+ applyGenerationResultTransforms,
12
13
  createGenerationContext,
13
14
  runGenerationError,
14
15
  runGenerationFinish,
@@ -84,6 +85,10 @@ export interface AudioActivityOptions<
84
85
  * `GenerationMiddleware` contract for a custom backend.
85
86
  */
86
87
  middleware?: Array<GenerationMiddleware>
88
+ /** Stable conversation/thread id for correlating this run when persisted. */
89
+ threadId?: string
90
+ /** Stable run id for correlating this run when persisted. */
91
+ runId?: string
87
92
  }
88
93
 
89
94
  // ===========================
@@ -134,8 +139,14 @@ export function generateAudio<
134
139
  options: AudioActivityOptions<TAdapter, TStream>,
135
140
  ): AudioActivityResult<TStream> {
136
141
  if (options.stream) {
137
- return streamGenerationResult(() =>
138
- runGenerateAudio(options),
142
+ return streamGenerationResult(
143
+ // Only `runId` is taken from the resolved wire identity. `threadId` stays
144
+ // the CALLER's: `streamGenerationResult` mints one for the RUN_* chunks
145
+ // when none was passed, and spreading that over the options would hand
146
+ // middleware a thread id known to nobody, which persistence would then
147
+ // file the run under. Matches `generateVideo`.
148
+ (resolved) => runGenerateAudio({ ...options, runId: resolved.runId }),
149
+ options,
139
150
  ) as AudioActivityResult<TStream>
140
151
  }
141
152
  return runGenerateAudio(options) as AudioActivityResult<TStream>
@@ -154,6 +165,8 @@ async function runGenerateAudio<
154
165
  stream: _stream,
155
166
  debug: _debug,
156
167
  middleware,
168
+ threadId,
169
+ runId,
157
170
  ...rest
158
171
  } = options
159
172
  const model = adapter.model
@@ -171,6 +184,9 @@ async function runGenerateAudio<
171
184
  provider: adapter.name,
172
185
  model,
173
186
  modelOptions: rest.modelOptions,
187
+ threadId,
188
+ runId,
189
+ artifactInputs: { prompt: rest.prompt, duration: rest.duration },
174
190
  createId,
175
191
  })
176
192
 
@@ -192,7 +208,8 @@ async function runGenerateAudio<
192
208
  })
193
209
 
194
210
  try {
195
- const result = await adapter.generateAudio({ ...rest, model, logger })
211
+ const rawResult = await adapter.generateAudio({ ...rest, model, logger })
212
+ const result = await applyGenerationResultTransforms(mwCtx, rawResult)
196
213
  const elapsedMs = Date.now() - startTime
197
214
 
198
215
  aiEventClient.emit('audio:request:completed', {
@@ -9,6 +9,7 @@ import { aiEventClient } from '@tanstack/ai-event-client'
9
9
  import { streamGenerationResult } from '../stream-generation-result.js'
10
10
  import { resolveDebugOption } from '../../logger/resolve'
11
11
  import {
12
+ applyGenerationResultTransforms,
12
13
  createGenerationContext,
13
14
  runGenerationError,
14
15
  runGenerationFinish,
@@ -137,6 +138,10 @@ export type ImageActivityOptions<
137
138
  * `GenerationMiddleware` contract for a custom backend.
138
139
  */
139
140
  middleware?: Array<GenerationMiddleware>
141
+ /** Stable conversation/thread id for correlating this run when persisted. */
142
+ threadId?: string
143
+ /** Stable run id for correlating this run when persisted. */
144
+ runId?: string
140
145
  } & ({} extends ImageProviderOptionsForModel<TAdapter, TAdapter['model']>
141
146
  ? {
142
147
  /** Provider-specific options for image generation */ modelOptions?: ImageProviderOptionsForModel<
@@ -225,8 +230,14 @@ export function generateImage<
225
230
  options: ImageActivityOptions<TAdapter, TStream>,
226
231
  ): ImageActivityResult<TStream> {
227
232
  if (options.stream) {
228
- return streamGenerationResult(() =>
229
- runGenerateImage(options),
233
+ return streamGenerationResult(
234
+ // Only `runId` is taken from the resolved wire identity. `threadId` stays
235
+ // the CALLER's: `streamGenerationResult` mints one for the RUN_* chunks
236
+ // when none was passed, and spreading that over the options would hand
237
+ // middleware a thread id known to nobody, which persistence would then
238
+ // file the run under. Matches `generateVideo`.
239
+ (resolved) => runGenerateImage({ ...options, runId: resolved.runId }),
240
+ options,
230
241
  ) as ImageActivityResult<TStream>
231
242
  }
232
243
 
@@ -247,6 +258,8 @@ async function runGenerateImage<
247
258
  stream: _stream,
248
259
  debug: _debug,
249
260
  middleware,
261
+ threadId,
262
+ runId,
250
263
  ...rest
251
264
  } = options
252
265
  const model = adapter.model
@@ -260,6 +273,9 @@ async function runGenerateImage<
260
273
  provider: adapter.name,
261
274
  model,
262
275
  modelOptions: rest.modelOptions,
276
+ threadId,
277
+ runId,
278
+ artifactInputs: { prompt: rest.prompt },
263
279
  createId,
264
280
  })
265
281
 
@@ -295,7 +311,8 @@ async function runGenerateImage<
295
311
  })
296
312
 
297
313
  try {
298
- const result = await adapter.generateImages({ ...rest, model, logger })
314
+ const rawResult = await adapter.generateImages({ ...rest, model, logger })
315
+ const result = await applyGenerationResultTransforms(mwCtx, rawResult)
299
316
  const duration = Date.now() - startTime
300
317
 
301
318
  aiEventClient.emit('image:request:completed', {
@@ -9,6 +9,7 @@ import { aiEventClient } from '@tanstack/ai-event-client'
9
9
  import { streamGenerationResult } from '../stream-generation-result.js'
10
10
  import { resolveDebugOption } from '../../logger/resolve'
11
11
  import {
12
+ applyGenerationResultTransforms,
12
13
  createGenerationContext,
13
14
  runGenerationError,
14
15
  runGenerationFinish,
@@ -87,6 +88,10 @@ export interface TTSActivityOptions<
87
88
  * `GenerationMiddleware` contract for a custom backend.
88
89
  */
89
90
  middleware?: Array<GenerationMiddleware>
91
+ /** Stable conversation/thread id for correlating this run when persisted. */
92
+ threadId?: string
93
+ /** Stable run id for correlating this run when persisted. */
94
+ runId?: string
90
95
  }
91
96
 
92
97
  // ===========================
@@ -144,8 +149,14 @@ export function generateSpeech<
144
149
  TStream extends boolean = false,
145
150
  >(options: TTSActivityOptions<TAdapter, TStream>): TTSActivityResult<TStream> {
146
151
  if (options.stream) {
147
- return streamGenerationResult(() =>
148
- runGenerateSpeech(options),
152
+ return streamGenerationResult(
153
+ // Only `runId` is taken from the resolved wire identity. `threadId` stays
154
+ // the CALLER's: `streamGenerationResult` mints one for the RUN_* chunks
155
+ // when none was passed, and spreading that over the options would hand
156
+ // middleware a thread id known to nobody, which persistence would then
157
+ // file the run under. Matches `generateVideo`.
158
+ (resolved) => runGenerateSpeech({ ...options, runId: resolved.runId }),
159
+ options,
149
160
  ) as TTSActivityResult<TStream>
150
161
  }
151
162
  return runGenerateSpeech(options) as TTSActivityResult<TStream>
@@ -162,6 +173,8 @@ async function runGenerateSpeech<
162
173
  stream: _stream,
163
174
  debug: _debug,
164
175
  middleware,
176
+ threadId,
177
+ runId,
165
178
  ...rest
166
179
  } = options
167
180
  const model = adapter.model
@@ -179,6 +192,14 @@ async function runGenerateSpeech<
179
192
  provider: adapter.name,
180
193
  model,
181
194
  modelOptions: rest.modelOptions,
195
+ artifactInputs: {
196
+ text: rest.text,
197
+ voice: rest.voice,
198
+ format: rest.format,
199
+ speed: rest.speed,
200
+ },
201
+ threadId,
202
+ runId,
182
203
  createId,
183
204
  })
184
205
 
@@ -202,7 +223,8 @@ async function runGenerateSpeech<
202
223
  })
203
224
 
204
225
  try {
205
- const result = await adapter.generateSpeech({ ...rest, model, logger })
226
+ const rawResult = await adapter.generateSpeech({ ...rest, model, logger })
227
+ const result = await applyGenerationResultTransforms(mwCtx, rawResult)
206
228
  const duration = Date.now() - startTime
207
229
 
208
230
  aiEventClient.emit('speech:request:completed', {
@@ -9,6 +9,7 @@ import { aiEventClient } from '@tanstack/ai-event-client'
9
9
  import { streamGenerationResult } from '../stream-generation-result.js'
10
10
  import { resolveDebugOption } from '../../logger/resolve'
11
11
  import {
12
+ applyGenerationResultTransforms,
12
13
  createGenerationContext,
13
14
  runGenerationError,
14
15
  runGenerationFinish,
@@ -94,6 +95,10 @@ export interface TranscriptionActivityOptions<
94
95
  * `GenerationMiddleware` contract for a custom backend.
95
96
  */
96
97
  middleware?: Array<GenerationMiddleware>
98
+ /** Stable conversation/thread id for correlating this run when persisted. */
99
+ threadId?: string
100
+ /** Stable run id for correlating this run when persisted. */
101
+ runId?: string
97
102
  }
98
103
 
99
104
  // ===========================
@@ -171,8 +176,15 @@ export function generateTranscription<
171
176
  options: TranscriptionActivityOptions<TAdapter, TStream>,
172
177
  ): TranscriptionActivityResult<TStream> {
173
178
  if (options.stream) {
174
- return streamGenerationResult(() =>
175
- runGenerateTranscription(options),
179
+ return streamGenerationResult(
180
+ // Only `runId` is taken from the resolved wire identity. `threadId` stays
181
+ // the CALLER's: `streamGenerationResult` mints one for the RUN_* chunks
182
+ // when none was passed, and spreading that over the options would hand
183
+ // middleware a thread id known to nobody, which persistence would then
184
+ // file the run under. Matches `generateVideo`.
185
+ (resolved) =>
186
+ runGenerateTranscription({ ...options, runId: resolved.runId }),
187
+ options,
176
188
  ) as TranscriptionActivityResult<TStream>
177
189
  }
178
190
 
@@ -197,6 +209,8 @@ async function runGenerateTranscription<
197
209
  stream: _stream,
198
210
  debug: _debug,
199
211
  middleware,
212
+ threadId,
213
+ runId,
200
214
  ...rest
201
215
  } = options
202
216
  const model = adapter.model
@@ -214,6 +228,14 @@ async function runGenerateTranscription<
214
228
  provider: adapter.name,
215
229
  model,
216
230
  modelOptions: rest.modelOptions,
231
+ artifactInputs: {
232
+ audio: rest.audio,
233
+ language: rest.language,
234
+ prompt: rest.prompt,
235
+ responseFormat: rest.responseFormat,
236
+ },
237
+ threadId,
238
+ runId,
217
239
  createId,
218
240
  })
219
241
 
@@ -236,7 +258,8 @@ async function runGenerateTranscription<
236
258
  })
237
259
 
238
260
  try {
239
- const result = await adapter.transcribe({ ...rest, model, logger })
261
+ const rawResult = await adapter.transcribe({ ...rest, model, logger })
262
+ const result = await applyGenerationResultTransforms(mwCtx, rawResult)
240
263
  const duration = Date.now() - startTime
241
264
 
242
265
  aiEventClient.emit('transcription:request:completed', {