@moureau/pipeflow 0.0.1 → 0.0.2

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 (311) hide show
  1. package/README.md +245 -117
  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/conversations/conversation/conversation.js +1 -1
  7. package/dist/cjs/conversations/conversation/conversation.js.map +3 -3
  8. package/dist/cjs/conversations/conversations.js +1 -1
  9. package/dist/cjs/conversations/conversations.js.map +3 -3
  10. package/dist/cjs/conversations/index.js +1 -1
  11. package/dist/cjs/conversations/index.js.map +3 -3
  12. package/dist/cjs/conversations/orchestration/coordination/coordination.js +10 -0
  13. package/dist/cjs/conversations/orchestration/coordination/coordination.js.map +7 -0
  14. package/dist/cjs/conversations/orchestration/coordination/index.js +2 -0
  15. package/dist/cjs/conversations/orchestration/coordination/index.js.map +7 -0
  16. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
  17. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
  18. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
  19. package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
  20. package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js +2 -0
  21. package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
  22. package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js +2 -0
  23. package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
  24. package/dist/cjs/conversations/orchestration/orchestrator/history/history.js +4 -0
  25. package/dist/cjs/conversations/orchestration/orchestrator/history/history.js.map +7 -0
  26. package/dist/cjs/conversations/orchestration/orchestrator/history/index.js +2 -0
  27. package/dist/cjs/conversations/orchestration/orchestrator/history/index.js.map +7 -0
  28. package/dist/cjs/conversations/orchestration/orchestrator/index.js +1 -1
  29. package/dist/cjs/conversations/orchestration/orchestrator/index.js.map +3 -3
  30. package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js +1 -2
  31. package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
  32. package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js +2 -0
  33. package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
  34. package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js +23 -0
  35. package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
  36. package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js +2 -0
  37. package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
  38. package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js +2 -0
  39. package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
  40. package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js +2 -0
  41. package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
  42. package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js +2 -0
  43. package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
  44. package/dist/cjs/conversations/orchestration/test-harness.js +2 -0
  45. package/dist/cjs/conversations/orchestration/test-harness.js.map +7 -0
  46. package/dist/cjs/conversations/orchestration/text-chunker/index.js +2 -0
  47. package/dist/cjs/conversations/orchestration/text-chunker/index.js.map +7 -0
  48. package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js +3 -0
  49. package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
  50. package/dist/cjs/conversations/stream/conversation-stream.js +2 -0
  51. package/dist/cjs/conversations/stream/conversation-stream.js.map +7 -0
  52. package/dist/cjs/conversations/stream/index.js +2 -0
  53. package/dist/cjs/conversations/stream/index.js.map +7 -0
  54. package/dist/cjs/conversations/types.js +1 -1
  55. package/dist/cjs/conversations/types.js.map +2 -2
  56. package/dist/cjs/index.js +1 -1
  57. package/dist/cjs/index.js.map +3 -3
  58. package/dist/cjs/persistence/adapters/sqlite/sqlite.js +18 -14
  59. package/dist/cjs/persistence/adapters/sqlite/sqlite.js.map +3 -3
  60. package/dist/cjs/pipeflow/index.js +2 -0
  61. package/dist/cjs/pipeflow/index.js.map +7 -0
  62. package/dist/cjs/pipeflow/pipeflow.js +2 -0
  63. package/dist/cjs/pipeflow/pipeflow.js.map +7 -0
  64. package/dist/cjs/providers/index.js +1 -1
  65. package/dist/cjs/providers/index.js.map +2 -2
  66. package/dist/cjs/providers/llm/adapters/claude/claude.js +5 -0
  67. package/dist/cjs/providers/llm/adapters/claude/claude.js.map +7 -0
  68. package/dist/cjs/providers/llm/adapters/claude/index.js +2 -0
  69. package/dist/cjs/providers/llm/adapters/claude/index.js.map +7 -0
  70. package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js +1 -1
  71. package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
  72. package/dist/cjs/providers/llm/adapters/index.js +1 -1
  73. package/dist/cjs/providers/llm/adapters/index.js.map +3 -3
  74. package/dist/cjs/providers/llm/adapters/openai/index.js +2 -0
  75. package/dist/cjs/providers/llm/adapters/openai/index.js.map +7 -0
  76. package/dist/cjs/providers/llm/adapters/openai/openai.js +2 -0
  77. package/dist/cjs/providers/llm/adapters/openai/openai.js.map +7 -0
  78. package/dist/cjs/providers/llm/adapters/openai-compatible.js +10 -0
  79. package/dist/cjs/providers/llm/adapters/openai-compatible.js.map +7 -0
  80. package/dist/cjs/providers/llm/adapters/openrouter/index.js +2 -0
  81. package/dist/cjs/providers/llm/adapters/openrouter/index.js.map +7 -0
  82. package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js +2 -0
  83. package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
  84. package/dist/cjs/providers/llm/index.js +1 -1
  85. package/dist/cjs/providers/llm/index.js.map +3 -3
  86. package/dist/cjs/providers/llm/toolmode/index.js +2 -0
  87. package/dist/cjs/providers/llm/toolmode/index.js.map +7 -0
  88. package/dist/cjs/providers/llm/toolmode/toolmode.js +2 -0
  89. package/dist/cjs/providers/llm/toolmode/toolmode.js.map +7 -0
  90. package/dist/cjs/providers/llm/types.js +1 -1
  91. package/dist/cjs/providers/llm/types.js.map +3 -3
  92. package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js +1 -1
  93. package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
  94. package/dist/cjs/providers/stt/adapters/index.js +1 -1
  95. package/dist/cjs/providers/stt/adapters/index.js.map +3 -3
  96. package/dist/cjs/providers/stt/adapters/openrouter/index.js +2 -0
  97. package/dist/cjs/providers/stt/adapters/openrouter/index.js.map +7 -0
  98. package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js +2 -0
  99. package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
  100. package/dist/cjs/providers/tts/adapters/index.js +1 -1
  101. package/dist/cjs/providers/tts/adapters/index.js.map +3 -3
  102. package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js +4 -1
  103. package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
  104. package/dist/cjs/providers/tts/adapters/openrouter/index.js +2 -0
  105. package/dist/cjs/providers/tts/adapters/openrouter/index.js.map +7 -0
  106. package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js +2 -0
  107. package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
  108. package/dist/cjs/transport/streamobject/field-stream/field-stream.js +2 -0
  109. package/dist/cjs/transport/streamobject/field-stream/field-stream.js.map +7 -0
  110. package/dist/cjs/transport/streamobject/field-stream/index.js +2 -0
  111. package/dist/cjs/transport/streamobject/field-stream/index.js.map +7 -0
  112. package/dist/cjs/transport/streamobject/index.js +2 -0
  113. package/dist/cjs/transport/streamobject/index.js.map +7 -0
  114. package/dist/cjs/transport/streamobject/json-adapter/index.js +2 -0
  115. package/dist/cjs/transport/streamobject/json-adapter/index.js.map +7 -0
  116. package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js +4 -0
  117. package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
  118. package/dist/cjs/transport/streamobject/reference/index.js +2 -0
  119. package/dist/cjs/transport/streamobject/reference/index.js.map +7 -0
  120. package/dist/cjs/transport/streamobject/reference/reference.js +2 -0
  121. package/dist/cjs/transport/streamobject/reference/reference.js.map +7 -0
  122. package/dist/cjs/transport/streamobject/stream-object/index.js +2 -0
  123. package/dist/cjs/transport/streamobject/stream-object/index.js.map +7 -0
  124. package/dist/cjs/transport/streamobject/stream-object/stream-object.js +2 -0
  125. package/dist/cjs/transport/streamobject/stream-object/stream-object.js.map +7 -0
  126. package/dist/esm/agents/agent.js +1 -1
  127. package/dist/esm/agents/agent.js.map +3 -3
  128. package/dist/esm/agents/tools/tools.js +1 -1
  129. package/dist/esm/agents/tools/tools.js.map +3 -3
  130. package/dist/esm/conversations/conversation/conversation.js +1 -1
  131. package/dist/esm/conversations/conversation/conversation.js.map +3 -3
  132. package/dist/esm/conversations/conversations.js +1 -1
  133. package/dist/esm/conversations/conversations.js.map +3 -3
  134. package/dist/esm/conversations/index.js +1 -1
  135. package/dist/esm/conversations/index.js.map +3 -3
  136. package/dist/esm/conversations/orchestration/coordination/coordination.js +10 -0
  137. package/dist/esm/conversations/orchestration/coordination/coordination.js.map +7 -0
  138. package/dist/esm/conversations/orchestration/coordination/index.js +2 -0
  139. package/dist/esm/conversations/orchestration/coordination/index.js.map +7 -0
  140. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
  141. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
  142. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
  143. package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
  144. package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js +2 -0
  145. package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
  146. package/dist/esm/conversations/orchestration/orchestrator/generation/index.js +2 -0
  147. package/dist/esm/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
  148. package/dist/esm/conversations/orchestration/orchestrator/history/history.js +4 -0
  149. package/dist/esm/conversations/orchestration/orchestrator/history/history.js.map +7 -0
  150. package/dist/esm/conversations/orchestration/orchestrator/history/index.js +2 -0
  151. package/dist/esm/conversations/orchestration/orchestrator/history/index.js.map +7 -0
  152. package/dist/esm/conversations/orchestration/orchestrator/index.js +1 -1
  153. package/dist/esm/conversations/orchestration/orchestrator/index.js.map +3 -3
  154. package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js +1 -2
  155. package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
  156. package/dist/esm/conversations/orchestration/orchestrator/routing/index.js +2 -0
  157. package/dist/esm/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
  158. package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js +23 -0
  159. package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
  160. package/dist/esm/conversations/orchestration/orchestrator/speech/index.js +2 -0
  161. package/dist/esm/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
  162. package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js +2 -0
  163. package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
  164. package/dist/esm/conversations/orchestration/orchestrator/tools/index.js +2 -0
  165. package/dist/esm/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
  166. package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js +2 -0
  167. package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
  168. package/dist/esm/conversations/orchestration/test-harness.js +2 -0
  169. package/dist/esm/conversations/orchestration/test-harness.js.map +7 -0
  170. package/dist/esm/conversations/orchestration/text-chunker/index.js +2 -0
  171. package/dist/esm/conversations/orchestration/text-chunker/index.js.map +7 -0
  172. package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js +3 -0
  173. package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
  174. package/dist/esm/conversations/stream/conversation-stream.js +2 -0
  175. package/dist/esm/conversations/stream/conversation-stream.js.map +7 -0
  176. package/dist/esm/conversations/stream/index.js +2 -0
  177. package/dist/esm/conversations/stream/index.js.map +7 -0
  178. package/dist/esm/conversations/types.js +1 -1
  179. package/dist/esm/conversations/types.js.map +2 -2
  180. package/dist/esm/index.js +1 -1
  181. package/dist/esm/index.js.map +3 -3
  182. package/dist/esm/persistence/adapters/sqlite/sqlite.js +18 -14
  183. package/dist/esm/persistence/adapters/sqlite/sqlite.js.map +3 -3
  184. package/dist/esm/pipeflow/index.js +2 -0
  185. package/dist/esm/pipeflow/index.js.map +7 -0
  186. package/dist/esm/pipeflow/pipeflow.js +2 -0
  187. package/dist/esm/pipeflow/pipeflow.js.map +7 -0
  188. package/dist/esm/providers/index.js +1 -1
  189. package/dist/esm/providers/index.js.map +3 -3
  190. package/dist/esm/providers/llm/adapters/claude/claude.js +5 -0
  191. package/dist/esm/providers/llm/adapters/claude/claude.js.map +7 -0
  192. package/dist/esm/providers/llm/adapters/claude/index.js +2 -0
  193. package/dist/esm/providers/llm/adapters/claude/index.js.map +7 -0
  194. package/dist/esm/providers/llm/adapters/deepseek/deepseek.js +1 -1
  195. package/dist/esm/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
  196. package/dist/esm/providers/llm/adapters/index.js +1 -1
  197. package/dist/esm/providers/llm/adapters/index.js.map +3 -3
  198. package/dist/esm/providers/llm/adapters/openai/index.js +2 -0
  199. package/dist/esm/providers/llm/adapters/openai/index.js.map +7 -0
  200. package/dist/esm/providers/llm/adapters/openai/openai.js +2 -0
  201. package/dist/esm/providers/llm/adapters/openai/openai.js.map +7 -0
  202. package/dist/esm/providers/llm/adapters/openai-compatible.js +10 -0
  203. package/dist/esm/providers/llm/adapters/openai-compatible.js.map +7 -0
  204. package/dist/esm/providers/llm/adapters/openrouter/index.js +2 -0
  205. package/dist/esm/providers/llm/adapters/openrouter/index.js.map +7 -0
  206. package/dist/esm/providers/llm/adapters/openrouter/openrouter.js +2 -0
  207. package/dist/esm/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
  208. package/dist/esm/providers/llm/index.js +1 -1
  209. package/dist/esm/providers/llm/index.js.map +3 -3
  210. package/dist/esm/providers/llm/toolmode/index.js +2 -0
  211. package/dist/esm/providers/llm/toolmode/index.js.map +7 -0
  212. package/dist/esm/providers/llm/toolmode/toolmode.js +2 -0
  213. package/dist/esm/providers/llm/toolmode/toolmode.js.map +7 -0
  214. package/dist/esm/providers/llm/types.js +1 -0
  215. package/dist/esm/providers/llm/types.js.map +4 -4
  216. package/dist/esm/providers/stt/adapters/deepgram/deepgram.js +1 -1
  217. package/dist/esm/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
  218. package/dist/esm/providers/stt/adapters/index.js +1 -1
  219. package/dist/esm/providers/stt/adapters/index.js.map +3 -3
  220. package/dist/esm/providers/stt/adapters/openrouter/index.js +2 -0
  221. package/dist/esm/providers/stt/adapters/openrouter/index.js.map +7 -0
  222. package/dist/esm/providers/stt/adapters/openrouter/openrouter.js +2 -0
  223. package/dist/esm/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
  224. package/dist/esm/providers/tts/adapters/index.js +1 -1
  225. package/dist/esm/providers/tts/adapters/index.js.map +3 -3
  226. package/dist/esm/providers/tts/adapters/kokoro/kokoro.js +4 -1
  227. package/dist/esm/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
  228. package/dist/esm/providers/tts/adapters/openrouter/index.js +2 -0
  229. package/dist/esm/providers/tts/adapters/openrouter/index.js.map +7 -0
  230. package/dist/esm/providers/tts/adapters/openrouter/openrouter.js +2 -0
  231. package/dist/esm/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
  232. package/dist/esm/transport/streamobject/field-stream/field-stream.js +2 -0
  233. package/dist/esm/transport/streamobject/field-stream/field-stream.js.map +7 -0
  234. package/dist/esm/transport/streamobject/field-stream/index.js +2 -0
  235. package/dist/esm/transport/streamobject/field-stream/index.js.map +7 -0
  236. package/dist/esm/transport/streamobject/index.js +2 -0
  237. package/dist/esm/transport/streamobject/index.js.map +7 -0
  238. package/dist/esm/transport/streamobject/json-adapter/index.js +2 -0
  239. package/dist/esm/transport/streamobject/json-adapter/index.js.map +7 -0
  240. package/dist/esm/transport/streamobject/json-adapter/json-adapter.js +4 -0
  241. package/dist/esm/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
  242. package/dist/esm/transport/streamobject/reference/index.js +2 -0
  243. package/dist/esm/transport/streamobject/reference/index.js.map +7 -0
  244. package/dist/esm/transport/streamobject/reference/reference.js +2 -0
  245. package/dist/esm/transport/streamobject/reference/reference.js.map +7 -0
  246. package/dist/esm/transport/streamobject/stream-object/index.js +2 -0
  247. package/dist/esm/transport/streamobject/stream-object/index.js.map +7 -0
  248. package/dist/esm/transport/streamobject/stream-object/stream-object.js +2 -0
  249. package/dist/esm/transport/streamobject/stream-object/stream-object.js.map +7 -0
  250. package/dist/types/agents/agent.d.ts +3 -0
  251. package/dist/types/agents/tools/tools.d.ts +28 -6
  252. package/dist/types/conversations/conversation/conversation.d.ts +85 -6
  253. package/dist/types/conversations/conversations.d.ts +11 -1
  254. package/dist/types/conversations/index.d.ts +2 -1
  255. package/dist/types/conversations/orchestration/coordination/coordination.d.ts +192 -0
  256. package/dist/types/conversations/orchestration/coordination/index.d.ts +2 -0
  257. package/dist/types/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.d.ts +108 -0
  258. package/dist/types/conversations/orchestration/orchestrator/coordination-runner/index.d.ts +2 -0
  259. package/dist/types/conversations/orchestration/orchestrator/generation/generation.d.ts +43 -0
  260. package/dist/types/conversations/orchestration/orchestrator/generation/index.d.ts +2 -0
  261. package/dist/types/conversations/orchestration/orchestrator/history/history.d.ts +62 -0
  262. package/dist/types/conversations/orchestration/orchestrator/history/index.d.ts +1 -0
  263. package/dist/types/conversations/orchestration/orchestrator/index.d.ts +10 -0
  264. package/dist/types/conversations/orchestration/orchestrator/orchestrator.d.ts +45 -27
  265. package/dist/types/conversations/orchestration/orchestrator/routing/index.d.ts +1 -0
  266. package/dist/types/conversations/orchestration/orchestrator/routing/routing.d.ts +19 -0
  267. package/dist/types/conversations/orchestration/orchestrator/speech/index.d.ts +2 -0
  268. package/dist/types/conversations/orchestration/orchestrator/speech/speech.d.ts +49 -0
  269. package/dist/types/conversations/orchestration/orchestrator/tools/index.d.ts +2 -0
  270. package/dist/types/conversations/orchestration/orchestrator/tools/tools.d.ts +31 -0
  271. package/dist/types/conversations/orchestration/test-harness.d.ts +96 -0
  272. package/dist/types/conversations/orchestration/text-chunker/index.d.ts +1 -0
  273. package/dist/types/conversations/orchestration/text-chunker/text-chunker.d.ts +39 -0
  274. package/dist/types/conversations/stream/conversation-stream.d.ts +42 -0
  275. package/dist/types/conversations/stream/index.d.ts +1 -0
  276. package/dist/types/conversations/types.d.ts +32 -0
  277. package/dist/types/index.d.ts +5 -38
  278. package/dist/types/pipeflow/index.d.ts +2 -0
  279. package/dist/types/pipeflow/pipeflow.d.ts +35 -0
  280. package/dist/types/providers/index.d.ts +1 -1
  281. package/dist/types/providers/llm/adapters/claude/claude.d.ts +45 -0
  282. package/dist/types/providers/llm/adapters/claude/index.d.ts +2 -0
  283. package/dist/types/providers/llm/adapters/deepseek/deepseek.d.ts +23 -2
  284. package/dist/types/providers/llm/adapters/index.d.ts +3 -0
  285. package/dist/types/providers/llm/adapters/openai/index.d.ts +2 -0
  286. package/dist/types/providers/llm/adapters/openai/openai.d.ts +45 -0
  287. package/dist/types/providers/llm/adapters/openai-compatible.d.ts +44 -0
  288. package/dist/types/providers/llm/adapters/openrouter/index.d.ts +2 -0
  289. package/dist/types/providers/llm/adapters/openrouter/openrouter.d.ts +60 -0
  290. package/dist/types/providers/llm/index.d.ts +5 -2
  291. package/dist/types/providers/llm/toolmode/index.d.ts +2 -0
  292. package/dist/types/providers/llm/toolmode/toolmode.d.ts +99 -0
  293. package/dist/types/providers/llm/types.d.ts +62 -0
  294. package/dist/types/providers/stt/adapters/deepgram/deepgram.d.ts +4 -1
  295. package/dist/types/providers/stt/adapters/index.d.ts +1 -0
  296. package/dist/types/providers/stt/adapters/openrouter/index.d.ts +2 -0
  297. package/dist/types/providers/stt/adapters/openrouter/openrouter.d.ts +94 -0
  298. package/dist/types/providers/tts/adapters/index.d.ts +1 -0
  299. package/dist/types/providers/tts/adapters/kokoro/kokoro.d.ts +17 -2
  300. package/dist/types/providers/tts/adapters/openrouter/index.d.ts +2 -0
  301. package/dist/types/providers/tts/adapters/openrouter/openrouter.d.ts +45 -0
  302. package/dist/types/transport/streamobject/field-stream/field-stream.d.ts +85 -0
  303. package/dist/types/transport/streamobject/field-stream/index.d.ts +2 -0
  304. package/dist/types/transport/streamobject/index.d.ts +8 -0
  305. package/dist/types/transport/streamobject/json-adapter/index.d.ts +2 -0
  306. package/dist/types/transport/streamobject/json-adapter/json-adapter.d.ts +65 -0
  307. package/dist/types/transport/streamobject/reference/index.d.ts +2 -0
  308. package/dist/types/transport/streamobject/reference/reference.d.ts +127 -0
  309. package/dist/types/transport/streamobject/stream-object/index.d.ts +2 -0
  310. package/dist/types/transport/streamobject/stream-object/stream-object.d.ts +31 -0
  311. package/package.json +23 -2
