@moureau/pipeflow 0.0.1 → 0.0.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 (336) hide show
  1. package/README.md +280 -130
  2. package/dist/cjs/agents/agent.js +1 -1
  3. package/dist/cjs/agents/agent.js.map +3 -3
  4. package/dist/cjs/agents/tools/tools.js +1 -1
  5. package/dist/cjs/agents/tools/tools.js.map +3 -3
  6. package/dist/cjs/client/client.js +2 -0
  7. package/dist/cjs/client/client.js.map +7 -0
  8. package/dist/cjs/client/index.js +2 -0
  9. package/dist/cjs/client/index.js.map +7 -0
  10. package/dist/cjs/client/json.js +2 -0
  11. package/dist/cjs/client/json.js.map +7 -0
  12. package/dist/cjs/client/protocol/websocket.js +2 -0
  13. package/dist/cjs/client/protocol/websocket.js.map +7 -0
  14. package/dist/cjs/client/protocol.js +2 -0
  15. package/dist/cjs/client/protocol.js.map +7 -0
  16. package/dist/cjs/conversations/conversation/conversation.js +1 -1
  17. package/dist/cjs/conversations/conversation/conversation.js.map +3 -3
  18. package/dist/cjs/conversations/conversations.js +1 -1
  19. package/dist/cjs/conversations/conversations.js.map +3 -3
  20. package/dist/cjs/conversations/index.js +1 -1
  21. package/dist/cjs/conversations/index.js.map +3 -3
  22. package/dist/cjs/conversations/orchestration/coordination/coordination.js +10 -0
  23. package/dist/cjs/conversations/orchestration/coordination/coordination.js.map +7 -0
  24. package/dist/cjs/conversations/orchestration/coordination/index.js +2 -0
  25. package/dist/cjs/conversations/orchestration/coordination/index.js.map +7 -0
  26. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
  27. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
  28. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
  29. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
  30. package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js +2 -0
  31. package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
  32. package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js +2 -0
  33. package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
  34. package/dist/cjs/conversations/orchestration/orchestrator/history/history.js +4 -0
  35. package/dist/cjs/conversations/orchestration/orchestrator/history/history.js.map +7 -0
  36. package/dist/cjs/conversations/orchestration/orchestrator/history/index.js +2 -0
  37. package/dist/cjs/conversations/orchestration/orchestrator/history/index.js.map +7 -0
  38. package/dist/cjs/conversations/orchestration/orchestrator/index.js +1 -1
  39. package/dist/cjs/conversations/orchestration/orchestrator/index.js.map +3 -3
  40. package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js +1 -2
  41. package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
  42. package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js +2 -0
  43. package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
  44. package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js +23 -0
  45. package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
  46. package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js +2 -0
  47. package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
  48. package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js +2 -0
  49. package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
  50. package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js +2 -0
  51. package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
  52. package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js +2 -0
  53. package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
  54. package/dist/cjs/conversations/orchestration/test-harness.js +2 -0
  55. package/dist/cjs/conversations/orchestration/test-harness.js.map +7 -0
  56. package/dist/cjs/conversations/orchestration/text-chunker/index.js +2 -0
  57. package/dist/cjs/conversations/orchestration/text-chunker/index.js.map +7 -0
  58. package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js +3 -0
  59. package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
  60. package/dist/cjs/conversations/stream/conversation-stream.js +2 -0
  61. package/dist/cjs/conversations/stream/conversation-stream.js.map +7 -0
  62. package/dist/cjs/conversations/stream/index.js +2 -0
  63. package/dist/cjs/conversations/stream/index.js.map +7 -0
  64. package/dist/cjs/conversations/types.js +1 -1
  65. package/dist/cjs/conversations/types.js.map +2 -2
  66. package/dist/cjs/index.js +1 -1
  67. package/dist/cjs/index.js.map +3 -3
  68. package/dist/cjs/persistence/adapters/sqlite/sqlite.js +18 -14
  69. package/dist/cjs/persistence/adapters/sqlite/sqlite.js.map +3 -3
  70. package/dist/cjs/pipeflow/index.js +2 -0
  71. package/dist/cjs/pipeflow/index.js.map +7 -0
  72. package/dist/cjs/pipeflow/pipeflow.js +2 -0
  73. package/dist/cjs/pipeflow/pipeflow.js.map +7 -0
  74. package/dist/cjs/providers/index.js +1 -1
  75. package/dist/cjs/providers/index.js.map +2 -2
  76. package/dist/cjs/providers/llm/adapters/claude/claude.js +5 -0
  77. package/dist/cjs/providers/llm/adapters/claude/claude.js.map +7 -0
  78. package/dist/cjs/providers/llm/adapters/claude/index.js +2 -0
  79. package/dist/cjs/providers/llm/adapters/claude/index.js.map +7 -0
  80. package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js +1 -1
  81. package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
  82. package/dist/cjs/providers/llm/adapters/index.js +1 -1
  83. package/dist/cjs/providers/llm/adapters/index.js.map +3 -3
  84. package/dist/cjs/providers/llm/adapters/openai/index.js +2 -0
  85. package/dist/cjs/providers/llm/adapters/openai/index.js.map +7 -0
  86. package/dist/cjs/providers/llm/adapters/openai/openai.js +2 -0
  87. package/dist/cjs/providers/llm/adapters/openai/openai.js.map +7 -0
  88. package/dist/cjs/providers/llm/adapters/openai-compatible.js +10 -0
  89. package/dist/cjs/providers/llm/adapters/openai-compatible.js.map +7 -0
  90. package/dist/cjs/providers/llm/adapters/openrouter/index.js +2 -0
  91. package/dist/cjs/providers/llm/adapters/openrouter/index.js.map +7 -0
  92. package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js +2 -0
  93. package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
  94. package/dist/cjs/providers/llm/index.js +1 -1
  95. package/dist/cjs/providers/llm/index.js.map +3 -3
  96. package/dist/cjs/providers/llm/toolmode/index.js +2 -0
  97. package/dist/cjs/providers/llm/toolmode/index.js.map +7 -0
  98. package/dist/cjs/providers/llm/toolmode/toolmode.js +2 -0
  99. package/dist/cjs/providers/llm/toolmode/toolmode.js.map +7 -0
  100. package/dist/cjs/providers/llm/types.js +1 -1
  101. package/dist/cjs/providers/llm/types.js.map +3 -3
  102. package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js +1 -1
  103. package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
  104. package/dist/cjs/providers/stt/adapters/index.js +1 -1
  105. package/dist/cjs/providers/stt/adapters/index.js.map +3 -3
  106. package/dist/cjs/providers/stt/adapters/openrouter/index.js +2 -0
  107. package/dist/cjs/providers/stt/adapters/openrouter/index.js.map +7 -0
  108. package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js +2 -0
  109. package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
  110. package/dist/cjs/providers/tts/adapters/index.js +1 -1
  111. package/dist/cjs/providers/tts/adapters/index.js.map +3 -3
  112. package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js +4 -1
  113. package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
  114. package/dist/cjs/providers/tts/adapters/openrouter/index.js +2 -0
  115. package/dist/cjs/providers/tts/adapters/openrouter/index.js.map +7 -0
  116. package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js +2 -0
  117. package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
  118. package/dist/cjs/transport/streamobject/field-stream/field-stream.js +2 -0
  119. package/dist/cjs/transport/streamobject/field-stream/field-stream.js.map +7 -0
  120. package/dist/cjs/transport/streamobject/field-stream/index.js +2 -0
  121. package/dist/cjs/transport/streamobject/field-stream/index.js.map +7 -0
  122. package/dist/cjs/transport/streamobject/index.js +2 -0
  123. package/dist/cjs/transport/streamobject/index.js.map +7 -0
  124. package/dist/cjs/transport/streamobject/json-adapter/index.js +2 -0
  125. package/dist/cjs/transport/streamobject/json-adapter/index.js.map +7 -0
  126. package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js +4 -0
  127. package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
  128. package/dist/cjs/transport/streamobject/reference/index.js +2 -0
  129. package/dist/cjs/transport/streamobject/reference/index.js.map +7 -0
  130. package/dist/cjs/transport/streamobject/reference/reference.js +2 -0
  131. package/dist/cjs/transport/streamobject/reference/reference.js.map +7 -0
  132. package/dist/cjs/transport/streamobject/stream-object/index.js +2 -0
  133. package/dist/cjs/transport/streamobject/stream-object/index.js.map +7 -0
  134. package/dist/cjs/transport/streamobject/stream-object/stream-object.js +2 -0
  135. package/dist/cjs/transport/streamobject/stream-object/stream-object.js.map +7 -0
  136. package/dist/esm/agents/agent.js +1 -1
  137. package/dist/esm/agents/agent.js.map +3 -3
  138. package/dist/esm/agents/tools/tools.js +1 -1
  139. package/dist/esm/agents/tools/tools.js.map +3 -3
  140. package/dist/esm/client/client.js +2 -0
  141. package/dist/esm/client/client.js.map +7 -0
  142. package/dist/esm/client/index.js +2 -0
  143. package/dist/esm/client/index.js.map +7 -0
  144. package/dist/esm/client/json.js +2 -0
  145. package/dist/esm/client/json.js.map +7 -0
  146. package/dist/esm/client/protocol/websocket.js +2 -0
  147. package/dist/esm/client/protocol/websocket.js.map +7 -0
  148. package/dist/esm/client/protocol.js +1 -0
  149. package/dist/esm/client/protocol.js.map +7 -0
  150. package/dist/esm/conversations/conversation/conversation.js +1 -1
  151. package/dist/esm/conversations/conversation/conversation.js.map +3 -3
  152. package/dist/esm/conversations/conversations.js +1 -1
  153. package/dist/esm/conversations/conversations.js.map +3 -3
  154. package/dist/esm/conversations/index.js +1 -1
  155. package/dist/esm/conversations/index.js.map +3 -3
  156. package/dist/esm/conversations/orchestration/coordination/coordination.js +10 -0
  157. package/dist/esm/conversations/orchestration/coordination/coordination.js.map +7 -0
  158. package/dist/esm/conversations/orchestration/coordination/index.js +2 -0
  159. package/dist/esm/conversations/orchestration/coordination/index.js.map +7 -0
  160. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
  161. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
  162. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
  163. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
  164. package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js +2 -0
  165. package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
  166. package/dist/esm/conversations/orchestration/orchestrator/generation/index.js +2 -0
  167. package/dist/esm/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
  168. package/dist/esm/conversations/orchestration/orchestrator/history/history.js +4 -0
  169. package/dist/esm/conversations/orchestration/orchestrator/history/history.js.map +7 -0
  170. package/dist/esm/conversations/orchestration/orchestrator/history/index.js +2 -0
  171. package/dist/esm/conversations/orchestration/orchestrator/history/index.js.map +7 -0
  172. package/dist/esm/conversations/orchestration/orchestrator/index.js +1 -1
  173. package/dist/esm/conversations/orchestration/orchestrator/index.js.map +3 -3
  174. package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js +1 -2
  175. package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
  176. package/dist/esm/conversations/orchestration/orchestrator/routing/index.js +2 -0
  177. package/dist/esm/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
  178. package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js +23 -0
  179. package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
  180. package/dist/esm/conversations/orchestration/orchestrator/speech/index.js +2 -0
  181. package/dist/esm/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
  182. package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js +2 -0
  183. package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
  184. package/dist/esm/conversations/orchestration/orchestrator/tools/index.js +2 -0
  185. package/dist/esm/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
  186. package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js +2 -0
  187. package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
  188. package/dist/esm/conversations/orchestration/test-harness.js +2 -0
  189. package/dist/esm/conversations/orchestration/test-harness.js.map +7 -0
  190. package/dist/esm/conversations/orchestration/text-chunker/index.js +2 -0
  191. package/dist/esm/conversations/orchestration/text-chunker/index.js.map +7 -0
  192. package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js +3 -0
  193. package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
  194. package/dist/esm/conversations/stream/conversation-stream.js +2 -0
  195. package/dist/esm/conversations/stream/conversation-stream.js.map +7 -0
  196. package/dist/esm/conversations/stream/index.js +2 -0
  197. package/dist/esm/conversations/stream/index.js.map +7 -0
  198. package/dist/esm/conversations/types.js +1 -1
  199. package/dist/esm/conversations/types.js.map +2 -2
  200. package/dist/esm/index.js +1 -1
  201. package/dist/esm/index.js.map +3 -3
  202. package/dist/esm/persistence/adapters/sqlite/sqlite.js +18 -14
  203. package/dist/esm/persistence/adapters/sqlite/sqlite.js.map +3 -3
  204. package/dist/esm/pipeflow/index.js +2 -0
  205. package/dist/esm/pipeflow/index.js.map +7 -0
  206. package/dist/esm/pipeflow/pipeflow.js +2 -0
  207. package/dist/esm/pipeflow/pipeflow.js.map +7 -0
  208. package/dist/esm/providers/index.js +1 -1
  209. package/dist/esm/providers/index.js.map +3 -3
  210. package/dist/esm/providers/llm/adapters/claude/claude.js +5 -0
  211. package/dist/esm/providers/llm/adapters/claude/claude.js.map +7 -0
  212. package/dist/esm/providers/llm/adapters/claude/index.js +2 -0
  213. package/dist/esm/providers/llm/adapters/claude/index.js.map +7 -0
  214. package/dist/esm/providers/llm/adapters/deepseek/deepseek.js +1 -1
  215. package/dist/esm/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
  216. package/dist/esm/providers/llm/adapters/index.js +1 -1
  217. package/dist/esm/providers/llm/adapters/index.js.map +3 -3
  218. package/dist/esm/providers/llm/adapters/openai/index.js +2 -0
  219. package/dist/esm/providers/llm/adapters/openai/index.js.map +7 -0
  220. package/dist/esm/providers/llm/adapters/openai/openai.js +2 -0
  221. package/dist/esm/providers/llm/adapters/openai/openai.js.map +7 -0
  222. package/dist/esm/providers/llm/adapters/openai-compatible.js +10 -0
  223. package/dist/esm/providers/llm/adapters/openai-compatible.js.map +7 -0
  224. package/dist/esm/providers/llm/adapters/openrouter/index.js +2 -0
  225. package/dist/esm/providers/llm/adapters/openrouter/index.js.map +7 -0
  226. package/dist/esm/providers/llm/adapters/openrouter/openrouter.js +2 -0
  227. package/dist/esm/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
  228. package/dist/esm/providers/llm/index.js +1 -1
  229. package/dist/esm/providers/llm/index.js.map +3 -3
  230. package/dist/esm/providers/llm/toolmode/index.js +2 -0
  231. package/dist/esm/providers/llm/toolmode/index.js.map +7 -0
  232. package/dist/esm/providers/llm/toolmode/toolmode.js +2 -0
  233. package/dist/esm/providers/llm/toolmode/toolmode.js.map +7 -0
  234. package/dist/esm/providers/llm/types.js +1 -0
  235. package/dist/esm/providers/llm/types.js.map +4 -4
  236. package/dist/esm/providers/stt/adapters/deepgram/deepgram.js +1 -1
  237. package/dist/esm/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
  238. package/dist/esm/providers/stt/adapters/index.js +1 -1
  239. package/dist/esm/providers/stt/adapters/index.js.map +3 -3
  240. package/dist/esm/providers/stt/adapters/openrouter/index.js +2 -0
  241. package/dist/esm/providers/stt/adapters/openrouter/index.js.map +7 -0
  242. package/dist/esm/providers/stt/adapters/openrouter/openrouter.js +2 -0
  243. package/dist/esm/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
  244. package/dist/esm/providers/tts/adapters/index.js +1 -1
  245. package/dist/esm/providers/tts/adapters/index.js.map +3 -3
  246. package/dist/esm/providers/tts/adapters/kokoro/kokoro.js +4 -1
  247. package/dist/esm/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
  248. package/dist/esm/providers/tts/adapters/openrouter/index.js +2 -0
  249. package/dist/esm/providers/tts/adapters/openrouter/index.js.map +7 -0
  250. package/dist/esm/providers/tts/adapters/openrouter/openrouter.js +2 -0
  251. package/dist/esm/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
  252. package/dist/esm/transport/streamobject/field-stream/field-stream.js +2 -0
  253. package/dist/esm/transport/streamobject/field-stream/field-stream.js.map +7 -0
  254. package/dist/esm/transport/streamobject/field-stream/index.js +2 -0
  255. package/dist/esm/transport/streamobject/field-stream/index.js.map +7 -0
  256. package/dist/esm/transport/streamobject/index.js +2 -0
  257. package/dist/esm/transport/streamobject/index.js.map +7 -0
  258. package/dist/esm/transport/streamobject/json-adapter/index.js +2 -0
  259. package/dist/esm/transport/streamobject/json-adapter/index.js.map +7 -0
  260. package/dist/esm/transport/streamobject/json-adapter/json-adapter.js +4 -0
  261. package/dist/esm/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
  262. package/dist/esm/transport/streamobject/reference/index.js +2 -0
  263. package/dist/esm/transport/streamobject/reference/index.js.map +7 -0
  264. package/dist/esm/transport/streamobject/reference/reference.js +2 -0
  265. package/dist/esm/transport/streamobject/reference/reference.js.map +7 -0
  266. package/dist/esm/transport/streamobject/stream-object/index.js +2 -0
  267. package/dist/esm/transport/streamobject/stream-object/index.js.map +7 -0
  268. package/dist/esm/transport/streamobject/stream-object/stream-object.js +2 -0
  269. package/dist/esm/transport/streamobject/stream-object/stream-object.js.map +7 -0
  270. package/dist/types/agents/agent.d.ts +3 -0
  271. package/dist/types/agents/tools/tools.d.ts +28 -6
  272. package/dist/types/client/client.d.ts +186 -0
  273. package/dist/types/client/index.d.ts +31 -0
  274. package/dist/types/client/json.d.ts +13 -0
  275. package/dist/types/client/protocol/websocket.d.ts +56 -0
  276. package/dist/types/client/protocol.d.ts +46 -0
  277. package/dist/types/conversations/conversation/conversation.d.ts +130 -6
  278. package/dist/types/conversations/conversations.d.ts +35 -1
  279. package/dist/types/conversations/index.d.ts +2 -1
  280. package/dist/types/conversations/orchestration/coordination/coordination.d.ts +192 -0
  281. package/dist/types/conversations/orchestration/coordination/index.d.ts +2 -0
  282. package/dist/types/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.d.ts +108 -0
  283. package/dist/types/conversations/orchestration/orchestrator/coordination-runner/index.d.ts +2 -0
  284. package/dist/types/conversations/orchestration/orchestrator/generation/generation.d.ts +60 -0
  285. package/dist/types/conversations/orchestration/orchestrator/generation/index.d.ts +2 -0
  286. package/dist/types/conversations/orchestration/orchestrator/history/history.d.ts +62 -0
  287. package/dist/types/conversations/orchestration/orchestrator/history/index.d.ts +1 -0
  288. package/dist/types/conversations/orchestration/orchestrator/index.d.ts +10 -0
  289. package/dist/types/conversations/orchestration/orchestrator/orchestrator.d.ts +68 -31
  290. package/dist/types/conversations/orchestration/orchestrator/routing/index.d.ts +1 -0
  291. package/dist/types/conversations/orchestration/orchestrator/routing/routing.d.ts +19 -0
  292. package/dist/types/conversations/orchestration/orchestrator/speech/index.d.ts +2 -0
  293. package/dist/types/conversations/orchestration/orchestrator/speech/speech.d.ts +78 -0
  294. package/dist/types/conversations/orchestration/orchestrator/tools/index.d.ts +2 -0
  295. package/dist/types/conversations/orchestration/orchestrator/tools/tools.d.ts +65 -0
  296. package/dist/types/conversations/orchestration/test-harness.d.ts +100 -0
  297. package/dist/types/conversations/orchestration/text-chunker/index.d.ts +1 -0
  298. package/dist/types/conversations/orchestration/text-chunker/text-chunker.d.ts +39 -0
  299. package/dist/types/conversations/stream/conversation-stream.d.ts +42 -0
  300. package/dist/types/conversations/stream/index.d.ts +1 -0
  301. package/dist/types/conversations/types.d.ts +32 -0
  302. package/dist/types/index.d.ts +5 -38
  303. package/dist/types/pipeflow/index.d.ts +2 -0
  304. package/dist/types/pipeflow/pipeflow.d.ts +43 -0
  305. package/dist/types/providers/index.d.ts +1 -1
  306. package/dist/types/providers/llm/adapters/claude/claude.d.ts +45 -0
  307. package/dist/types/providers/llm/adapters/claude/index.d.ts +2 -0
  308. package/dist/types/providers/llm/adapters/deepseek/deepseek.d.ts +23 -2
  309. package/dist/types/providers/llm/adapters/index.d.ts +3 -0
  310. package/dist/types/providers/llm/adapters/openai/index.d.ts +2 -0
  311. package/dist/types/providers/llm/adapters/openai/openai.d.ts +45 -0
  312. package/dist/types/providers/llm/adapters/openai-compatible.d.ts +44 -0
  313. package/dist/types/providers/llm/adapters/openrouter/index.d.ts +2 -0
  314. package/dist/types/providers/llm/adapters/openrouter/openrouter.d.ts +60 -0
  315. package/dist/types/providers/llm/index.d.ts +5 -2
  316. package/dist/types/providers/llm/toolmode/index.d.ts +2 -0
  317. package/dist/types/providers/llm/toolmode/toolmode.d.ts +99 -0
  318. package/dist/types/providers/llm/types.d.ts +65 -0
  319. package/dist/types/providers/stt/adapters/deepgram/deepgram.d.ts +4 -1
  320. package/dist/types/providers/stt/adapters/index.d.ts +1 -0
  321. package/dist/types/providers/stt/adapters/openrouter/index.d.ts +2 -0
  322. package/dist/types/providers/stt/adapters/openrouter/openrouter.d.ts +196 -0
  323. package/dist/types/providers/tts/adapters/index.d.ts +1 -0
  324. package/dist/types/providers/tts/adapters/kokoro/kokoro.d.ts +18 -3
  325. package/dist/types/providers/tts/adapters/openrouter/index.d.ts +2 -0
  326. package/dist/types/providers/tts/adapters/openrouter/openrouter.d.ts +64 -0
  327. package/dist/types/transport/streamobject/field-stream/field-stream.d.ts +85 -0
  328. package/dist/types/transport/streamobject/field-stream/index.d.ts +2 -0
  329. package/dist/types/transport/streamobject/index.d.ts +8 -0
  330. package/dist/types/transport/streamobject/json-adapter/index.d.ts +2 -0
  331. package/dist/types/transport/streamobject/json-adapter/json-adapter.d.ts +65 -0
  332. package/dist/types/transport/streamobject/reference/index.d.ts +2 -0
  333. package/dist/types/transport/streamobject/reference/reference.d.ts +127 -0
  334. package/dist/types/transport/streamobject/stream-object/index.d.ts +2 -0
  335. package/dist/types/transport/streamobject/stream-object/stream-object.d.ts +31 -0
  336. package/package.json +29 -2
