@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.
- package/README.md +280 -130
- package/dist/cjs/agents/agent.js +1 -1
- package/dist/cjs/agents/agent.js.map +3 -3
- package/dist/cjs/agents/tools/tools.js +1 -1
- package/dist/cjs/agents/tools/tools.js.map +3 -3
- package/dist/cjs/client/client.js +2 -0
- package/dist/cjs/client/client.js.map +7 -0
- package/dist/cjs/client/index.js +2 -0
- package/dist/cjs/client/index.js.map +7 -0
- package/dist/cjs/client/json.js +2 -0
- package/dist/cjs/client/json.js.map +7 -0
- package/dist/cjs/client/protocol/websocket.js +2 -0
- package/dist/cjs/client/protocol/websocket.js.map +7 -0
- package/dist/cjs/client/protocol.js +2 -0
- package/dist/cjs/client/protocol.js.map +7 -0
- package/dist/cjs/conversations/conversation/conversation.js +1 -1
- package/dist/cjs/conversations/conversation/conversation.js.map +3 -3
- package/dist/cjs/conversations/conversations.js +1 -1
- package/dist/cjs/conversations/conversations.js.map +3 -3
- package/dist/cjs/conversations/index.js +1 -1
- package/dist/cjs/conversations/index.js.map +3 -3
- package/dist/cjs/conversations/orchestration/coordination/coordination.js +10 -0
- package/dist/cjs/conversations/orchestration/coordination/coordination.js.map +7 -0
- package/dist/cjs/conversations/orchestration/coordination/index.js +2 -0
- package/dist/cjs/conversations/orchestration/coordination/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
- package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/history/history.js +4 -0
- package/dist/cjs/conversations/orchestration/orchestrator/history/history.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/history/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/history/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/index.js +1 -1
- package/dist/cjs/conversations/orchestration/orchestrator/index.js.map +3 -3
- package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js +1 -2
- package/dist/cjs/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
- package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js +23 -0
- package/dist/cjs/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js +2 -0
- package/dist/cjs/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
- package/dist/cjs/conversations/orchestration/test-harness.js +2 -0
- package/dist/cjs/conversations/orchestration/test-harness.js.map +7 -0
- package/dist/cjs/conversations/orchestration/text-chunker/index.js +2 -0
- package/dist/cjs/conversations/orchestration/text-chunker/index.js.map +7 -0
- package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js +3 -0
- package/dist/cjs/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
- package/dist/cjs/conversations/stream/conversation-stream.js +2 -0
- package/dist/cjs/conversations/stream/conversation-stream.js.map +7 -0
- package/dist/cjs/conversations/stream/index.js +2 -0
- package/dist/cjs/conversations/stream/index.js.map +7 -0
- package/dist/cjs/conversations/types.js +1 -1
- package/dist/cjs/conversations/types.js.map +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/persistence/adapters/sqlite/sqlite.js +18 -14
- package/dist/cjs/persistence/adapters/sqlite/sqlite.js.map +3 -3
- package/dist/cjs/pipeflow/index.js +2 -0
- package/dist/cjs/pipeflow/index.js.map +7 -0
- package/dist/cjs/pipeflow/pipeflow.js +2 -0
- package/dist/cjs/pipeflow/pipeflow.js.map +7 -0
- package/dist/cjs/providers/index.js +1 -1
- package/dist/cjs/providers/index.js.map +2 -2
- package/dist/cjs/providers/llm/adapters/claude/claude.js +5 -0
- package/dist/cjs/providers/llm/adapters/claude/claude.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/claude/index.js +2 -0
- package/dist/cjs/providers/llm/adapters/claude/index.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js +1 -1
- package/dist/cjs/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
- package/dist/cjs/providers/llm/adapters/index.js +1 -1
- package/dist/cjs/providers/llm/adapters/index.js.map +3 -3
- package/dist/cjs/providers/llm/adapters/openai/index.js +2 -0
- package/dist/cjs/providers/llm/adapters/openai/index.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/openai/openai.js +2 -0
- package/dist/cjs/providers/llm/adapters/openai/openai.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/openai-compatible.js +10 -0
- package/dist/cjs/providers/llm/adapters/openai-compatible.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/openrouter/index.js +2 -0
- package/dist/cjs/providers/llm/adapters/openrouter/index.js.map +7 -0
- package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js +2 -0
- package/dist/cjs/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/cjs/providers/llm/index.js +1 -1
- package/dist/cjs/providers/llm/index.js.map +3 -3
- package/dist/cjs/providers/llm/toolmode/index.js +2 -0
- package/dist/cjs/providers/llm/toolmode/index.js.map +7 -0
- package/dist/cjs/providers/llm/toolmode/toolmode.js +2 -0
- package/dist/cjs/providers/llm/toolmode/toolmode.js.map +7 -0
- package/dist/cjs/providers/llm/types.js +1 -1
- package/dist/cjs/providers/llm/types.js.map +3 -3
- package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js +1 -1
- package/dist/cjs/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
- package/dist/cjs/providers/stt/adapters/index.js +1 -1
- package/dist/cjs/providers/stt/adapters/index.js.map +3 -3
- package/dist/cjs/providers/stt/adapters/openrouter/index.js +2 -0
- package/dist/cjs/providers/stt/adapters/openrouter/index.js.map +7 -0
- package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js +2 -0
- package/dist/cjs/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/cjs/providers/tts/adapters/index.js +1 -1
- package/dist/cjs/providers/tts/adapters/index.js.map +3 -3
- package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js +4 -1
- package/dist/cjs/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
- package/dist/cjs/providers/tts/adapters/openrouter/index.js +2 -0
- package/dist/cjs/providers/tts/adapters/openrouter/index.js.map +7 -0
- package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js +2 -0
- package/dist/cjs/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/cjs/transport/streamobject/field-stream/field-stream.js +2 -0
- package/dist/cjs/transport/streamobject/field-stream/field-stream.js.map +7 -0
- package/dist/cjs/transport/streamobject/field-stream/index.js +2 -0
- package/dist/cjs/transport/streamobject/field-stream/index.js.map +7 -0
- package/dist/cjs/transport/streamobject/index.js +2 -0
- package/dist/cjs/transport/streamobject/index.js.map +7 -0
- package/dist/cjs/transport/streamobject/json-adapter/index.js +2 -0
- package/dist/cjs/transport/streamobject/json-adapter/index.js.map +7 -0
- package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js +4 -0
- package/dist/cjs/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
- package/dist/cjs/transport/streamobject/reference/index.js +2 -0
- package/dist/cjs/transport/streamobject/reference/index.js.map +7 -0
- package/dist/cjs/transport/streamobject/reference/reference.js +2 -0
- package/dist/cjs/transport/streamobject/reference/reference.js.map +7 -0
- package/dist/cjs/transport/streamobject/stream-object/index.js +2 -0
- package/dist/cjs/transport/streamobject/stream-object/index.js.map +7 -0
- package/dist/cjs/transport/streamobject/stream-object/stream-object.js +2 -0
- package/dist/cjs/transport/streamobject/stream-object/stream-object.js.map +7 -0
- package/dist/esm/agents/agent.js +1 -1
- package/dist/esm/agents/agent.js.map +3 -3
- package/dist/esm/agents/tools/tools.js +1 -1
- package/dist/esm/agents/tools/tools.js.map +3 -3
- package/dist/esm/client/client.js +2 -0
- package/dist/esm/client/client.js.map +7 -0
- package/dist/esm/client/index.js +2 -0
- package/dist/esm/client/index.js.map +7 -0
- package/dist/esm/client/json.js +2 -0
- package/dist/esm/client/json.js.map +7 -0
- package/dist/esm/client/protocol/websocket.js +2 -0
- package/dist/esm/client/protocol/websocket.js.map +7 -0
- package/dist/esm/client/protocol.js +1 -0
- package/dist/esm/client/protocol.js.map +7 -0
- package/dist/esm/conversations/conversation/conversation.js +1 -1
- package/dist/esm/conversations/conversation/conversation.js.map +3 -3
- package/dist/esm/conversations/conversations.js +1 -1
- package/dist/esm/conversations/conversations.js.map +3 -3
- package/dist/esm/conversations/index.js +1 -1
- package/dist/esm/conversations/index.js.map +3 -3
- package/dist/esm/conversations/orchestration/coordination/coordination.js +10 -0
- package/dist/esm/conversations/orchestration/coordination/coordination.js.map +7 -0
- package/dist/esm/conversations/orchestration/coordination/index.js +2 -0
- package/dist/esm/conversations/orchestration/coordination/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js +4 -0
- package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/coordination-runner/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/generation/generation.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/generation/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/generation/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/history/history.js +4 -0
- package/dist/esm/conversations/orchestration/orchestrator/history/history.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/history/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/history/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/index.js +1 -1
- package/dist/esm/conversations/orchestration/orchestrator/index.js.map +3 -3
- package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js +1 -2
- package/dist/esm/conversations/orchestration/orchestrator/orchestrator.js.map +3 -3
- package/dist/esm/conversations/orchestration/orchestrator/routing/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/routing/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js +23 -0
- package/dist/esm/conversations/orchestration/orchestrator/routing/routing.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/speech/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/speech/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/speech/speech.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/tools/index.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/tools/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js +2 -0
- package/dist/esm/conversations/orchestration/orchestrator/tools/tools.js.map +7 -0
- package/dist/esm/conversations/orchestration/test-harness.js +2 -0
- package/dist/esm/conversations/orchestration/test-harness.js.map +7 -0
- package/dist/esm/conversations/orchestration/text-chunker/index.js +2 -0
- package/dist/esm/conversations/orchestration/text-chunker/index.js.map +7 -0
- package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js +3 -0
- package/dist/esm/conversations/orchestration/text-chunker/text-chunker.js.map +7 -0
- package/dist/esm/conversations/stream/conversation-stream.js +2 -0
- package/dist/esm/conversations/stream/conversation-stream.js.map +7 -0
- package/dist/esm/conversations/stream/index.js +2 -0
- package/dist/esm/conversations/stream/index.js.map +7 -0
- package/dist/esm/conversations/types.js +1 -1
- package/dist/esm/conversations/types.js.map +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +3 -3
- package/dist/esm/persistence/adapters/sqlite/sqlite.js +18 -14
- package/dist/esm/persistence/adapters/sqlite/sqlite.js.map +3 -3
- package/dist/esm/pipeflow/index.js +2 -0
- package/dist/esm/pipeflow/index.js.map +7 -0
- package/dist/esm/pipeflow/pipeflow.js +2 -0
- package/dist/esm/pipeflow/pipeflow.js.map +7 -0
- package/dist/esm/providers/index.js +1 -1
- package/dist/esm/providers/index.js.map +3 -3
- package/dist/esm/providers/llm/adapters/claude/claude.js +5 -0
- package/dist/esm/providers/llm/adapters/claude/claude.js.map +7 -0
- package/dist/esm/providers/llm/adapters/claude/index.js +2 -0
- package/dist/esm/providers/llm/adapters/claude/index.js.map +7 -0
- package/dist/esm/providers/llm/adapters/deepseek/deepseek.js +1 -1
- package/dist/esm/providers/llm/adapters/deepseek/deepseek.js.map +3 -3
- package/dist/esm/providers/llm/adapters/index.js +1 -1
- package/dist/esm/providers/llm/adapters/index.js.map +3 -3
- package/dist/esm/providers/llm/adapters/openai/index.js +2 -0
- package/dist/esm/providers/llm/adapters/openai/index.js.map +7 -0
- package/dist/esm/providers/llm/adapters/openai/openai.js +2 -0
- package/dist/esm/providers/llm/adapters/openai/openai.js.map +7 -0
- package/dist/esm/providers/llm/adapters/openai-compatible.js +10 -0
- package/dist/esm/providers/llm/adapters/openai-compatible.js.map +7 -0
- package/dist/esm/providers/llm/adapters/openrouter/index.js +2 -0
- package/dist/esm/providers/llm/adapters/openrouter/index.js.map +7 -0
- package/dist/esm/providers/llm/adapters/openrouter/openrouter.js +2 -0
- package/dist/esm/providers/llm/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/esm/providers/llm/index.js +1 -1
- package/dist/esm/providers/llm/index.js.map +3 -3
- package/dist/esm/providers/llm/toolmode/index.js +2 -0
- package/dist/esm/providers/llm/toolmode/index.js.map +7 -0
- package/dist/esm/providers/llm/toolmode/toolmode.js +2 -0
- package/dist/esm/providers/llm/toolmode/toolmode.js.map +7 -0
- package/dist/esm/providers/llm/types.js +1 -0
- package/dist/esm/providers/llm/types.js.map +4 -4
- package/dist/esm/providers/stt/adapters/deepgram/deepgram.js +1 -1
- package/dist/esm/providers/stt/adapters/deepgram/deepgram.js.map +3 -3
- package/dist/esm/providers/stt/adapters/index.js +1 -1
- package/dist/esm/providers/stt/adapters/index.js.map +3 -3
- package/dist/esm/providers/stt/adapters/openrouter/index.js +2 -0
- package/dist/esm/providers/stt/adapters/openrouter/index.js.map +7 -0
- package/dist/esm/providers/stt/adapters/openrouter/openrouter.js +2 -0
- package/dist/esm/providers/stt/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/esm/providers/tts/adapters/index.js +1 -1
- package/dist/esm/providers/tts/adapters/index.js.map +3 -3
- package/dist/esm/providers/tts/adapters/kokoro/kokoro.js +4 -1
- package/dist/esm/providers/tts/adapters/kokoro/kokoro.js.map +3 -3
- package/dist/esm/providers/tts/adapters/openrouter/index.js +2 -0
- package/dist/esm/providers/tts/adapters/openrouter/index.js.map +7 -0
- package/dist/esm/providers/tts/adapters/openrouter/openrouter.js +2 -0
- package/dist/esm/providers/tts/adapters/openrouter/openrouter.js.map +7 -0
- package/dist/esm/transport/streamobject/field-stream/field-stream.js +2 -0
- package/dist/esm/transport/streamobject/field-stream/field-stream.js.map +7 -0
- package/dist/esm/transport/streamobject/field-stream/index.js +2 -0
- package/dist/esm/transport/streamobject/field-stream/index.js.map +7 -0
- package/dist/esm/transport/streamobject/index.js +2 -0
- package/dist/esm/transport/streamobject/index.js.map +7 -0
- package/dist/esm/transport/streamobject/json-adapter/index.js +2 -0
- package/dist/esm/transport/streamobject/json-adapter/index.js.map +7 -0
- package/dist/esm/transport/streamobject/json-adapter/json-adapter.js +4 -0
- package/dist/esm/transport/streamobject/json-adapter/json-adapter.js.map +7 -0
- package/dist/esm/transport/streamobject/reference/index.js +2 -0
- package/dist/esm/transport/streamobject/reference/index.js.map +7 -0
- package/dist/esm/transport/streamobject/reference/reference.js +2 -0
- package/dist/esm/transport/streamobject/reference/reference.js.map +7 -0
- package/dist/esm/transport/streamobject/stream-object/index.js +2 -0
- package/dist/esm/transport/streamobject/stream-object/index.js.map +7 -0
- package/dist/esm/transport/streamobject/stream-object/stream-object.js +2 -0
- package/dist/esm/transport/streamobject/stream-object/stream-object.js.map +7 -0
- package/dist/types/agents/agent.d.ts +3 -0
- package/dist/types/agents/tools/tools.d.ts +28 -6
- package/dist/types/client/client.d.ts +186 -0
- package/dist/types/client/index.d.ts +31 -0
- package/dist/types/client/json.d.ts +13 -0
- package/dist/types/client/protocol/websocket.d.ts +56 -0
- package/dist/types/client/protocol.d.ts +46 -0
- package/dist/types/conversations/conversation/conversation.d.ts +130 -6
- package/dist/types/conversations/conversations.d.ts +35 -1
- package/dist/types/conversations/index.d.ts +2 -1
- package/dist/types/conversations/orchestration/coordination/coordination.d.ts +192 -0
- package/dist/types/conversations/orchestration/coordination/index.d.ts +2 -0
- package/dist/types/conversations/orchestration/orchestrator/coordination-runner/coordination-runner.d.ts +108 -0
- package/dist/types/conversations/orchestration/orchestrator/coordination-runner/index.d.ts +2 -0
- package/dist/types/conversations/orchestration/orchestrator/generation/generation.d.ts +60 -0
- package/dist/types/conversations/orchestration/orchestrator/generation/index.d.ts +2 -0
- package/dist/types/conversations/orchestration/orchestrator/history/history.d.ts +62 -0
- package/dist/types/conversations/orchestration/orchestrator/history/index.d.ts +1 -0
- package/dist/types/conversations/orchestration/orchestrator/index.d.ts +10 -0
- package/dist/types/conversations/orchestration/orchestrator/orchestrator.d.ts +68 -31
- package/dist/types/conversations/orchestration/orchestrator/routing/index.d.ts +1 -0
- package/dist/types/conversations/orchestration/orchestrator/routing/routing.d.ts +19 -0
- package/dist/types/conversations/orchestration/orchestrator/speech/index.d.ts +2 -0
- package/dist/types/conversations/orchestration/orchestrator/speech/speech.d.ts +78 -0
- package/dist/types/conversations/orchestration/orchestrator/tools/index.d.ts +2 -0
- package/dist/types/conversations/orchestration/orchestrator/tools/tools.d.ts +65 -0
- package/dist/types/conversations/orchestration/test-harness.d.ts +100 -0
- package/dist/types/conversations/orchestration/text-chunker/index.d.ts +1 -0
- package/dist/types/conversations/orchestration/text-chunker/text-chunker.d.ts +39 -0
- package/dist/types/conversations/stream/conversation-stream.d.ts +42 -0
- package/dist/types/conversations/stream/index.d.ts +1 -0
- package/dist/types/conversations/types.d.ts +32 -0
- package/dist/types/index.d.ts +5 -38
- package/dist/types/pipeflow/index.d.ts +2 -0
- package/dist/types/pipeflow/pipeflow.d.ts +43 -0
- package/dist/types/providers/index.d.ts +1 -1
- package/dist/types/providers/llm/adapters/claude/claude.d.ts +45 -0
- package/dist/types/providers/llm/adapters/claude/index.d.ts +2 -0
- package/dist/types/providers/llm/adapters/deepseek/deepseek.d.ts +23 -2
- package/dist/types/providers/llm/adapters/index.d.ts +3 -0
- package/dist/types/providers/llm/adapters/openai/index.d.ts +2 -0
- package/dist/types/providers/llm/adapters/openai/openai.d.ts +45 -0
- package/dist/types/providers/llm/adapters/openai-compatible.d.ts +44 -0
- package/dist/types/providers/llm/adapters/openrouter/index.d.ts +2 -0
- package/dist/types/providers/llm/adapters/openrouter/openrouter.d.ts +60 -0
- package/dist/types/providers/llm/index.d.ts +5 -2
- package/dist/types/providers/llm/toolmode/index.d.ts +2 -0
- package/dist/types/providers/llm/toolmode/toolmode.d.ts +99 -0
- package/dist/types/providers/llm/types.d.ts +65 -0
- package/dist/types/providers/stt/adapters/deepgram/deepgram.d.ts +4 -1
- package/dist/types/providers/stt/adapters/index.d.ts +1 -0
- package/dist/types/providers/stt/adapters/openrouter/index.d.ts +2 -0
- package/dist/types/providers/stt/adapters/openrouter/openrouter.d.ts +196 -0
- package/dist/types/providers/tts/adapters/index.d.ts +1 -0
- package/dist/types/providers/tts/adapters/kokoro/kokoro.d.ts +18 -3
- package/dist/types/providers/tts/adapters/openrouter/index.d.ts +2 -0
- package/dist/types/providers/tts/adapters/openrouter/openrouter.d.ts +64 -0
- package/dist/types/transport/streamobject/field-stream/field-stream.d.ts +85 -0
- package/dist/types/transport/streamobject/field-stream/index.d.ts +2 -0
- package/dist/types/transport/streamobject/index.d.ts +8 -0
- package/dist/types/transport/streamobject/json-adapter/index.d.ts +2 -0
- package/dist/types/transport/streamobject/json-adapter/json-adapter.d.ts +65 -0
- package/dist/types/transport/streamobject/reference/index.d.ts +2 -0
- package/dist/types/transport/streamobject/reference/reference.d.ts +127 -0
- package/dist/types/transport/streamobject/stream-object/index.d.ts +2 -0
- package/dist/types/transport/streamobject/stream-object/stream-object.d.ts +31 -0
- 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** —
|
|
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
|
-
|
|
74
|
-
repository (`bun add pipeflow`) or build
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
118
|
-
conversation,
|
|
119
|
-
agent: jarvis,
|
|
120
|
-
stt,
|
|
121
|
-
tts,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
await orchestrator.start();
|
|
133
|
+
await conversation.start();
|
|
125
134
|
```
|
|
126
135
|
|
|
127
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
|
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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
|
|
464
|
-
|
|
549
|
+
const jarvis = pipeflow.agent({
|
|
550
|
+
name: "Jarvis",
|
|
551
|
+
context: "You are a helpful assistant.",
|
|
552
|
+
tools: [getWeather],
|
|
553
|
+
});
|
|
465
554
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
|
487
|
-
// audio in, turns and transcripts out.
|
|
488
|
-
|
|
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
|
-
|
|
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
|
-
|
|
697
|
+
## Providers
|
|
611
698
|
|
|
612
|
-
|
|
699
|
+
<details>
|
|
700
|
+
<summary>Vendor-independent interfaces and the current adapters: Deepgram, DeepSeek, OpenRouter, Kokoro</summary>
|
|
613
701
|
|
|
614
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
789
|
+
<details>
|
|
790
|
+
<summary>Storage adapters: in-memory for development, SQLite for lightweight persistence</summary>
|
|
683
791
|
|
|
684
|
-
|
|
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
|
-
```
|
|
687
|
-
persistence
|
|
688
|
-
└── adapters/
|
|
689
|
-
├── memory/
|
|
690
|
-
└── sqlite/
|
|
691
|
-
```
|
|
798
|
+
```ts
|
|
799
|
+
import { SQLitePersistence } from "@moureau/pipeflow/persistence";
|
|
692
800
|
|
|
693
|
-
|
|
801
|
+
const pipeflow = new Pipeflow({
|
|
802
|
+
persistence: new SQLitePersistence({ filename: "./pipeflow.db" }),
|
|
803
|
+
});
|
|
804
|
+
```
|
|
694
805
|
|
|
695
|
-
|
|
806
|
+
See [src/persistence/README.md](src/persistence/README.md) for the storage
|
|
807
|
+
contract and adapters.
|
|
696
808
|
|
|
697
|
-
|
|
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).
|