package/README.md CHANGED
@@ -10,9 +10,9 @@ It handles the plumbing between audio, speech-to-text, LLMs, text-to-speech, con
10
10
 
11
11
  ## Highlights
12
12
 
13
- * **Small** — under 100 kB packed, zero runtime dependencies.
13
+ * **Small** — ~140 kB packed, one runtime dependency ([zod](https://github.com/colinhacks/zod)).
14
14
  * **Realtime by default** — audio, transcripts, and speech stream continuously, with built-in interruption and barge-in handling.
15
- * **Provider-agnostic** — STT, LLM, and TTS are swappable adapters (Deepgram, DeepSeek, and Kokoro today).
15
+ * **Provider-agnostic** — STT, LLM, and TTS are swappable adapters (Deepgram, DeepSeek, OpenRouter, and Kokoro today).
16
16
  * **Your backend stays yours** — tools and the audio transport are owned by your application; Pipeflow never executes your code.
17
17
 
18
18
  ## Status
@@ -21,6 +21,19 @@ It handles the plumbing between audio, speech-to-text, LLMs, text-to-speech, con
21
21
 
22
22
  The API is evolving and should be considered experimental.
23
23
 
24
+ ## Current vs. designed for
25
+
26
+ Some capabilities ship today; others are architectural boundaries the API is
27
+ shaped around but not yet implemented.
28
+
29
+ | Area | Current | Designed for |
30
+ | --- | --- | --- |
31
+ | Providers | DeepSeek, OpenRouter (LLM), Deepgram Flux (STT), Kokoro (TTS) | additional providers behind the same interfaces |
32
+ | Persistence | in-memory, SQLite | Postgres, Redis, … behind the same contract |
33
+ | Transport | in-memory (tests, development) | WebSocket, WebRTC, … |
34
+ | Conversation addressing | agent names and aliases | floor management, multi-participant turn-taking |
35
+ | Realtime bounds | step-bounded coordination graph | hierarchical latency budgets |
36
+
24
37
  ## Philosophy
25
38
 
26
39
  Pipeflow has four core concepts:
@@ -62,25 +75,26 @@ An agent does not inherently own a conversation. A conversation does not require
62
75
  │ │ │
63
76
  ▼ ▼ ▼
64
77
  Deepgram DeepSeek Kokoro
78
+ OpenRouter
65
79
  ```
66
80
 
67
81
  ## Installation
68
82
 
69
83
  ```bash
70
- bun add pipeflow
84
+ bun add @moureau/pipeflow
71
85
  ```
72
86
 
73
- The package is not published to npm yet. Until then, install from the
74
- repository (`bun add pipeflow`) or build from
75
- source — see [Development](#development).
87
+ Published on npm as `@moureau/pipeflow`. Alternatively, install directly from
88
+ the repository (`bun add git@github.com:moureau-dev/pipeflow.git`) or build
89
+ from source — see [Development](#development).
76
90
 
77
91
  ## Basic voice agent
78
92
 
79
93
  Create an agent:
80
94
 
81
95
  ```ts
82
- import { Pipeflow, Orchestrator } from "pipeflow";
83
- import { DeepSeekLLM, DeepgramSTT, KokoroTTS } from "pipeflow/providers";
96
+ import { Pipeflow } from "@moureau/pipeflow";
97
+ import { DeepSeekLLM, DeepgramSTT, KokoroTTS } from "@moureau/pipeflow/providers";
84
98
 
85
99
  // Providers are configured explicitly with their own credentials —
86
100
  // Pipeflow itself does not hold an API key.
@@ -111,28 +125,15 @@ const conversation = await pipeflow.conversations.create({
111
125
  });
112
126
  ```
113
127
 
114
- Attach the orchestrator it runs the realtime pipeline (STT → turns → LLM → TTS) for the conversation:
128
+ Starting a conversation starts its realtime machinery: `start()` attaches the
129
+ orchestrator, which runs the STT → turns → LLM → TTS pipeline for the
130
+ conversation.
115
131
 
116
132
  ```ts
117
- const orchestrator = new Orchestrator({
118
- conversation,
119
- agent: jarvis,
120
- stt,
121
- tts,
122
- });
123
-
124
- await orchestrator.start();
133
+ await conversation.start();
125
134
  ```
126
135
 
127
- Start the conversation and add a participant:
128
-
129
- ```ts
130
- conversation.start();
131
-
132
- await conversation.participate({
133
- userId: "alice",
134
- });
135
- ```
136
+ Add a participant:
136
137
 
137
138
  Feed it audio as it arrives:
138
139
 
@@ -182,6 +183,9 @@ Your application
182
183
 
183
184
  A conversation is the persistent entity representing a realtime interaction.
184
185
 
186
+ See [src/conversations/README.md](src/conversations/README.md) for the
187
+ conversation domain.
188
+
185
189
  ```ts
186
190
  const conversation =
187
191
  await pipeflow.conversations.create({
@@ -190,43 +194,37 @@ const conversation =
190
194
 
191
195
  console.log(conversation.id);
192
196
 
193
- conversation.start();
197
+ await conversation.start();
194
198
  ```
195
199
 
196
- Creation and realtime execution are deliberately separate.
200
+ Creation and realtime execution are deliberately separate:
197
201
 
198
202
  ```ts
199
203
  create() // creates the persistent conversation
200
204
  start() // moves the conversation into the started state
201
205
  participate() // adds participants
202
206
  listen() // sends audio
207
+ send() // injects a finalized text turn (no STT)
203
208
  stop() // finalizes the realtime session
204
209
  ```
205
210
 
206
- Realtime processing itself is the orchestrator's job: once attached, it
207
- subscribes to `audio-in` events, runs the STT/LLM/TTS pipeline, and pushes
208
- generated audio, turns, transcripts, and tool calls back through conversation
209
- events.
211
+ `start()` attaches the orchestrator, which subscribes to `audio-in` events,
212
+ runs the STT/LLM/TTS pipeline, and pushes generated audio, turns, transcripts,
213
+ and tool calls back through conversation events.
210
214
 
211
- `listen()` is intentionally synchronous:
215
+ `listen()` is intentionally synchronous — it means "send this audio packet",
216
+ not "wait for this utterance to finish":
212
217
 
213
218
  ```ts
214
- conversation.listen({
215
- userId,
216
- audio,
217
- });
219
+ conversation.listen({ userId, audio });
218
220
  ```
219
221
 
220
- It means:
221
-
222
- > Send this audio packet.
223
-
224
- It does not mean:
225
-
226
- > Wait for this utterance to finish.
227
-
228
222
  This makes it suitable for high-frequency realtime audio streams.
229
223
 
224
+ `send({ userId, text })` does the same for a finalized text turn, bypassing
225
+ STT — text-first integrations (chat, Discord text channels) route through the
226
+ same pipeline: routing, coordination, clarification, and generation.
227
+
230
228
  ## Participants
231
229
 
232
230
  Participants can be added individually:
@@ -269,6 +267,10 @@ Interruptions can be triggered by the application — or automatically: the
269
267
  orchestrator detects when a participant starts speaking while the agent is
270
268
  responding (barge-in).
271
269
 
270
+ `interrupt()` is a semantic guarantee: it stops the active generation and
271
+ prevents any further generated audio from reaching the conversation (tested to
272
+ stop audio within ~100ms). The next turn starts fresh.
273
+
272
274
  ```ts
273
275
  conversation.interrupt(); // stops TTS, cancels the current generation
274
276
  ```
@@ -301,6 +303,7 @@ This keeps interactions responsive even when the user interrupts the agent halfw
301
303
  The conversation emits a typed event stream the application can subscribe to:
302
304
 
303
305
  * `audio-in` — raw audio fed in via `listen()`
306
+ * `text-in` — a finalized text turn via `send()`
304
307
  * `partial-transcript` — live STT partials (captions)
305
308
  * `turn` — a finalized participant turn
306
309
  * `transcript` — a transcript entry
@@ -318,6 +321,9 @@ conversation.on("partial-transcript", ({ text }) => captions.update(text));
318
321
 
319
322
  ## Multi-participant conversations
320
323
 
324
+ <details>
325
+ <summary>Batching participants, conversational state, and the roadmap for floor management and addressing</summary>
326
+
321
327
  Conversations can contain multiple participants and agents.
322
328
 
323
329
  ```ts
@@ -333,26 +339,25 @@ await conversation.participate([
333
339
  ]);
334
340
  ```
335
341
 
336
- The conversation orchestrator maintains conversational state such as:
337
-
338
- * active turns
339
- * participant identity
340
- * interruptions
341
- * agent generations
342
- * transcript state
343
-
344
342
  In a one-to-one conversation, speech is treated as an interaction: every
345
343
  finalized participant turn produces an agent generation.
346
344
 
347
- Multi-participant floor management and addressing (determining when an agent is
348
- being spoken to using participant context, agent names, aliases, and floor
349
- rules) are on the roadmap. A wake word is not intended to be a fundamental
350
- requirement.
345
+ Addressing works at a basic level: in a multi-agent conversation, a turn is
346
+ routed to the agent whose name or alias appears in the speech, and unaddressed
347
+ turns go through the built-in `understand` coordination, which may delegate to
348
+ agents, ask the user, or answer directly. Floor management, multi-participant
349
+ turn-taking rules, and richer addressing heuristics are on the roadmap. A wake
350
+ word is not intended to be a fundamental requirement.
351
+
352
+ </details>
351
353
 
352
354
  ## Agents
353
355
 
354
356
  An agent defines an AI persona and its capabilities.
355
357
 
358
+ See [src/agents/README.md](src/agents/README.md) for the agent and tool
359
+ abstractions.
360
+
356
361
  ```ts
357
362
  const jarvis = pipeflow.agent({
358
363
  name: "Jarvis",
@@ -385,39 +390,119 @@ This is useful for ordinary LLM workloads where realtime audio and conversation
385
390
 
386
391
  When an agent is attached to a conversation, it can take conversational turns as part of the realtime orchestration.
387
392
 
388
- The conversation owns the runtime.
393
+ A conversation can coordinate **multiple agents**: `create({ agents })` accepts
394
+ a roster. A turn that explicitly addresses an agent by name or alias goes
395
+ straight to that agent; unaddressed turns go through the built-in `understand`
396
+ coordination, which decides whether to delegate, ask the user, or answer
397
+ directly. In a single-agent conversation, every turn goes to that agent. Each
398
+ agent keeps its own context and its own LLM; the conversation owns the shared
399
+ runtime (STT, TTS, history, interruptions).
389
400
 
390
- The agent owns the intelligence.
401
+ ```ts
402
+ const receptionist = pipeflow.agent({
403
+ name: "Receptionist",
404
+ context: `
405
+ You are the front desk. Greet people and route requests.
406
+ `,
407
+ });
391
408
 
392
- ```text
393
- Agent
394
- ├── context
395
- └── tools
409
+ const specialist = pipeflow.agent({
410
+ name: "Technical Specialist",
411
+ aliases: ["tech"],
412
+ context: `
413
+ You are the technical support specialist.
414
+ `,
415
+ });
396
416
 
397
- Conversation
398
- ├── participants
399
- ├── turns
400
- ├── audio
401
- ├── interruption
402
- └── orchestration
417
+ const conversation =
418
+ await pipeflow.conversations.create({
419
+ agents: [receptionist, specialist],
420
+ });
403
421
  ```
404
422
 
423
+ "Ask the technical specialist about X" is routed to the specialist; an
424
+ unaddressed turn goes through the built-in `understand` coordination.
425
+
426
+ ### Collaborative orchestration
427
+
428
+ `understand` is a hardcoded **coordination**: a reasoning unit that decides
429
+ what should happen next rather than doing the work itself. It can:
430
+
431
+ - **delegate** to one or more agents (in parallel), each with a self-contained
432
+ prompt;
433
+ - **pass the work to another coordination**;
434
+ - **ask the user** for missing details via a structured, batched `clarify`
435
+ action — every missing detail goes into one question, and question rounds
436
+ are capped per run (default 2), after which reasonable assumptions are
437
+ stated;
438
+ - **complete** with a direct answer.
439
+
440
+ ```text
441
+ User: "Book a flight and check whether my calendar conflicts."
442
+
443
+
444
+ ┌────────────┐
445
+ │ understand │ ← built-in coordination
446
+ └─────┬──────┘
447
+
448
+ ┌──────┴───────┐
449
+ ▼ ▼
450
+ Travel Agent Calendar Agent
451
+ │ │
452
+ └──────┬───────┘
453
+
454
+ understand
455
+
456
+
457
+ User
458
+ ```
459
+
460
+ Agent delegation runs as **sub-generations**: the target agent executes on its
461
+ own LLM, context, and tools (which still run in your backend), and every
462
+ delegated prompt is stamped with the current time so time-sensitive tasks
463
+ reason about the right "now". Delegated agents are text-only — the coordination
464
+ narrates while they work and speaks the merged answer.
465
+
466
+ Clarification is a first-class operation: an ambiguous request parks the
467
+ coordination and **resumes on the next turn** instead of starting fresh.
468
+ While waiting, participant speech is treated as the answer, not as a barge-in.
469
+
470
+ See [src/conversations/orchestration/coordination/README.md](src/conversations/orchestration/coordination/README.md)
471
+ for the coordination model and
472
+ [src/conversations/orchestration/orchestrator/README.md](src/conversations/orchestration/orchestrator/README.md)
473
+ for how it is wired into the realtime pipeline.
474
+
405
475
  ## Tools
406
476
 
407
477
  Tools expose capabilities from your application to an agent.
408
478
 
409
479
  ```ts
480
+ import { z } from "zod";
481
+
410
482
  const getWeather = new PipeflowTool({
411
483
  name: "get_weather",
412
484
 
413
485
  description: "Get the current weather for a city.",
414
486
 
487
+ // One zod schema drives both sides: it derives the JSON schema the model
488
+ // sees, and validates the arguments before execute() runs.
489
+ schema: {
490
+ in: z.object({ city: z.string().describe("The city to look up.") }),
491
+ },
492
+
415
493
  execute: async ({ city }) => {
416
494
  return weatherService.getCurrent(city);
417
495
  },
418
496
  });
419
497
  ```
420
498
 
499
+ `schema.in` is what the model sends; `schema.out` (optional, defaults to `in`)
500
+ is what `execute` receives after validation, and may transform the arguments.
501
+ Prefer `schema` — it keeps the model contract and your `execute` signature in
502
+ sync and rejects bad arguments with a clear error instead of crashing inside
503
+ the tool. If you need a hand-written JSON schema instead, pass `parameters`
504
+ (no runtime validation).
505
+
421
506
  Then:
422
507
 
423
508
  ```ts
@@ -473,6 +558,10 @@ conversation.on("tool-call", async ({ call }) => {
473
558
  The agent's narration continues while the tool runs, and the generation resumes
474
559
  with the tool result once it is resolved.
475
560
 
561
+ Tool calls the model requests together run concurrently: `run()` executes
562
+ them in parallel, and in a conversation your backend resolves them in
563
+ parallel.
564
+
476
565
  ## Meeting transcription
477
566
 
478
567
  A conversation does not require an agent.
@@ -483,16 +572,9 @@ This makes Pipeflow useful as a realtime transcription primitive.
483
572
  const conversation =
484
573
  await pipeflow.conversations.create();
485
574
 
486
- // Without an agent, the orchestrator runs in transcription-only mode:
487
- // audio in, turns and transcripts out.
488
- const orchestrator = new Orchestrator({
489
- conversation,
490
- stt,
491
- });
492
-
493
- await orchestrator.start();
494
-
495
- conversation.start();
575
+ // Without an agent, `start()` attaches the orchestrator in
576
+ // transcription-only mode: audio in, turns and transcripts out.
577
+ await conversation.start();
496
578
 
497
579
  await conversation.participate([
498
580
  { userId: "alice" },
@@ -524,6 +606,9 @@ Pagination can be supported for long conversations.
524
606
 
525
607
  ## Meeting summaries
526
608
 
609
+ <details>
610
+ <summary>Summarizing a meeting with a notetaker agent — as a plain LLM task or through a transcript tool</summary>
611
+
527
612
  A meeting summary can simply be another agent task.
528
613
 
529
614
  ```ts
@@ -585,38 +670,22 @@ The agent does not receive special access to conversations.
585
670
 
586
671
  If it needs conversation data, **a tool provides that capability**.
587
672
 
588
- ## Providers
589
-
590
- Pipeflow separates provider interfaces from provider implementations.
673
+ </details>
591
674
 
592
- ```text
593
- providers/
594
- ├── llm/
595
- │ ├── types.ts
596
- │ └── adapters/
597
- │ └── deepseek/
598
-
599
- ├── stt/
600
- │ ├── types.ts
601
- │ └── adapters/
602
- │ └── deepgram/
603
-
604
- └── tts/
605
- ├── types.ts
606
- └── adapters/
607
- └── kokoro/
608
- ```
609
-
610
- The orchestrator works against provider interfaces rather than directly against vendor APIs.
675
+ ## Providers
611
676
 
612
- This makes it possible to replace providers without changing the conversation layer.
677
+ <details>
678
+ <summary>Vendor-independent interfaces and the current adapters: Deepgram, DeepSeek, OpenRouter, Kokoro</summary>
613
679
 
614
- ### Current providers
680
+ Pipeflow separates provider interfaces (LLM, STT, TTS) from their
681
+ implementations. The orchestrator works against the interfaces rather than
682
+ directly against vendor APIs, so providers can be replaced without changing the
683
+ conversation layer.
615
684
 
616
- The project currently contains adapters for:
685
+ The project currently ships adapters for:
617
686
 
618
687
  * **STT:** Deepgram
619
- * **LLM:** DeepSeek
688
+ * **LLM:** DeepSeek, OpenRouter, OpenAI, Claude (Anthropic)
620
689
  * **TTS:** Kokoro
621
690
 
622
691
  Providers are configured with their own credentials — Pipeflow itself does
@@ -624,8 +693,16 @@ not hold an API key.
624
693
 
625
694
  Provider availability and configuration are evolving during early development.
626
695
 
696
+ See [src/providers/README.md](src/providers/README.md) for the interfaces and
697
+ adapter contracts.
698
+
699
+ </details>
700
+
627
701
  ## Architecture
628
702
 
703
+ <details>
704
+ <summary>How the layers fit together: agents, conversations, persistence, providers, transport</summary>
705
+
629
706
  Pipeflow is designed around a small number of independent layers.
630
707
 
631
708
  ```text
@@ -647,9 +724,11 @@ src/
647
724
  ### Conversation
648
725
 
649
726
  Public realtime conversation API and lifecycle.
727
+ See [src/conversations/conversation/README.md](src/conversations/conversation/README.md).
650
728
 
651
729
  ### Orchestration
652
730
 
731
+ See [src/conversations/orchestration/README.md](src/conversations/orchestration/README.md).
653
732
  The state machine coordinating:
654
733
 
655
734
  * speech
@@ -664,40 +743,54 @@ The state machine coordinating:
664
743
  ### Transcription
665
744
 
666
745
  Conversation transcription and transcript state.
746
+ See [src/conversations/transcription/README.md](src/conversations/transcription/README.md).
667
747
 
668
748
  ### Providers
669
749
 
670
750
  Vendor-independent interfaces and provider adapters.
751
+ See [src/providers/README.md](src/providers/README.md).
671
752
 
672
753
  ### Persistence
673
754
 
674
755
  Persistence abstractions with adapters such as SQLite and in-memory storage.
756
+ See [src/persistence/README.md](src/persistence/README.md).
675
757
 
676
758
  ### Transport
677
759
 
678
- Realtime communication between Pipeflow and the application using Pipeflow.
760
+ Realtime communication between Pipeflow and the application.
761
+ See [src/transport/README.md](src/transport/README.md).
762
+
763
+ </details>
679
764
 
680
765
  ## Persistence
681
766
 
682
- Pipeflow separates persistence from the conversation domain.
767
+ <details>
768
+ <summary>Storage adapters: in-memory for development, SQLite for lightweight persistence</summary>
683
769
 
684
- The project currently includes:
770
+ Pipeflow separates persistence from the conversation domain. The in-memory
771
+ adapter is useful for tests and development; SQLite provides a lightweight
772
+ persistent backend suitable for local applications and early deployments. The
773
+ persistence interface is intentionally provider-independent so other storage
774
+ implementations can be added later.
685
775
 
686
- ```text
687
- persistence/
688
- └── adapters/
689
- ├── memory/
690
- └── sqlite/
691
- ```
776
+ ```ts
777
+ import { SQLitePersistence } from "@moureau/pipeflow/persistence";
692
778
 
693
- The in-memory adapter is useful for tests and development.
779
+ const pipeflow = new Pipeflow({
780
+ persistence: new SQLitePersistence({ filename: "./pipeflow.db" }),
781
+ });
782
+ ```
694
783
 
695
- SQLite provides a lightweight persistent backend suitable for local applications and early deployments.
784
+ See [src/persistence/README.md](src/persistence/README.md) for the storage
785
+ contract and adapters.
696
786
 
697
- The persistence interface is intentionally provider-independent so other storage implementations can be added later.
787
+ </details>
698
788
 
699
789
  ## Realtime architecture
700
790
 
791
+ <details>
792
+ <summary>How audio flows through the pipeline as a continuous stream</summary>
793
+
701
794
  A typical voice interaction looks like:
702
795
 
703
796
  ```text
@@ -752,14 +845,21 @@ audio
752
845
 
753
846
  This allows the system to begin producing speech as early as possible.
754
847
 
848
+ </details>
849
+
755
850
  ## Open source
756
851
 
852
+ <details>
853
+ <summary>Why the project is open and how the provider layer stays modular</summary>
854
+
757
855
  Pipeflow is open source.
758
856
 
759
857
  The project is designed to make realtime voice infrastructure accessible without requiring applications to implement their own orchestration layer.
760
858
 
761
859
  The provider layer is intentionally modular so applications can choose between hosted and self-hosted services.
762
860
 
861
+ </details>
862
+
763
863
  ## Development
764
864
 
765
865
  Clone the repository and install dependencies:
@@ -776,6 +876,29 @@ Run tests:
776
876
  bun test
777
877
  ```
778
878
 
879
+ End-to-end tests hit the real LLM API and are skipped when no key is
880
+ available. They prefer `OPENROUTER_API_KEY` (default model
881
+ `google/gemini-2.5-flash-lite`, override with `LLM_MODEL`) and fall back to
882
+ `DEEPSEEK_API_KEY`. Add either to `.env` (loaded automatically) and run:
883
+
884
+ ```bash
885
+ bun run test:e2e
886
+ ```
887
+
888
+ The latency benchmark runs the pipeline repeatedly against the real model and
889
+ reports p50/p95 per hop: first token, first speechable text, TTS request, TTS
890
+ first audio, first audio delivered, and completion. STT and TTS are faked by
891
+ default; point `KOKORO_URL` at a Kokoro endpoint to measure the real synthesis
892
+ path, including inter-chunk audio gaps:
893
+
894
+ ```bash
895
+ bun run benchmark # 10 runs; BENCH_RUNS=5 to change
896
+ KOKORO_URL=http://localhost:8880 bun run benchmark # local kokoro-fastapi
897
+ KOKORO_URL=https://api.together.ai \
898
+ KOKORO_API_KEY=... KOKORO_MODEL=hexgrad/Kokoro-82M \
899
+ bun run benchmark # Together AI
900
+ ```
901
+
779
902
  Build and type-check:
780
903
 
781
904
  ```bash
@@ -787,6 +910,9 @@ The project uses Bun and TypeScript.
787
910
 
788
911
  ## Design principles
789
912
 
913
+ <details>
914
+ <summary>The rules the API is built around: realtime first, provider agnostic, app-owned tools</summary>
915
+
790
916
  ### Realtime first
791
917
 
792
918
  Audio is streamed continuously rather than processed as completed recordings.
@@ -828,6 +954,8 @@ Tool
828
954
 
829
955
  Everything else should remain replaceable implementation detail for as long as possible.
830
956
 
957
+ </details>
958
+
831
959
  ## License
832
960
 
833
961
  See [LICENSE](LICENSE).
@@ -1,2 +1,2 @@
1
- "use strict";var u=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(r,e)=>u(r,"name",{value:e,configurable:!0});var L=(r,e)=>{for(var t in e)u(r,t,{get:e[t],enumerable:!0})},x=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of d(e))!p.call(r,n)&&n!==t&&u(r,n,{get:()=>e[n],enumerable:!(o=h(e,n))||o.enumerable});return r};var f=r=>x(u({},"__esModule",{value:!0}),r);var y={};L(y,{Agent:()=>T});module.exports=f(y);var M=require("./tools/tools.js");class T{static{c(this,"Agent")}name;context;toolRegistry=new Map;llm;constructor(e){const t=e.name.trim();if(!t)throw new Error("Agent requires a non-empty name");this.name=t,this.context=e.context?.trim()??"",this.llm=e.llm;for(const o of e.tools??[])this.addTool(o)}get tools(){return[...this.toolRegistry.values()]}addTool(e){if(this.toolRegistry.has(e.name))throw new Error(`Agent already has a tool named "${e.name}"`);this.toolRegistry.set(e.name,e)}hasTool(e){return this.toolRegistry.has(e)}getTool(e){return this.toolRegistry.get(e)}async run(e){if(!this.llm)throw new Error(`Agent "${this.name}" has no LLM provider configured. Pass an LLM when constructing the agent or the Pipeflow instance.`);const t=[];this.context&&t.push({role:"system",content:this.context}),e.history&&t.push(...e.history),t.push({role:"user",content:e.prompt});const o=this.tools.map(a=>({name:a.name,description:a.description,parameters:a.parameters??{type:"object",properties:{}}})),n=[],m=e.maxToolIterations??10;for(let a=0;a<m;a++){const{text:l,toolCalls:i}=await this.streamOnce({llm:this.llm,messages:t,definitions:o,temperature:e.temperature,maxTokens:e.maxTokens});if(i.length===0)return{text:l,messages:t,toolCalls:n};t.push({role:"assistant",content:l,toolCalls:i});for(const s of i){const g=await this.executeToolCall(s);n.push(g),t.push({role:"tool",toolCallId:s.id,name:s.name,content:JSON.stringify(g.result)})}}throw new Error(`Agent "${this.name}" exceeded ${m} tool iterations`)}async streamOnce(e){const{llm:t,messages:o,definitions:n,temperature:m,maxTokens:a}=e;let l="";const i=[];for await(const s of t.stream({messages:o,tools:n,temperature:m,maxTokens:a}))switch(s.type){case"delta":l+=s.content;break;case"tool_call":i.push({id:s.id,name:s.name,arguments:s.arguments});break;case"done":return{text:l,toolCalls:i};case"error":throw s.error}return{text:l,toolCalls:i}}async executeToolCall(e){const t=this.toolRegistry.get(e.name);let o;try{o=JSON.parse(e.arguments)}catch{o=e.arguments}if(!t)return{id:e.id,name:e.name,arguments:o,result:{error:`Unknown tool "${e.name}"`}};try{const n=await t.execute(o);return{id:e.id,name:e.name,arguments:o,result:n}}catch(n){return{id:e.id,name:e.name,arguments:o,result:{error:n instanceof Error?n.message:String(n)}}}}}
1
+ "use strict";var g=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(r,e)=>g(r,"name",{value:e,configurable:!0});var L=(r,e)=>{for(var t in e)g(r,t,{get:e[t],enumerable:!0})},x=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of d(e))!p.call(r,n)&&n!==t&&g(r,n,{get:()=>e[n],enumerable:!(o=h(e,n))||o.enumerable});return r};var f=r=>x(g({},"__esModule",{value:!0}),r);var y={};L(y,{Agent:()=>T});module.exports=f(y);var M=require("./tools/tools.js");class T{static{c(this,"Agent")}name;aliases;context;toolRegistry=new Map;llm;constructor(e){const t=e.name.trim();if(!t)throw new Error("Agent requires a non-empty name");this.name=t,this.aliases=[...e.aliases??[]],this.context=e.context?.trim()??"",this.llm=e.llm;for(const o of e.tools??[])this.addTool(o)}get tools(){return[...this.toolRegistry.values()]}addTool(e){if(this.toolRegistry.has(e.name))throw new Error(`Agent already has a tool named "${e.name}"`);this.toolRegistry.set(e.name,e)}hasTool(e){return this.toolRegistry.has(e)}getTool(e){return this.toolRegistry.get(e)}async run(e){if(!this.llm)throw new Error(`Agent "${this.name}" has no LLM provider configured. Pass an LLM when constructing the agent or the Pipeflow instance.`);const t=[];this.context&&t.push({role:"system",content:this.context}),e.history&&t.push(...e.history),t.push({role:"user",content:e.prompt});const o=this.tools.map(s=>({name:s.name,description:s.description,parameters:s.parameters??{type:"object",properties:{}}})),n=[],u=e.maxToolIterations??10;for(let s=0;s<u;s++){const{text:l,toolCalls:i}=await this.streamOnce({llm:this.llm,messages:t,definitions:o,temperature:e.temperature,maxTokens:e.maxTokens});if(i.length===0)return{text:l,messages:t,toolCalls:n};t.push({role:"assistant",content:l,toolCalls:i});const a=await Promise.all(i.map(m=>this.executeToolCall(m)));for(const m of a)n.push(m),t.push({role:"tool",toolCallId:m.id,name:m.name,content:JSON.stringify(m.result)})}throw new Error(`Agent "${this.name}" exceeded ${u} tool iterations`)}async streamOnce(e){const{llm:t,messages:o,definitions:n,temperature:u,maxTokens:s}=e;let l="";const i=[];for await(const a of t.stream({messages:o,tools:n,temperature:u,maxTokens:s}))switch(a.type){case"delta":l+=a.content;break;case"tool_call":i.push({id:a.id,name:a.name,arguments:a.arguments});break;case"done":return{text:l,toolCalls:i};case"error":throw a.error}return{text:l,toolCalls:i}}async executeToolCall(e){const t=this.toolRegistry.get(e.name);let o;try{o=JSON.parse(e.arguments)}catch{o=e.arguments}if(!t)return{id:e.id,name:e.name,arguments:o,result:{error:`Unknown tool "${e.name}"`}};try{const n=await t.execute(o);return{id:e.id,name:e.name,arguments:o,result:n}}catch(n){return{id:e.id,name:e.name,arguments:o,result:{error:n instanceof Error?n.message:String(n)}}}}}
2
2
  //# sourceMappingURL=agent.js.map