@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
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,12 +303,14 @@ 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
307
310
  * `audio` — generated audio to play
308
311
  * `generation` — an agent generation
309
- * `tool-call` / `tool-call-result` — tool execution round trips
312
+ * `tool-call` / `tool-call-result` — every tool round trip (auto-executed by
313
+ default; observable even when the framework runs the tool)
310
314
  * `interrupt` — an interruption occurred
311
315
  * `error` — a provider failure
312
316
  * `start` / `stop` / `state` — lifecycle
@@ -318,6 +322,9 @@ conversation.on("partial-transcript", ({ text }) => captions.update(text));
318
322
 
319
323
  ## Multi-participant conversations
320
324
 
325
+ <details>
326
+ <summary>Batching participants, conversational state, and the roadmap for floor management and addressing</summary>
327
+
321
328
  Conversations can contain multiple participants and agents.
322
329
 
323
330
  ```ts
@@ -333,26 +340,25 @@ await conversation.participate([
333
340
  ]);
334
341
  ```
335
342
 
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
343
  In a one-to-one conversation, speech is treated as an interaction: every
345
344
  finalized participant turn produces an agent generation.
346
345
 
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.
346
+ Addressing works at a basic level: in a multi-agent conversation, a turn is
347
+ routed to the agent whose name or alias appears in the speech, and unaddressed
348
+ turns go through the built-in `understand` coordination, which may delegate to
349
+ agents, ask the user, or answer directly. Floor management, multi-participant
350
+ turn-taking rules, and richer addressing heuristics are on the roadmap. A wake
351
+ word is not intended to be a fundamental requirement.
352
+
353
+ </details>
351
354
 
352
355
  ## Agents
353
356
 
354
357
  An agent defines an AI persona and its capabilities.
355
358
 
359
+ See [src/agents/README.md](src/agents/README.md) for the agent and tool
360
+ abstractions.
361
+
356
362
  ```ts
357
363
  const jarvis = pipeflow.agent({
358
364
  name: "Jarvis",
@@ -385,39 +391,119 @@ This is useful for ordinary LLM workloads where realtime audio and conversation
385
391
 
386
392
  When an agent is attached to a conversation, it can take conversational turns as part of the realtime orchestration.
387
393
 
388
- The conversation owns the runtime.
394
+ A conversation can coordinate **multiple agents**: `create({ agents })` accepts
395
+ a roster. A turn that explicitly addresses an agent by name or alias goes
396
+ straight to that agent; unaddressed turns go through the built-in `understand`
397
+ coordination, which decides whether to delegate, ask the user, or answer
398
+ directly. In a single-agent conversation, every turn goes to that agent. Each
399
+ agent keeps its own context and its own LLM; the conversation owns the shared
400
+ runtime (STT, TTS, history, interruptions).
389
401
 
390
- The agent owns the intelligence.
402
+ ```ts
403
+ const receptionist = pipeflow.agent({
404
+ name: "Receptionist",
405
+ context: `
406
+ You are the front desk. Greet people and route requests.
407
+ `,
408
+ });
391
409
 
392
- ```text
393
- Agent
394
- ├── context
395
- └── tools
410
+ const specialist = pipeflow.agent({
411
+ name: "Technical Specialist",
412
+ aliases: ["tech"],
413
+ context: `
414
+ You are the technical support specialist.
415
+ `,
416
+ });
396
417
 
397
- Conversation
398
- ├── participants
399
- ├── turns
400
- ├── audio
401
- ├── interruption
402
- └── orchestration
418
+ const conversation =
419
+ await pipeflow.conversations.create({
420
+ agents: [receptionist, specialist],
421
+ });
403
422
  ```
404
423
 
