@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
@@ -0,0 +1,183 @@
1
+ // Dependency-free SHA-256 (FIPS 180-4). Sync and isomorphic (Node + browser)
2
+ // so interrupt hashing needs no crypto library. Users can replace the whole
3
+ // algorithm through the `interrupts.hash` option; this is only the default.
4
+ // ponytail: bundled ~60-line hash, swap via interrupts.hash if you need more.
5
+ const SHA256_K = new Uint32Array([
6
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
7
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
8
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
9
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
10
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
11
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
12
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
13
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
14
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
15
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
16
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
17
+ ])
18
+
19
+ function rotr(x: number, n: number): number {
20
+ return (x >>> n) | (x << (32 - n))
21
+ }
22
+
23
+ function sha256Hex(input: string): string {
24
+ const msg = new TextEncoder().encode(input)
25
+
26
+ const bitLen = msg.length * 8
27
+ const withOne = msg.length + 1
28
+ const total = withOne + ((56 - (withOne % 64) + 64) % 64) + 8
29
+ const bytes = new Uint8Array(total)
30
+ bytes.set(msg)
31
+ bytes[msg.length] = 0x80
32
+ const view = new DataView(bytes.buffer)
33
+ view.setUint32(total - 8, Math.floor(bitLen / 0x100000000))
34
+ view.setUint32(total - 4, bitLen >>> 0)
35
+
36
+ let h0 = 0x6a09e667
37
+ let h1 = 0xbb67ae85
38
+ let h2 = 0x3c6ef372
39
+ let h3 = 0xa54ff53a
40
+ let h4 = 0x510e527f
41
+ let h5 = 0x9b05688c
42
+ let h6 = 0x1f83d9ab
43
+ let h7 = 0x5be0cd19
44
+
45
+ const w = new Uint32Array(64)
46
+ for (let offset = 0; offset < total; offset += 64) {
47
+ for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4)
48
+ for (let i = 16; i < 64; i++) {
49
+ const x15 = w[i - 15] ?? 0
50
+ const x2 = w[i - 2] ?? 0
51
+ const s0 = rotr(x15, 7) ^ rotr(x15, 18) ^ (x15 >>> 3)
52
+ const s1 = rotr(x2, 17) ^ rotr(x2, 19) ^ (x2 >>> 10)
53
+ w[i] = ((w[i - 16] ?? 0) + s0 + (w[i - 7] ?? 0) + s1) >>> 0
54
+ }
55
+
56
+ let a = h0
57
+ let b = h1
58
+ let c = h2
59
+ let d = h3
60
+ let e = h4
61
+ let f = h5
62
+ let g = h6
63
+ let hh = h7
64
+ for (let i = 0; i < 64; i++) {
65
+ const bigS1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)
66
+ const ch = (e & f) ^ (~e & g)
67
+ const t1 = (hh + bigS1 + ch + (SHA256_K[i] ?? 0) + (w[i] ?? 0)) >>> 0
68
+ const bigS0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)
69
+ const maj = (a & b) ^ (a & c) ^ (b & c)
70
+ const t2 = (bigS0 + maj) >>> 0
71
+ hh = g
72
+ g = f
73
+ f = e
74
+ e = (d + t1) >>> 0
75
+ d = c
76
+ c = b
77
+ b = a
78
+ a = (t1 + t2) >>> 0
79
+ }
80
+ h0 = (h0 + a) >>> 0
81
+ h1 = (h1 + b) >>> 0
82
+ h2 = (h2 + c) >>> 0
83
+ h3 = (h3 + d) >>> 0
84
+ h4 = (h4 + e) >>> 0
85
+ h5 = (h5 + f) >>> 0
86
+ h6 = (h6 + g) >>> 0
87
+ h7 = (h7 + hh) >>> 0
88
+ }
89
+
90
+ const hex = (n: number): string => (n >>> 0).toString(16).padStart(8, '0')
91
+ return (
92
+ hex(h0) +
93
+ hex(h1) +
94
+ hex(h2) +
95
+ hex(h3) +
96
+ hex(h4) +
97
+ hex(h5) +
98
+ hex(h6) +
99
+ hex(h7)
100
+ )
101
+ }
102
+
103
+ /**
104
+ * A hash function for interrupt bindings and resolution fingerprints. Receives
105
+ * canonical JSON text and returns an opaque string. Must be deterministic; the
106
+ * server compares hashes it computed against the ones in a binding, so the same
107
+ * function has to run wherever a given binding is produced and checked.
108
+ */
109
+ export type InterruptHash = (canonicalJson: string) => string
110
+
111
+ /** The built-in default: SHA-256, prefixed so the algorithm is self-describing. */
112
+ export function defaultInterruptHash(canonicalJson: string): string {
113
+ return `sha256:${sha256Hex(canonicalJson)}`
114
+ }
115
+
116
+ function canonical(value: unknown, active: WeakSet<object>): string {
117
+ if (value === null) return 'null'
118
+ if (typeof value === 'string' || typeof value === 'boolean') {
119
+ return JSON.stringify(value)
120
+ }
121
+ if (typeof value === 'number' && Number.isFinite(value)) {
122
+ return JSON.stringify(value)
123
+ }
124
+ if (typeof value !== 'object') {
125
+ throw new TypeError('Interrupt values must be JSON-compatible.')
126
+ }
127
+ if (active.has(value)) {
128
+ throw new TypeError('Interrupt values must not cycle.')
129
+ }
130
+ if (
131
+ !Array.isArray(value) &&
132
+ Object.getPrototypeOf(value) !== Object.prototype &&
133
+ Object.getPrototypeOf(value) !== null
134
+ ) {
135
+ throw new TypeError('Interrupt values must use plain JSON objects.')
136
+ }
137
+
138
+ active.add(value)
139
+ let encoded: string
140
+ if (Array.isArray(value)) {
141
+ const items: Array<string> = []
142
+ for (let index = 0; index < value.length; index++) {
143
+ items.push(canonical(value[index], active))
144
+ }
145
+ encoded = `[${items.join(',')}]`
146
+ } else {
147
+ const record = value as Record<string, unknown>
148
+ encoded = `{${Object.keys(record)
149
+ .sort()
150
+ .map((key) => `${JSON.stringify(key)}:${canonical(record[key], active)}`)
151
+ .join(',')}}`
152
+ }
153
+ active.delete(value)
154
+ return encoded
155
+ }
156
+
157
+ export function canonicalInterruptJson(value: unknown): string {
158
+ return canonical(value, new WeakSet<object>())
159
+ }
160
+
161
+ export function digestInterruptJson(
162
+ canonicalJson: string,
163
+ hash: InterruptHash = defaultInterruptHash,
164
+ ): string {
165
+ if (typeof canonicalJson !== 'string') {
166
+ throw new TypeError('Interrupt digests require canonical JSON text.')
167
+ }
168
+ return hash(canonicalJson)
169
+ }
170
+
171
+ function freezeTree(value: unknown): void {
172
+ if (value === null || typeof value !== 'object' || Object.isFrozen(value)) {
173
+ return
174
+ }
175
+ Object.values(value).forEach(freezeTree)
176
+ Object.freeze(value)
177
+ }
178
+
179
+ export function cloneAndDeepFreezeJson<T>(value: T): T {
180
+ const clone: T = JSON.parse(canonicalInterruptJson(value))
181
+ freezeTree(clone)
182
+ return clone
183
+ }
@@ -0,0 +1,146 @@
1
+ import {
2
+ canonicalInterruptJson,
3
+ cloneAndDeepFreezeJson,
4
+ digestInterruptJson,
5
+ } from './interrupt-serialization'
6
+ import type { RunAgentResumeItem } from './types'
7
+
8
+ export interface InterruptCorrelation {
9
+ threadId: string
10
+ interruptedRunId: string
11
+ generation: number
12
+ submissionId?: string
13
+ continuationRunId?: string
14
+ }
15
+
16
+ export type ItemInterruptErrorCode =
17
+ | 'invalid-payload'
18
+ | 'invalid-edited-args'
19
+ | 'invalid-tool-output'
20
+ | 'invalid-response-schema'
21
+ | 'unknown-interrupt'
22
+ | 'expired'
23
+ | 'stale'
24
+ | 'conflict'
25
+ | 'legacy-unsupported'
26
+
27
+ export type BatchInterruptErrorCode =
28
+ | 'incomplete-batch'
29
+ | 'item-validation-failed'
30
+ | 'unsupported-bulk-operation'
31
+ | 'async-resolver'
32
+ | 'inactive-transaction'
33
+ | 'mixed-provenance'
34
+ | 'transport'
35
+ | 'server'
36
+ | 'protocol'
37
+ | 'invalid-response-schema'
38
+ | 'expired'
39
+ | 'stale'
40
+ | 'conflict'
41
+ | 'legacy-submit-failed'
42
+
43
+ export interface ItemInterruptError extends InterruptCorrelation {
44
+ scope: 'item'
45
+ interruptId: string
46
+ code: ItemInterruptErrorCode
47
+ message: string
48
+ path?: ReadonlyArray<string | number>
49
+ source: 'client' | 'server'
50
+ retryable: boolean
51
+ }
52
+
53
+ export interface BatchInterruptError extends InterruptCorrelation {
54
+ scope: 'batch'
55
+ code: BatchInterruptErrorCode
56
+ message: string
57
+ source: 'client' | 'server' | 'transport'
58
+ retryable: boolean
59
+ interruptIds: ReadonlyArray<string>
60
+ }
61
+
62
+ export type InterruptSubmissionError = ItemInterruptError | BatchInterruptError
63
+
64
+ /**
65
+ * Wire version of {@link InterruptBinding}.
66
+ *
67
+ * The binding is the only part of an AG-UI `Interrupt` that this package
68
+ * claims — it rides in `metadata` under
69
+ * {@link INTERRUPT_BINDING_METADATA_KEY} and tells the resume path how to
70
+ * correlate an answer back to a paused run. Producers stamp `v`; readers
71
+ * reject any version they don't understand rather than duck-typing the fields.
72
+ *
73
+ * That matters because an AG-UI `Interrupt` is a shared envelope. Another
74
+ * producer — a workflow engine projecting a durable approval, a third-party
75
+ * agent — can legitimately put its own binding in the same envelope. Versioning
76
+ * makes "not mine" a clean rejection instead of a partial match that resumes
77
+ * against the wrong owner.
78
+ */
79
+ export const INTERRUPT_BINDING_VERSION = 1 as const
80
+
81
+ interface InterruptBindingBase {
82
+ /** @see INTERRUPT_BINDING_VERSION */
83
+ v: typeof INTERRUPT_BINDING_VERSION
84
+ interruptId: string
85
+ interruptedRunId: string
86
+ generation: number
87
+ responseSchemaHash: string
88
+ expiresAt?: string
89
+ }
90
+
91
+ export type InterruptBinding =
92
+ | (InterruptBindingBase & {
93
+ kind: 'tool-approval'
94
+ toolName: string
95
+ toolCallId: string
96
+ originalArgs: unknown
97
+ inputSchemaHash: string
98
+ approvalSchemaHash: string
99
+ })
100
+ | (InterruptBindingBase & {
101
+ kind: 'client-tool-execution'
102
+ toolName: string
103
+ toolCallId: string
104
+ outputSchemaHash: string
105
+ })
106
+ | (InterruptBindingBase & {
107
+ kind: 'generic'
108
+ })
109
+
110
+ export type UnopenedInterruptBinding = InterruptBinding extends infer TBinding
111
+ ? TBinding extends InterruptBinding
112
+ ? Omit<TBinding, 'interruptedRunId' | 'generation'>
113
+ : never
114
+ : never
115
+
116
+ export type ToolApprovalResolution =
117
+ | boolean
118
+ | {
119
+ approved: true
120
+ editedArgs?: unknown
121
+ payload?: unknown
122
+ }
123
+ | {
124
+ approved: false
125
+ payload?: unknown
126
+ editedArgs?: never
127
+ }
128
+
129
+ export function canonicalizeInterruptResolutions(
130
+ resolutions: ReadonlyArray<RunAgentResumeItem>,
131
+ ): {
132
+ resolutions: ReadonlyArray<RunAgentResumeItem>
133
+ canonicalResolutions: string
134
+ fingerprint: string
135
+ } {
136
+ const sorted = [...resolutions].sort((left, right) =>
137
+ left.interruptId.localeCompare(right.interruptId),
138
+ )
139
+ const frozen = cloneAndDeepFreezeJson(sorted)
140
+ const canonicalResolutions = canonicalInterruptJson(frozen)
141
+ return Object.freeze({
142
+ resolutions: frozen,
143
+ canonicalResolutions,
144
+ fingerprint: digestInterruptJson(canonicalResolutions),
145
+ })
146
+ }
package/src/locks.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Distributed-mutex primitive — coordination, not state persistence.
3
+ *
4
+ * Its own subpath (`@tanstack/ai/locks`) so it stays out of the main barrel and
5
+ * consumers opt in explicitly. Provide a store with `withLocks`; downstream
6
+ * middleware (e.g. `@tanstack/ai-sandbox`'s `ensure`) reads it via `getLocks` /
7
+ * `LocksCapability`. Import from here, not from `@tanstack/ai-persistence`.
8
+ */
9
+ export {
10
+ LocksCapability,
11
+ getLocks,
12
+ provideLocks,
13
+ InMemoryLockStore,
14
+ withLocks,
15
+ defineLock,
16
+ } from './activities/chat/middleware/index'
17
+ export type { LockStore } from './activities/chat/middleware/index'
@@ -29,7 +29,7 @@ export interface Logger {
29
29
  */
30
30
  export interface DebugCategories {
31
31
  /**
32
- * Raw chunks/frames received from a provider SDK (OpenAI, Anthropic, Gemini, Ollama, Grok, Groq, OpenRouter, fal, ElevenLabs). Emitted inside every streaming adapter's chunk loop.
32
+ * Raw chunks/frames received from a provider SDK (OpenAI, Anthropic, Gemini, Ollama, Grok, Groq, OpenRouter, fal, ElevenLabs, BytePlus). Emitted inside every streaming adapter's chunk loop.
33
33
  */
34
34
  provider?: boolean
35
35
  /**
@@ -83,6 +83,7 @@ const OPERATION_NAME: Record<GenerationActivity, string> = {
83
83
  audio: 'audio_generation',
84
84
  tts: 'text_to_speech',
85
85
  transcription: 'transcription',
86
+ summarize: 'summarize',
86
87
  }
87
88
 
88
89
  export interface OtelMiddlewareOptions {
@@ -19,15 +19,11 @@ export type * from './types'
19
19
  * import { realtimeToken } from '@tanstack/ai'
20
20
  * import { openaiRealtimeToken } from '@tanstack/ai-openai'
21
21
  *
22
- * // Server function (TanStack Start example)
23
- * export const getRealtimeToken = createServerFn()
24
- * .handler(async () => {
25
- * return realtimeToken({
26
- * adapter: openaiRealtimeToken({
27
- * model: 'gpt-realtime',
28
- * }),
29
- * })
30
- * })
22
+ * // On the server (e.g. inside a server route or framework server
23
+ * // function), mint an ephemeral token for the client:
24
+ * const token = await realtimeToken({
25
+ * adapter: openaiRealtimeToken({ model: 'gpt-realtime' }),
26
+ * })
31
27
  * ```
32
28
  */
33
29
  export async function realtimeToken(
package/src/scope.ts ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Shared identity/isolation scope for the TanStack AI subsystems that persist
3
+ * or recall per-conversation data — `@tanstack/ai-persistence` (keyed CRUD over
4
+ * threads, runs, interrupts) and `@tanstack/ai-memory` (ranked recall/save).
5
+ *
6
+ * Both subsystems answer the same underlying question — "whose data is this?" —
7
+ * so they share ONE identity vocabulary defined here rather than each inventing
8
+ * its own. `threadId` is the single conversation key across the codebase (it is
9
+ * `ChatMiddlewareContext.threadId`, and `conversationId` is deprecated in favor
10
+ * of it); a subsystem must never introduce a second name (`sessionId`,
11
+ * `conversationId`, …) for the same concept.
12
+ *
13
+ * ## Security
14
+ *
15
+ * A `Scope` is an isolation boundary. Derive every field server-side from
16
+ * trusted, validated session state — **never** from client input. `threadId`
17
+ * in particular resolves from a client-supplied value on the request, so a
18
+ * subsystem that reads/writes user-owned data (memory, per-user metadata) must
19
+ * pair it with a server-trusted `userId`/`tenantId` and must not treat a bare
20
+ * client `threadId` as sufficient isolation: thread ids are guessable, so on
21
+ * their own they let one caller read another's data.
22
+ */
23
+ export interface Scope {
24
+ /**
25
+ * The conversation this data belongs to. Required — the minimal isolation
26
+ * key both subsystems already center on. Same concept as
27
+ * `ChatMiddlewareContext.threadId`.
28
+ */
29
+ threadId: string
30
+ /**
31
+ * Durable end-user identity, for cross-thread recall and per-user isolation.
32
+ * Optional, but required in practice for any multi-user deployment — a
33
+ * `threadId` alone is not an authorization boundary (see Security above).
34
+ */
35
+ userId?: string
36
+ /**
37
+ * Tenant/organization boundary for multi-tenant deployments. When present,
38
+ * every read and write must be confined to it.
39
+ */
40
+ tenantId?: string
41
+ /**
42
+ * Logical partition within a tenant/user (e.g. separating distinct memory
43
+ * banks or persistence namespaces). Reserved — no subsystem keys on it yet;
44
+ * adapters that don't understand it must ignore it rather than error.
45
+ */
46
+ namespace?: string
47
+ }