@superblocksteam/vite-plugin-file-sync 2.0.59-next.2 → 2.0.59-next.3

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 (277) hide show
  1. package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
  2. package/dist/ai-service/agent/prompts/build-base-system-prompt.js +10 -1
  3. package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
  4. package/dist/ai-service/agent/subagents/apis/examples.d.ts.map +1 -1
  5. package/dist/ai-service/agent/subagents/apis/examples.js +137 -10
  6. package/dist/ai-service/agent/subagents/apis/examples.js.map +1 -1
  7. package/dist/ai-service/agent/subagents/apis/static-analysis.d.ts.map +1 -1
  8. package/dist/ai-service/agent/subagents/apis/static-analysis.js +14 -7
  9. package/dist/ai-service/agent/subagents/apis/static-analysis.js.map +1 -1
  10. package/dist/ai-service/agent/tool-message-utils.d.ts.map +1 -1
  11. package/dist/ai-service/agent/tool-message-utils.js +6 -2
  12. package/dist/ai-service/agent/tool-message-utils.js.map +1 -1
  13. package/dist/ai-service/agent/tools/apis/analysis.d.ts +9 -0
  14. package/dist/ai-service/agent/tools/apis/analysis.d.ts.map +1 -0
  15. package/dist/ai-service/agent/tools/apis/analysis.js +357 -0
  16. package/dist/ai-service/agent/tools/apis/analysis.js.map +1 -0
  17. package/dist/ai-service/agent/{subagents → tools}/apis/api-executor.d.ts +35 -10
  18. package/dist/ai-service/agent/tools/apis/api-executor.d.ts.map +1 -0
  19. package/dist/ai-service/agent/{subagents → tools}/apis/api-executor.js +179 -94
  20. package/dist/ai-service/agent/tools/apis/api-executor.js.map +1 -0
  21. package/dist/ai-service/agent/tools/apis/api-source.d.ts +19 -0
  22. package/dist/ai-service/agent/tools/apis/api-source.d.ts.map +1 -0
  23. package/dist/ai-service/agent/tools/apis/api-source.js +73 -0
  24. package/dist/ai-service/agent/tools/apis/api-source.js.map +1 -0
  25. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.d.ts +51 -0
  26. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.d.ts.map +1 -0
  27. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js +510 -0
  28. package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js.map +1 -0
  29. package/dist/ai-service/agent/tools/apis/build-api-artifact.d.ts +32 -0
  30. package/dist/ai-service/agent/tools/apis/build-api-artifact.d.ts.map +1 -0
  31. package/dist/ai-service/agent/tools/apis/build-api-artifact.js +313 -0
  32. package/dist/ai-service/agent/tools/apis/build-api-artifact.js.map +1 -0
  33. package/dist/ai-service/agent/tools/apis/build-api.d.ts +1 -10
  34. package/dist/ai-service/agent/tools/apis/build-api.d.ts.map +1 -1
  35. package/dist/ai-service/agent/tools/apis/build-api.js +26 -238
  36. package/dist/ai-service/agent/tools/apis/build-api.js.map +1 -1
  37. package/dist/ai-service/agent/tools/apis/get-api-docs.d.ts +11 -0
  38. package/dist/ai-service/agent/tools/apis/get-api-docs.d.ts.map +1 -0
  39. package/dist/ai-service/agent/tools/apis/get-api-docs.js +1809 -0
  40. package/dist/ai-service/agent/tools/apis/get-api-docs.js.map +1 -0
  41. package/dist/ai-service/agent/tools/apis/integration-types.d.ts +37 -0
  42. package/dist/ai-service/agent/tools/apis/integration-types.d.ts.map +1 -0
  43. package/dist/ai-service/agent/tools/apis/integration-types.js +697 -0
  44. package/dist/ai-service/agent/tools/apis/integration-types.js.map +1 -0
  45. package/dist/ai-service/agent/tools/apis/test-api.d.ts +25 -0
  46. package/dist/ai-service/agent/tools/apis/test-api.d.ts.map +1 -0
  47. package/dist/ai-service/agent/tools/apis/test-api.js +194 -0
  48. package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -0
  49. package/dist/ai-service/agent/tools/apis/write-api.d.ts +11 -0
  50. package/dist/ai-service/agent/tools/apis/write-api.d.ts.map +1 -0
  51. package/dist/ai-service/agent/tools/apis/write-api.js +41 -0
  52. package/dist/ai-service/agent/tools/apis/write-api.js.map +1 -0
  53. package/dist/ai-service/agent/tools/build-read-files.js +2 -2
  54. package/dist/ai-service/agent/tools/build-read-files.js.map +1 -1
  55. package/dist/ai-service/agent/tools.d.ts +2 -5
  56. package/dist/ai-service/agent/tools.d.ts.map +1 -1
  57. package/dist/ai-service/agent/tools.js +51 -22
  58. package/dist/ai-service/agent/tools.js.map +1 -1
  59. package/dist/ai-service/agent/tools2/access-control.d.ts +1 -0
  60. package/dist/ai-service/agent/tools2/access-control.d.ts.map +1 -1
  61. package/dist/ai-service/agent/tools2/access-control.js +15 -13
  62. package/dist/ai-service/agent/tools2/access-control.js.map +1 -1
  63. package/dist/ai-service/agent/tools2/registry.d.ts +2 -1
  64. package/dist/ai-service/agent/tools2/registry.d.ts.map +1 -1
  65. package/dist/ai-service/agent/tools2/registry.js +4 -3
  66. package/dist/ai-service/agent/tools2/registry.js.map +1 -1
  67. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts +2 -1
  68. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
  69. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +103 -88
  70. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
  71. package/dist/ai-service/agent/tools2/tools/grep-metadata.d.ts.map +1 -1
  72. package/dist/ai-service/agent/tools2/tools/grep-metadata.js +25 -4
  73. package/dist/ai-service/agent/tools2/tools/grep-metadata.js.map +1 -1
  74. package/dist/ai-service/agent/tools2/types.d.ts +1 -1
  75. package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
  76. package/dist/ai-service/agent/tools2/types.js.map +1 -1
  77. package/dist/ai-service/agent/tools2/utils.d.ts.map +1 -1
  78. package/dist/ai-service/agent/tools2/utils.js +4 -1
  79. package/dist/ai-service/agent/tools2/utils.js.map +1 -1
  80. package/dist/ai-service/agent/utils.d.ts +1 -3
  81. package/dist/ai-service/agent/utils.d.ts.map +1 -1
  82. package/dist/ai-service/agent/utils.js +44 -4
  83. package/dist/ai-service/agent/utils.js.map +1 -1
  84. package/dist/ai-service/app-interface/shell.d.ts +5 -0
  85. package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
  86. package/dist/ai-service/app-interface/shell.js +17 -2
  87. package/dist/ai-service/app-interface/shell.js.map +1 -1
  88. package/dist/ai-service/chat/chat-session-store.d.ts +7 -0
  89. package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
  90. package/dist/ai-service/chat/chat-session-store.js +26 -0
  91. package/dist/ai-service/chat/chat-session-store.js.map +1 -1
  92. package/dist/ai-service/const.d.ts +2 -1
  93. package/dist/ai-service/const.d.ts.map +1 -1
  94. package/dist/ai-service/const.js +1 -0
  95. package/dist/ai-service/const.js.map +1 -1
  96. package/dist/ai-service/index.d.ts +5 -1
  97. package/dist/ai-service/index.d.ts.map +1 -1
  98. package/dist/ai-service/index.js +55 -7
  99. package/dist/ai-service/index.js.map +1 -1
  100. package/dist/ai-service/integrations/metadata-storage/index.d.ts +10 -0
  101. package/dist/ai-service/integrations/metadata-storage/index.d.ts.map +1 -1
  102. package/dist/ai-service/integrations/metadata-storage/local.d.ts +4 -2
  103. package/dist/ai-service/integrations/metadata-storage/local.d.ts.map +1 -1
  104. package/dist/ai-service/integrations/metadata-storage/local.js +35 -9
  105. package/dist/ai-service/integrations/metadata-storage/local.js.map +1 -1
  106. package/dist/ai-service/integrations/store.d.ts +27 -2
  107. package/dist/ai-service/integrations/store.d.ts.map +1 -1
  108. package/dist/ai-service/integrations/store.js +129 -62
  109. package/dist/ai-service/integrations/store.js.map +1 -1
  110. package/dist/ai-service/llm/client.d.ts +123 -0
  111. package/dist/ai-service/llm/client.d.ts.map +1 -0
  112. package/dist/ai-service/llm/client.js +168 -0
  113. package/dist/ai-service/llm/client.js.map +1 -0
  114. package/dist/ai-service/llm/context/context-handle.d.ts +4 -4
  115. package/dist/ai-service/llm/context/context-handle.d.ts.map +1 -1
  116. package/dist/ai-service/llm/context/context-handle.js +7 -3
  117. package/dist/ai-service/llm/context/context-handle.js.map +1 -1
  118. package/dist/ai-service/llm/context/context.d.ts +28 -0
  119. package/dist/ai-service/llm/context/context.d.ts.map +1 -1
  120. package/dist/ai-service/llm/context/context.js +117 -0
  121. package/dist/ai-service/llm/context/context.js.map +1 -1
  122. package/dist/ai-service/llm/context/manager.d.ts +22 -2
  123. package/dist/ai-service/llm/context/manager.d.ts.map +1 -1
  124. package/dist/ai-service/llm/context/manager.js +86 -13
  125. package/dist/ai-service/llm/context/manager.js.map +1 -1
  126. package/dist/ai-service/llm/context/storage/index.d.ts +1 -0
  127. package/dist/ai-service/llm/context/storage/index.d.ts.map +1 -1
  128. package/dist/ai-service/llm/context/storage/local.d.ts +1 -0
  129. package/dist/ai-service/llm/context/storage/local.d.ts.map +1 -1
  130. package/dist/ai-service/llm/context/storage/local.js +13 -1
  131. package/dist/ai-service/llm/context/storage/local.js.map +1 -1
  132. package/dist/ai-service/llm/error.d.ts +14 -4
  133. package/dist/ai-service/llm/error.d.ts.map +1 -1
  134. package/dist/ai-service/llm/error.js +49 -4
  135. package/dist/ai-service/llm/error.js.map +1 -1
  136. package/dist/ai-service/llm/interaction/adapters/vercel.d.ts +67 -0
  137. package/dist/ai-service/llm/interaction/adapters/vercel.d.ts.map +1 -0
  138. package/dist/ai-service/llm/interaction/adapters/vercel.js +110 -0
  139. package/dist/ai-service/llm/interaction/adapters/vercel.js.map +1 -0
  140. package/dist/ai-service/llm/interaction/compose.d.ts +71 -0
  141. package/dist/ai-service/llm/interaction/compose.d.ts.map +1 -0
  142. package/dist/ai-service/llm/interaction/compose.js +88 -0
  143. package/dist/ai-service/llm/interaction/compose.js.map +1 -0
  144. package/dist/ai-service/llm/interaction/index.d.ts +68 -0
  145. package/dist/ai-service/llm/interaction/index.d.ts.map +1 -0
  146. package/dist/ai-service/llm/interaction/index.js +70 -0
  147. package/dist/ai-service/llm/interaction/index.js.map +1 -0
  148. package/dist/ai-service/llm/interaction/middleware.d.ts +52 -0
  149. package/dist/ai-service/llm/interaction/middleware.d.ts.map +1 -0
  150. package/dist/ai-service/llm/interaction/middleware.js +17 -0
  151. package/dist/ai-service/llm/interaction/middleware.js.map +1 -0
  152. package/dist/ai-service/llm/interaction/middlewares/llmobs.d.ts +45 -0
  153. package/dist/ai-service/llm/interaction/middlewares/llmobs.d.ts.map +1 -0
  154. package/dist/ai-service/llm/interaction/middlewares/llmobs.js +85 -0
  155. package/dist/ai-service/llm/interaction/middlewares/llmobs.js.map +1 -0
  156. package/dist/ai-service/llm/interaction/middlewares/logging.d.ts +88 -0
  157. package/dist/ai-service/llm/interaction/middlewares/logging.d.ts.map +1 -0
  158. package/dist/ai-service/llm/interaction/middlewares/logging.js +238 -0
  159. package/dist/ai-service/llm/interaction/middlewares/logging.js.map +1 -0
  160. package/dist/ai-service/llm/interaction/middlewares/profiler.d.ts +47 -0
  161. package/dist/ai-service/llm/interaction/middlewares/profiler.d.ts.map +1 -0
  162. package/dist/ai-service/llm/interaction/middlewares/profiler.js +183 -0
  163. package/dist/ai-service/llm/interaction/middlewares/profiler.js.map +1 -0
  164. package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts +121 -0
  165. package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts.map +1 -0
  166. package/dist/ai-service/llm/interaction/middlewares/stream-retry.js +291 -0
  167. package/dist/ai-service/llm/interaction/middlewares/stream-retry.js.map +1 -0
  168. package/dist/ai-service/llm/interaction/provider.d.ts +158 -0
  169. package/dist/ai-service/llm/interaction/provider.d.ts.map +1 -0
  170. package/dist/ai-service/llm/interaction/provider.js +15 -0
  171. package/dist/ai-service/llm/interaction/provider.js.map +1 -0
  172. package/dist/ai-service/llm/interaction/stream-lifecycle.d.ts +48 -0
  173. package/dist/ai-service/llm/interaction/stream-lifecycle.d.ts.map +1 -0
  174. package/dist/ai-service/llm/interaction/stream-lifecycle.js +131 -0
  175. package/dist/ai-service/llm/interaction/stream-lifecycle.js.map +1 -0
  176. package/dist/ai-service/llm/provider.d.ts +1 -2
  177. package/dist/ai-service/llm/provider.d.ts.map +1 -1
  178. package/dist/ai-service/llm/provider.js +3 -6
  179. package/dist/ai-service/llm/provider.js.map +1 -1
  180. package/dist/ai-service/llmobs/helpers.d.ts +7 -8
  181. package/dist/ai-service/llmobs/helpers.d.ts.map +1 -1
  182. package/dist/ai-service/llmobs/helpers.js +8 -48
  183. package/dist/ai-service/llmobs/helpers.js.map +1 -1
  184. package/dist/ai-service/llmobs/middleware/stream-text.d.ts +19 -21
  185. package/dist/ai-service/llmobs/middleware/stream-text.d.ts.map +1 -1
  186. package/dist/ai-service/llmobs/middleware/stream-text.js +98 -106
  187. package/dist/ai-service/llmobs/middleware/stream-text.js.map +1 -1
  188. package/dist/ai-service/llmobs/types.d.ts +14 -1
  189. package/dist/ai-service/llmobs/types.d.ts.map +1 -1
  190. package/dist/ai-service/state-machine/clark-fsm.d.ts +75 -5
  191. package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
  192. package/dist/ai-service/state-machine/clark-fsm.js +100 -0
  193. package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
  194. package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
  195. package/dist/ai-service/state-machine/handlers/agent-planning.js +4 -0
  196. package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
  197. package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
  198. package/dist/ai-service/state-machine/handlers/llm-generating.js +91 -456
  199. package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
  200. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js +1 -1
  201. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js.map +1 -1
  202. package/dist/ai-service/state-machine/helpers/peer.d.ts.map +1 -1
  203. package/dist/ai-service/state-machine/helpers/peer.js +15 -0
  204. package/dist/ai-service/state-machine/helpers/peer.js.map +1 -1
  205. package/dist/ai-service/state-machine/mocks.d.ts.map +1 -1
  206. package/dist/ai-service/state-machine/mocks.js +1 -0
  207. package/dist/ai-service/state-machine/mocks.js.map +1 -1
  208. package/dist/ai-service/types.d.ts +30 -0
  209. package/dist/ai-service/types.d.ts.map +1 -1
  210. package/dist/binding-extraction/extract-identifiers.d.ts +14 -0
  211. package/dist/binding-extraction/extract-identifiers.d.ts.map +1 -1
  212. package/dist/binding-extraction/extract-identifiers.js +46 -1
  213. package/dist/binding-extraction/extract-identifiers.js.map +1 -1
  214. package/dist/binding-extraction/js-identifiers.d.ts +14 -0
  215. package/dist/binding-extraction/js-identifiers.d.ts.map +1 -1
  216. package/dist/binding-extraction/js-identifiers.js +168 -0
  217. package/dist/binding-extraction/js-identifiers.js.map +1 -1
  218. package/dist/binding-extraction/python-identifiers.d.ts +5 -0
  219. package/dist/binding-extraction/python-identifiers.d.ts.map +1 -1
  220. package/dist/binding-extraction/python-identifiers.js +76 -7
  221. package/dist/binding-extraction/python-identifiers.js.map +1 -1
  222. package/dist/file-sync-vite-plugin.d.ts.map +1 -1
  223. package/dist/file-sync-vite-plugin.js +73 -3
  224. package/dist/file-sync-vite-plugin.js.map +1 -1
  225. package/dist/file-system-manager.d.ts.map +1 -1
  226. package/dist/file-system-manager.js +6 -4
  227. package/dist/file-system-manager.js.map +1 -1
  228. package/dist/index.d.ts +1 -1
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +1 -1
  231. package/dist/index.js.map +1 -1
  232. package/dist/lock-service/activity-tracker.d.ts +14 -2
  233. package/dist/lock-service/activity-tracker.d.ts.map +1 -1
  234. package/dist/lock-service/activity-tracker.js +43 -6
  235. package/dist/lock-service/activity-tracker.js.map +1 -1
  236. package/dist/lock-service/index.d.ts +13 -2
  237. package/dist/lock-service/index.d.ts.map +1 -1
  238. package/dist/lock-service/index.js +130 -44
  239. package/dist/lock-service/index.js.map +1 -1
  240. package/dist/parsing/jsx.d.ts.map +1 -1
  241. package/dist/parsing/jsx.js +78 -66
  242. package/dist/parsing/jsx.js.map +1 -1
  243. package/dist/socket-manager.js +1 -1
  244. package/dist/socket-manager.js.map +1 -1
  245. package/dist/sync-service/list-dir.d.ts.map +1 -1
  246. package/dist/sync-service/list-dir.js +41 -18
  247. package/dist/sync-service/list-dir.js.map +1 -1
  248. package/dist/vite-plugin-yaml-types.d.ts.map +1 -1
  249. package/dist/vite-plugin-yaml-types.js +2 -4
  250. package/dist/vite-plugin-yaml-types.js.map +1 -1
  251. package/package.json +7 -7
  252. package/dist/ai-service/agent/subagents/apis/api-executor.d.ts.map +0 -1
  253. package/dist/ai-service/agent/subagents/apis/api-executor.js.map +0 -1
  254. package/dist/ai-service/agent/subagents/apis/context.d.ts +0 -12
  255. package/dist/ai-service/agent/subagents/apis/context.d.ts.map +0 -1
  256. package/dist/ai-service/agent/subagents/apis/context.js +0 -18
  257. package/dist/ai-service/agent/subagents/apis/context.js.map +0 -1
  258. package/dist/ai-service/agent/subagents/apis/generate-api-source.d.ts +0 -40
  259. package/dist/ai-service/agent/subagents/apis/generate-api-source.d.ts.map +0 -1
  260. package/dist/ai-service/agent/subagents/apis/generate-api-source.js +0 -516
  261. package/dist/ai-service/agent/subagents/apis/generate-api-source.js.map +0 -1
  262. package/dist/ai-service/agent/subagents/apis/state.d.ts +0 -49
  263. package/dist/ai-service/agent/subagents/apis/state.d.ts.map +0 -1
  264. package/dist/ai-service/agent/subagents/apis/state.js +0 -25
  265. package/dist/ai-service/agent/subagents/apis/state.js.map +0 -1
  266. package/dist/ai-service/agent/subagents/apis/system-prompt.d.ts +0 -3
  267. package/dist/ai-service/agent/subagents/apis/system-prompt.d.ts.map +0 -1
  268. package/dist/ai-service/agent/subagents/apis/system-prompt.js +0 -1704
  269. package/dist/ai-service/agent/subagents/apis/system-prompt.js.map +0 -1
  270. package/dist/ai-service/agent/tools/apis/finalize-api.d.ts +0 -11
  271. package/dist/ai-service/agent/tools/apis/finalize-api.d.ts.map +0 -1
  272. package/dist/ai-service/agent/tools/apis/finalize-api.js +0 -133
  273. package/dist/ai-service/agent/tools/apis/finalize-api.js.map +0 -1
  274. package/dist/ai-service/llm/middleware/retry.d.ts +0 -112
  275. package/dist/ai-service/llm/middleware/retry.d.ts.map +0 -1
  276. package/dist/ai-service/llm/middleware/retry.js +0 -239
  277. package/dist/ai-service/llm/middleware/retry.js.map +0 -1
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Retry middleware for StreamText operations.
3
+ *
4
+ * This middleware wraps entire streamText() calls to handle failures during
5
+ * stream consumption. When a stream fails mid-consumption (e.g., network timeout),
6
+ * this middleware retries the entire streamText call with accumulated messages
7
+ * from successful steps preserved via Context.
8
+ *
9
+ * **Two-phase retry architecture:**
10
+ * 1. **Initial call retry**: Retries errors when calling streamText() to get metadata
11
+ * 2. **Stream consumption retry**: Retries mid-stream errors during stream consumption
12
+ *
13
+ * **Separate retry budgets:**
14
+ * Each phase has its own independent retry budget. For example, with maxRetries: 3:
15
+ * - Phase 1 can retry up to 3 times (4 total attempts to get initial metadata)
16
+ * - Phase 2 can retry up to 3 times (4 total attempts to consume stream)
17
+ * - Maximum total attempts: 4 (phase 1) + 4 (phase 2) = 8
18
+ *
19
+ * This design ensures that failures in one phase don't prevent retries in the other phase.
20
+ *
21
+ * ## Why at StreamText Level?
22
+ *
23
+ * Retrying at the streamText level (vs model.doStream level) ensures:
24
+ * 1. **Fresh Vercel SDK state**: Each retry gets a new eventProcessor with no
25
+ * partial chunk pollution from failed attempts
26
+ * 2. **Correct message sequences**: No orphaned content IDs or invalid message structures
27
+ * 3. **Natural continuation**: Vercel SDK's built-in logic handles multi-step resumption
28
+ *
29
+ * ## How It Works with Context
30
+ *
31
+ * The Context system provides the accumulated messages for retry:
32
+ * - Step 1 succeeds → Context.endStep() records messages
33
+ * - Step 2 fails → No endStep() call, empty step array remains
34
+ * - Retry → Context.getMessages() provides Step 1's messages
35
+ * - Fresh streamText() call receives those messages and continues from Step 2 Context.startStep() is idempotent → reuses empty step array
36
+ *
37
+ * ## Multi-Step Scenarios
38
+ *
39
+ * For multi-step flows (e.g., tool calling):
40
+ * - Step 1 (tool call) succeeds
41
+ * - Step 2 (continuation) fails
42
+ * - Retry receives Step 1's messages (including tool-results)
43
+ * - Vercel SDK sees tool-results and continues to Step 2
44
+ * - Does NOT re-execute Step 1's tools (already have results)
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const middleware = createStreamRetryMiddleware({
49
+ * maxRetries: 3,
50
+ * maxTotalRetryTimeMs: 120000,
51
+ * isRetryable: (error) => isNetworkError(error)
52
+ * });
53
+ *
54
+ * const provider = applyMiddleware(baseProvider, middleware);
55
+ * const result = await provider.streamText({ model, messages, tools });
56
+ * // Automatically retries on stream consumption failures
57
+ * ```
58
+ */
59
+ import { type Logger } from "../../../../util/logger.js";
60
+ import { type BackoffStrategy } from "../../../util/backoff-strategy.js";
61
+ import type { StreamTextMiddleware } from "../middleware.js";
62
+ export interface StreamRetryOptions {
63
+ /**
64
+ * Maximum number of retry attempts per phase (not including the initial attempt).
65
+ * Each phase (initial call, stream consumption) gets its own retry budget.
66
+ * Default: Infinity (unlimited)
67
+ */
68
+ maxRetries?: number;
69
+ /**
70
+ * Custom backoff strategy for calculating retry delays.
71
+ * If not provided, uses ExponentialBackoff.
72
+ */
73
+ backoffStrategy?: BackoffStrategy;
74
+ /**
75
+ * Initial delay in milliseconds before the first retry.
76
+ * Default: 500 (0.5 seconds)
77
+ */
78
+ initialDelayMs?: number;
79
+ /**
80
+ * Maximum delay in milliseconds for exponential backoff.
81
+ * Default: 5000 (5 seconds)
82
+ */
83
+ maxDelayMs?: number;
84
+ /**
85
+ * Backoff multiplier for exponential backoff.
86
+ * Default: 2
87
+ */
88
+ backoffMultiplier?: number;
89
+ /**
90
+ * Maximum total time in milliseconds for all retry attempts.
91
+ * Default: undefined (no time limit)
92
+ */
93
+ maxTotalRetryTimeMs?: number;
94
+ /**
95
+ * Function to determine if an error is retryable.
96
+ * Default: checks for timeout and connection errors
97
+ */
98
+ isRetryable?: (error: unknown) => boolean;
99
+ /**
100
+ * Callback invoked before each retry attempt.
101
+ */
102
+ onRetry?: (error: unknown, attempt: number, delayMs: number, totalRetryTimeMs: number) => void | Promise<void>;
103
+ /**
104
+ * Optional abort signal to cancel retry attempts.
105
+ * When the signal is aborted, no further retries will be attempted.
106
+ */
107
+ abortSignal?: AbortSignal;
108
+ /** Logger instance for retry operations */
109
+ logger?: Logger;
110
+ }
111
+ /**
112
+ * Creates a middleware that retries streamText calls on failure.
113
+ *
114
+ * This middleware wraps the entire streamText operation, catching errors during
115
+ * both the initial call and stream consumption. Retries with accumulated messages from Context.
116
+ *
117
+ * @param options - Configuration for retry behavior
118
+ * @returns A StreamTextMiddleware
119
+ */
120
+ export declare function createStreamRetryMiddleware(options?: StreamRetryOptions): StreamTextMiddleware;
121
+ //# sourceMappingURL=stream-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-retry.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,OAAO,EACL,KAAK,MAAM,EAGZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,mCAAmC,CAAC;AAI3C,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,kBAAuB,GAC/B,oBAAoB,CAgHtB"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Retry middleware for StreamText operations.
3
+ *
4
+ * This middleware wraps entire streamText() calls to handle failures during
5
+ * stream consumption. When a stream fails mid-consumption (e.g., network timeout),
6
+ * this middleware retries the entire streamText call with accumulated messages
7
+ * from successful steps preserved via Context.
8
+ *
9
+ * **Two-phase retry architecture:**
10
+ * 1. **Initial call retry**: Retries errors when calling streamText() to get metadata
11
+ * 2. **Stream consumption retry**: Retries mid-stream errors during stream consumption
12
+ *
13
+ * **Separate retry budgets:**
14
+ * Each phase has its own independent retry budget. For example, with maxRetries: 3:
15
+ * - Phase 1 can retry up to 3 times (4 total attempts to get initial metadata)
16
+ * - Phase 2 can retry up to 3 times (4 total attempts to consume stream)
17
+ * - Maximum total attempts: 4 (phase 1) + 4 (phase 2) = 8
18
+ *
19
+ * This design ensures that failures in one phase don't prevent retries in the other phase.
20
+ *
21
+ * ## Why at StreamText Level?
22
+ *
23
+ * Retrying at the streamText level (vs model.doStream level) ensures:
24
+ * 1. **Fresh Vercel SDK state**: Each retry gets a new eventProcessor with no
25
+ * partial chunk pollution from failed attempts
26
+ * 2. **Correct message sequences**: No orphaned content IDs or invalid message structures
27
+ * 3. **Natural continuation**: Vercel SDK's built-in logic handles multi-step resumption
28
+ *
29
+ * ## How It Works with Context
30
+ *
31
+ * The Context system provides the accumulated messages for retry:
32
+ * - Step 1 succeeds → Context.endStep() records messages
33
+ * - Step 2 fails → No endStep() call, empty step array remains
34
+ * - Retry → Context.getMessages() provides Step 1's messages
35
+ * - Fresh streamText() call receives those messages and continues from Step 2 Context.startStep() is idempotent → reuses empty step array
36
+ *
37
+ * ## Multi-Step Scenarios
38
+ *
39
+ * For multi-step flows (e.g., tool calling):
40
+ * - Step 1 (tool call) succeeds
41
+ * - Step 2 (continuation) fails
42
+ * - Retry receives Step 1's messages (including tool-results)
43
+ * - Vercel SDK sees tool-results and continues to Step 2
44
+ * - Does NOT re-execute Step 1's tools (already have results)
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const middleware = createStreamRetryMiddleware({
49
+ * maxRetries: 3,
50
+ * maxTotalRetryTimeMs: 120000,
51
+ * isRetryable: (error) => isNetworkError(error)
52
+ * });
53
+ *
54
+ * const provider = applyMiddleware(baseProvider, middleware);
55
+ * const result = await provider.streamText({ model, messages, tools });
56
+ * // Automatically retries on stream consumption failures
57
+ * ```
58
+ */
59
+ import { getErrorMeta, getPrefixedLogger, } from "../../../../util/logger.js";
60
+ import { ExponentialBackoff, } from "../../../util/backoff-strategy.js";
61
+ import { LLMProviderError } from "../../error.js";
62
+ import { isProviderErrorRetryable } from "../../util/provider-errors.js";
63
+ /**
64
+ * Creates a middleware that retries streamText calls on failure.
65
+ *
66
+ * This middleware wraps the entire streamText operation, catching errors during
67
+ * both the initial call and stream consumption. Retries with accumulated messages from Context.
68
+ *
69
+ * @param options - Configuration for retry behavior
70
+ * @returns A StreamTextMiddleware
71
+ */
72
+ export function createStreamRetryMiddleware(options = {}) {
73
+ const { maxRetries = Infinity, initialDelayMs = 500, maxDelayMs = 5000, backoffMultiplier = 2, maxTotalRetryTimeMs, isRetryable = isProviderErrorRetryable, onRetry, abortSignal, logger = getPrefixedLogger("[StreamRetry]"), } = options;
74
+ const backoffStrategy = options.backoffStrategy ??
75
+ new ExponentialBackoff({
76
+ initialDelayMs,
77
+ maxDelayMs,
78
+ backoffMultiplier,
79
+ });
80
+ const maxRetriesDisplay = maxRetries === Infinity ? "unlimited" : String(maxRetries);
81
+ return {
82
+ wrap(provider) {
83
+ return {
84
+ async streamText(streamOptions) {
85
+ // Phase 1: Retry initial streamText call
86
+ let httpAttempt = 0;
87
+ let totalRetryTime = 0;
88
+ const overallStartTime = Date.now();
89
+ let initialResult;
90
+ while (true) {
91
+ try {
92
+ initialResult = await provider.streamText(streamOptions);
93
+ break; // Success!
94
+ }
95
+ catch (err) {
96
+ httpAttempt++;
97
+ const error = wrapError(err);
98
+ const delay = await handleRetryAttempt(error, httpAttempt, totalRetryTime, {
99
+ maxRetries,
100
+ maxRetriesDisplay,
101
+ maxTotalRetryTimeMs,
102
+ overallStartTime,
103
+ backoffStrategy,
104
+ isRetryable,
105
+ onRetry,
106
+ abortSignal,
107
+ logger,
108
+ errorContext: "HTTP error",
109
+ });
110
+ totalRetryTime += delay;
111
+ }
112
+ }
113
+ // Phase 2: Wrap streams to handle consumption errors
114
+ const retryingFullStream = createRetryingAsyncIterable(provider, streamOptions, () => initialResult.fullStream, {
115
+ maxRetries,
116
+ maxRetriesDisplay,
117
+ maxTotalRetryTimeMs,
118
+ overallStartTime,
119
+ backoffStrategy,
120
+ isRetryable,
121
+ onRetry,
122
+ abortSignal,
123
+ logger,
124
+ });
125
+ const retryingTextStream = createRetryingAsyncIterable(provider, streamOptions, () => initialResult.textStream, {
126
+ maxRetries,
127
+ maxRetriesDisplay,
128
+ maxTotalRetryTimeMs,
129
+ overallStartTime,
130
+ backoffStrategy,
131
+ isRetryable,
132
+ onRetry,
133
+ abortSignal,
134
+ logger,
135
+ });
136
+ // Return result with retrying streams
137
+ return {
138
+ ...initialResult,
139
+ fullStream: retryingFullStream,
140
+ textStream: retryingTextStream,
141
+ };
142
+ },
143
+ };
144
+ },
145
+ };
146
+ }
147
+ /**
148
+ * Creates an AsyncIterableStream that retries on consumption errors.
149
+ */
150
+ function createRetryingAsyncIterable(provider, streamOptions, getInitialStream, config) {
151
+ // Create an AsyncIterable that implements the retry logic
152
+ const retryingIterable = {
153
+ async *[Symbol.asyncIterator]() {
154
+ let consumptionAttempt = 0;
155
+ let isFirstAttempt = true;
156
+ while (true) {
157
+ try {
158
+ // Get stream for current attempt
159
+ const iterator = isFirstAttempt
160
+ ? getInitialStream()[Symbol.asyncIterator]()
161
+ : await (async () => {
162
+ const streamResult = await provider.streamText(streamOptions);
163
+ // Use fullStream for retries (contains all chunk types)
164
+ return streamResult.fullStream[Symbol.asyncIterator]();
165
+ })();
166
+ isFirstAttempt = false;
167
+ // Iterate through chunks
168
+ while (true) {
169
+ const { value: chunk, done } = await iterator.next();
170
+ if (done) {
171
+ return; // Success!
172
+ }
173
+ // Check for error chunks
174
+ if (typeof chunk === "object" &&
175
+ chunk !== null &&
176
+ "type" in chunk &&
177
+ chunk.type === "error") {
178
+ throw wrapError(chunk.error);
179
+ }
180
+ // Normal chunk - yield it
181
+ yield chunk;
182
+ // Reset consumption attempt on successful chunk
183
+ consumptionAttempt = 0;
184
+ }
185
+ }
186
+ catch (err) {
187
+ const error = wrapError(err);
188
+ // Handle error - check if we should retry
189
+ consumptionAttempt++;
190
+ const totalElapsed = Date.now() - config.overallStartTime;
191
+ try {
192
+ await handleRetryAttempt(error, consumptionAttempt, totalElapsed, {
193
+ ...config,
194
+ errorContext: "Stream error",
195
+ });
196
+ // Loop continues - will try again with fresh stream
197
+ }
198
+ catch (finalError) {
199
+ // Exhausted or non-retryable - yield error and exit
200
+ yield {
201
+ type: "error",
202
+ error: finalError,
203
+ };
204
+ return;
205
+ }
206
+ }
207
+ }
208
+ },
209
+ };
210
+ // Convert AsyncIterable to ReadableStream
211
+ const readableStream = new ReadableStream({
212
+ async start(controller) {
213
+ try {
214
+ for await (const chunk of retryingIterable) {
215
+ controller.enqueue(chunk);
216
+ }
217
+ controller.close();
218
+ }
219
+ catch (error) {
220
+ controller.error(error);
221
+ }
222
+ },
223
+ });
224
+ // Return as AsyncIterableStream (ReadableStream with async iteration support)
225
+ return readableStream;
226
+ }
227
+ /**
228
+ * Wraps an error in LLMProviderError if it isn't already.
229
+ */
230
+ function wrapError(err, provider) {
231
+ if (err instanceof LLMProviderError) {
232
+ return err;
233
+ }
234
+ // Provider is optional here since we may not know it at this level
235
+ return new LLMProviderError({
236
+ provider: provider,
237
+ cause: err,
238
+ });
239
+ }
240
+ /**
241
+ * Checks if retry is allowed and executes retry logic.
242
+ * Returns the delay in milliseconds if a retry should be attempted.
243
+ * Throws if no retry is possible.
244
+ */
245
+ async function handleRetryAttempt(error, attempt, totalRetryTime, config) {
246
+ // Check abort signal
247
+ if (config.abortSignal?.aborted) {
248
+ const abortError = new LLMProviderError({
249
+ provider: error.provider,
250
+ message: "Request aborted",
251
+ type: "aborted",
252
+ isRetryable: false,
253
+ });
254
+ config.logger.info("Request aborted, stopping retry attempts");
255
+ throw abortError;
256
+ }
257
+ // Check retry conditions
258
+ const withinMaxRetries = attempt <= config.maxRetries;
259
+ const withinTimeLimit = !config.maxTotalRetryTimeMs ||
260
+ Date.now() - config.overallStartTime < config.maxTotalRetryTimeMs;
261
+ const errorIsRetryable = config.isRetryable(error);
262
+ const canRetry = errorIsRetryable && withinMaxRetries && withinTimeLimit;
263
+ if (!canRetry) {
264
+ if (errorIsRetryable) {
265
+ const reason = !withinMaxRetries
266
+ ? `after ${config.maxRetriesDisplay} retries`
267
+ : `total retry time exceeded ${config.maxTotalRetryTimeMs}ms`;
268
+ config.logger.error(`Exceeded retry limits: ${reason}`, getErrorMeta(error.cause));
269
+ throw new LLMProviderError({
270
+ provider: error.provider,
271
+ message: `${config.errorContext} ${reason}`,
272
+ type: "retries_exhausted",
273
+ isRetryable: false,
274
+ cause: error,
275
+ });
276
+ }
277
+ config.logger.error("Non-retryable error encountered", getErrorMeta(error.cause));
278
+ throw error;
279
+ }
280
+ // Calculate backoff delay
281
+ const delay = config.backoffStrategy.getNextDelay(attempt);
282
+ config.logger.warn(`${config.errorContext} (type: ${error.type}). Attempt ${attempt}/${config.maxRetriesDisplay}. Retrying in ${delay}ms...`);
283
+ // Call onRetry callback
284
+ if (config.onRetry) {
285
+ await config.onRetry(error, attempt, delay, totalRetryTime);
286
+ }
287
+ // Wait before retry
288
+ await new Promise((resolve) => setTimeout(resolve, delay));
289
+ return delay;
290
+ }
291
+ //# sourceMappingURL=stream-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-retry.js","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * High-level provider interface for LLM streaming interactions.
3
+ *
4
+ * This interface defines a complete, SDK-agnostic contract for multi-step
5
+ * LLM streaming, including all lifecycle hooks. Concrete implementations
6
+ * (adapters) bridge this interface to specific SDKs (Vercel AI, Anthropic, etc.).
7
+ *
8
+ * Key features:
9
+ * - Complete lifecycle: prepareStep → onChunk → onStepFinish → onFinish → onFinally
10
+ * - onFinally: Guaranteed to run after stream consumption (our addition!)
11
+ * - SDK-agnostic: Could be implemented with any LLM SDK
12
+ * - Testable: Easy to mock for testing
13
+ */
14
+ import type { Tool } from "../../agent/tools2/types.js";
15
+ import type { StopCondition } from "../../util/stop-condition.js";
16
+ import type { ProviderOptions } from "@ai-sdk/provider-utils";
17
+ import type { LanguageModel, TextStreamPart, LanguageModelUsage, ModelMessage, UserModelMessage } from "ai";
18
+ /**
19
+ * Provider interface for LLM streaming interactions.
20
+ *
21
+ * Implementations of this interface wrap specific SDKs and provide
22
+ * a consistent, high-level API with complete lifecycle management.
23
+ */
24
+ export interface StreamTextProvider {
25
+ /**
26
+ * Streams text from an LLM with multi-step tool calling support.
27
+ *
28
+ * @param options - Configuration and lifecycle hooks
29
+ * @returns Promise resolving to stream result with text/full streams
30
+ */
31
+ streamText<TOOLS extends Record<string, Tool> = Record<string, Tool>>(options: StreamTextOptions<TOOLS>): Promise<StreamTextResult<TOOLS>>;
32
+ }
33
+ /**
34
+ * Options for a streamText call.
35
+ *
36
+ * Includes model configuration, messages, tools, and comprehensive
37
+ * lifecycle hooks including onFinally (runs after stream consumption).
38
+ */
39
+ export interface StreamTextOptions<TOOLS extends Record<string, Tool>> {
40
+ /** The language model to use */
41
+ model: LanguageModel;
42
+ /**
43
+ * Conversation messages.
44
+ * Note: When using context middleware, this will be populated automatically
45
+ * from context history. You typically provide user instead.
46
+ */
47
+ messages?: ModelMessage[];
48
+ /**
49
+ * User message for this interaction.
50
+ * When using context middleware, this is added to the conversation history
51
+ * and messages are populated automatically from context.
52
+ */
53
+ user?: UserModelMessage;
54
+ /** Available tools the model can call */
55
+ tools?: TOOLS;
56
+ /**
57
+ * System prompt.
58
+ * When using context middleware, this is set on the context.
59
+ */
60
+ system?: string;
61
+ /** Maximum number of automatic tool call steps */
62
+ maxSteps?: number;
63
+ /** Abort signal for cancellation */
64
+ abortSignal?: AbortSignal;
65
+ /** Custom headers for the request */
66
+ headers?: Record<string, string | undefined>;
67
+ /** Provider-specific options */
68
+ providerOptions?: ProviderOptions;
69
+ /**
70
+ * Vercel AI SDK specific: Condition to stop generation early.
71
+ * Pass through to the underlying SDK.
72
+ */
73
+ stopWhen?: StopCondition<any> | StopCondition<any>[];
74
+ /**
75
+ * Vercel AI SDK specific: Transformation stream for the output.
76
+ * Pass through to the underlying SDK.
77
+ */
78
+ experimental_transform?: any;
79
+ /**
80
+ * Called before each LLM step.
81
+ * Can transform the step parameters before execution.
82
+ */
83
+ prepareStep?: (step: StepParameters) => Promise<StepParameters> | StepParameters;
84
+ /**
85
+ * Called for each chunk in the stream during generation.
86
+ */
87
+ onChunk?: (event: {
88
+ chunk: StreamChunk;
89
+ }) => Promise<void> | void;
90
+ /**
91
+ * Called after each step completes (after tool execution).
92
+ */
93
+ onStepFinish?: (step: StepResult) => Promise<void> | void;
94
+ /**
95
+ * Called when the entire multi-step interaction finishes.
96
+ * This fires after generation completes, before stream consumption.
97
+ */
98
+ onFinish?: (result: FinalResult) => Promise<void> | void;
99
+ /**
100
+ * Called after stream consumption completes.
101
+ *
102
+ * This is the key lifecycle hook for cleanup operations:
103
+ * - Releasing locks (context handles)
104
+ * - Finishing tracing spans
105
+ * - Closing database connections
106
+ * - Saving final artifacts
107
+ *
108
+ * Guarantees:
109
+ * - Runs exactly once, even if multiple stream accessors are used
110
+ * - Runs after the stream is fully consumed OR abandoned
111
+ * - Runs in error cases as well (usage may be partial)
112
+ * - Idempotent and safe to call multiple times
113
+ *
114
+ */
115
+ onFinally?: () => Promise<void> | void;
116
+ /**
117
+ * Called if an error occurs during generation or consumption.
118
+ */
119
+ onError?: (error: Error) => Promise<void> | void;
120
+ /**
121
+ * Called if the operation is aborted via the abortSignal.
122
+ */
123
+ onAbort?: () => Promise<void> | void;
124
+ }
125
+ /**
126
+ * Parameters for a single LLM step.
127
+ */
128
+ export interface StepParameters {
129
+ messages: ModelMessage[];
130
+ stepNumber: number;
131
+ }
132
+ /**
133
+ * A chunk from the streaming response.
134
+ * This is a direct re-export of Vercel AI SDK's TextStreamPart.
135
+ */
136
+ export type StreamChunk = TextStreamPart<Record<string, Tool>>;
137
+ import type { StepResult as VercelStepResult } from "ai";
138
+ /**
139
+ * Result of a single LLM step.
140
+ * Re-exported from Vercel AI SDK to avoid type incompatibilities.
141
+ */
142
+ export type StepResult = VercelStepResult<any>;
143
+ /**
144
+ * Final result of the entire multi-step interaction.
145
+ * This is the result passed to onFinish callback.
146
+ * Re-exported from Vercel AI SDK's internal type.
147
+ */
148
+ export type FinalResult = StepResult & {
149
+ readonly steps: StepResult[];
150
+ readonly totalUsage: LanguageModelUsage;
151
+ };
152
+ import type { StreamTextResult as VercelStreamTextResult } from "ai";
153
+ /**
154
+ * Result of a streamText call.
155
+ * Re-exported from Vercel AI SDK with default for PARTIAL_OUTPUT.
156
+ */
157
+ export type StreamTextResult<TOOLS extends Record<string, Tool> = Record<string, Tool>> = VercelStreamTextResult<TOOLS, any>;
158
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/interaction/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * High-level provider interface for LLM streaming interactions.
3
+ *
4
+ * This interface defines a complete, SDK-agnostic contract for multi-step
5
+ * LLM streaming, including all lifecycle hooks. Concrete implementations
6
+ * (adapters) bridge this interface to specific SDKs (Vercel AI, Anthropic, etc.).
7
+ *
8
+ * Key features:
9
+ * - Complete lifecycle: prepareStep → onChunk → onStepFinish → onFinish → onFinally
10
+ * - onFinally: Guaranteed to run after stream consumption (our addition!)
11
+ * - SDK-agnostic: Could be implemented with any LLM SDK
12
+ * - Testable: Easy to mock for testing
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../src/ai-service/llm/interaction/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Stream lifecycle management utilities.
3
+ *
4
+ * Provides utilities for wrapping streams with lifecycle hooks, particularly
5
+ * `onFinally` which runs after stream consumption completes.
6
+ *
7
+ * Key challenge: The `streamText()` function returns immediately, but the
8
+ * streams are consumed asynchronously later. We need to track when consumption
9
+ * actually completes to run cleanup logic.
10
+ *
11
+ * Solution: Wrap streams with `TransformStream` that tracks consumption via
12
+ * the `flush()` method, which runs when the input stream closes.
13
+ */
14
+ import type { StreamTextResult } from "./provider.js";
15
+ import type { Tool } from "../../agent/tools2/types.js";
16
+ /**
17
+ * Wraps a StreamTextResult to add onFinally lifecycle hook.
18
+ *
19
+ * The onFinally callback runs after stream consumption completes, handling:
20
+ * - Normal completion (stream exhausted)
21
+ * - Errors during consumption
22
+ * - Stream cancellation/abandonment
23
+ *
24
+ * Guarantees:
25
+ * - Runs exactly once, even if multiple stream accessors are used
26
+ * - Idempotent (safe to call multiple times)
27
+ * - Works with all consumption patterns (iteration, promises, piping)
28
+ *
29
+ * @param result - The stream result to wrap
30
+ * @param onFinally - Callback to run after consumption
31
+ * @returns Wrapped result with lifecycle tracking
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const result = await streamText({ model, messages });
36
+ * const wrapped = withStreamLifecycle(result, async () => {
37
+ * console.log('Stream consumed!');
38
+ * await cleanup();
39
+ * });
40
+ *
41
+ * for await (const text of wrapped.textStream) {
42
+ * console.log(text);
43
+ * }
44
+ * // onFinally runs here ^
45
+ * ```
46
+ */
47
+ export declare function withStreamLifecycle<TOOLS extends Record<string, Tool> = Record<string, Tool>>(result: StreamTextResult<TOOLS>, onFinally: () => Promise<void> | void): StreamTextResult<TOOLS>;
48
+ //# sourceMappingURL=stream-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-lifecycle.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/interaction/stream-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAEzD,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC/B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACpC,gBAAgB,CAAC,KAAK,CAAC,CAmCzB"}