424
+ "Ask the technical specialist about X" is routed to the specialist; an
425
+ unaddressed turn goes through the built-in `understand` coordination.
426
+
427
+ ### Collaborative orchestration
428
+
429
+ `understand` is a hardcoded **coordination**: a reasoning unit that decides
430
+ what should happen next rather than doing the work itself. It can:
431
+
432
+ - **delegate** to one or more agents (in parallel), each with a self-contained
433
+ prompt;
434
+ - **pass the work to another coordination**;
435
+ - **ask the user** for missing details via a structured, batched `clarify`
436
+ action — every missing detail goes into one question, and question rounds
437
+ are capped per run (default 2), after which reasonable assumptions are
438
+ stated;
439
+ - **complete** with a direct answer.
440
+
441
+ ```text
442
+ User: "Book a flight and check whether my calendar conflicts."
443
+
444
+
445
+ ┌────────────┐
446
+ │ understand │ ← built-in coordination
447
+ └─────┬──────┘
448
+
449
+ ┌──────┴───────┐
450
+ ▼ ▼
451
+ Travel Agent Calendar Agent
452
+ │ │
453
+ └──────┬───────┘
454
+
455
+ understand
456
+
457
+
458
+ User
459
+ ```
460
+
461
+ Agent delegation runs as **sub-generations**: the target agent executes on its
462
+ own LLM, context, and tools (which still run in your backend), and every
463
+ delegated prompt is stamped with the current time so time-sensitive tasks
464
+ reason about the right "now". Delegated agents are text-only — the coordination
465
+ narrates while they work and speaks the merged answer.
466
+
467
+ Clarification is a first-class operation: an ambiguous request parks the
468
+ coordination and **resumes on the next turn** instead of starting fresh.
469
+ While waiting, participant speech is treated as the answer, not as a barge-in.
470
+
471
+ See [src/conversations/orchestration/coordination/README.md](src/conversations/orchestration/coordination/README.md)
472
+ for the coordination model and
473
+ [src/conversations/orchestration/orchestrator/README.md](src/conversations/orchestration/orchestrator/README.md)
474
+ for how it is wired into the realtime pipeline.
475
+
405
476
  ## Tools
406
477
 
407
478
  Tools expose capabilities from your application to an agent.
408
479
 
409
480
  ```ts
481
+ import { z } from "zod";
482
+
410
483
  const getWeather = new PipeflowTool({
411
484
  name: "get_weather",
412
485
 
413
486
  description: "Get the current weather for a city.",
414
487
 
488
+ // One zod schema drives both sides: it derives the JSON schema the model
489
+ // sees, and validates the arguments before execute() runs.
490
+ schema: {
491
+ in: z.object({ city: z.string().describe("The city to look up.") }),
492
+ },
493
+
415
494
  execute: async ({ city }) => {
416
495
  return weatherService.getCurrent(city);
417
496
  },
418
497
  });
419
498
  ```
420
499
 
500
+ `schema.in` is what the model sends; `schema.out` (optional, defaults to `in`)
501
+ is what `execute` receives after validation, and may transform the arguments.
502
+ Prefer `schema` — it keeps the model contract and your `execute` signature in
503
+ sync and rejects bad arguments with a clear error instead of crashing inside
504
+ the tool. If you need a hand-written JSON schema instead, pass `parameters`
505
+ (no runtime validation).
506
+
421
507
  Then:
422
508
 
423
509
  ```ts
@@ -430,9 +516,8 @@ const jarvis = pipeflow.agent({
430
516
  });
431
517
  ```
432
518
 
433
- Tools execute in **your backend**.
434
-
435
- Pipeflow does not execute arbitrary application code.
519
+ Tools execute in **your backend**: the `execute` function is your code, and it
520
+ runs in your process — Pipeflow only invokes the callbacks you registered.
436
521
 
437
522
  ```text
438
523
  Pipeflow
@@ -455,18 +540,44 @@ Pipeflow does not execute arbitrary application code.
455
540
 
456
541
  This allows tools to access your database, APIs, Discord bot, business logic, filesystem, or anything else your application controls.
457
542
 
458
- In a conversation, tool calls never execute inside Pipeflow. The orchestrator
459
- emits a `tool-call` event with the requested tool and its arguments; your
460
- backend executes it and reports back:
543
+ ### In a conversation: tools auto-execute
544
+
545
+ Attach tools to an agent and they just work — the orchestrator runs each tool
546
+ and feeds the result back into the generation (same loop as `Agent.run()`):
461
547
 
462
548
  ```ts