@@ -1,4 +1,4 @@
1
- "use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var r=(i,e)=>a(i,"name",{value:e,configurable:!0});var N=(i,e)=>{for(var t in e)a(i,t,{get:e[t],enumerable:!0})},p=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of T(e))!u.call(i,s)&&s!==t&&a(i,s,{get:()=>e[s],enumerable:!(n=c(e,s))||n.enumerable});return i};var R=i=>p(a({},"__esModule",{value:!0}),i);var v={};N(v,{SQLitePersistence:()=>_});module.exports=R(v);var d=require("bun:sqlite"),E=require("../../../conversations/transcription/transcription.js");class _{static{r(this,"SQLitePersistence")}db;constructor(e={}){this.db=new d.Database(e.filename??":memory:"),this.db.exec(`
1
+ "use strict";var a=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var r=(i,n)=>a(i,"name",{value:n,configurable:!0});var p=(i,n)=>{for(var e in n)a(i,e,{get:n[e],enumerable:!0})},_=(i,n,e,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of c(n))!u.call(i,s)&&s!==e&&a(i,s,{get:()=>n[s],enumerable:!(t=T(n,s))||t.enumerable});return i};var N=i=>_(a({},"__esModule",{value:!0}),i);var m={};p(m,{SQLitePersistence:()=>R});module.exports=N(m);var d=require("bun:sqlite"),E=require("../../../conversations/transcription/transcription.js");class R{static{r(this,"SQLitePersistence")}db;constructor(n={}){this.db=new d.Database(n.filename??":memory:"),this.db.exec(`
2
2
  CREATE TABLE IF NOT EXISTS conversations (
3
3
  id TEXT PRIMARY KEY,
4
4
  agent_names TEXT NOT NULL,
@@ -36,23 +36,27 @@
36
36
  );
37
37
 
38
38
  CREATE TABLE IF NOT EXISTS generations (
39
- id TEXT PRIMARY KEY,
40
- conversation_id TEXT NOT NULL,
41
- agent_name TEXT NOT NULL,
42
- text TEXT NOT NULL,
43
- status TEXT NOT NULL,
44
- started_at INTEGER NOT NULL,
45
- ended_at INTEGER
39
+ id TEXT PRIMARY KEY,
40
+ conversation_id TEXT NOT NULL,
41
+ agent_name TEXT NOT NULL,
42
+ text TEXT NOT NULL,
43
+ status TEXT NOT NULL,
44
+ started_at INTEGER NOT NULL,
45
+ ended_at INTEGER,
46
+ kind TEXT,
47
+ parent_generation_id TEXT,
48
+ timing TEXT
46
49
  );
47
50
 
48
51
  CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);
49
52
  CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);
50
53
  CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);
51
54
  CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);
52
- `)}close(){this.db.close()}async createConversation(e={}){const t={id:e.id??crypto.randomUUID(),agentNames:e.agentNames??[],createdAt:e.createdAt??Date.now(),endedAt:null};return this.db.query(`INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)
53
- VALUES (?, ?, ?, ?)`).run(t.id,JSON.stringify(t.agentNames),t.createdAt,null),{...t}}async getConversation(e){const t=this.db.query("SELECT * FROM conversations WHERE id = ?").get(e);return t?o(t):null}async listConversations(){return this.db.query("SELECT * FROM conversations ORDER BY created_at ASC").all().map(o)}async finalizeConversation(e,t=Date.now()){return this.db.query("UPDATE conversations SET ended_at = ? WHERE id = ?").run(t,e).changes===0?null:this.getConversation(e)}async deleteConversation(e){return this.db.query("SELECT id FROM conversations WHERE id = ?").get(e)?(this.db.query("DELETE FROM participants WHERE conversation_id = ?").run(e),this.db.query("DELETE FROM transcript WHERE conversation_id = ?").run(e),this.db.query("DELETE FROM turns WHERE conversation_id = ?").run(e),this.db.query("DELETE FROM generations WHERE conversation_id = ?").run(e),this.db.query("DELETE FROM conversations WHERE id = ?").run(e),!0):!1}async addParticipant(e,t){this.db.query(`INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)
54
- VALUES (?, ?, ?, ?)`).run(e,t.userId,JSON.stringify(t.aliases),t.joinedAt)}async listParticipants(e){return this.db.query("SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC").all(e).map(n=>({userId:n.user_id,aliases:JSON.parse(n.aliases),joinedAt:n.joined_at}))}async appendTranscript(e,t){this.db.query(`INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)
55
- VALUES (?, ?, ?, ?, ?, ?, ?)`).run(t.id,e,t.speaker,t.speakerKind,t.text,t.timestamp,t.sequence)}async listTranscript(e){return this.db.query("SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC").all(e).map(n=>E.TranscriptEntry.fromPlain({id:n.id,conversationId:n.conversation_id,speaker:n.speaker,speakerKind:n.speaker_kind,text:n.text,timestamp:n.timestamp,sequence:n.sequence}))}async appendTurn(e,t){this.db.query(`INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)
56
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(t.id,e,t.participantId,t.participantName,t.text,t.startedAt,t.endedAt,t.sequence)}async listTurns(e){return this.db.query("SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC").all(e).map(n=>({id:n.id,conversationId:n.conversation_id,participantId:n.participant_id,participantName:n.participant_name,text:n.text,startedAt:n.started_at,endedAt:n.ended_at,sequence:n.sequence}))}async appendGeneration(e,t){this.db.query(`INSERT OR REPLACE INTO generations (id, conversation_id, agent_name, text, status, started_at, ended_at)
57
- VALUES (?, ?, ?, ?, ?, ?, ?)`).run(t.id,e,t.agentName,t.text,t.status,t.startedAt,t.endedAt??null)}async listGenerations(e){return this.db.query("SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC").all(e).map(n=>({id:n.id,conversationId:n.conversation_id,agentName:n.agent_name,text:n.text,status:n.status,startedAt:n.started_at,endedAt:n.ended_at??void 0}))}}function o(i){return{id:i.id,agentNames:JSON.parse(i.agent_names),createdAt:i.created_at,endedAt:i.ended_at}}r(o,"rowToConversation");
55
+ `);const e=new Set(this.db.query("PRAGMA table_info(generations)").all().map(t=>t.name));e.has("kind")||this.db.exec("ALTER TABLE generations ADD COLUMN kind TEXT"),e.has("parent_generation_id")||this.db.exec("ALTER TABLE generations ADD COLUMN parent_generation_id TEXT"),e.has("timing")||this.db.exec("ALTER TABLE generations ADD COLUMN timing TEXT")}close(){this.db.close()}async createConversation(n={}){const e={id:n.id??crypto.randomUUID(),agentNames:n.agentNames??[],createdAt:n.createdAt??Date.now(),endedAt:null};return this.db.query(`INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)
56
+ VALUES (?, ?, ?, ?)`).run(e.id,JSON.stringify(e.agentNames),e.createdAt,null),{...e}}async getConversation(n){const e=this.db.query("SELECT * FROM conversations WHERE id = ?").get(n);return e?o(e):null}async listConversations(){return this.db.query("SELECT * FROM conversations ORDER BY created_at ASC").all().map(o)}async finalizeConversation(n,e=Date.now()){return this.db.query("UPDATE conversations SET ended_at = ? WHERE id = ?").run(e,n).changes===0?null:this.getConversation(n)}async deleteConversation(n){return this.db.query("SELECT id FROM conversations WHERE id = ?").get(n)?(this.db.query("DELETE FROM participants WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM transcript WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM turns WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM generations WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM conversations WHERE id = ?").run(n),!0):!1}async addParticipant(n,e){this.db.query(`INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)
57
+ VALUES (?, ?, ?, ?)`).run(n,e.userId,JSON.stringify(e.aliases),e.joinedAt)}async listParticipants(n){return this.db.query("SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC").all(n).map(t=>({userId:t.user_id,aliases:JSON.parse(t.aliases),joinedAt:t.joined_at}))}async appendTranscript(n,e){this.db.query(`INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)
58
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.speaker,e.speakerKind,e.text,e.timestamp,e.sequence)}async listTranscript(n){return this.db.query("SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC").all(n).map(t=>E.TranscriptEntry.fromPlain({id:t.id,conversationId:t.conversation_id,speaker:t.speaker,speakerKind:t.speaker_kind,text:t.text,timestamp:t.timestamp,sequence:t.sequence}))}async appendTurn(n,e){this.db.query(`INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)
59
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.participantId,e.participantName,e.text,e.startedAt,e.endedAt,e.sequence)}async listTurns(n){return this.db.query("SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC").all(n).map(t=>({id:t.id,conversationId:t.conversation_id,participantId:t.participant_id,participantName:t.participant_name,text:t.text,startedAt:t.started_at,endedAt:t.ended_at,sequence:t.sequence}))}async appendGeneration(n,e){this.db.query(`INSERT OR REPLACE INTO generations
60
+ (id, conversation_id, agent_name, text, status, started_at, ended_at, kind, parent_generation_id, timing)
61
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.agentName,e.text,e.status,e.startedAt,e.endedAt??null,e.kind??null,e.parentGenerationId??null,e.timing?JSON.stringify(e.timing):null)}async listGenerations(n){return this.db.query("SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC").all(n).map(t=>({id:t.id,conversationId:t.conversation_id,agentName:t.agent_name,text:t.text,status:t.status,startedAt:t.started_at,endedAt:t.ended_at??void 0,kind:t.kind==="sub"?"sub":void 0,parentGenerationId:t.parent_generation_id??void 0,timing:t.timing?JSON.parse(t.timing):void 0}))}}function o(i){return{id:i.id,agentNames:JSON.parse(i.agent_names),createdAt:i.created_at,endedAt:i.ended_at}}r(o,"rowToConversation");
58
62
  //# sourceMappingURL=sqlite.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/persistence/adapters/sqlite/sqlite.ts"],
4
- "sourcesContent": ["import { Database } from \"bun:sqlite\";\nimport type {\n ConversationId,\n Generation,\n Participant,\n Turn,\n UserId,\n} from \"../../../conversations/types\";\nimport { TranscriptEntry } from \"../../../conversations/transcription/transcription\";\nimport type {\n ConversationRecord,\n NewConversation,\n Persistence,\n} from \"../../persistence\";\n\nexport interface SQLitePersistenceOptions {\n /** Database filename. Defaults to an in-memory database. */\n filename?: string;\n}\n\ninterface ConversationRow {\n id: string;\n agent_names: string;\n created_at: number;\n ended_at: number | null;\n}\n\ninterface ParticipantRow {\n conversation_id: string;\n user_id: string;\n aliases: string;\n joined_at: number;\n}\n\ninterface TranscriptRow {\n id: string;\n conversation_id: string;\n speaker: string;\n speaker_kind: string;\n text: string;\n timestamp: number;\n sequence: number;\n}\n\ninterface TurnRow {\n id: string;\n conversation_id: string;\n participant_id: string;\n participant_name: string;\n text: string;\n started_at: number;\n ended_at: number;\n sequence: number;\n}\n\ninterface GenerationRow {\n id: string;\n conversation_id: string;\n agent_name: string;\n text: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n}\n\n/**\n * SQLite-backed persistence adapter (via bun:sqlite).\n *\n * A lightweight persistent backend for local applications and early\n * deployments.\n */\nexport class SQLitePersistence implements Persistence {\n private readonly db: Database;\n\n constructor(options: SQLitePersistenceOptions = {}) {\n this.db = new Database(options.filename ?? \":memory:\");\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n agent_names TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS participants (\n conversation_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n aliases TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n PRIMARY KEY (conversation_id, user_id)\n );\n\n CREATE TABLE IF NOT EXISTS transcript (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n speaker TEXT NOT NULL,\n speaker_kind TEXT NOT NULL,\n text TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS turns (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n participant_id TEXT NOT NULL,\n participant_name TEXT NOT NULL,\n text TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS generations (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);\n `);\n }\n\n close(): void {\n this.db.close();\n }\n\n async createConversation(input: NewConversation = {}): Promise<ConversationRecord> {\n const record: ConversationRecord = {\n id: input.id ?? crypto.randomUUID(),\n agentNames: input.agentNames ?? [],\n createdAt: input.createdAt ?? Date.now(),\n endedAt: null,\n };\n this.db\n .query(\n `INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(record.id, JSON.stringify(record.agentNames), record.createdAt, null);\n return { ...record };\n }\n\n async getConversation(id: ConversationId): Promise<ConversationRecord | null> {\n const row = this.db\n .query<ConversationRow, [string]>(`SELECT * FROM conversations WHERE id = ?`)\n .get(id);\n return row ? rowToConversation(row) : null;\n }\n\n async listConversations(): Promise<ConversationRecord[]> {\n const rows = this.db\n .query<ConversationRow, []>(`SELECT * FROM conversations ORDER BY created_at ASC`)\n .all();\n return rows.map(rowToConversation);\n }\n\n async finalizeConversation(\n id: ConversationId,\n endedAt = Date.now(),\n ): Promise<ConversationRecord | null> {\n const result = this.db\n .query<unknown, [number, string]>(`UPDATE conversations SET ended_at = ? WHERE id = ?`)\n .run(endedAt, id);\n if (result.changes === 0) return null;\n return this.getConversation(id);\n }\n\n async deleteConversation(id: ConversationId): Promise<boolean> {\n const conversation = this.db\n .query<ConversationRow, [string]>(`SELECT id FROM conversations WHERE id = ?`)\n .get(id);\n if (!conversation) return false;\n this.db.query(`DELETE FROM participants WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM transcript WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM turns WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM generations WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM conversations WHERE id = ?`).run(id);\n return true;\n }\n\n async addParticipant(\n conversationId: ConversationId,\n participant: Participant,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(\n conversationId,\n participant.userId,\n JSON.stringify(participant.aliases),\n participant.joinedAt,\n );\n }\n\n async listParticipants(conversationId: ConversationId): Promise<Participant[]> {\n const rows = this.db\n .query<ParticipantRow, [string]>(\n `SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n userId: row.user_id,\n aliases: JSON.parse(row.aliases) as string[],\n joinedAt: row.joined_at,\n }));\n }\n\n async appendTranscript(\n conversationId: ConversationId,\n entry: TranscriptEntry,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.id,\n conversationId,\n entry.speaker,\n entry.speakerKind,\n entry.text,\n entry.timestamp,\n entry.sequence,\n );\n }\n\n async listTranscript(conversationId: ConversationId): Promise<TranscriptEntry[]> {\n const rows = this.db\n .query<TranscriptRow, [string]>(\n `SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) =>\n TranscriptEntry.fromPlain({\n id: row.id,\n conversationId: row.conversation_id,\n speaker: row.speaker,\n speakerKind: row.speaker_kind as TranscriptEntry[\"speakerKind\"],\n text: row.text,\n timestamp: row.timestamp,\n sequence: row.sequence,\n }),\n );\n }\n\n async appendTurn(conversationId: ConversationId, turn: Turn): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n turn.id,\n conversationId,\n turn.participantId,\n turn.participantName,\n turn.text,\n turn.startedAt,\n turn.endedAt,\n turn.sequence,\n );\n }\n\n async listTurns(conversationId: ConversationId): Promise<Turn[]> {\n const rows = this.db\n .query<TurnRow, [string]>(\n `SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n participantId: row.participant_id,\n participantName: row.participant_name,\n text: row.text,\n startedAt: row.started_at,\n endedAt: row.ended_at,\n sequence: row.sequence,\n }));\n }\n\n async appendGeneration(\n conversationId: ConversationId,\n generation: Generation,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO generations (id, conversation_id, agent_name, text, status, started_at, ended_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n generation.id,\n conversationId,\n generation.agentName,\n generation.text,\n generation.status,\n generation.startedAt,\n generation.endedAt ?? null,\n );\n }\n\n async listGenerations(conversationId: ConversationId): Promise<Generation[]> {\n const rows = this.db\n .query<GenerationRow, [string]>(\n `SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n agentName: row.agent_name,\n text: row.text,\n status: row.status as Generation[\"status\"],\n startedAt: row.started_at,\n endedAt: row.ended_at ?? undefined,\n }));\n }\n}\n\nfunction rowToConversation(row: ConversationRow): ConversationRecord {\n return {\n id: row.id,\n agentNames: JSON.parse(row.agent_names) as string[],\n createdAt: row.created_at,\n endedAt: row.ended_at,\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["sqlite_exports", "__export", "SQLitePersistence", "__toCommonJS", "import_bun_sqlite", "import_transcription", "SQLitePersistence", "__name", "options", "input", "record", "id", "row", "rowToConversation", "endedAt", "conversationId", "participant", "entry", "turn", "generation"]
4
+ "sourcesContent": ["import { Database } from \"bun:sqlite\";\nimport type {\n ConversationId,\n Generation,\n GenerationTiming,\n Participant,\n Turn,\n UserId,\n} from \"../../../conversations/types\";\nimport { TranscriptEntry } from \"../../../conversations/transcription/transcription\";\nimport type {\n ConversationRecord,\n NewConversation,\n Persistence,\n} from \"../../persistence\";\n\nexport interface SQLitePersistenceOptions {\n /** Database filename. Defaults to an in-memory database. */\n filename?: string;\n}\n\ninterface ConversationRow {\n id: string;\n agent_names: string;\n created_at: number;\n ended_at: number | null;\n}\n\ninterface ParticipantRow {\n conversation_id: string;\n user_id: string;\n aliases: string;\n joined_at: number;\n}\n\ninterface TranscriptRow {\n id: string;\n conversation_id: string;\n speaker: string;\n speaker_kind: string;\n text: string;\n timestamp: number;\n sequence: number;\n}\n\ninterface TurnRow {\n id: string;\n conversation_id: string;\n participant_id: string;\n participant_name: string;\n text: string;\n started_at: number;\n ended_at: number;\n sequence: number;\n}\n\ninterface GenerationRow {\n id: string;\n conversation_id: string;\n agent_name: string;\n text: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n kind: string | null;\n parent_generation_id: string | null;\n timing: string | null;\n}\n\n/**\n * SQLite-backed persistence adapter (via bun:sqlite).\n *\n * A lightweight persistent backend for local applications and early\n * deployments.\n */\nexport class SQLitePersistence implements Persistence {\n private readonly db: Database;\n\n constructor(options: SQLitePersistenceOptions = {}) {\n this.db = new Database(options.filename ?? \":memory:\");\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n agent_names TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS participants (\n conversation_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n aliases TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n PRIMARY KEY (conversation_id, user_id)\n );\n\n CREATE TABLE IF NOT EXISTS transcript (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n speaker TEXT NOT NULL,\n speaker_kind TEXT NOT NULL,\n text TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS turns (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n participant_id TEXT NOT NULL,\n participant_name TEXT NOT NULL,\n text TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS generations (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER,\n kind TEXT,\n parent_generation_id TEXT,\n timing TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);\n `);\n\n // Lightweight migration for databases created before the generation\n // columns existed: CREATE TABLE IF NOT EXISTS leaves existing tables\n // untouched, so add the missing columns when needed.\n const generationColumns = new Set(\n (this.db.query(`PRAGMA table_info(generations)`).all() as { name: string }[]).map(\n (column) => column.name,\n ),\n );\n if (!generationColumns.has(\"kind\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN kind TEXT`);\n }\n if (!generationColumns.has(\"parent_generation_id\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN parent_generation_id TEXT`);\n }\n if (!generationColumns.has(\"timing\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN timing TEXT`);\n }\n }\n\n close(): void {\n this.db.close();\n }\n\n async createConversation(input: NewConversation = {}): Promise<ConversationRecord> {\n const record: ConversationRecord = {\n id: input.id ?? crypto.randomUUID(),\n agentNames: input.agentNames ?? [],\n createdAt: input.createdAt ?? Date.now(),\n endedAt: null,\n };\n this.db\n .query(\n `INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(record.id, JSON.stringify(record.agentNames), record.createdAt, null);\n return { ...record };\n }\n\n async getConversation(id: ConversationId): Promise<ConversationRecord | null> {\n const row = this.db\n .query<ConversationRow, [string]>(`SELECT * FROM conversations WHERE id = ?`)\n .get(id);\n return row ? rowToConversation(row) : null;\n }\n\n async listConversations(): Promise<ConversationRecord[]> {\n const rows = this.db\n .query<ConversationRow, []>(`SELECT * FROM conversations ORDER BY created_at ASC`)\n .all();\n return rows.map(rowToConversation);\n }\n\n async finalizeConversation(\n id: ConversationId,\n endedAt = Date.now(),\n ): Promise<ConversationRecord | null> {\n const result = this.db\n .query<unknown, [number, string]>(`UPDATE conversations SET ended_at = ? WHERE id = ?`)\n .run(endedAt, id);\n if (result.changes === 0) return null;\n return this.getConversation(id);\n }\n\n async deleteConversation(id: ConversationId): Promise<boolean> {\n const conversation = this.db\n .query<ConversationRow, [string]>(`SELECT id FROM conversations WHERE id = ?`)\n .get(id);\n if (!conversation) return false;\n this.db.query(`DELETE FROM participants WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM transcript WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM turns WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM generations WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM conversations WHERE id = ?`).run(id);\n return true;\n }\n\n async addParticipant(\n conversationId: ConversationId,\n participant: Participant,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(\n conversationId,\n participant.userId,\n JSON.stringify(participant.aliases),\n participant.joinedAt,\n );\n }\n\n async listParticipants(conversationId: ConversationId): Promise<Participant[]> {\n const rows = this.db\n .query<ParticipantRow, [string]>(\n `SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n userId: row.user_id,\n aliases: JSON.parse(row.aliases) as string[],\n joinedAt: row.joined_at,\n }));\n }\n\n async appendTranscript(\n conversationId: ConversationId,\n entry: TranscriptEntry,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.id,\n conversationId,\n entry.speaker,\n entry.speakerKind,\n entry.text,\n entry.timestamp,\n entry.sequence,\n );\n }\n\n async listTranscript(conversationId: ConversationId): Promise<TranscriptEntry[]> {\n const rows = this.db\n .query<TranscriptRow, [string]>(\n `SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) =>\n TranscriptEntry.fromPlain({\n id: row.id,\n conversationId: row.conversation_id,\n speaker: row.speaker,\n speakerKind: row.speaker_kind as TranscriptEntry[\"speakerKind\"],\n text: row.text,\n timestamp: row.timestamp,\n sequence: row.sequence,\n }),\n );\n }\n\n async appendTurn(conversationId: ConversationId, turn: Turn): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n turn.id,\n conversationId,\n turn.participantId,\n turn.participantName,\n turn.text,\n turn.startedAt,\n turn.endedAt,\n turn.sequence,\n );\n }\n\n async listTurns(conversationId: ConversationId): Promise<Turn[]> {\n const rows = this.db\n .query<TurnRow, [string]>(\n `SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n participantId: row.participant_id,\n participantName: row.participant_name,\n text: row.text,\n startedAt: row.started_at,\n endedAt: row.ended_at,\n sequence: row.sequence,\n }));\n }\n\n async appendGeneration(\n conversationId: ConversationId,\n generation: Generation,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO generations\n (id, conversation_id, agent_name, text, status, started_at, ended_at, kind, parent_generation_id, timing)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n generation.id,\n conversationId,\n generation.agentName,\n generation.text,\n generation.status,\n generation.startedAt,\n generation.endedAt ?? null,\n generation.kind ?? null,\n generation.parentGenerationId ?? null,\n generation.timing ? JSON.stringify(generation.timing) : null,\n );\n }\n\n async listGenerations(conversationId: ConversationId): Promise<Generation[]> {\n const rows = this.db\n .query<GenerationRow, [string]>(\n `SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n agentName: row.agent_name,\n text: row.text,\n status: row.status as Generation[\"status\"],\n startedAt: row.started_at,\n endedAt: row.ended_at ?? undefined,\n kind: row.kind === \"sub\" ? \"sub\" : undefined,\n parentGenerationId: row.parent_generation_id ?? undefined,\n timing: row.timing ? (JSON.parse(row.timing) as GenerationTiming) : undefined,\n }));\n }\n}\n\nfunction rowToConversation(row: ConversationRow): ConversationRecord {\n return {\n id: row.id,\n agentNames: JSON.parse(row.agent_names) as string[],\n createdAt: row.created_at,\n endedAt: row.ended_at,\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["sqlite_exports", "__export", "SQLitePersistence", "__toCommonJS", "import_bun_sqlite", "import_transcription", "SQLitePersistence", "__name", "options", "generationColumns", "column", "input", "record", "id", "row", "rowToConversation", "endedAt", "conversationId", "participant", "entry", "turn", "generation"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var x=(p,o)=>{for(var f in o)i(p,f,{get:o[f],enumerable:!0})},P=(p,o,f,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of w(o))!m.call(p,e)&&e!==f&&i(p,e,{get:()=>o[e],enumerable:!(r=l(o,e))||r.enumerable});return p};var n=p=>P(i({},"__esModule",{value:!0}),p);var s={};x(s,{Pipeflow:()=>t.Pipeflow});module.exports=n(s);var t=require("./pipeflow.js");
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/pipeflow/index.ts"],
4
+ "sourcesContent": ["export { Pipeflow } from \"./pipeflow\";\nexport type { PipeflowOptions } from \"./pipeflow\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0CAAAE,EAAAF,GAAA,IAAAG,EAAyB",
6
+ "names": ["pipeflow_exports", "__export", "__toCommonJS", "import_pipeflow"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var o=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var i=(e,t)=>o(e,"name",{value:t,configurable:!0});var f=(e,t)=>{for(var s in t)o(e,s,{get:t[s],enumerable:!0})},d=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of a(t))!T.call(e,r)&&r!==s&&o(e,r,{get:()=>t[r],enumerable:!(n=c(t,r))||n.enumerable});return e};var y=e=>d(o({},"__esModule",{value:!0}),e);var L={};f(L,{Pipeflow:()=>u});module.exports=y(L);var l=require("../agents/agent.js"),m=require("../conversations/conversations.js"),p=require("../persistence/adapters/memory/memory.js");class u{static{i(this,"Pipeflow")}llm;stt;tts;conversations;constructor(t={}){this.llm=t.llm,this.stt=t.stt,this.tts=t.tts;const s=t.persistence??new p.MemoryPersistence;this.conversations=new m.Conversations({persistence:s,stt:t.stt,tts:t.tts,autoExecuteTools:t.autoExecuteTools})}agent(t){return new l.Agent({...t,llm:t.llm??this.llm})}}
2
+ //# sourceMappingURL=pipeflow.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/pipeflow/pipeflow.ts"],
4
+ "sourcesContent": ["import { Agent, type AgentOptions } from \"../agents/agent\";\nimport { Conversations } from \"../conversations/conversations\";\nimport { MemoryPersistence } from \"../persistence/adapters/memory/memory\";\nimport type { Persistence } from \"../persistence/persistence\";\nimport type { LLM } from \"../providers/llm/types\";\nimport type { STT } from \"../providers/stt/types\";\nimport type { TTS } from \"../providers/tts/types\";\n\nexport interface PipeflowOptions {\n llm?: LLM;\n stt?: STT;\n tts?: TTS;\n persistence?: Persistence;\n /**\n * Default for created conversations: auto-execute the agents' tools\n * (default `true`), feeding each tool's result back into the model loop.\n * Set `false` to resolve tool calls from your own backend via\n * `resolveToolCall()`. Override per conversation in\n * `pipeflow.conversations.create()`.\n */\n autoExecuteTools?: boolean;\n}\n\n/**\n * The Pipeflow entry point.\n *\n * ```ts\n * const pipeflow = new Pipeflow({ llm });\n * const agent = pipeflow.agent({ name: \"Jarvis\", context: \"...\" });\n * const conversation = await pipeflow.conversations.create({ agents: [agent] });\n * ```\n */\nexport class Pipeflow {\n readonly llm: LLM | undefined;\n readonly stt: STT | undefined;\n readonly tts: TTS | undefined;\n readonly conversations: Conversations;\n\n constructor(options: PipeflowOptions = {}) {\n this.llm = options.llm;\n this.stt = options.stt;\n this.tts = options.tts;\n const persistence = options.persistence ?? new MemoryPersistence();\n this.conversations = new Conversations({\n persistence,\n stt: options.stt,\n tts: options.tts,\n autoExecuteTools: options.autoExecuteTools,\n });\n }\n\n /**\n * Create an agent. Agents inherit the Pipeflow instance's LLM provider so\n * `agent.run()` works out of the box.\n */\n agent(options: Omit<AgentOptions, \"llm\"> & { llm?: LLM }): Agent {\n return new Agent({ ...options, llm: options.llm ?? this.llm });\n }\n}\n"],
5
+ "mappings": "4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAyC,2BACzCC,EAA8B,0CAC9BC,EAAkC,iDA8B3B,MAAMC,CAAS,CAhCtB,MAgCsB,CAAAC,EAAA,iBACX,IACA,IACA,IACA,cAET,YAAYC,EAA2B,CAAC,EAAG,CACzC,KAAK,IAAMA,EAAQ,IACnB,KAAK,IAAMA,EAAQ,IACnB,KAAK,IAAMA,EAAQ,IACnB,MAAMC,EAAcD,EAAQ,aAAe,IAAI,oBAC/C,KAAK,cAAgB,IAAI,gBAAc,CACrC,YAAAC,EACA,IAAKD,EAAQ,IACb,IAAKA,EAAQ,IACb,iBAAkBA,EAAQ,gBAC5B,CAAC,CACH,CAMA,MAAMA,EAA2D,CAC/D,OAAO,IAAI,QAAM,CAAE,GAAGA,EAAS,IAAKA,EAAQ,KAAO,KAAK,GAAI,CAAC,CAC/D,CACF",
6
+ "names": ["pipeflow_exports", "__export", "Pipeflow", "__toCommonJS", "import_agent", "import_conversations", "import_memory", "Pipeflow", "__name", "options", "persistence"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var i=(o,e)=>{for(var L in e)r(o,L,{get:e[L],enumerable:!0})},l=(o,e,L,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let T of M(e))!S.call(o,T)&&T!==L&&r(o,T,{get:()=>e[T],enumerable:!(p=x(e,T))||p.enumerable});return o};var n=o=>l(r({},"__esModule",{value:!0}),o);var f={};i(f,{DeepSeekLLM:()=>t.DeepSeekLLM,DeepgramSTT:()=>m.DeepgramSTT,KokoroTTS:()=>s.KokoroTTS,complete:()=>t.complete,streamText:()=>t.streamText});module.exports=n(f);var t=require("./llm/index.js"),m=require("./stt/index.js"),s=require("./tts/index.js");
1
+ "use strict";var r=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var n=Object.prototype.hasOwnProperty;var S=(t,e)=>{for(var T in e)r(t,T,{get:e[T],enumerable:!0})},i=(t,e,T,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let L of M(e))!n.call(t,L)&&L!==T&&r(t,L,{get:()=>e[L],enumerable:!(p=x(e,L))||p.enumerable});return t};var l=t=>i(r({},"__esModule",{value:!0}),t);var f={};S(f,{DeepSeekLLM:()=>o.DeepSeekLLM,DeepgramSTT:()=>m.DeepgramSTT,KokoroTTS:()=>s.KokoroTTS,OpenRouterLLM:()=>o.OpenRouterLLM,complete:()=>o.complete,streamText:()=>o.streamText});module.exports=l(f);var o=require("./llm/index.js"),m=require("./stt/index.js"),s=require("./tts/index.js");
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/providers/index.ts"],
4
- "sourcesContent": ["export type { LLM, LLMEvent, LLMMessage, LLMRole, LLMToolCall, LLMToolDefinition, LLMRequest } from \"./llm/index\";\nexport type { STT, STTOptions, STTSession } from \"./stt/index\";\nexport type { TTS, TTSRequest } from \"./tts/index\";\n\nexport { complete, streamText, DeepSeekLLM } from \"./llm/index\";\nexport { DeepgramSTT } from \"./stt/index\";\nexport { KokoroTTS } from \"./tts/index\";\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4JAAAE,EAAAF,GAIA,IAAAG,EAAkD,uBAClDC,EAA4B,uBAC5BC,EAA0B",
4
+ "sourcesContent": ["export type { LLM, LLMEvent, LLMMessage, LLMRole, LLMToolCall, LLMToolDefinition, LLMRequest } from \"./llm/index\";\nexport type { STT, STTOptions, STTSession } from \"./stt/index\";\nexport type { TTS, TTSRequest } from \"./tts/index\";\n\nexport { complete, streamText, DeepSeekLLM, OpenRouterLLM } from \"./llm/index\";\nexport { DeepgramSTT } from \"./stt/index\";\nexport { KokoroTTS } from \"./tts/index\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8LAAAE,EAAAF,GAIA,IAAAG,EAAiE,uBACjEC,EAA4B,uBAC5BC,EAA0B",
6
6
  "names": ["providers_exports", "__export", "__toCommonJS", "import_llm", "import_stt", "import_tts"]
7
7
  }
@@ -0,0 +1,5 @@
1
+ "use strict";var b=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var u=(r,e)=>b(r,"name",{value:e,configurable:!0});var w=(r,e)=>{for(var s in e)b(r,s,{get:e[s],enumerable:!0})},T=(r,e,s,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of k(e))!L.call(r,o)&&o!==s&&b(r,o,{get:()=>e[o],enumerable:!(a=y(e,o))||a.enumerable});return r};var _=r=>T(b({},"__esModule",{value:!0}),r);var x={};w(x,{ClaudeLLM:()=>M});module.exports=_(x);class M{static{u(this,"ClaudeLLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("ClaudeLLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"claude-sonnet-4-5",this.baseUrl=(e.baseUrl??"https://api.anthropic.com/v1").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage}stop(){for(const e of this.streams)e.abort()}async*stream(e){const s=new AbortController;this.streams.add(s);try{const{system:a,wire:o}=v(e.messages);this.onTiming?.("request-start");const d=await this.fetchImpl(`${this.baseUrl}/messages`,{method:"POST",headers:{"content-type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:this.model,max_tokens:e.maxTokens??4096,...a.length>0?{system:a}:{},messages:o,...e.tools&&e.tools.length>0?{tools:e.tools.map(n=>({name:n.name,description:n.description,input_schema:n.parameters??{type:"object",properties:{}}}))}:{},...e.temperature!==void 0?{temperature:e.temperature}:{},stream:!0}),signal:s.signal});if(!d.ok){const n=await d.text();throw new Error(`Claude request failed (${d.status}): ${n}`)}if(!d.body)throw new Error("Claude returned an empty body");this.onTiming?.("headers");const l=new Map;let p,g,c=!1;for await(const n of C(d.body,s.signal,this.onTiming,this.idleTimeoutMs)){switch(n.event){case"message_start":{p=n.data.message?.usage?.input_tokens;break}case"content_block_start":{const t=n.data.content_block;t.type==="tool_use"&&t.id&&t.name&&l.set(n.data.index,{id:t.id,name:t.name,json:""});break}case"content_block_delta":{const t=n.data.delta;if(t.type==="text_delta"&&t.text)yield{type:"delta",content:t.text};else if(t.type==="input_json_delta"&&t.partial_json){const i=l.get(n.data.index);i&&(i.json+=t.partial_json)}break}case"content_block_stop":{const t=l.get(n.data.index);if(t){let i="{}";if(t.json.length>0)try{i=t.json,JSON.parse(i)}catch{i="{}"}yield{type:"tool_call",id:t.id,name:t.name,arguments:i},l.delete(n.data.index)}break}case"message_delta":{const t=n.data.usage;t?.output_tokens!==void 0&&(g=t.output_tokens);break}case"message_stop":(p!==void 0||g!==void 0)&&this.onUsage?.({promptTokens:p??0,completionTokens:g??0}),c=!0;break;case"error":{const t=n.data.error;yield{type:"error",error:new Error(`Claude stream error: ${t?.message??JSON.stringify(n.data)}`)},c=!0;break}}if(c)break}}finally{this.streams.delete(s)}yield{type:"done"}}}function v(r){const e=[],s=[];for(const a of r)switch(a.role){case"system":e.push(a.content);break;case"user":s.push({role:"user",content:a.content});break;case"assistant":{const o=[];a.content&&o.push({type:"text",text:a.content});for(const d of a.toolCalls??[]){let l={};try{l=JSON.parse(d.arguments)}catch{l={}}o.push({type:"tool_use",id:d.id,name:d.name,input:l})}s.push({role:"assistant",content:o});break}case"tool":s.push({role:"user",content:[{type:"tool_result",tool_use_id:a.toolCallId,content:a.content}]});break}return{system:e.join(`
2
+
3
+ `),wire:s}}u(v,"mapMessages");async function*C(r,e,s,a){const o=r.getReader(),d=new TextDecoder;let l="",p=!1;const g=u(()=>{let c;return new Promise((n,t)=>{const i=u(()=>{c!==void 0&&clearTimeout(c),e.removeEventListener("abort",f)},"cleanup"),f=u(()=>{i(),t(new DOMException("The operation was aborted.","AbortError"))},"onAbort");o.read().then(m=>{i(),n(m)},m=>{i(),t(m)}),c=setTimeout(()=>{i(),o.cancel().catch(()=>{}),t(new Error(`Claude stream idle for ${a}ms \u2014 no data received; aborting the stalled stream`))},a),e.addEventListener("abort",f,{once:!0})})},"readWithTimeout");for(;;){if(e.aborted)throw new DOMException("The operation was aborted.","AbortError");const{done:c,value:n}=await g();if(c)break;l+=d.decode(n,{stream:!0});const t=l.split(/\r?\n\r?\n/);l=t.pop()??"";for(const i of t){p||(p=!0,s?.("first-chunk"));let f="";const m=[];for(const h of i.split(/\r?\n/))h.startsWith("event:")?f=h.slice(6).trim():h.startsWith("data:")&&m.push(h.slice(5).trimStart());if(m.length!==0)try{yield{event:f,data:JSON.parse(m.join(`
4
+ `))}}catch{}}}}u(C,"readClaudeSSE");
5
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/providers/llm/adapters/claude/claude.ts"],
4
+ "sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMMessage,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\n\nexport interface ClaudeOptions {\n apiKey: string;\n /** Defaults to `claude-sonnet-4-5`. */\n model?: string;\n /** Defaults to `https://api.anthropic.com/v1`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n}\n\n/** An SSE frame: the `event:` type plus the parsed `data:` payload. */\ninterface ClaudeEvent {\n event: string;\n data: Record<string, unknown>;\n}\n\n/**\n * Claude LLM adapter (Anthropic Messages API over SSE).\n *\n * The wire format differs from the OpenAI-compatible adapters: tools are\n * `input_schema` blocks, tool calls arrive as `tool_use` content blocks with\n * `input_json_delta` fragments (reassembled here into `tool_call` events),\n * tool results are `tool_result` blocks inside user messages, and `max_tokens`\n * is required. There is no `response_format`, so `toolMode` is not supported \u2014\n * tool calling is always native.\n */\nexport class ClaudeLLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: ClaudeOptions) {\n if (!options.apiKey) {\n throw new Error(\"ClaudeLLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"claude-sonnet-4-5\";\n this.baseUrl = (options.baseUrl ?? \"https://api.anthropic.com/v1\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n const { system, wire } = mapMessages(request.messages);\n\n this.onTiming?.(\"request-start\");\n const response = await this.fetchImpl(`${this.baseUrl}/messages`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": this.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: this.model,\n // Required by the Anthropic API.\n max_tokens: request.maxTokens ?? 4096,\n ...(system.length > 0 ? { system } : {}),\n messages: wire,\n ...(request.tools && request.tools.length > 0\n ? {\n tools: request.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.parameters ?? { type: \"object\", properties: {} },\n })),\n }\n : {}),\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n stream: true,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Claude request failed (${response.status}): ${body}`);\n }\n if (!response.body) {\n throw new Error(\"Claude returned an empty body\");\n }\n this.onTiming?.(\"headers\");\n\n // Tool_use blocks can interleave and complete in any order; keyed by\n // block index. Arguments arrive as `input_json_delta` fragments.\n const toolBlocks = new Map<\n number,\n { id: string; name: string; json: string }\n >();\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let finished = false;\n\n for await (const frame of readClaudeSSE(\n response.body,\n controller.signal,\n this.onTiming,\n this.idleTimeoutMs,\n )) {\n switch (frame.event) {\n case \"message_start\": {\n const usage = frame.data.message as { usage?: { input_tokens?: number } };\n inputTokens = usage?.usage?.input_tokens;\n break;\n }\n case \"content_block_start\": {\n const block = frame.data.content_block as {\n type: string;\n id?: string;\n name?: string;\n };\n if (block.type === \"tool_use\" && block.id && block.name) {\n toolBlocks.set(frame.data.index as number, {\n id: block.id,\n name: block.name,\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const delta = frame.data.delta as { type: string; text?: string; partial_json?: string };\n if (delta.type === \"text_delta\" && delta.text) {\n yield { type: \"delta\", content: delta.text };\n } else if (delta.type === \"input_json_delta\" && delta.partial_json) {\n const block = toolBlocks.get(frame.data.index as number);\n if (block) block.json += delta.partial_json;\n }\n break;\n }\n case \"content_block_stop\": {\n const block = toolBlocks.get(frame.data.index as number);\n if (block) {\n let args = \"{}\";\n if (block.json.length > 0) {\n try {\n args = block.json;\n JSON.parse(args); // validate before handing off\n } catch {\n args = \"{}\";\n }\n }\n yield {\n type: \"tool_call\",\n id: block.id,\n name: block.name,\n arguments: args,\n };\n toolBlocks.delete(frame.data.index as number);\n }\n break;\n }\n case \"message_delta\": {\n const usage = frame.data.usage as { output_tokens?: number };\n if (usage?.output_tokens !== undefined) outputTokens = usage.output_tokens;\n break;\n }\n case \"message_stop\":\n if (inputTokens !== undefined || outputTokens !== undefined) {\n this.onUsage?.({\n promptTokens: inputTokens ?? 0,\n completionTokens: outputTokens ?? 0,\n });\n }\n finished = true;\n break;\n case \"error\": {\n const error = frame.data.error as { message?: string } | undefined;\n yield {\n type: \"error\",\n error: new Error(\n `Claude stream error: ${error?.message ?? JSON.stringify(frame.data)}`,\n ),\n };\n finished = true;\n break;\n }\n }\n if (finished) break;\n }\n } finally {\n this.streams.delete(controller);\n }\n\n yield { type: \"done\" };\n }\n}\n\n/** Anthropic messages: leading system messages become `system`; the rest map to wire roles. */\nfunction mapMessages(messages: LLMMessage[]): { system: string; wire: unknown[] } {\n const system: string[] = [];\n const wire: unknown[] = [];\n for (const message of messages) {\n switch (message.role) {\n case \"system\":\n system.push(message.content);\n break;\n case \"user\":\n wire.push({ role: \"user\", content: message.content });\n break;\n case \"assistant\": {\n const blocks: unknown[] = [];\n if (message.content) blocks.push({ type: \"text\", text: message.content });\n for (const call of message.toolCalls ?? []) {\n let input: unknown = {};\n try {\n input = JSON.parse(call.arguments);\n } catch {\n input = {};\n }\n blocks.push({ type: \"tool_use\", id: call.id, name: call.name, input });\n }\n wire.push({ role: \"assistant\", content: blocks });\n break;\n }\n case \"tool\":\n wire.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: message.toolCallId,\n content: message.content,\n },\n ],\n });\n break;\n }\n }\n return { system: system.join(\"\\n\\n\"), wire };\n}\n\n/**\n * Parse the Anthropic SSE stream into `{ event, data }` frames. Unlike the\n * OpenAI-compatible streamer, the `event:` line matters \u2014 it distinguishes\n * text deltas from tool-argument deltas. Bounded by the idle timeout.\n */\nasync function* readClaudeSSE(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n onTiming: LLMStreamTimingCallback | undefined,\n idleTimeoutMs: number,\n): AsyncGenerator<ClaudeEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let firstEvent = false;\n\n const readWithTimeout = (): Promise<Awaited<ReturnType<typeof reader.read>>> => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n return new Promise((resolve, reject) => {\n const cleanup = () => {\n if (timer !== undefined) clearTimeout(timer);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = () => {\n cleanup();\n reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n };\n reader.read().then(\n (result) => {\n cleanup();\n resolve(result);\n },\n (error) => {\n cleanup();\n reject(error);\n },\n );\n timer = setTimeout(() => {\n cleanup();\n void reader.cancel().catch(() => {});\n reject(\n new Error(\n `Claude stream idle for ${idleTimeoutMs}ms \u2014 no data received; aborting the stalled stream`,\n ),\n );\n }, idleTimeoutMs);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n };\n\n while (true) {\n if (signal.aborted) {\n throw new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n const { done, value } = await readWithTimeout();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const frames = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = frames.pop() ?? \"\";\n for (const frame of frames) {\n if (!firstEvent) {\n firstEvent = true;\n onTiming?.(\"first-chunk\");\n }\n let event = \"\";\n const dataLines: string[] = [];\n for (const line of frame.split(/\\r?\\n/)) {\n if (line.startsWith(\"event:\")) event = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) dataLines.push(line.slice(5).trimStart());\n }\n if (dataLines.length === 0) continue;\n try {\n yield { event, data: JSON.parse(dataLines.join(\"\\n\")) as Record<string, unknown> };\n } catch {\n // Ignore malformed frames.\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["claude_exports", "__export", "ClaudeLLM", "__toCommonJS", "ClaudeLLM", "__name", "options", "controller", "request", "system", "wire", "mapMessages", "response", "tool", "body", "toolBlocks", "inputTokens", "outputTokens", "finished", "frame", "readClaudeSSE", "block", "delta", "args", "usage", "error", "messages", "message", "blocks", "call", "input", "signal", "onTiming", "idleTimeoutMs", "reader", "decoder", "buffer", "firstEvent", "readWithTimeout", "timer", "resolve", "reject", "cleanup", "onAbort", "result", "done", "value", "frames", "event", "dataLines", "line"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var t=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var r in e)t(o,r,{get:e[r],enumerable:!0})},x=(o,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of u(e))!f.call(o,p)&&p!==r&&t(o,p,{get:()=>e[p],enumerable:!(a=l(e,p))||a.enumerable});return o};var C=o=>x(t({},"__esModule",{value:!0}),o);var L={};m(L,{ClaudeLLM:()=>d.ClaudeLLM});module.exports=C(L);var d=require("./claude.js");
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/providers/llm/adapters/claude/index.ts"],
4
+ "sourcesContent": ["export { ClaudeLLM } from \"./claude\";\nexport type { ClaudeOptions } from \"./claude\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4CAAAE,EAAAF,GAAA,IAAAG,EAA0B",
6
+ "names": ["claude_exports", "__export", "__toCommonJS", "import_claude"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var f=(r,e)=>d(r,"name",{value:e,configurable:!0});var y=(r,e)=>{for(var a in e)d(r,a,{get:e[a],enumerable:!0})},b=(r,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of h(e))!u.call(r,t)&&t!==a&&d(r,t,{get:()=>e[t],enumerable:!(o=m(e,t))||o.enumerable});return r};var g=r=>b(d({},"__esModule",{value:!0}),r);var S={};y(S,{DeepSeekLLM:()=>k});module.exports=g(S);class k{static{f(this,"DeepSeekLLM")}apiKey;model;baseUrl;fetchImpl;abort=null;constructor(e){if(!e.apiKey)throw new Error("DeepSeekLLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"deepseek-chat",this.baseUrl=(e.baseUrl??"https://api.deepseek.com").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch}stop(){this.abort?.abort()}async*stream(e){this.abort?.abort();const a=new AbortController;this.abort=a;try{const o=await this.fetchImpl(`${this.baseUrl}/chat/completions`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({model:this.model,messages:e.messages,tools:e.tools?.map(i=>({type:"function",function:i})),stream:!0,temperature:e.temperature,max_tokens:e.maxTokens}),signal:a.signal});if(!o.ok){const i=await o.text();throw new Error(`DeepSeek request failed (${o.status}): ${i}`)}if(!o.body)throw new Error("DeepSeek returned an empty body");const t=new Map;for await(const i of L(o.body,a.signal)){const l=i.choices?.[0];if(!l)continue;const c=l.delta;c?.content&&(yield{type:"delta",content:c.content});for(const n of c?.tool_calls??[]){const p=n.index??0,s=t.get(p)??{id:"",name:"",arguments:""};n.id&&(s.id=n.id),n.function?.name&&(s.name+=n.function.name),n.function?.arguments&&(s.arguments+=n.function.arguments),t.set(p,s)}if(l.finish_reason==="tool_calls"){for(const n of t.values())yield{type:"tool_call",id:n.id,name:n.name,arguments:n.arguments};break}if(l.finish_reason==="stop")break}yield{type:"done"}}finally{this.abort===a&&(this.abort=null)}}}async function*L(r,e){const a=r.getReader(),o=new TextDecoder;let t="";for(;;){if(e.aborted)throw new DOMException("The operation was aborted.","AbortError");const{done:i,value:l}=await a.read();if(i)break;t+=o.decode(l,{stream:!0});const c=t.split(/\r?\n\r?\n/);t=c.pop()??"";for(const n of c)for(const p of n.split(/\r?\n/)){if(!p.startsWith("data:"))continue;const s=p.slice(5).trim();if(s==="[DONE]")return;try{yield JSON.parse(s)}catch{}}}}f(L,"parseSSE");
1
+ "use strict";var o=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var l=(t,e)=>o(t,"name",{value:e,configurable:!0});var p=(t,e)=>{for(var i in e)o(t,i,{get:e[i],enumerable:!0})},h=(t,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of d(e))!m.call(t,a)&&a!==i&&o(t,a,{get:()=>e[a],enumerable:!(r=n(e,a))||r.enumerable});return t};var L=t=>h(o({},"__esModule",{value:!0}),t);var M={};p(M,{DeepSeekLLM:()=>c});module.exports=L(M);var s=require("../openai-compatible.js");class c{static{l(this,"DeepSeekLLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;toolMode;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("DeepSeekLLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"deepseek-chat",this.baseUrl=(e.baseUrl??"https://api.deepseek.com").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage,this.toolMode=e.toolMode}stop(){for(const e of this.streams)e.abort()}async*stream(e){const i=new AbortController;this.streams.add(i);try{yield*(0,s.openAICompatibleStream)({baseUrl:this.baseUrl,apiKey:this.apiKey,model:this.model,fetchImpl:this.fetchImpl,request:e,signal:i.signal,extraBody:{thinking:{type:"disabled"}},label:"DeepSeek",onTiming:this.onTiming,idleTimeoutMs:this.idleTimeoutMs,onUsage:this.onUsage,toolMode:this.toolMode})}finally{this.streams.delete(i)}}}
2
2
  //# sourceMappingURL=deepseek.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/providers/llm/adapters/deepseek/deepseek.ts"],
4
- "sourcesContent": ["import type { LLM, LLMEvent, LLMRequest } from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\n\nexport interface DeepSeekOptions {\n apiKey: string;\n /** Defaults to `deepseek-chat`. */\n model?: string;\n /** Defaults to `https://api.deepseek.com`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n}\n\ninterface DeepSeekDeltaToolCall {\n index?: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n}\n\ninterface DeepSeekChunk {\n choices?: Array<{\n delta?: { content?: string | null; tool_calls?: DeepSeekDeltaToolCall[] };\n finish_reason?: string | null;\n }>;\n}\n\n/**\n * DeepSeek LLM adapter (OpenAI-compatible chat completions over SSE).\n */\nexport class DeepSeekLLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private abort: AbortController | null = null;\n\n constructor(options: DeepSeekOptions) {\n if (!options.apiKey) {\n throw new Error(\"DeepSeekLLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"deepseek-chat\";\n this.baseUrl = (options.baseUrl ?? \"https://api.deepseek.com\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n }\n\n stop(): void {\n this.abort?.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n // Only one generation at a time per adapter instance.\n this.abort?.abort();\n const controller = new AbortController();\n this.abort = controller;\n\n try {\n const response = await this.fetchImpl(`${this.baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n messages: request.messages,\n tools: request.tools?.map((tool) => ({ type: \"function\", function: tool })),\n stream: true,\n temperature: request.temperature,\n max_tokens: request.maxTokens,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`DeepSeek request failed (${response.status}): ${body}`);\n }\n if (!response.body) {\n throw new Error(\"DeepSeek returned an empty body\");\n }\n\n // Tool calls arrive fragmented across chunks and are reassembled by\n // index before being emitted once the stream signals `tool_calls`.\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n\n for await (const chunk of parseSSE(response.body, controller.signal)) {\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n const delta = choice.delta;\n if (delta?.content) {\n yield { type: \"delta\", content: delta.content };\n }\n\n for (const tc of delta?.tool_calls ?? []) {\n const index = tc.index ?? 0;\n const accumulated = toolCalls.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (tc.id) accumulated.id = tc.id;\n if (tc.function?.name) accumulated.name += tc.function.name;\n if (tc.function?.arguments) accumulated.arguments += tc.function.arguments;\n toolCalls.set(index, accumulated);\n }\n\n if (choice.finish_reason === \"tool_calls\") {\n for (const call of toolCalls.values()) {\n yield {\n type: \"tool_call\",\n id: call.id,\n name: call.name,\n arguments: call.arguments,\n };\n }\n break;\n }\n if (choice.finish_reason === \"stop\") {\n break;\n }\n }\n\n yield { type: \"done\" };\n } finally {\n if (this.abort === controller) {\n this.abort = null;\n }\n }\n }\n}\n\n/**\n * Parse an SSE byte stream into JSON events. Supports both LF and CRLF\n * framing, ignores comments and malformed frames, and stops at `[DONE]`.\n * Aborts with an `AbortError` once the signal fires.\n */\nasync function* parseSSE(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n): AsyncGenerator<DeepSeekChunk> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n if (signal.aborted) {\n throw new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const frames = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = frames.pop() ?? \"\";\n for (const frame of frames) {\n for (const line of frame.split(/\\r?\\n/)) {\n if (!line.startsWith(\"data:\")) continue;\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n try {\n yield JSON.parse(data) as DeepSeekChunk;\n } catch {\n // Ignore malformed frames.\n }\n }\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["deepseek_exports", "__export", "DeepSeekLLM", "__toCommonJS", "DeepSeekLLM", "__name", "options", "request", "controller", "response", "tool", "body", "toolCalls", "chunk", "parseSSE", "choice", "delta", "tc", "index", "accumulated", "call", "signal", "reader", "decoder", "buffer", "done", "value", "frames", "frame", "line", "data"]
4
+ "sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n ToolMode,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\nimport { openAICompatibleStream } from \"../openai-compatible\";\n\nexport interface DeepSeekOptions {\n apiKey: string;\n /** Defaults to `deepseek-chat`. */\n model?: string;\n /** Defaults to `https://api.deepseek.com`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n /**\n * Default tool encoding for requests that don't set `toolMode` (the\n * request's `toolMode` wins). For models whose endpoints lack native tool\n * calling.\n */\n toolMode?: ToolMode;\n}\n\n/**\n * DeepSeek LLM adapter (OpenAI-compatible chat completions over SSE).\n */\nexport class DeepSeekLLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly toolMode: ToolMode | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: DeepSeekOptions) {\n if (!options.apiKey) {\n throw new Error(\"DeepSeekLLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"deepseek-chat\";\n this.baseUrl = (options.baseUrl ?? \"https://api.deepseek.com\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n this.toolMode = options.toolMode;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n // Multiple generations can stream concurrently (e.g. delegated\n // sub-agents); each gets its own controller, and stop() aborts them all.\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n yield* openAICompatibleStream({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n model: this.model,\n fetchImpl: this.fetchImpl,\n request,\n signal: controller.signal,\n // Reasoning models default to enabled thinking; disable it so the\n // adapter behaves uniformly on deepseek-chat.\n extraBody: { thinking: { type: \"disabled\" } },\n label: \"DeepSeek\",\n onTiming: this.onTiming,\n idleTimeoutMs: this.idleTimeoutMs,\n onUsage: this.onUsage,\n toolMode: this.toolMode,\n });\n } finally {\n this.streams.delete(controller);\n }\n }\n}\n"],
5
+ "mappings": "4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,IAAA,eAAAC,EAAAH,GASA,IAAAI,EAAuC,gCA+BhC,MAAMC,CAA2B,CAxCxC,MAwCwC,CAAAC,EAAA,oBACrB,OACA,MACA,QACA,UACA,SACA,cACA,QACA,SACA,QAAU,IAAI,IAE/B,YAAYC,EAA0B,CACpC,GAAI,CAACA,EAAQ,OACX,MAAM,IAAI,MAAM,gCAAgC,EAElD,KAAK,OAASA,EAAQ,OACtB,KAAK,MAAQA,EAAQ,OAAS,gBAC9B,KAAK,SAAWA,EAAQ,SAAW,4BAA4B,QAAQ,OAAQ,EAAE,EACjF,KAAK,UAAYA,EAAQ,OAAS,MAClC,KAAK,SAAWA,EAAQ,SACxB,KAAK,cAAgBA,EAAQ,eAAiB,IAC9C,KAAK,QAAUA,EAAQ,QACvB,KAAK,SAAWA,EAAQ,QAC1B,CAGA,MAAa,CACX,UAAWC,KAAc,KAAK,QAASA,EAAW,MAAM,CAC1D,CAEA,MAAO,OAAOC,EAA+C,CAG3D,MAAMD,EAAa,IAAI,gBACvB,KAAK,QAAQ,IAAIA,CAAU,EAE3B,GAAI,CACF,SAAO,0BAAuB,CAC5B,QAAS,KAAK,QACd,OAAQ,KAAK,OACb,MAAO,KAAK,MACZ,UAAW,KAAK,UAChB,QAAAC,EACA,OAAQD,EAAW,OAGnB,UAAW,CAAE,SAAU,CAAE,KAAM,UAAW,CAAE,EAC5C,MAAO,WACP,SAAU,KAAK,SACf,cAAe,KAAK,cACpB,QAAS,KAAK,QACd,SAAU,KAAK,QACjB,CAAC,CACH,QAAE,CACA,KAAK,QAAQ,OAAOA,CAAU,CAChC,CACF,CACF",
6
+ "names": ["deepseek_exports", "__export", "DeepSeekLLM", "__toCommonJS", "import_openai_compatible", "DeepSeekLLM", "__name", "options", "controller", "request"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var L=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var t=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var D=(o,e)=>{for(var r in e)L(o,r,{get:e[r],enumerable:!0})},M=(o,e,r,f)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of t(e))!x.call(o,p)&&p!==r&&L(o,p,{get:()=>e[p],enumerable:!(f=m(e,p))||f.enumerable});return o};var S=o=>M(L({},"__esModule",{value:!0}),o);var a={};D(a,{DeepSeekLLM:()=>k.DeepSeekLLM});module.exports=S(a);var k=require("./deepseek/deepseek.js");
1
+ "use strict";var p=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var a=(o,e)=>{for(var L in e)p(o,L,{get:e[L],enumerable:!0})},d=(o,e,L,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of u(e))!O.call(o,r)&&r!==L&&p(o,r,{get:()=>e[r],enumerable:!(t=n(e,r))||t.enumerable});return o};var k=o=>d(p({},"__esModule",{value:!0}),o);var l={};a(l,{ClaudeLLM:()=>M.ClaudeLLM,DeepSeekLLM:()=>f.DeepSeekLLM,OpenAILLM:()=>x.OpenAILLM,OpenRouterLLM:()=>m.OpenRouterLLM});module.exports=k(l);var f=require("./deepseek/deepseek.js"),m=require("./openrouter/openrouter.js"),x=require("./openai/openai.js"),M=require("./claude/claude.js");
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/providers/llm/adapters/index.ts"],
4
- "sourcesContent": ["export { DeepSeekLLM } from \"./deepseek/deepseek\";\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gDAAAE,EAAAF,GAAA,IAAAG,EAA4B",
6
- "names": ["adapters_exports", "__export", "__toCommonJS", "import_deepseek"]
4
+ "sourcesContent": ["export { DeepSeekLLM } from \"./deepseek/deepseek\";\nexport { OpenRouterLLM } from \"./openrouter/openrouter\";\nexport { OpenAILLM } from \"./openai/openai\";\nexport { ClaudeLLM } from \"./claude/claude\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sIAAAE,EAAAF,GAAA,IAAAG,EAA4B,+BAC5BC,EAA8B,mCAC9BC,EAA0B,2BAC1BC,EAA0B",
6
+ "names": ["adapters_exports", "__export", "__toCommonJS", "import_deepseek", "import_openrouter", "import_openai", "import_claude"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var r=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var x=(e,p)=>{for(var n in p)r(e,n,{get:p[n],enumerable:!0})},A=(e,p,n,t)=>{if(p&&typeof p=="object"||typeof p=="function")for(let o of i(p))!m.call(e,o)&&o!==n&&r(e,o,{get:()=>p[o],enumerable:!(t=f(p,o))||t.enumerable});return e};var I=e=>A(r({},"__esModule",{value:!0}),e);var L={};x(L,{OpenAILLM:()=>O.OpenAILLM});module.exports=I(L);var O=require("./openai.js");
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/providers/llm/adapters/openai/index.ts"],
4
+ "sourcesContent": ["export { OpenAILLM } from \"./openai\";\nexport type { OpenAIOptions } from \"./openai\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,4CAAAE,EAAAF,GAAA,IAAAG,EAA0B",
6
+ "names": ["openai_exports", "__export", "__toCommonJS", "import_openai"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(t,e)=>a(t,"name",{value:e,configurable:!0});var p=(t,e)=>{for(var i in e)a(t,i,{get:e[i],enumerable:!0})},h=(t,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of m(e))!d.call(t,o)&&o!==i&&a(t,o,{get:()=>e[o],enumerable:!(r=s(e,o))||r.enumerable});return t};var L=t=>h(a({},"__esModule",{value:!0}),t);var c={};p(c,{OpenAILLM:()=>M});module.exports=L(c);var n=require("../openai-compatible.js");class M{static{l(this,"OpenAILLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;toolMode;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("OpenAILLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"gpt-4o-mini",this.baseUrl=(e.baseUrl??"https://api.openai.com/v1").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage,this.toolMode=e.toolMode}stop(){for(const e of this.streams)e.abort()}async*stream(e){const i=new AbortController;this.streams.add(i);try{yield*(0,n.openAICompatibleStream)({baseUrl:this.baseUrl,apiKey:this.apiKey,model:this.model,fetchImpl:this.fetchImpl,request:e,signal:i.signal,label:"OpenAI",onTiming:this.onTiming,idleTimeoutMs:this.idleTimeoutMs,onUsage:this.onUsage,toolMode:this.toolMode})}finally{this.streams.delete(i)}}}
2
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/providers/llm/adapters/openai/openai.ts"],
4
+ "sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n ToolMode,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\nimport { openAICompatibleStream } from \"../openai-compatible\";\n\nexport interface OpenAIOptions {\n apiKey: string;\n /** Defaults to `gpt-4o-mini`. */\n model?: string;\n /** Defaults to `https://api.openai.com/v1`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n /**\n * Default tool encoding for requests that don't set `toolMode` (the\n * request's `toolMode` wins). For models whose endpoints lack native tool\n * calling.\n */\n toolMode?: ToolMode;\n}\n\n/**\n * OpenAI LLM adapter (OpenAI-compatible chat completions over SSE).\n */\nexport class OpenAILLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly toolMode: ToolMode | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: OpenAIOptions) {\n if (!options.apiKey) {\n throw new Error(\"OpenAILLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"gpt-4o-mini\";\n this.baseUrl = (options.baseUrl ?? \"https://api.openai.com/v1\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n this.toolMode = options.toolMode;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n // Multiple generations can stream concurrently (e.g. delegated\n // sub-agents); each gets its own controller, and stop() aborts them all.\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n yield* openAICompatibleStream({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n model: this.model,\n fetchImpl: this.fetchImpl,\n request,\n signal: controller.signal,\n label: \"OpenAI\",\n onTiming: this.onTiming,\n idleTimeoutMs: this.idleTimeoutMs,\n onUsage: this.onUsage,\n toolMode: this.toolMode,\n });\n } finally {\n this.streams.delete(controller);\n }\n }\n}\n"],
5
+ "mappings": "4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,GASA,IAAAI,EAAuC,gCA+BhC,MAAMC,CAAyB,CAxCtC,MAwCsC,CAAAC,EAAA,kBACnB,OACA,MACA,QACA,UACA,SACA,cACA,QACA,SACA,QAAU,IAAI,IAE/B,YAAYC,EAAwB,CAClC,GAAI,CAACA,EAAQ,OACX,MAAM,IAAI,MAAM,8BAA8B,EAEhD,KAAK,OAASA,EAAQ,OACtB,KAAK,MAAQA,EAAQ,OAAS,cAC9B,KAAK,SAAWA,EAAQ,SAAW,6BAA6B,QAAQ,OAAQ,EAAE,EAClF,KAAK,UAAYA,EAAQ,OAAS,MAClC,KAAK,SAAWA,EAAQ,SACxB,KAAK,cAAgBA,EAAQ,eAAiB,IAC9C,KAAK,QAAUA,EAAQ,QACvB,KAAK,SAAWA,EAAQ,QAC1B,CAGA,MAAa,CACX,UAAWC,KAAc,KAAK,QAASA,EAAW,MAAM,CAC1D,CAEA,MAAO,OAAOC,EAA+C,CAG3D,MAAMD,EAAa,IAAI,gBACvB,KAAK,QAAQ,IAAIA,CAAU,EAE3B,GAAI,CACF,SAAO,0BAAuB,CAC5B,QAAS,KAAK,QACd,OAAQ,KAAK,OACb,MAAO,KAAK,MACZ,UAAW,KAAK,UAChB,QAAAC,EACA,OAAQD,EAAW,OACnB,MAAO,SACP,SAAU,KAAK,SACf,cAAe,KAAK,cACpB,QAAS,KAAK,QACd,SAAU,KAAK,QACjB,CAAC,CACH,QAAE,CACA,KAAK,QAAQ,OAAOA,CAAU,CAChC,CACF,CACF",
6
+ "names": ["openai_exports", "__export", "OpenAILLM", "__toCommonJS", "import_openai_compatible", "OpenAILLM", "__name", "options", "controller", "request"]
7
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";var M=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var d=(o,n)=>M(o,"name",{value:n,configurable:!0});var Y=(o,n)=>{for(var e in n)M(o,e,{get:n[e],enumerable:!0})},B=(o,n,e,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let f of j(n))!P.call(o,f)&&f!==e&&M(o,f,{get:()=>n[f],enumerable:!(i=W(n,f))||i.enumerable});return o};var F=o=>B(M({},"__esModule",{value:!0}),o);var Z={};Y(Z,{openAICompatibleStream:()=>V});module.exports=F(Z);function U(o){return{type:"object",properties:{answer:{type:"string",description:"Your spoken reply when no tool call is needed."},calls:{type:"array",description:"The tool calls to execute, when the request needs tools.",items:{type:"object",properties:{name:{type:"string",enum:o.map(n=>n.name)},arguments:{description:"The arguments for the named tool, per its schema.",oneOf:o.map(n=>n.parameters??{type:"object"})}},required:["name","arguments"],additionalProperties:!1}}}}}d(U,"buildEnvelopeSchema");function z(o){return`When the user's request requires a tool, respond with ONLY valid JSON matching this schema, with no prose and no markdown fences:
2
+ `+JSON.stringify(U(o))+`
3
+ The JSON must be either {"answer": "..."} or {"calls": [{"name": "...", "arguments": {...}}]}. When no tool is needed, respond in plain conversational text with no JSON.`}d(z,"promptedEnvelopeInstruction");function G(o){const n=o.trim();return n.startsWith("{")||n.startsWith("[")||/^```(?:json)?/i.test(n)}d(G,"looksLikeJsonAttempt");function H(o){const n=o.replace(/```(?:json)?/gi,"").replace(/^[^{]*/,"").replace(/[^}]*$/,"");if(n.length===0)return null;const e=n.indexOf("{"),i=n.lastIndexOf("}");return e===-1||i===-1||i<=e?null:n.slice(e,i+1)}d(H,"extractEnvelope");function K(){const o="<thinking>",n="</thinking>";let e="",i=!1;const f=d((r,a)=>{const m=Math.min(r.length,a.length-1);for(let l=m;l>=1;l--)if(a.startsWith(r.slice(-l)))return l;return 0},"prefixTail");return{push(r){let a="",m="";for(e+=r;;){if(i){const c=e.indexOf(n);if(c!==-1){m+=e.slice(0,c),e=e.slice(c+n.length),i=!1;continue}const w=f(e,n);return m+=e.slice(0,e.length-w),e=e.slice(e.length-w),{text:a,reasoning:m}}const l=e.indexOf(o);if(l!==-1){a+=e.slice(0,l),e=e.slice(l+o.length),i=!0;continue}const g=f(e,o);return a+=e.slice(0,e.length-g),e=e.slice(e.length-g),{text:a,reasoning:m}}},flush(){let r="",a="";return i?a=e:e.length>0&&!o.startsWith(e)&&(r=e),e="",i=!1,{text:r,reasoning:a}}}}d(K,"inlineThinking");function Q(o){return`You have access to the following tools. When the user's request requires one, respond with ONLY the tool-call JSON envelope shown in the request \u2014 no prose, no markdown, no tool-call syntax. When no tool is needed, reply conversationally in plain text \u2014 no JSON at all.
4
+
5
+ Available tools:
6
+ `+o.map(e=>`- ${e.name}: ${e.description}`).join(`
7
+ `)}d(Q,"buildToolContract");async function*V(o){const{baseUrl:n,apiKey:e,model:i,fetchImpl:f,request:r,signal:a,extraHeaders:m,extraBody:l,label:g,onTiming:c,idleTimeoutMs:w,onUsage:k}=o;c?.("request-start");const p=r.toolMode??o.toolMode??"native",u=p!=="native"&&(r.tools?.length??0)>0,h=u?Q(r.tools):null,N=r.messages.findIndex(t=>t.role!=="system"),J=N===-1?r.messages.length:N,C=[];r.messages.forEach((t,s,L)=>{s===J&&h!==null&&C.push({role:"system",content:h});const b={role:t.role,content:t.content};t.name&&(b.name=t.name),t.toolCallId&&(b.tool_call_id=t.toolCallId),t.toolCalls&&(b.tool_calls=t.toolCalls.map(O=>({id:O.id,type:"function",function:{name:O.name,arguments:O.arguments}}))),p==="prompted"&&u&&s===L.length-1&&(b.content=`${t.content}
8
+
9
+ ${z(r.tools)}`),C.push(b)}),J===r.messages.length&&h!==null&&C.push({role:"system",content:h});const T=await f(`${n}/chat/completions`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e}`,...m},body:JSON.stringify({model:i,messages:C,...!u&&r.tools&&r.tools.length>0?{tools:r.tools.map(t=>({type:"function",function:t}))}:{},...u&&p==="envelope"?{response_format:{type:"json_schema",json_schema:{name:"tool_envelope",strict:!1,schema:U(r.tools)}}}:{},stream:!0,temperature:r.temperature,max_tokens:r.maxTokens,stream_options:{include_usage:!0},...l}),signal:a});if(!T.ok){const t=await T.text();throw new Error(`${g} request failed (${T.status}): ${t}`)}if(!T.body)throw new Error(`${g} returned an empty body`);c?.("headers");const _=new Map;let E=!1,v=0,q=!1,D=!1,x="";const R=K();for await(const t of X(T.body,a,c,w,g)){const s=t.choices?.[0];if(t.error){yield{type:"error",error:new Error(`${g} provider aborted the stream: ${t.error.message??JSON.stringify(t.error)}`)};break}if(t.usage&&(t.usage.prompt_tokens??0)>0&&(q=!0,v=0,k?.({promptTokens:t.usage.prompt_tokens??0,completionTokens:t.usage.completion_tokens??0})),!s)continue;const L=s.delta,b=R.push(L?.content??""),A=(L?.reasoning??L?.reasoning_content??"")+b.reasoning;u?x+=b.text:(b.text.length>0||A.length>0)&&(yield{type:"delta",content:b.text,...A.length>0?{reasoning:A}:{}});for(const y of L?.tool_calls??[]){const I=y.index??0,S=_.get(I)??{id:"",name:"",arguments:""};y.id&&(S.id=y.id),y.function?.name&&(S.name+=y.function.name),y.function?.arguments&&(S.arguments+=y.function.arguments),_.set(I,S)}if(s.finish_reason==="tool_calls"&&!D){for(const y of _.values())yield{type:"tool_call",id:y.id,name:y.name,arguments:y.arguments};D=!0,E=!0}else if(s.finish_reason==="stop")E=!0;else if(s.finish_reason==="error"||s.finish_reason==="content_filter"){yield{type:"error",error:new Error(`${g} stream finished with "${s.finish_reason}"`+(_.size>0?"":" and produced no output"))};break}if(E&&(q||(v===0&&(v=Date.now()),Date.now()-v>500)))break}const $=R.flush();if($.text&&(u?x+=$.text:yield{type:"delta",content:$.text}),u){let t;try{t=JSON.parse(x)}catch{const s=H(x);if(s!==null)try{t=JSON.parse(s)}catch{t=void 0}if(t===void 0)try{t=JSON.parse(`{${x}`)}catch{t=void 0}}if(t===void 0)if(p==="prompted"&&!G(x)){const s=x.trim();s.length>0&&(yield{type:"delta",content:s})}else yield{type:"error",error:new Error(`${g} ${p} tool mode: model did not return a JSON envelope (${x.slice(0,120)})`)};else{typeof t.answer=="string"&&t.answer.length>0&&(yield{type:"delta",content:t.answer});for(const s of t.calls??[])typeof s.name=="string"&&(yield{type:"tool_call",id:crypto.randomUUID(),name:s.name,arguments:JSON.stringify(s.arguments??{})})}}yield{type:"done"}}d(V,"openAICompatibleStream");async function*X(o,n,e,i=8e3,f="LLM"){const r=o.getReader(),a=new TextDecoder;let m="",l=!1;const g=d(()=>{let c;return new Promise((w,k)=>{const p=d(()=>{c!==void 0&&clearTimeout(c),n.removeEventListener("abort",u)},"cleanup"),u=d(()=>{p(),k(new DOMException("The operation was aborted.","AbortError"))},"onAbort");r.read().then(h=>{p(),w(h)},h=>{p(),k(h)}),c=setTimeout(()=>{p(),r.cancel().catch(()=>{}),k(new Error(`${f} stream idle for ${i}ms \u2014 no data received; aborting the stalled stream`))},i),n.addEventListener("abort",u,{once:!0})})},"readWithTimeout");for(;;){if(n.aborted)throw new DOMException("The operation was aborted.","AbortError");const{done:c,value:w}=await g();if(c)break;m+=a.decode(w,{stream:!0});const k=m.split(/\r?\n\r?\n/);m=k.pop()??"";for(const p of k)for(const u of p.split(/\r?\n/)){if(!u.startsWith("data:"))continue;const h=u.slice(5).trim();if(h==="[DONE]")return;l||(l=!0,e?.("first-chunk"));try{yield JSON.parse(h)}catch{}}}}d(X,"parseSSE");
10
+ //# sourceMappingURL=openai-compatible.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/providers/llm/adapters/openai-compatible.ts"],
4
+ "sourcesContent": ["import type {\n LLMEvent,\n LLMRequest,\n LLMToolDefinition,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n ToolMode,\n} from \"../types\";\nimport type { FetchLike } from \"../../shared\";\n\ninterface DeltaToolCall {\n index?: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n}\n\ninterface ChatCompletionChunk {\n choices?: Array<{\n delta?: {\n content?: string | null;\n tool_calls?: DeltaToolCall[];\n // OpenRouter normalizes reasoning tokens to `reasoning`; DeepSeek uses\n // `reasoning_content`. Both are surfaced on the delta event.\n reasoning?: string | null;\n reasoning_content?: string | null;\n };\n finish_reason?: string | null;\n }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n /** Provider failure delivered as an SSE data chunk (no choices). */\n error?: { code?: number | string; message?: string };\n}\n\nexport interface OpenAICompatibleStreamParams {\n /** Provider base URL, e.g. `https://openrouter.ai/api/v1`. */\n baseUrl: string;\n apiKey: string;\n model: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetchImpl: FetchLike;\n request: LLMRequest;\n signal: AbortSignal;\n /** Extra headers merged into the request (e.g. attribution headers). */\n extraHeaders?: Record<string, string>;\n /** Extra body fields merged after the standard ones. */\n extraBody?: Record<string, unknown>;\n /** Provider name used in error messages. */\n label: string;\n /** Optional provider-timeline hook (see `LLMStreamTimingPoint`). */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Default tool encoding for requests that do not set `toolMode`\n * themselves (the request's `toolMode` wins when present). Useful for\n * models whose endpoints lack native tool calling.\n */\n toolMode?: ToolMode;\n /**\n * Abort the stream if no data arrives for this long (default 8000ms).\n * Protects against providers whose connection goes silent after the model\n * has already produced its output (e.g. a tool call that is never followed\n * by a terminating frame).\n */\n idleTimeoutMs?: number;\n /**\n * Called with the provider-reported token usage when the stream includes\n * it (OpenRouter sends usage in the final chunk).\n */\n onUsage?: LLMUsageCallback;\n}\n\n/**\n * JSON schema for the `envelope`/`prompted` tool modes: the model answers\n * either directly (`answer`) or with a list of tool calls (`calls`). The\n * adapter turns the parsed envelope back into the standard `LLMEvent`\n * surface, so consumers never see the envelope format.\n *\n * The `arguments` of each call carry a per-tool `oneOf` of the tools' own\n * parameter schemas (index-aligned with the `name` enum), so the model sees\n * the same argument contract it would in native mode \u2014 without the native\n * tool-calling endpoint.\n */\nfunction buildEnvelopeSchema(tools: LLMToolDefinition[]): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n answer: {\n type: \"string\",\n description: \"Your spoken reply when no tool call is needed.\",\n },\n calls: {\n type: \"array\",\n description: \"The tool calls to execute, when the request needs tools.\",\n items: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n enum: tools.map((tool) => tool.name),\n },\n arguments: {\n description: \"The arguments for the named tool, per its schema.\",\n oneOf: tools.map((tool) => tool.parameters ?? { type: \"object\" }),\n },\n },\n required: [\"name\", \"arguments\"],\n additionalProperties: false,\n },\n },\n },\n };\n}\n\n/** Instruction appended to the last user message in `prompted` mode. */\nfunction promptedEnvelopeInstruction(tools: LLMToolDefinition[]): string {\n return (\n \"When the user's request requires a tool, respond with ONLY valid JSON matching this \" +\n \"schema, with no prose and no markdown fences:\\n\" +\n JSON.stringify(buildEnvelopeSchema(tools)) +\n '\\nThe JSON must be either {\"answer\": \"...\"} or {\"calls\": [{\"name\": \"...\", \"arguments\": {...}}]}. ' +\n \"When no tool is needed, respond in plain conversational text with no JSON.\"\n );\n}\n\n/**\n * True when the model's output looks like a (possibly broken) JSON envelope\n * attempt rather than plain prose \u2014 used to decide whether a parse failure is\n * a garbled tool call (error) or an envelope-ignoring model that simply\n * answered (speak the text).\n */\nfunction looksLikeJsonAttempt(content: string): boolean {\n const trimmed = content.trim();\n return (\n trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\") || /^```(?:json)?/i.test(trimmed)\n );\n}\n\n/**\n * Fallback extraction for prompted mode: strip markdown fences and keep the\n * outermost JSON object, rescuing models that wrap or preface the envelope\n * despite the instruction (the endpoint guarantees nothing without\n * `response_format`).\n */\nfunction extractEnvelope(raw: string): string | null {\n const stripped = raw\n .replace(/```(?:json)?/gi, \"\")\n .replace(/^[^{]*/, \"\")\n .replace(/[^}]*$/, \"\");\n if (stripped.length === 0) return null;\n const start = stripped.indexOf(\"{\");\n const end = stripped.lastIndexOf(\"}\");\n if (start === -1 || end === -1 || end <= start) return null;\n return stripped.slice(start, end + 1);\n}\n\n/**\n * Stream-partition inline `<thinking>\u2026</thinking>` spans out of model content.\n * Reasoning-style models (DeepSeek-R1 and distills, Qwen3, \u2026) emit their\n * chain of thought between visible tags whenever the serving layer has no\n * native reasoning channel, and some providers prompt tags even on models\n * without native thinking. The tags are reasoning \u2014 never reply text \u2014 so\n * they are streamed out as `reasoning` (the same surface a provider\n * `reasoning`/`reasoning_content` field uses) and the surrounding text alone\n * is content. Tags can split across any chunk boundary, so trailing\n * characters that could still form a tag are held back until the next chunk.\n */\nfunction inlineThinking() {\n const OPEN = \"<thinking>\";\n const CLOSE = \"</thinking>\";\n let buffer = \"\";\n let inTag = false;\n\n /** How many trailing chars of `text` could still begin `token`. */\n const prefixTail = (text: string, token: string): number => {\n const max = Math.min(text.length, token.length - 1);\n for (let keep = max; keep >= 1; keep--) {\n if (token.startsWith(text.slice(-keep))) return keep;\n }\n return 0;\n };\n\n return {\n /** Feed one content chunk; returns the text and reasoning it releases. */\n push(chunk: string): { text: string; reasoning: string } {\n let text = \"\";\n let reasoning = \"\";\n buffer += chunk;\n for (;;) {\n if (inTag) {\n const close = buffer.indexOf(CLOSE);\n if (close !== -1) {\n reasoning += buffer.slice(0, close);\n buffer = buffer.slice(close + CLOSE.length);\n inTag = false;\n continue;\n }\n const keep = prefixTail(buffer, CLOSE);\n reasoning += buffer.slice(0, buffer.length - keep);\n buffer = buffer.slice(buffer.length - keep);\n return { text, reasoning };\n }\n const open = buffer.indexOf(OPEN);\n if (open !== -1) {\n text += buffer.slice(0, open);\n buffer = buffer.slice(open + OPEN.length);\n inTag = true;\n continue;\n }\n const keep = prefixTail(buffer, OPEN);\n text += buffer.slice(0, buffer.length - keep);\n buffer = buffer.slice(buffer.length - keep);\n return { text, reasoning };\n }\n },\n /** Release whatever is still buffered once the stream ends. */\n flush(): { text: string; reasoning: string } {\n let text = \"\";\n let reasoning = \"\";\n if (inTag) {\n // Unclosed thinking (truncated stream) is reasoning, not content.\n reasoning = buffer;\n } else if (buffer.length > 0 && !OPEN.startsWith(buffer)) {\n // A tail shorter than the tag was an aborted tag start, not content.\n text = buffer;\n }\n buffer = \"\";\n inTag = false;\n return { text, reasoning };\n },\n };\n}\n\n/**\n * System-level tool contract for `envelope`/`prompted` modes. The envelope\n * schema itself carries only tool names + argument shapes, so without this\n * the model never sees tool descriptions or the output rule up front \u2014 which\n * invites prose, native tool-call syntax, or waffling instead of the envelope.\n */\nfunction buildToolContract(tools: LLMToolDefinition[]): string {\n const list = tools.map((tool) => `- ${tool.name}: ${tool.description}`).join(\"\\n\");\n return (\n \"You have access to the following tools. When the user's request requires one, \" +\n \"respond with ONLY the tool-call JSON envelope shown in the request \u2014 no prose, \" +\n \"no markdown, no tool-call syntax. When no tool is needed, reply conversationally \" +\n \"in plain text \u2014 no JSON at all.\\n\\nAvailable tools:\\n\" +\n list\n );\n}\n\n/**\n * Stream a request through any OpenAI-compatible `/chat/completions`\n * endpoint, reassembling fragmented tool calls and normalizing the SSE\n * stream into `LLMEvent`s. Shared by the DeepSeek and OpenRouter adapters.\n */\nexport async function* openAICompatibleStream(\n params: OpenAICompatibleStreamParams,\n): AsyncGenerator<LLMEvent> {\n const {\n baseUrl,\n apiKey,\n model,\n fetchImpl,\n request,\n signal,\n extraHeaders,\n extraBody,\n label,\n onTiming,\n idleTimeoutMs,\n onUsage,\n } = params;\n\n onTiming?.(\"request-start\");\n // Precedence: the per-request override wins, then the adapter default, then\n // native.\n const toolMode = request.toolMode ?? params.toolMode ?? \"native\";\n const usesEnvelope = toolMode !== \"native\" && (request.tools?.length ?? 0) > 0;\n // In envelope modes the tools are hidden from the provider, so the model\n // never sees their descriptions (or the output rule) unless we say so.\n // Insert the contract after the caller's system messages, where formatting\n // rules belong.\n const toolContract = usesEnvelope ? buildToolContract(request.tools!) : null;\n const contractAt = request.messages.findIndex((message) => message.role !== \"system\");\n const insertAt = contractAt === -1 ? request.messages.length : contractAt;\n const wireMessages: Record<string, unknown>[] = [];\n request.messages.forEach((message, index, all) => {\n if (index === insertAt && toolContract !== null) {\n wireMessages.push({ role: \"system\", content: toolContract });\n }\n const wire: Record<string, unknown> = {\n role: message.role,\n content: message.content,\n };\n if (message.name) wire.name = message.name;\n if (message.toolCallId) wire.tool_call_id = message.toolCallId;\n if (message.toolCalls) {\n wire.tool_calls = message.toolCalls.map((call) => ({\n id: call.id,\n type: \"function\",\n function: { name: call.name, arguments: call.arguments },\n }));\n }\n if (toolMode === \"prompted\" && usesEnvelope && index === all.length - 1) {\n // The only way to constrain output without provider support: ask\n // the model directly, and parse/validate the result ourselves.\n wire.content = `${message.content}\\n\\n${promptedEnvelopeInstruction(request.tools!)}`;\n }\n wireMessages.push(wire);\n });\n if (insertAt === request.messages.length && toolContract !== null) {\n wireMessages.push({ role: \"system\", content: toolContract });\n }\n const response = await fetchImpl(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n ...extraHeaders,\n },\n body: JSON.stringify({\n model,\n // LLMMessage uses camelCase; the wire format is snake_case.\n messages: wireMessages,\n // Envelope modes hide the tools from the provider and encode them in a\n // schema the model must emit as JSON; native mode uses the provider's\n // own tool-calling contract.\n ...(!usesEnvelope && request.tools && request.tools.length > 0\n ? { tools: request.tools.map((tool) => ({ type: \"function\", function: tool })) }\n : {}),\n ...(usesEnvelope && toolMode === \"envelope\"\n ? {\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: \"tool_envelope\",\n strict: false,\n schema: buildEnvelopeSchema(request.tools!),\n },\n },\n }\n : {}),\n stream: true,\n temperature: request.temperature,\n max_tokens: request.maxTokens,\n // Ask the provider to include usage in the final chunk so token\n // accounting (and latency-vs-tokens curves) are possible.\n stream_options: { include_usage: true },\n ...extraBody,\n }),\n signal,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`${label} request failed (${response.status}): ${body}`);\n }\n if (!response.body) {\n throw new Error(`${label} returned an empty body`);\n }\n onTiming?.(\"headers\");\n\n // Tool calls arrive fragmented across chunks and are reassembled by\n // index before being emitted once the stream signals `tool_calls`.\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n // After the content finishes (finish_reason), keep reading briefly so the\n // provider-reported usage chunk \u2014 which arrives right after \u2014 is captured.\n let contentFinished = false;\n let finishAt = 0;\n let sawUsage = false;\n let toolCallsEmitted = false;\n // Envelope modes buffer the model's JSON and translate it into events at\n // the end of the stream (the JSON is not speech and cannot be acted on\n // until it is complete).\n let envelopeContent = \"\";\n // Reasoning models sometimes stream their chain of thought as inline\n // `<thinking>` tags instead of a native reasoning field; strip them out of\n // content and surface them as `reasoning` (stateful across chunk splits).\n const thinking = inlineThinking();\n\n for await (const chunk of parseSSE(response.body, signal, onTiming, idleTimeoutMs, label)) {\n const choice = chunk.choices?.[0];\n\n if (chunk.error) {\n // Some providers (e.g. Bedrock via OpenRouter) abort mid-stream and\n // deliver the failure as an SSE chunk with no choices. Surface it\n // instead of silently swallowing it into a confusing empty stream.\n yield {\n type: \"error\",\n error: new Error(\n `${label} provider aborted the stream: ${chunk.error.message ?? JSON.stringify(chunk.error)}`,\n ),\n };\n break;\n }\n\n if (chunk.usage && (chunk.usage.prompt_tokens ?? 0) > 0) {\n sawUsage = true;\n finishAt = 0;\n onUsage?.({\n promptTokens: chunk.usage.prompt_tokens ?? 0,\n completionTokens: chunk.usage.completion_tokens ?? 0,\n });\n }\n if (!choice) continue;\n\n const delta = choice.delta;\n // Strip inline `<thinking>` blocks out of the content (they are the\n // model's reasoning, not the reply); the stripped text rides on the same\n // `reasoning` surface as a provider reasoning field, which consumers can\n // measure or display but is never spoken or written into the reply.\n const partition = thinking.push(delta?.content ?? \"\");\n const providerReasoning = (delta?.reasoning ?? delta?.reasoning_content) ?? \"\";\n const reasoning = providerReasoning + partition.reasoning;\n if (usesEnvelope) {\n envelopeContent += partition.text;\n } else if (partition.text.length > 0 || reasoning.length > 0) {\n yield {\n type: \"delta\",\n content: partition.text,\n ...(reasoning.length > 0 ? { reasoning } : {}),\n };\n }\n\n for (const tc of delta?.tool_calls ?? []) {\n const index = tc.index ?? 0;\n const accumulated = toolCalls.get(index) ?? { id: \"\", name: \"\", arguments: \"\" };\n if (tc.id) accumulated.id = tc.id;\n if (tc.function?.name) accumulated.name += tc.function.name;\n if (tc.function?.arguments) accumulated.arguments += tc.function.arguments;\n toolCalls.set(index, accumulated);\n }\n\n if (choice.finish_reason === \"tool_calls\" && !toolCallsEmitted) {\n for (const call of toolCalls.values()) {\n yield {\n type: \"tool_call\",\n id: call.id,\n name: call.name,\n arguments: call.arguments,\n };\n }\n toolCallsEmitted = true;\n contentFinished = true;\n } else if (choice.finish_reason === \"stop\") {\n contentFinished = true;\n } else if (choice.finish_reason === \"error\" || choice.finish_reason === \"content_filter\") {\n // Some providers (e.g. gemini models via OpenRouter) return HTTP 200\n // with an empty body and finish_reason \"error\"/\"content_filter\"\n // instead of a real failure. Surface it as an error event rather than\n // silently completing with an empty generation.\n yield {\n type: \"error\",\n error: new Error(\n `${label} stream finished with \"${choice.finish_reason}\"` +\n (toolCalls.size > 0 ? \"\" : \" and produced no output\"),\n ),\n };\n break;\n }\n\n if (contentFinished) {\n if (sawUsage) break; // usage captured \u2014 no need to wait for [DONE]\n if (finishAt === 0) finishAt = Date.now();\n // Grace for providers that send finish_reason but never [DONE] or\n // usage: proceed after a short wait instead of stalling the run.\n if (Date.now() - finishAt > 500) break;\n }\n }\n\n // Anything left in the thinking partitioner once the stream ends: unclosed\n // reasoning is dropped (never content), and an aborted tag start is dropped\n // too. Real trailing content is flushed here.\n const tail = thinking.flush();\n if (tail.text) {\n if (usesEnvelope) envelopeContent += tail.text;\n else yield { type: \"delta\", content: tail.text };\n }\n\n if (usesEnvelope) {\n let envelope:\n | { answer?: unknown; calls?: Array<{ name?: unknown; arguments?: unknown }> }\n | undefined;\n try {\n envelope = JSON.parse(envelopeContent);\n } catch {\n // Prompted mode has no endpoint guarantee: the model may wrap the JSON\n // in fences or preface it with prose. Retry with extraction before\n // failing the stream.\n const extracted = extractEnvelope(envelopeContent);\n if (extracted !== null) {\n try {\n envelope = JSON.parse(extracted);\n } catch {\n envelope = undefined;\n }\n }\n if (envelope === undefined) {\n // Some providers drop the opening bytes of the stream (observed with\n // llama-4-scout via OpenRouter): the content starts mid-object but\n // closes cleanly. Prepend the brace and retry.\n try {\n envelope = JSON.parse(`{${envelopeContent}`);\n } catch {\n envelope = undefined;\n }\n }\n }\n if (envelope === undefined) {\n // Prompted mode has no endpoint guarantee (`envelope` mode's\n // response_format enforces JSON). Smaller chat models often ignore the\n // envelope instruction and reply in plain prose \u2014 that is still a valid\n // reply, so speak it as the model's `answer` instead of failing the\n // turn with a technical error. Only output that looks like a (broken)\n // JSON attempt keeps the loud error, so a truncated envelope is never\n // spoken as garbage.\n if (toolMode === \"prompted\" && !looksLikeJsonAttempt(envelopeContent)) {\n const answer = envelopeContent.trim();\n if (answer.length > 0) yield { type: \"delta\", content: answer };\n } else {\n yield {\n type: \"error\",\n error: new Error(\n `${label} ${toolMode} tool mode: model did not return a JSON envelope (${envelopeContent.slice(0, 120)})`,\n ),\n };\n }\n } else {\n if (typeof envelope.answer === \"string\" && envelope.answer.length > 0) {\n yield { type: \"delta\", content: envelope.answer };\n }\n for (const call of envelope.calls ?? []) {\n if (typeof call.name !== \"string\") continue;\n // Envelope mode has no provider-assigned call ids; synthesize them so\n // consumers can match results to calls (id uniqueness is the contract).\n yield {\n type: \"tool_call\",\n id: crypto.randomUUID(),\n name: call.name,\n arguments: JSON.stringify(call.arguments ?? {}),\n };\n }\n }\n }\n\n yield { type: \"done\" };\n}\n\n/**\n * Parse an SSE byte stream into JSON events. Supports both LF and CRLF\n * framing, ignores comments and malformed frames, and stops at `[DONE]`.\n * Aborts with an `AbortError` once the signal fires.\n */\nasync function* parseSSE(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n onTiming?: LLMStreamTimingCallback,\n idleTimeoutMs = 8_000,\n label = \"LLM\",\n): AsyncGenerator<ChatCompletionChunk> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let firstChunkEmitted = false;\n\n // `reader.read()` bounded by an idle timeout: if no bytes arrive within\n // `idleTimeoutMs`, cancel the connection and fail the stream. Only bytes\n // reset the timer \u2014 a connection that stays open but silent still trips it.\n const readWithTimeout = (): Promise<Awaited<ReturnType<typeof reader.read>>> => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n return new Promise((resolve, reject) => {\n const cleanup = () => {\n if (timer !== undefined) clearTimeout(timer);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = () => {\n cleanup();\n reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n };\n reader.read().then(\n (result) => {\n cleanup();\n resolve(result);\n },\n (error) => {\n cleanup();\n reject(error);\n },\n );\n timer = setTimeout(() => {\n cleanup();\n // Cancel the reader so the underlying connection is actually closed.\n void reader.cancel().catch(() => {});\n reject(\n new Error(\n `${label} stream idle for ${idleTimeoutMs}ms \u2014 no data received; aborting the stalled stream`,\n ),\n );\n }, idleTimeoutMs);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n };\n\n while (true) {\n if (signal.aborted) {\n throw new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n const { done, value } = await readWithTimeout();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const frames = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = frames.pop() ?? \"\";\n for (const frame of frames) {\n for (const line of frame.split(/\\r?\\n/)) {\n if (!line.startsWith(\"data:\")) continue;\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n if (!firstChunkEmitted) {\n firstChunkEmitted = true;\n onTiming?.(\"first-chunk\");\n }\n try {\n yield JSON.parse(data) as ChatCompletionChunk;\n } catch {\n // Ignore malformed frames.\n }\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["openai_compatible_exports", "__export", "openAICompatibleStream", "__toCommonJS", "buildEnvelopeSchema", "tools", "tool", "__name", "promptedEnvelopeInstruction", "looksLikeJsonAttempt", "content", "trimmed", "extractEnvelope", "raw", "stripped", "start", "end", "inlineThinking", "OPEN", "CLOSE", "buffer", "inTag", "prefixTail", "text", "token", "max", "keep", "chunk", "reasoning", "close", "open", "buildToolContract", "openAICompatibleStream", "params", "baseUrl", "apiKey", "model", "fetchImpl", "request", "signal", "extraHeaders", "extraBody", "label", "onTiming", "idleTimeoutMs", "onUsage", "toolMode", "usesEnvelope", "toolContract", "contractAt", "message", "insertAt", "wireMessages", "index", "all", "wire", "call", "response", "body", "toolCalls", "contentFinished", "finishAt", "sawUsage", "toolCallsEmitted", "envelopeContent", "thinking", "parseSSE", "choice", "delta", "partition", "tc", "accumulated", "tail", "envelope", "extracted", "answer", "reader", "decoder", "firstChunkEmitted", "readWithTimeout", "timer", "resolve", "reject", "cleanup", "onAbort", "result", "error", "done", "value", "frames", "frame", "line", "data"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var t=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var x=(o,e)=>{for(var p in e)t(o,p,{get:e[p],enumerable:!0})},L=(o,e,p,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of f(e))!m.call(o,r)&&r!==p&&t(o,r,{get:()=>e[r],enumerable:!(n=O(e,r))||n.enumerable});return o};var R=o=>L(t({},"__esModule",{value:!0}),o);var i={};x(i,{OpenRouterLLM:()=>u.OpenRouterLLM});module.exports=R(i);var u=require("./openrouter.js");
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/providers/llm/adapters/openrouter/index.ts"],
4
+ "sourcesContent": ["export { OpenRouterLLM } from \"./openrouter\";\nexport type { OpenRouterOptions } from \"./openrouter\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oDAAAE,EAAAF,GAAA,IAAAG,EAA8B",
6
+ "names": ["openrouter_exports", "__export", "__toCommonJS", "import_openrouter"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var o=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(t,e)=>o(t,"name",{value:e,configurable:!0});var m=(t,e)=>{for(var r in e)o(t,r,{get:e[r],enumerable:!0})},h=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of p(e))!d.call(t,i)&&i!==r&&o(t,i,{get:()=>e[i],enumerable:!(a=n(e,i))||a.enumerable});return t};var L=t=>h(o({},"__esModule",{value:!0}),t);var c={};m(c,{OpenRouterLLM:()=>M});module.exports=L(c);var s=require("../openai-compatible.js");class M{static{l(this,"OpenRouterLLM")}apiKey;model;baseUrl;appUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;toolMode;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("OpenRouterLLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"openrouter/auto",this.baseUrl=(e.baseUrl??"https://openrouter.ai/api/v1").replace(/\/+$/,""),this.appUrl=e.appUrl??"https://moureau.dev",this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage,this.toolMode=e.toolMode}stop(){for(const e of this.streams)e.abort()}async*stream(e){const r=new AbortController;this.streams.add(r);try{yield*(0,s.openAICompatibleStream)({baseUrl:this.baseUrl,apiKey:this.apiKey,model:this.model,fetchImpl:this.fetchImpl,request:e,signal:r.signal,extraHeaders:{"http-referer":this.appUrl,"x-title":"pipeflow"},label:"OpenRouter",onTiming:this.onTiming,idleTimeoutMs:this.idleTimeoutMs,onUsage:this.onUsage,toolMode:this.toolMode})}finally{this.streams.delete(r)}}}
2
+ //# sourceMappingURL=openrouter.js.map