463
- conversation.on("tool-call", async ({ call }) => {
464
- const result = await myBackend.execute(call.name, call.arguments);
549
+ const jarvis = pipeflow.agent({
550
+ name: "Jarvis",
551
+ context: "You are a helpful assistant.",
552
+ tools: [getWeather],
553
+ });
465
554
 
466
- conversation.resolveToolCall({
467
- id: call.id,
468
- result,
469
- });
555
+ const conversation = await pipeflow.conversations.create({ agents: [jarvis] });
556
+ // no tool-call handler needed — get_weather runs automatically
557
+ ```
558
+
559
+ The `tool-call` (and `tool-call-result`) events still fire for every call, so
560
+ you can observe or log them. A thrown tool error is caught and returned to the
561
+ model as `{ "error": ... }` so the agent can recover; an unknown tool name
562
+ reports `Unknown tool "..."` the same way. Tool calls the model issues together
563
+ run concurrently, and a hung tool is bounded by `toolTimeoutMs` (default 30s).
564
+
565
+ ### Opt out: resolve tool calls yourself
566
+
567
+ When a tool needs approval, or runs in a *different* backend, pass
568
+ `autoExecuteTools: false` (on `Pipeflow`, `pipeflow.conversations.create()`, or
569
+ `Conversation`) and the orchestrator hands the call to you:
570
+
571
+ ```ts
572
+ const conversation = await pipeflow.conversations.create({
573
+ agents: [jarvis],
574
+ autoExecuteTools: false,
575
+ });
576
+
577
+ conversation.on("tool-call", async ({ call }) => {
578
+ // call.arguments is already parsed JSON
579
+ const result = await myBackend.executeTool(call.name, call.arguments);
580
+ conversation.resolveToolCall({ id: call.id, result });
470
581
  });
471
582
  ```
472
583
 
@@ -483,16 +594,9 @@ This makes Pipeflow useful as a realtime transcription primitive.
483
594
  const conversation =
484
595
  await pipeflow.conversations.create();
485
596
 
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();
597
+ // Without an agent, `start()` attaches the orchestrator in
598
+ // transcription-only mode: audio in, turns and transcripts out.
599
+ await conversation.start();
496
600
 
497
601
  await conversation.participate([
498
602
  { userId: "alice" },
@@ -524,6 +628,9 @@ Pagination can be supported for long conversations.
524
628
 
525
629
  ## Meeting summaries
526
630
 
631
+ <details>
632
+ <summary>Summarizing a meeting with a notetaker agent — as a plain LLM task or through a transcript tool</summary>
633
+
527
634
  A meeting summary can simply be another agent task.
528
635
 
529
636
  ```ts
@@ -585,38 +692,22 @@ The agent does not receive special access to conversations.
585
692
 
586
693
  If it needs conversation data, **a tool provides that capability**.
587
694
 
588
- ## Providers
589
-
590
- Pipeflow separates provider interfaces from provider implementations.
591
-
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
- ```
695
+ </details>
609
696
 
610
- The orchestrator works against provider interfaces rather than directly against vendor APIs.
697
+ ## Providers
611
698
 
612
- This makes it possible to replace providers without changing the conversation layer.
699
+ <details>
700
+ <summary>Vendor-independent interfaces and the current adapters: Deepgram, DeepSeek, OpenRouter, Kokoro</summary>
613
701
 
614
- ### Current providers
702
+ Pipeflow separates provider interfaces (LLM, STT, TTS) from their
703
+ implementations. The orchestrator works against the interfaces rather than
704
+ directly against vendor APIs, so providers can be replaced without changing the
705
+ conversation layer.
615
706
 
616
- The project currently contains adapters for:
707
+ The project currently ships adapters for:
617
708
 
618
709
  * **STT:** Deepgram
619
- * **LLM:** DeepSeek
710
+ * **LLM:** DeepSeek, OpenRouter, OpenAI, Claude (Anthropic)
620
711
  * **TTS:** Kokoro
621
712
 
622
713
  Providers are configured with their own credentials — Pipeflow itself does
@@ -624,8 +715,16 @@ not hold an API key.
624
715
 
625
716
  Provider availability and configuration are evolving during early development.
626
717
 
718
+ See [src/providers/README.md](src/providers/README.md) for the interfaces and
719
+ adapter contracts.
720
+
721
+ </details>
722
+
627
723
  ## Architecture
628
724
 
725
+ <details>
726
+ <summary>How the layers fit together: agents, conversations, persistence, providers, transport</summary>
727
+
629
728
  Pipeflow is designed around a small number of independent layers.
630
729
 
631
730
  ```text
@@ -647,9 +746,11 @@ src/
647
746
  ### Conversation
648
747
 
649
748
  Public realtime conversation API and lifecycle.
749
+ See [src/conversations/conversation/README.md](src/conversations/conversation/README.md).
650
750
 
651
751
  ### Orchestration
652
752
 
753
+ See [src/conversations/orchestration/README.md](src/conversations/orchestration/README.md).
653
754
  The state machine coordinating:
654
755
 
655
756
  * speech
@@ -664,40 +765,54 @@ The state machine coordinating:
664
765
  ### Transcription
665
766
 
666
767
  Conversation transcription and transcript state.
768
+ See [src/conversations/transcription/README.md](src/conversations/transcription/README.md).
667
769
 
668
770
  ### Providers
669
771
 
670
772
  Vendor-independent interfaces and provider adapters.
773
+ See [src/providers/README.md](src/providers/README.md).
671
774
 
672
775
  ### Persistence
673
776
 
674
777
  Persistence abstractions with adapters such as SQLite and in-memory storage.
778
+ See [src/persistence/README.md](src/persistence/README.md).
675
779
 
676
780
  ### Transport
677
781
 
678
- Realtime communication between Pipeflow and the application using Pipeflow.
782
+ Realtime communication between Pipeflow and the application.
783
+ See [src/transport/README.md](src/transport/README.md).
784
+
785
+ </details>
679
786
 
680
787
  ## Persistence
681
788
 
682
- Pipeflow separates persistence from the conversation domain.
789
+ <details>
790
+ <summary>Storage adapters: in-memory for development, SQLite for lightweight persistence</summary>
683
791
 
684
- The project currently includes:
792
+ Pipeflow separates persistence from the conversation domain. The in-memory
793
+ adapter is useful for tests and development; SQLite provides a lightweight
794
+ persistent backend suitable for local applications and early deployments. The
795
+ persistence interface is intentionally provider-independent so other storage
796
+ implementations can be added later.
685
797
 
686
- ```text
687
- persistence/
688
- └── adapters/
689
- ├── memory/
690
- └── sqlite/
691
- ```
798
+ ```ts
799
+ import { SQLitePersistence } from "@moureau/pipeflow/persistence";
692
800
 
693
- The in-memory adapter is useful for tests and development.
801
+ const pipeflow = new Pipeflow({
802
+ persistence: new SQLitePersistence({ filename: "./pipeflow.db" }),
803
+ });
804
+ ```
694
805
 
695
- SQLite provides a lightweight persistent backend suitable for local applications and early deployments.
806
+ See [src/persistence/README.md](src/persistence/README.md) for the storage
807
+ contract and adapters.
696
808
 
697
- The persistence interface is intentionally provider-independent so other storage implementations can be added later.
809
+ </details>
698
810
 
699
811
  ## Realtime architecture
700
812
 
813
+ <details>
814
+ <summary>How audio flows through the pipeline as a continuous stream</summary>
815
+
701
816
  A typical voice interaction looks like:
702
817
 
703
818
  ```text
@@ -752,14 +867,21 @@ audio
752
867
 
753
868
  This allows the system to begin producing speech as early as possible.
754
869
 
870
+ </details>
871
+
755
872
  ## Open source
756
873
 
874
+ <details>
875
+ <summary>Why the project is open and how the provider layer stays modular</summary>
876
+
757
877
  Pipeflow is open source.
758
878
 
759
879
  The project is designed to make realtime voice infrastructure accessible without requiring applications to implement their own orchestration layer.
760
880
 
761
881
  The provider layer is intentionally modular so applications can choose between hosted and self-hosted services.
762
882
 
883
+ </details>
884
+
763
885
  ## Development
764
886
 
765
887
  Clone the repository and install dependencies:
@@ -776,6 +898,29 @@ Run tests:
776
898
  bun test
777
899
  ```
778
900
 
901
+ End-to-end tests hit the real LLM API and are skipped when no key is
902
+ available. They prefer `OPENROUTER_API_KEY` (default model
903
+ `google/gemini-2.5-flash-lite`, override with `LLM_MODEL`) and fall back to
904
+ `DEEPSEEK_API_KEY`. Add either to `.env` (loaded automatically) and run:
905
+
906
+ ```bash
907
+ bun run test:e2e
908
+ ```
909
+
910
+ The latency benchmark runs the pipeline repeatedly against the real model and
911
+ reports p50/p95 per hop: first token, first speechable text, TTS request, TTS
912
+ first audio, first audio delivered, and completion. STT and TTS are faked by
913
+ default; point `KOKORO_URL` at a Kokoro endpoint to measure the real synthesis
914
+ path, including inter-chunk audio gaps:
915
+
916
+ ```bash
917
+ bun run benchmark # 10 runs; BENCH_RUNS=5 to change
918
+ KOKORO_URL=http://localhost:8880 bun run benchmark # local kokoro-fastapi
919
+ KOKORO_URL=https://api.together.ai \
920
+ KOKORO_API_KEY=... KOKORO_MODEL=hexgrad/Kokoro-82M \
921
+ bun run benchmark # Together AI
922
+ ```
923
+
779
924
  Build and type-check:
780
925
 
781
926
  ```bash
@@ -787,6 +932,9 @@ The project uses Bun and TypeScript.
787
932
 
788
933
  ## Design principles
789
934
 
935
+ <details>
936
+ <summary>The rules the API is built around: realtime first, provider agnostic, app-owned tools</summary>
937
+
790
938
  ### Realtime first
791
939
 
792
940
  Audio is streamed continuously rather than processed as completed recordings.
@@ -828,6 +976,8 @@ Tool
828
976
 
829
977
  Everything else should remain replaceable implementation detail for as long as possible.
830
978
 
979
+ </details>
980
+
831
981
  ## License
832
982
 
833
983
  See [LICENSE](LICENSE).