@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
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/conversations/stream/conversation-stream.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * ConversationStream \u2014 the conversation's semantic reply stream.\n *\n * Turns a Conversation's event stream (LLM text fragments + generation\n * completion) into FieldStream completion events: consumers act on partial\n * reply text without waiting for the reply to finish.\n *\n * const replies = new ConversationStream(conversation);\n * replies.whenItem(\"text\", (fragment, i) => render(fragment));\n * replies.when(\"agent\", (agent) => showSpeaker(agent));\n * replies.whenObjectDone((reply) => finalize(reply));\n * replies.cancel(); // aborts the current generation (interrupts the LLM)\n *\n * One semantic object per top-level generation (agent or coordination\n * reply). The `text` field is an ordered sequence of completed text\n * fragments \u2014 semantically \"the next fragment of the reply arrived\", not\n * \"whatever happened to be inside a provider SSE packet\". Fragment sizes are\n * an implementation detail of the producer and may be coalesced later.\n *\n * Lifecycle per reply:\n *\n * first fragment \u2500\u2500\u25B6 STREAMING \u2500\u2500generation-complete\u2500\u2500\u25B6 DONE\n * \u251C\u2500\u2500cancel()/interrupt\u2500\u2500\u25B6 CANCELLED\n * \u2514\u2500\u2500provider error\u2500\u2500\u2500\u2500\u2500\u2500\u25B6 FAILED\n *\n * Each boundary fires at most once; no completion event fires after a\n * terminal state. Interruptions and errors leave already-delivered fragments\n * as valid partial state. Delegated sub-generation results do not terminate\n * the top-level reply \u2014 only the top-level generation's completion does.\n */\nimport { FieldStream } from \"../../transport/streamobject/field-stream/field-stream\";\nimport type {\n Event,\n Schema,\n} from \"../../transport/streamobject/reference/reference\";\nimport type { Conversation } from \"../conversation/conversation\";\n\nconst REPLY_SCHEMA: Schema = [\n { path: [\"agent\"], type: \"string\", maxLength: 128 },\n { path: [\"text\"], type: \"string\", mode: \"array\", maxItems: 4096, maxLength: 4096 },\n];\n\nconst AGENT_FIELD = 0;\nconst TEXT_FIELD = 1;\n\nexport class ConversationStream extends FieldStream {\n private readonly unsubscribers: Array<() => void>;\n private active: { agentName: string | undefined; items: string[] } | null = null;\n\n constructor(conversation: Conversation) {\n // cancel() interrupts the conversation, which stops the current\n // generation's LLM through the orchestrator. Idempotent.\n super(REPLY_SCHEMA, { onCancel: () => conversation.interrupt() });\n this.unsubscribers = [\n conversation.on(\"text-delta\", ({ text, agentName }) => this.onDelta(text, agentName)),\n conversation.on(\"generation-complete\", () => this.completeReply()),\n conversation.on(\"error\", ({ error }) => this.fail(error)),\n conversation.on(\"interrupt\", () => this.abortReply()),\n ];\n }\n\n /** Stop listening to the conversation. */\n dispose(): void {\n for (const unsubscribe of this.unsubscribers) unsubscribe();\n }\n\n private onDelta(text: string, agentName: string | undefined): void {\n if (this.active === null) {\n this.beginObject();\n this.active = { agentName, items: [] };\n if (agentName !== undefined) this.emitField(AGENT_FIELD, agentName);\n }\n const index = this.active.items.length;\n this.active.items.push(text);\n this.emitItem(TEXT_FIELD, index, text);\n }\n\n private completeReply(): void {\n const active = this.active;\n if (active === null) return;\n this.active = null;\n const events: Event[] = [];\n if (active.agentName !== undefined) {\n events.push({ kind: \"field\", field: AGENT_FIELD, value: active.agentName });\n }\n events.push({ kind: \"field\", field: TEXT_FIELD, value: active.items });\n events.push({ kind: \"object-complete\" });\n this.emitObject(events);\n }\n\n private abortReply(): void {\n this.active = null;\n this.cancelObject(); // delivered fragments remain valid partial state\n }\n}\n"],
|
|
5
|
+
"mappings": "+EA8BA,OAAS,eAAAA,MAAmB,yDAO5B,MAAMC,EAAuB,CAC3B,CAAE,KAAM,CAAC,OAAO,EAAG,KAAM,SAAU,UAAW,GAAI,EAClD,CAAE,KAAM,CAAC,MAAM,EAAG,KAAM,SAAU,KAAM,QAAS,SAAU,KAAM,UAAW,IAAK,CACnF,EAEMC,EAAc,EACdC,EAAa,EAEZ,MAAMC,UAA2BJ,CAAY,CA7CpD,MA6CoD,CAAAK,EAAA,2BACjC,cACT,OAAoE,KAE5E,YAAYC,EAA4B,CAGtC,MAAML,EAAc,CAAE,SAAUI,EAAA,IAAMC,EAAa,UAAU,EAA7B,WAA+B,CAAC,EAChE,KAAK,cAAgB,CACnBA,EAAa,GAAG,aAAc,CAAC,CAAE,KAAAC,EAAM,UAAAC,CAAU,IAAM,KAAK,QAAQD,EAAMC,CAAS,CAAC,EACpFF,EAAa,GAAG,sBAAuB,IAAM,KAAK,cAAc,CAAC,EACjEA,EAAa,GAAG,QAAS,CAAC,CAAE,MAAAG,CAAM,IAAM,KAAK,KAAKA,CAAK,CAAC,EACxDH,EAAa,GAAG,YAAa,IAAM,KAAK,WAAW,CAAC,CACtD,CACF,CAGA,SAAgB,CACd,UAAWI,KAAe,KAAK,cAAeA,EAAY,CAC5D,CAEQ,QAAQH,EAAcC,EAAqC,CAC7D,KAAK,SAAW,OAClB,KAAK,YAAY,EACjB,KAAK,OAAS,CAAE,UAAAA,EAAW,MAAO,CAAC,CAAE,EACjCA,IAAc,QAAW,KAAK,UAAUN,EAAaM,CAAS,GAEpE,MAAMG,EAAQ,KAAK,OAAO,MAAM,OAChC,KAAK,OAAO,MAAM,KAAKJ,CAAI,EAC3B,KAAK,SAASJ,EAAYQ,EAAOJ,CAAI,CACvC,CAEQ,eAAsB,CAC5B,MAAMK,EAAS,KAAK,OACpB,GAAIA,IAAW,KAAM,OACrB,KAAK,OAAS,KACd,MAAMC,EAAkB,CAAC,EACrBD,EAAO,YAAc,QACvBC,EAAO,KAAK,CAAE,KAAM,QAAS,MAAOX,EAAa,MAAOU,EAAO,SAAU,CAAC,EAE5EC,EAAO,KAAK,CAAE,KAAM,QAAS,MAAOV,EAAY,MAAOS,EAAO,KAAM,CAAC,EACrEC,EAAO,KAAK,CAAE,KAAM,iBAAkB,CAAC,EACvC,KAAK,WAAWA,CAAM,CACxB,CAEQ,YAAmB,CACzB,KAAK,OAAS,KACd,KAAK,aAAa,CACpB,CACF",
|
|
6
|
+
"names": ["FieldStream", "REPLY_SCHEMA", "AGENT_FIELD", "TEXT_FIELD", "ConversationStream", "__name", "conversation", "text", "agentName", "error", "unsubscribe", "index", "active", "events"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var r=Object.defineProperty;var e=(t,n)=>r(t,"name",{value:n,configurable:!0});function
|
|
1
|
+
var r=Object.defineProperty;var e=(t,n)=>r(t,"name",{value:n,configurable:!0});function a(t="created"){return{status:t,participants:new Map,floor:null,currentTurn:null,currentGeneration:null,transcriptCount:0}}e(a,"createConversationState");export{a as createConversationState};
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/conversations/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Core domain types shared across Pipeflow modules.\n */\n\n// ---------------------------------------------------------------------------\n// Identities\n// ---------------------------------------------------------------------------\n\nexport type ConversationId = string;\nexport type UserId = string;\nexport type TurnId = string;\n\n// ---------------------------------------------------------------------------\n// Participants\n// ---------------------------------------------------------------------------\n\nexport interface ParticipantInput {\n userId: UserId;\n aliases?: string[];\n}\n\nexport interface Participant {\n userId: UserId;\n aliases: string[];\n joinedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Turns & generations\n// ---------------------------------------------------------------------------\n\nexport interface Turn {\n id: TurnId;\n conversationId: ConversationId;\n participantId: UserId;\n participantName: string;\n text: string;\n sequence: number;\n startedAt: number;\n endedAt: number;\n}\n\nexport type GenerationStatus = \"streaming\" | \"completed\" | \"cancelled\";\n\nexport interface Generation {\n id: string;\n conversationId: ConversationId;\n agentName: string;\n text: string;\n status: GenerationStatus;\n startedAt: number;\n endedAt?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Tool calls\n// ---------------------------------------------------------------------------\n\nexport interface ToolCall {\n id: string;\n name: string;\n /** Parsed arguments, or the raw JSON string if parsing failed. */\n arguments: unknown;\n}\n\nexport type ToolCallResult =\n | { id: string; result: unknown }\n | { id: string; error: string };\n\n// ---------------------------------------------------------------------------\n// Audio\n// ---------------------------------------------------------------------------\n\nexport interface AudioChunk {\n data: Uint8Array;\n timestamp: number;\n sequence: number;\n}\n\n// ---------------------------------------------------------------------------\n// Conversation state\n// ---------------------------------------------------------------------------\n\nexport type ConversationStatus = \"created\" | \"started\" | \"stopped\";\n\nexport interface ConversationState {\n status: ConversationStatus;\n participants: Map<UserId, Participant>;\n floor: UserId | null;\n currentTurn: Turn | null;\n currentGeneration: Generation | null;\n transcriptCount: number;\n}\n\nexport function createConversationState(\n status: ConversationStatus = \"created\",\n): ConversationState {\n return {\n status,\n participants: new Map(),\n floor: null,\n currentTurn: null,\n currentGeneration: null,\n transcriptCount: 0,\n };\n}\n"],
|
|
5
|
-
"mappings": "+
|
|
4
|
+
"sourcesContent": ["/**\n * Core domain types shared across Pipeflow modules.\n */\n\n// ---------------------------------------------------------------------------\n// Identities\n// ---------------------------------------------------------------------------\n\nexport type ConversationId = string;\nexport type UserId = string;\nexport type TurnId = string;\n\n// ---------------------------------------------------------------------------\n// Participants\n// ---------------------------------------------------------------------------\n\nexport interface ParticipantInput {\n userId: UserId;\n aliases?: string[];\n}\n\nexport interface Participant {\n userId: UserId;\n aliases: string[];\n joinedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Turns & generations\n// ---------------------------------------------------------------------------\n\nexport interface Turn {\n id: TurnId;\n conversationId: ConversationId;\n participantId: UserId;\n participantName: string;\n text: string;\n sequence: number;\n startedAt: number;\n endedAt: number;\n}\n\nexport type GenerationStatus = \"streaming\" | \"completed\" | \"cancelled\";\n\n/**\n * Latency instrumentation for a generation. Times are epoch milliseconds;\n * only `startedAt` is always present. The chain distinguishes each hop:\n *\n * ```text\n * turn \u2192 first LLM token \u2192 first TTS text (buffering flush)\n * \u2192 TTS requested \u2192 TTS first audio \u2192 audio delivered \u2192 completed\n * ```\n */\nexport interface GenerationTiming {\n startedAt: number;\n /** First LLM delta of this generation (first-token latency). */\n firstTokenAt?: number;\n /** First sentence flushed to TTS (text buffering latency). */\n firstTtsTextAt?: number;\n /** First TTS stream request issued (queue latency). */\n firstTtsRequestAt?: number;\n /** First audio chunk produced by the TTS provider (provider latency). */\n firstTtsAudioAt?: number;\n /** First TTS audio chunk delivered to the application (transport latency). */\n firstAudioAt?: number;\n completedAt?: number;\n}\n\nexport interface Generation {\n id: string;\n conversationId: ConversationId;\n agentName: string;\n text: string;\n status: GenerationStatus;\n startedAt: number;\n endedAt?: number;\n /**\n * \"sub\" marks a task dispatched to another agent by the coordinator.\n * Regular agent replies omit this field.\n */\n kind?: \"sub\";\n /** For sub-generations: the id of the coordinator generation that dispatched them. */\n parentGenerationId?: string;\n /** Latency instrumentation, recorded as the generation streams. */\n timing?: GenerationTiming;\n}\n\n// ---------------------------------------------------------------------------\n// Tool calls\n// ---------------------------------------------------------------------------\n\nexport interface ToolCall {\n id: string;\n name: string;\n /** Parsed arguments, or the raw JSON string if parsing failed. */\n arguments: unknown;\n}\n\nexport type ToolCallResult =\n | { id: string; result: unknown }\n | { id: string; error: string };\n\n// ---------------------------------------------------------------------------\n// Audio\n// ---------------------------------------------------------------------------\n\nexport interface AudioChunk {\n data: Uint8Array;\n timestamp: number;\n sequence: number;\n}\n\n// ---------------------------------------------------------------------------\n// Conversation state\n// ---------------------------------------------------------------------------\n\nexport type ConversationStatus = \"created\" | \"started\" | \"stopped\";\n\nexport interface ConversationState {\n status: ConversationStatus;\n participants: Map<UserId, Participant>;\n floor: UserId | null;\n currentTurn: Turn | null;\n currentGeneration: Generation | null;\n transcriptCount: number;\n}\n\nexport function createConversationState(\n status: ConversationStatus = \"created\",\n): ConversationState {\n return {\n status,\n participants: new Map(),\n floor: null,\n currentTurn: null,\n currentGeneration: null,\n transcriptCount: 0,\n };\n}\n"],
|
|
5
|
+
"mappings": "+EA+HO,SAASA,EACdC,EAA6B,UACV,CACnB,MAAO,CACL,OAAAA,EACA,aAAc,IAAI,IAClB,MAAO,KACP,YAAa,KACb,kBAAmB,KACnB,gBAAiB,CACnB,CACF,CAXgBC,EAAAF,EAAA",
|
|
6
6
|
"names": ["createConversationState", "status", "__name"]
|
|
7
7
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import{Pipeflow as e}from"./pipeflow.js";import{Agent as n}from"./agents/agent.js";import{Tool as p,Tool as i}from"./agents/tools/tools.js";import{Conversation as l,Conversations as T,Transcription as f,TranscriptEntry as u}from"./conversations/index.js";export{n as Agent,l as Conversation,T as Conversations,e as Pipeflow,i as PipeflowTool,p as Tool,u as TranscriptEntry,f as Transcription};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["// ---------------------------------------------------------------------------\n// Core public API\n// ---------------------------------------------------------------------------\n\nexport { Pipeflow } from \"./pipeflow\";\nexport type { PipeflowOptions } from \"./pipeflow\";\n\nexport { Agent } from \"./agents/agent\";\nexport type {\n AgentOptions,\n AgentRunRequest,\n AgentRunResult,\n ExecutedToolCall,\n} from \"./agents/agent\";\nexport { Tool, Tool as PipeflowTool } from \"./agents/tools/tools\";\nexport type { ToolOptions } from \"./agents/tools/tools\";\n\nexport {\n Conversation,\n Conversations,\n Transcription,\n TranscriptEntry,\n} from \"./conversations/index\";\nexport type {\n AudioChunk,\n ConversationEvents,\n ConversationId,\n ConversationOptions,\n ConversationState,\n ConversationStatus,\n CreateConversationOptions,\n Generation,\n GenerationStatus,\n Participant,\n ParticipantInput,\n ToolCall,\n ToolCallResult,\n TranscriptEntryInput,\n TranscriptSpeakerKind,\n Turn,\n TurnId,\n UserId,\n} from \"./conversations/index\";\n\n// Realtime machinery (Orchestrator and friends) lives behind the\n// `@moureau/pipeflow/conversations` subpath \u2014 it is implementation detail\n// that `Conversation.start()` attaches automatically.\n\n// ---------------------------------------------------------------------------\n// Configuration interfaces.\n//\n// Provider and persistence *implementations* are intentionally not exported\n// from the main entry \u2014 they are replaceable implementation detail. Import\n// them from their module subpaths when needed:\n//\n// import { DeepSeekLLM } from \"pipeflow/providers\";\n// import { SQLitePersistence } from \"pipeflow/persistence\";\n// import { MemoryTransport } from \"pipeflow/transport\";\n// ---------------------------------------------------------------------------\n\nexport type { LLM, LLMMessage } from \"./providers/llm/types\";\nexport type { STT } from \"./providers/stt/types\";\nexport type { TTS } from \"./providers/tts/types\";\nexport type { Persistence } from \"./persistence/persistence\";\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,YAAAA,MAAgB,aAGzB,OAAS,SAAAC,MAAa,iBAOtB,OAAS,QAAAC,EAAc,QAARA,MAA4B,uBAG3C,OACE,gBAAAC,EACA,iBAAAC,EACA,iBAAAC,EACA,mBAAAC,MACK",
|
|
6
|
+
"names": ["Pipeflow", "Agent", "Tool", "Conversation", "Conversations", "Transcription", "TranscriptEntry"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var r=Object.defineProperty;var s=(i,
|
|
1
|
+
var r=Object.defineProperty;var s=(i,n)=>r(i,"name",{value:n,configurable:!0});import{Database as o}from"bun:sqlite";import{TranscriptEntry as d}from"../../../conversations/transcription/transcription.js";class u{static{s(this,"SQLitePersistence")}db;constructor(n={}){this.db=new o(n.filename??":memory:"),this.db.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS conversations (
|
|
3
3
|
id TEXT PRIMARY KEY,
|
|
4
4
|
agent_names TEXT NOT NULL,
|
|
@@ -36,23 +36,27 @@ var r=Object.defineProperty;var s=(i,t)=>r(i,"name",{value:t,configurable:!0});i
|
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
CREATE TABLE IF NOT EXISTS generations (
|
|
39
|
-
id
|
|
40
|
-
conversation_id
|
|
41
|
-
agent_name
|
|
42
|
-
text
|
|
43
|
-
status
|
|
44
|
-
started_at
|
|
45
|
-
ended_at
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
conversation_id TEXT NOT NULL,
|
|
41
|
+
agent_name TEXT NOT NULL,
|
|
42
|
+
text TEXT NOT NULL,
|
|
43
|
+
status TEXT NOT NULL,
|
|
44
|
+
started_at INTEGER NOT NULL,
|
|
45
|
+
ended_at INTEGER,
|
|
46
|
+
kind TEXT,
|
|
47
|
+
parent_generation_id TEXT,
|
|
48
|
+
timing TEXT
|
|
46
49
|
);
|
|
47
50
|
|
|
48
51
|
CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);
|
|
49
52
|
CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);
|
|
50
53
|
CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);
|
|
51
54
|
CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);
|
|
52
|
-
`)}close(){this.db.close()}async createConversation(
|
|
53
|
-
VALUES (?, ?, ?, ?)`).run(e.id,JSON.stringify(e.agentNames),e.createdAt,null),{...e}}async getConversation(
|
|
54
|
-
VALUES (?, ?, ?, ?)`).run(
|
|
55
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(e.id,
|
|
56
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,
|
|
57
|
-
|
|
55
|
+
`);const e=new Set(this.db.query("PRAGMA table_info(generations)").all().map(t=>t.name));e.has("kind")||this.db.exec("ALTER TABLE generations ADD COLUMN kind TEXT"),e.has("parent_generation_id")||this.db.exec("ALTER TABLE generations ADD COLUMN parent_generation_id TEXT"),e.has("timing")||this.db.exec("ALTER TABLE generations ADD COLUMN timing TEXT")}close(){this.db.close()}async createConversation(n={}){const e={id:n.id??crypto.randomUUID(),agentNames:n.agentNames??[],createdAt:n.createdAt??Date.now(),endedAt:null};return this.db.query(`INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)
|
|
56
|
+
VALUES (?, ?, ?, ?)`).run(e.id,JSON.stringify(e.agentNames),e.createdAt,null),{...e}}async getConversation(n){const e=this.db.query("SELECT * FROM conversations WHERE id = ?").get(n);return e?a(e):null}async listConversations(){return this.db.query("SELECT * FROM conversations ORDER BY created_at ASC").all().map(a)}async finalizeConversation(n,e=Date.now()){return this.db.query("UPDATE conversations SET ended_at = ? WHERE id = ?").run(e,n).changes===0?null:this.getConversation(n)}async deleteConversation(n){return this.db.query("SELECT id FROM conversations WHERE id = ?").get(n)?(this.db.query("DELETE FROM participants WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM transcript WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM turns WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM generations WHERE conversation_id = ?").run(n),this.db.query("DELETE FROM conversations WHERE id = ?").run(n),!0):!1}async addParticipant(n,e){this.db.query(`INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)
|
|
57
|
+
VALUES (?, ?, ?, ?)`).run(n,e.userId,JSON.stringify(e.aliases),e.joinedAt)}async listParticipants(n){return this.db.query("SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC").all(n).map(t=>({userId:t.user_id,aliases:JSON.parse(t.aliases),joinedAt:t.joined_at}))}async appendTranscript(n,e){this.db.query(`INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)
|
|
58
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.speaker,e.speakerKind,e.text,e.timestamp,e.sequence)}async listTranscript(n){return this.db.query("SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC").all(n).map(t=>d.fromPlain({id:t.id,conversationId:t.conversation_id,speaker:t.speaker,speakerKind:t.speaker_kind,text:t.text,timestamp:t.timestamp,sequence:t.sequence}))}async appendTurn(n,e){this.db.query(`INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)
|
|
59
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.participantId,e.participantName,e.text,e.startedAt,e.endedAt,e.sequence)}async listTurns(n){return this.db.query("SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC").all(n).map(t=>({id:t.id,conversationId:t.conversation_id,participantId:t.participant_id,participantName:t.participant_name,text:t.text,startedAt:t.started_at,endedAt:t.ended_at,sequence:t.sequence}))}async appendGeneration(n,e){this.db.query(`INSERT OR REPLACE INTO generations
|
|
60
|
+
(id, conversation_id, agent_name, text, status, started_at, ended_at, kind, parent_generation_id, timing)
|
|
61
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(e.id,n,e.agentName,e.text,e.status,e.startedAt,e.endedAt??null,e.kind??null,e.parentGenerationId??null,e.timing?JSON.stringify(e.timing):null)}async listGenerations(n){return this.db.query("SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC").all(n).map(t=>({id:t.id,conversationId:t.conversation_id,agentName:t.agent_name,text:t.text,status:t.status,startedAt:t.started_at,endedAt:t.ended_at??void 0,kind:t.kind==="sub"?"sub":void 0,parentGenerationId:t.parent_generation_id??void 0,timing:t.timing?JSON.parse(t.timing):void 0}))}}function a(i){return{id:i.id,agentNames:JSON.parse(i.agent_names),createdAt:i.created_at,endedAt:i.ended_at}}s(a,"rowToConversation");export{u as SQLitePersistence};
|
|
58
62
|
//# sourceMappingURL=sqlite.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/persistence/adapters/sqlite/sqlite.ts"],
|
|
4
|
-
"sourcesContent": ["import { Database } from \"bun:sqlite\";\nimport type {\n ConversationId,\n Generation,\n Participant,\n Turn,\n UserId,\n} from \"../../../conversations/types\";\nimport { TranscriptEntry } from \"../../../conversations/transcription/transcription\";\nimport type {\n ConversationRecord,\n NewConversation,\n Persistence,\n} from \"../../persistence\";\n\nexport interface SQLitePersistenceOptions {\n /** Database filename. Defaults to an in-memory database. */\n filename?: string;\n}\n\ninterface ConversationRow {\n id: string;\n agent_names: string;\n created_at: number;\n ended_at: number | null;\n}\n\ninterface ParticipantRow {\n conversation_id: string;\n user_id: string;\n aliases: string;\n joined_at: number;\n}\n\ninterface TranscriptRow {\n id: string;\n conversation_id: string;\n speaker: string;\n speaker_kind: string;\n text: string;\n timestamp: number;\n sequence: number;\n}\n\ninterface TurnRow {\n id: string;\n conversation_id: string;\n participant_id: string;\n participant_name: string;\n text: string;\n started_at: number;\n ended_at: number;\n sequence: number;\n}\n\ninterface GenerationRow {\n id: string;\n conversation_id: string;\n agent_name: string;\n text: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n}\n\n/**\n * SQLite-backed persistence adapter (via bun:sqlite).\n *\n * A lightweight persistent backend for local applications and early\n * deployments.\n */\nexport class SQLitePersistence implements Persistence {\n private readonly db: Database;\n\n constructor(options: SQLitePersistenceOptions = {}) {\n this.db = new Database(options.filename ?? \":memory:\");\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n agent_names TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS participants (\n conversation_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n aliases TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n PRIMARY KEY (conversation_id, user_id)\n );\n\n CREATE TABLE IF NOT EXISTS transcript (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n speaker TEXT NOT NULL,\n speaker_kind TEXT NOT NULL,\n text TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS turns (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n participant_id TEXT NOT NULL,\n participant_name TEXT NOT NULL,\n text TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS generations (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);\n `);\n }\n\n close(): void {\n this.db.close();\n }\n\n async createConversation(input: NewConversation = {}): Promise<ConversationRecord> {\n const record: ConversationRecord = {\n id: input.id ?? crypto.randomUUID(),\n agentNames: input.agentNames ?? [],\n createdAt: input.createdAt ?? Date.now(),\n endedAt: null,\n };\n this.db\n .query(\n `INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(record.id, JSON.stringify(record.agentNames), record.createdAt, null);\n return { ...record };\n }\n\n async getConversation(id: ConversationId): Promise<ConversationRecord | null> {\n const row = this.db\n .query<ConversationRow, [string]>(`SELECT * FROM conversations WHERE id = ?`)\n .get(id);\n return row ? rowToConversation(row) : null;\n }\n\n async listConversations(): Promise<ConversationRecord[]> {\n const rows = this.db\n .query<ConversationRow, []>(`SELECT * FROM conversations ORDER BY created_at ASC`)\n .all();\n return rows.map(rowToConversation);\n }\n\n async finalizeConversation(\n id: ConversationId,\n endedAt = Date.now(),\n ): Promise<ConversationRecord | null> {\n const result = this.db\n .query<unknown, [number, string]>(`UPDATE conversations SET ended_at = ? WHERE id = ?`)\n .run(endedAt, id);\n if (result.changes === 0) return null;\n return this.getConversation(id);\n }\n\n async deleteConversation(id: ConversationId): Promise<boolean> {\n const conversation = this.db\n .query<ConversationRow, [string]>(`SELECT id FROM conversations WHERE id = ?`)\n .get(id);\n if (!conversation) return false;\n this.db.query(`DELETE FROM participants WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM transcript WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM turns WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM generations WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM conversations WHERE id = ?`).run(id);\n return true;\n }\n\n async addParticipant(\n conversationId: ConversationId,\n participant: Participant,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(\n conversationId,\n participant.userId,\n JSON.stringify(participant.aliases),\n participant.joinedAt,\n );\n }\n\n async listParticipants(conversationId: ConversationId): Promise<Participant[]> {\n const rows = this.db\n .query<ParticipantRow, [string]>(\n `SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n userId: row.user_id,\n aliases: JSON.parse(row.aliases) as string[],\n joinedAt: row.joined_at,\n }));\n }\n\n async appendTranscript(\n conversationId: ConversationId,\n entry: TranscriptEntry,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.id,\n conversationId,\n entry.speaker,\n entry.speakerKind,\n entry.text,\n entry.timestamp,\n entry.sequence,\n );\n }\n\n async listTranscript(conversationId: ConversationId): Promise<TranscriptEntry[]> {\n const rows = this.db\n .query<TranscriptRow, [string]>(\n `SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) =>\n TranscriptEntry.fromPlain({\n id: row.id,\n conversationId: row.conversation_id,\n speaker: row.speaker,\n speakerKind: row.speaker_kind as TranscriptEntry[\"speakerKind\"],\n text: row.text,\n timestamp: row.timestamp,\n sequence: row.sequence,\n }),\n );\n }\n\n async appendTurn(conversationId: ConversationId, turn: Turn): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n turn.id,\n conversationId,\n turn.participantId,\n turn.participantName,\n turn.text,\n turn.startedAt,\n turn.endedAt,\n turn.sequence,\n );\n }\n\n async listTurns(conversationId: ConversationId): Promise<Turn[]> {\n const rows = this.db\n .query<TurnRow, [string]>(\n `SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n participantId: row.participant_id,\n participantName: row.participant_name,\n text: row.text,\n startedAt: row.started_at,\n endedAt: row.ended_at,\n sequence: row.sequence,\n }));\n }\n\n async appendGeneration(\n conversationId: ConversationId,\n generation: Generation,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO generations (id, conversation_id, agent_name, text, status, started_at, ended_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n generation.id,\n conversationId,\n generation.agentName,\n generation.text,\n generation.status,\n generation.startedAt,\n generation.endedAt ?? null,\n );\n }\n\n async listGenerations(conversationId: ConversationId): Promise<Generation[]> {\n const rows = this.db\n .query<GenerationRow, [string]>(\n `SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n agentName: row.agent_name,\n text: row.text,\n status: row.status as Generation[\"status\"],\n startedAt: row.started_at,\n endedAt: row.ended_at ?? undefined,\n }));\n }\n}\n\nfunction rowToConversation(row: ConversationRow): ConversationRecord {\n return {\n id: row.id,\n agentNames: JSON.parse(row.agent_names) as string[],\n createdAt: row.created_at,\n endedAt: row.ended_at,\n };\n}\n"],
|
|
5
|
-
"mappings": "+EAAA,OAAS,YAAAA,MAAgB,
|
|
6
|
-
"names": ["Database", "TranscriptEntry", "SQLitePersistence", "__name", "options", "input", "record", "id", "row", "rowToConversation", "endedAt", "conversationId", "participant", "entry", "turn", "generation"]
|
|
4
|
+
"sourcesContent": ["import { Database } from \"bun:sqlite\";\nimport type {\n ConversationId,\n Generation,\n GenerationTiming,\n Participant,\n Turn,\n UserId,\n} from \"../../../conversations/types\";\nimport { TranscriptEntry } from \"../../../conversations/transcription/transcription\";\nimport type {\n ConversationRecord,\n NewConversation,\n Persistence,\n} from \"../../persistence\";\n\nexport interface SQLitePersistenceOptions {\n /** Database filename. Defaults to an in-memory database. */\n filename?: string;\n}\n\ninterface ConversationRow {\n id: string;\n agent_names: string;\n created_at: number;\n ended_at: number | null;\n}\n\ninterface ParticipantRow {\n conversation_id: string;\n user_id: string;\n aliases: string;\n joined_at: number;\n}\n\ninterface TranscriptRow {\n id: string;\n conversation_id: string;\n speaker: string;\n speaker_kind: string;\n text: string;\n timestamp: number;\n sequence: number;\n}\n\ninterface TurnRow {\n id: string;\n conversation_id: string;\n participant_id: string;\n participant_name: string;\n text: string;\n started_at: number;\n ended_at: number;\n sequence: number;\n}\n\ninterface GenerationRow {\n id: string;\n conversation_id: string;\n agent_name: string;\n text: string;\n status: string;\n started_at: number;\n ended_at: number | null;\n kind: string | null;\n parent_generation_id: string | null;\n timing: string | null;\n}\n\n/**\n * SQLite-backed persistence adapter (via bun:sqlite).\n *\n * A lightweight persistent backend for local applications and early\n * deployments.\n */\nexport class SQLitePersistence implements Persistence {\n private readonly db: Database;\n\n constructor(options: SQLitePersistenceOptions = {}) {\n this.db = new Database(options.filename ?? \":memory:\");\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n agent_names TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n ended_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS participants (\n conversation_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n aliases TEXT NOT NULL,\n joined_at INTEGER NOT NULL,\n PRIMARY KEY (conversation_id, user_id)\n );\n\n CREATE TABLE IF NOT EXISTS transcript (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n speaker TEXT NOT NULL,\n speaker_kind TEXT NOT NULL,\n text TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS turns (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n participant_id TEXT NOT NULL,\n participant_name TEXT NOT NULL,\n text TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER NOT NULL,\n sequence INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS generations (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n started_at INTEGER NOT NULL,\n ended_at INTEGER,\n kind TEXT,\n parent_generation_id TEXT,\n timing TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_participants_conversation ON participants (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_transcript_conversation ON transcript (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns (conversation_id);\n CREATE INDEX IF NOT EXISTS idx_generations_conversation ON generations (conversation_id);\n `);\n\n // Lightweight migration for databases created before the generation\n // columns existed: CREATE TABLE IF NOT EXISTS leaves existing tables\n // untouched, so add the missing columns when needed.\n const generationColumns = new Set(\n (this.db.query(`PRAGMA table_info(generations)`).all() as { name: string }[]).map(\n (column) => column.name,\n ),\n );\n if (!generationColumns.has(\"kind\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN kind TEXT`);\n }\n if (!generationColumns.has(\"parent_generation_id\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN parent_generation_id TEXT`);\n }\n if (!generationColumns.has(\"timing\")) {\n this.db.exec(`ALTER TABLE generations ADD COLUMN timing TEXT`);\n }\n }\n\n close(): void {\n this.db.close();\n }\n\n async createConversation(input: NewConversation = {}): Promise<ConversationRecord> {\n const record: ConversationRecord = {\n id: input.id ?? crypto.randomUUID(),\n agentNames: input.agentNames ?? [],\n createdAt: input.createdAt ?? Date.now(),\n endedAt: null,\n };\n this.db\n .query(\n `INSERT OR REPLACE INTO conversations (id, agent_names, created_at, ended_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(record.id, JSON.stringify(record.agentNames), record.createdAt, null);\n return { ...record };\n }\n\n async getConversation(id: ConversationId): Promise<ConversationRecord | null> {\n const row = this.db\n .query<ConversationRow, [string]>(`SELECT * FROM conversations WHERE id = ?`)\n .get(id);\n return row ? rowToConversation(row) : null;\n }\n\n async listConversations(): Promise<ConversationRecord[]> {\n const rows = this.db\n .query<ConversationRow, []>(`SELECT * FROM conversations ORDER BY created_at ASC`)\n .all();\n return rows.map(rowToConversation);\n }\n\n async finalizeConversation(\n id: ConversationId,\n endedAt = Date.now(),\n ): Promise<ConversationRecord | null> {\n const result = this.db\n .query<unknown, [number, string]>(`UPDATE conversations SET ended_at = ? WHERE id = ?`)\n .run(endedAt, id);\n if (result.changes === 0) return null;\n return this.getConversation(id);\n }\n\n async deleteConversation(id: ConversationId): Promise<boolean> {\n const conversation = this.db\n .query<ConversationRow, [string]>(`SELECT id FROM conversations WHERE id = ?`)\n .get(id);\n if (!conversation) return false;\n this.db.query(`DELETE FROM participants WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM transcript WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM turns WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM generations WHERE conversation_id = ?`).run(id);\n this.db.query(`DELETE FROM conversations WHERE id = ?`).run(id);\n return true;\n }\n\n async addParticipant(\n conversationId: ConversationId,\n participant: Participant,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO participants (conversation_id, user_id, aliases, joined_at)\n VALUES (?, ?, ?, ?)`,\n )\n .run(\n conversationId,\n participant.userId,\n JSON.stringify(participant.aliases),\n participant.joinedAt,\n );\n }\n\n async listParticipants(conversationId: ConversationId): Promise<Participant[]> {\n const rows = this.db\n .query<ParticipantRow, [string]>(\n `SELECT * FROM participants WHERE conversation_id = ? ORDER BY joined_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n userId: row.user_id,\n aliases: JSON.parse(row.aliases) as string[],\n joinedAt: row.joined_at,\n }));\n }\n\n async appendTranscript(\n conversationId: ConversationId,\n entry: TranscriptEntry,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO transcript (id, conversation_id, speaker, speaker_kind, text, timestamp, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.id,\n conversationId,\n entry.speaker,\n entry.speakerKind,\n entry.text,\n entry.timestamp,\n entry.sequence,\n );\n }\n\n async listTranscript(conversationId: ConversationId): Promise<TranscriptEntry[]> {\n const rows = this.db\n .query<TranscriptRow, [string]>(\n `SELECT * FROM transcript WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) =>\n TranscriptEntry.fromPlain({\n id: row.id,\n conversationId: row.conversation_id,\n speaker: row.speaker,\n speakerKind: row.speaker_kind as TranscriptEntry[\"speakerKind\"],\n text: row.text,\n timestamp: row.timestamp,\n sequence: row.sequence,\n }),\n );\n }\n\n async appendTurn(conversationId: ConversationId, turn: Turn): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO turns (id, conversation_id, participant_id, participant_name, text, started_at, ended_at, sequence)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n turn.id,\n conversationId,\n turn.participantId,\n turn.participantName,\n turn.text,\n turn.startedAt,\n turn.endedAt,\n turn.sequence,\n );\n }\n\n async listTurns(conversationId: ConversationId): Promise<Turn[]> {\n const rows = this.db\n .query<TurnRow, [string]>(\n `SELECT * FROM turns WHERE conversation_id = ? ORDER BY sequence ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n participantId: row.participant_id,\n participantName: row.participant_name,\n text: row.text,\n startedAt: row.started_at,\n endedAt: row.ended_at,\n sequence: row.sequence,\n }));\n }\n\n async appendGeneration(\n conversationId: ConversationId,\n generation: Generation,\n ): Promise<void> {\n this.db\n .query(\n `INSERT OR REPLACE INTO generations\n (id, conversation_id, agent_name, text, status, started_at, ended_at, kind, parent_generation_id, timing)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n generation.id,\n conversationId,\n generation.agentName,\n generation.text,\n generation.status,\n generation.startedAt,\n generation.endedAt ?? null,\n generation.kind ?? null,\n generation.parentGenerationId ?? null,\n generation.timing ? JSON.stringify(generation.timing) : null,\n );\n }\n\n async listGenerations(conversationId: ConversationId): Promise<Generation[]> {\n const rows = this.db\n .query<GenerationRow, [string]>(\n `SELECT * FROM generations WHERE conversation_id = ? ORDER BY started_at ASC`,\n )\n .all(conversationId);\n return rows.map((row) => ({\n id: row.id,\n conversationId: row.conversation_id,\n agentName: row.agent_name,\n text: row.text,\n status: row.status as Generation[\"status\"],\n startedAt: row.started_at,\n endedAt: row.ended_at ?? undefined,\n kind: row.kind === \"sub\" ? \"sub\" : undefined,\n parentGenerationId: row.parent_generation_id ?? undefined,\n timing: row.timing ? (JSON.parse(row.timing) as GenerationTiming) : undefined,\n }));\n }\n}\n\nfunction rowToConversation(row: ConversationRow): ConversationRecord {\n return {\n id: row.id,\n agentNames: JSON.parse(row.agent_names) as string[],\n createdAt: row.created_at,\n endedAt: row.ended_at,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Database", "TranscriptEntry", "SQLitePersistence", "__name", "options", "generationColumns", "column", "input", "record", "id", "row", "rowToConversation", "endedAt", "conversationId", "participant", "entry", "turn", "generation"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var o=Object.defineProperty;var s=(e,t)=>o(e,"name",{value:t,configurable:!0});import{Agent as n}from"../agents/agent.js";import{Conversations as i}from"../conversations/conversations.js";import{MemoryPersistence as l}from"../persistence/adapters/memory/memory.js";class T{static{s(this,"Pipeflow")}llm;stt;tts;conversations;constructor(t={}){this.llm=t.llm,this.stt=t.stt,this.tts=t.tts;const r=t.persistence??new l;this.conversations=new i({persistence:r,stt:t.stt,tts:t.tts,autoExecuteTools:t.autoExecuteTools})}agent(t){return new n({...t,llm:t.llm??this.llm})}}export{T as Pipeflow};
|
|
2
|
+
//# sourceMappingURL=pipeflow.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/pipeflow/pipeflow.ts"],
|
|
4
|
+
"sourcesContent": ["import { Agent, type AgentOptions } from \"../agents/agent\";\nimport { Conversations } from \"../conversations/conversations\";\nimport { MemoryPersistence } from \"../persistence/adapters/memory/memory\";\nimport type { Persistence } from \"../persistence/persistence\";\nimport type { LLM } from \"../providers/llm/types\";\nimport type { STT } from \"../providers/stt/types\";\nimport type { TTS } from \"../providers/tts/types\";\n\nexport interface PipeflowOptions {\n llm?: LLM;\n stt?: STT;\n tts?: TTS;\n persistence?: Persistence;\n /**\n * Default for created conversations: auto-execute the agents' tools\n * (default `true`), feeding each tool's result back into the model loop.\n * Set `false` to resolve tool calls from your own backend via\n * `resolveToolCall()`. Override per conversation in\n * `pipeflow.conversations.create()`.\n */\n autoExecuteTools?: boolean;\n}\n\n/**\n * The Pipeflow entry point.\n *\n * ```ts\n * const pipeflow = new Pipeflow({ llm });\n * const agent = pipeflow.agent({ name: \"Jarvis\", context: \"...\" });\n * const conversation = await pipeflow.conversations.create({ agents: [agent] });\n * ```\n */\nexport class Pipeflow {\n readonly llm: LLM | undefined;\n readonly stt: STT | undefined;\n readonly tts: TTS | undefined;\n readonly conversations: Conversations;\n\n constructor(options: PipeflowOptions = {}) {\n this.llm = options.llm;\n this.stt = options.stt;\n this.tts = options.tts;\n const persistence = options.persistence ?? new MemoryPersistence();\n this.conversations = new Conversations({\n persistence,\n stt: options.stt,\n tts: options.tts,\n autoExecuteTools: options.autoExecuteTools,\n });\n }\n\n /**\n * Create an agent. Agents inherit the Pipeflow instance's LLM provider so\n * `agent.run()` works out of the box.\n */\n agent(options: Omit<AgentOptions, \"llm\"> & { llm?: LLM }): Agent {\n return new Agent({ ...options, llm: options.llm ?? this.llm });\n }\n}\n"],
|
|
5
|
+
"mappings": "+EAAA,OAAS,SAAAA,MAAgC,kBACzC,OAAS,iBAAAC,MAAqB,iCAC9B,OAAS,qBAAAC,MAAyB,wCA8B3B,MAAMC,CAAS,CAhCtB,MAgCsB,CAAAC,EAAA,iBACX,IACA,IACA,IACA,cAET,YAAYC,EAA2B,CAAC,EAAG,CACzC,KAAK,IAAMA,EAAQ,IACnB,KAAK,IAAMA,EAAQ,IACnB,KAAK,IAAMA,EAAQ,IACnB,MAAMC,EAAcD,EAAQ,aAAe,IAAIH,EAC/C,KAAK,cAAgB,IAAID,EAAc,CACrC,YAAAK,EACA,IAAKD,EAAQ,IACb,IAAKA,EAAQ,IACb,iBAAkBA,EAAQ,gBAC5B,CAAC,CACH,CAMA,MAAMA,EAA2D,CAC/D,OAAO,IAAIL,EAAM,CAAE,GAAGK,EAAS,IAAKA,EAAQ,KAAO,KAAK,GAAI,CAAC,CAC/D,CACF",
|
|
6
|
+
"names": ["Agent", "Conversations", "MemoryPersistence", "Pipeflow", "__name", "options", "persistence"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{complete as t,streamText as
|
|
1
|
+
import{complete as t,streamText as L,DeepSeekLLM as T,OpenRouterLLM as r}from"./llm/index.js";import{DeepgramSTT as m}from"./stt/index.js";import{KokoroTTS as x}from"./tts/index.js";export{T as DeepSeekLLM,m as DeepgramSTT,x as KokoroTTS,r as OpenRouterLLM,t as complete,L as streamText};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/providers/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type { LLM, LLMEvent, LLMMessage, LLMRole, LLMToolCall, LLMToolDefinition, LLMRequest } from \"./llm/index\";\nexport type { STT, STTOptions, STTSession } from \"./stt/index\";\nexport type { TTS, TTSRequest } from \"./tts/index\";\n\nexport { complete, streamText, DeepSeekLLM } from \"./llm/index\";\nexport { DeepgramSTT } from \"./stt/index\";\nexport { KokoroTTS } from \"./tts/index\";\n"],
|
|
5
|
-
"mappings": "AAIA,OAAS,YAAAA,EAAU,cAAAC,EAAY,eAAAC,
|
|
6
|
-
"names": ["complete", "streamText", "DeepSeekLLM", "DeepgramSTT", "KokoroTTS"]
|
|
4
|
+
"sourcesContent": ["export type { LLM, LLMEvent, LLMMessage, LLMRole, LLMToolCall, LLMToolDefinition, LLMRequest } from \"./llm/index\";\nexport type { STT, STTOptions, STTSession } from \"./stt/index\";\nexport type { TTS, TTSRequest } from \"./tts/index\";\n\nexport { complete, streamText, DeepSeekLLM, OpenRouterLLM } from \"./llm/index\";\nexport { DeepgramSTT } from \"./stt/index\";\nexport { KokoroTTS } from \"./tts/index\";\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,YAAAA,EAAU,cAAAC,EAAY,eAAAC,EAAa,iBAAAC,MAAqB,cACjE,OAAS,eAAAC,MAAmB,cAC5B,OAAS,aAAAC,MAAiB",
|
|
6
|
+
"names": ["complete", "streamText", "DeepSeekLLM", "OpenRouterLLM", "DeepgramSTT", "KokoroTTS"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var b=Object.defineProperty;var m=(u,t)=>b(u,"name",{value:t,configurable:!0});class w{static{m(this,"ClaudeLLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;streams=new Set;constructor(t){if(!t.apiKey)throw new Error("ClaudeLLM requires an apiKey");this.apiKey=t.apiKey,this.model=t.model??"claude-sonnet-4-5",this.baseUrl=(t.baseUrl??"https://api.anthropic.com/v1").replace(/\/+$/,""),this.fetchImpl=t.fetch??fetch,this.onTiming=t.onTiming,this.idleTimeoutMs=t.idleTimeoutMs??8e3,this.onUsage=t.onUsage}stop(){for(const t of this.streams)t.abort()}async*stream(t){const o=new AbortController;this.streams.add(o);try{const{system:a,wire:d}=y(t.messages);this.onTiming?.("request-start");const i=await this.fetchImpl(`${this.baseUrl}/messages`,{method:"POST",headers:{"content-type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:this.model,max_tokens:t.maxTokens??4096,...a.length>0?{system:a}:{},messages:d,...t.tools&&t.tools.length>0?{tools:t.tools.map(n=>({name:n.name,description:n.description,input_schema:n.parameters??{type:"object",properties:{}}}))}:{},...t.temperature!==void 0?{temperature:t.temperature}:{},stream:!0}),signal:o.signal});if(!i.ok){const n=await i.text();throw new Error(`Claude request failed (${i.status}): ${n}`)}if(!i.body)throw new Error("Claude returned an empty body");this.onTiming?.("headers");const r=new Map;let p,g,l=!1;for await(const n of k(i.body,o.signal,this.onTiming,this.idleTimeoutMs)){switch(n.event){case"message_start":{p=n.data.message?.usage?.input_tokens;break}case"content_block_start":{const e=n.data.content_block;e.type==="tool_use"&&e.id&&e.name&&r.set(n.data.index,{id:e.id,name:e.name,json:""});break}case"content_block_delta":{const e=n.data.delta;if(e.type==="text_delta"&&e.text)yield{type:"delta",content:e.text};else if(e.type==="input_json_delta"&&e.partial_json){const s=r.get(n.data.index);s&&(s.json+=e.partial_json)}break}case"content_block_stop":{const e=r.get(n.data.index);if(e){let s="{}";if(e.json.length>0)try{s=e.json,JSON.parse(s)}catch{s="{}"}yield{type:"tool_call",id:e.id,name:e.name,arguments:s},r.delete(n.data.index)}break}case"message_delta":{const e=n.data.usage;e?.output_tokens!==void 0&&(g=e.output_tokens);break}case"message_stop":(p!==void 0||g!==void 0)&&this.onUsage?.({promptTokens:p??0,completionTokens:g??0}),l=!0;break;case"error":{const e=n.data.error;yield{type:"error",error:new Error(`Claude stream error: ${e?.message??JSON.stringify(n.data)}`)},l=!0;break}}if(l)break}}finally{this.streams.delete(o)}yield{type:"done"}}}function y(u){const t=[],o=[];for(const a of u)switch(a.role){case"system":t.push(a.content);break;case"user":o.push({role:"user",content:a.content});break;case"assistant":{const d=[];a.content&&d.push({type:"text",text:a.content});for(const i of a.toolCalls??[]){let r={};try{r=JSON.parse(i.arguments)}catch{r={}}d.push({type:"tool_use",id:i.id,name:i.name,input:r})}o.push({role:"assistant",content:d});break}case"tool":o.push({role:"user",content:[{type:"tool_result",tool_use_id:a.toolCallId,content:a.content}]});break}return{system:t.join(`
|
|
2
|
+
|
|
3
|
+
`),wire:o}}m(y,"mapMessages");async function*k(u,t,o,a){const d=u.getReader(),i=new TextDecoder;let r="",p=!1;const g=m(()=>{let l;return new Promise((n,e)=>{const s=m(()=>{l!==void 0&&clearTimeout(l),t.removeEventListener("abort",f)},"cleanup"),f=m(()=>{s(),e(new DOMException("The operation was aborted.","AbortError"))},"onAbort");d.read().then(c=>{s(),n(c)},c=>{s(),e(c)}),l=setTimeout(()=>{s(),d.cancel().catch(()=>{}),e(new Error(`Claude stream idle for ${a}ms \u2014 no data received; aborting the stalled stream`))},a),t.addEventListener("abort",f,{once:!0})})},"readWithTimeout");for(;;){if(t.aborted)throw new DOMException("The operation was aborted.","AbortError");const{done:l,value:n}=await g();if(l)break;r+=i.decode(n,{stream:!0});const e=r.split(/\r?\n\r?\n/);r=e.pop()??"";for(const s of e){p||(p=!0,o?.("first-chunk"));let f="";const c=[];for(const h of s.split(/\r?\n/))h.startsWith("event:")?f=h.slice(6).trim():h.startsWith("data:")&&c.push(h.slice(5).trimStart());if(c.length!==0)try{yield{event:f,data:JSON.parse(c.join(`
|
|
4
|
+
`))}}catch{}}}}m(k,"readClaudeSSE");export{w as ClaudeLLM};
|
|
5
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/providers/llm/adapters/claude/claude.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMMessage,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\n\nexport interface ClaudeOptions {\n apiKey: string;\n /** Defaults to `claude-sonnet-4-5`. */\n model?: string;\n /** Defaults to `https://api.anthropic.com/v1`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n}\n\n/** An SSE frame: the `event:` type plus the parsed `data:` payload. */\ninterface ClaudeEvent {\n event: string;\n data: Record<string, unknown>;\n}\n\n/**\n * Claude LLM adapter (Anthropic Messages API over SSE).\n *\n * The wire format differs from the OpenAI-compatible adapters: tools are\n * `input_schema` blocks, tool calls arrive as `tool_use` content blocks with\n * `input_json_delta` fragments (reassembled here into `tool_call` events),\n * tool results are `tool_result` blocks inside user messages, and `max_tokens`\n * is required. There is no `response_format`, so `toolMode` is not supported \u2014\n * tool calling is always native.\n */\nexport class ClaudeLLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: ClaudeOptions) {\n if (!options.apiKey) {\n throw new Error(\"ClaudeLLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"claude-sonnet-4-5\";\n this.baseUrl = (options.baseUrl ?? \"https://api.anthropic.com/v1\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n const { system, wire } = mapMessages(request.messages);\n\n this.onTiming?.(\"request-start\");\n const response = await this.fetchImpl(`${this.baseUrl}/messages`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": this.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: this.model,\n // Required by the Anthropic API.\n max_tokens: request.maxTokens ?? 4096,\n ...(system.length > 0 ? { system } : {}),\n messages: wire,\n ...(request.tools && request.tools.length > 0\n ? {\n tools: request.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.parameters ?? { type: \"object\", properties: {} },\n })),\n }\n : {}),\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n stream: true,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Claude request failed (${response.status}): ${body}`);\n }\n if (!response.body) {\n throw new Error(\"Claude returned an empty body\");\n }\n this.onTiming?.(\"headers\");\n\n // Tool_use blocks can interleave and complete in any order; keyed by\n // block index. Arguments arrive as `input_json_delta` fragments.\n const toolBlocks = new Map<\n number,\n { id: string; name: string; json: string }\n >();\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let finished = false;\n\n for await (const frame of readClaudeSSE(\n response.body,\n controller.signal,\n this.onTiming,\n this.idleTimeoutMs,\n )) {\n switch (frame.event) {\n case \"message_start\": {\n const usage = frame.data.message as { usage?: { input_tokens?: number } };\n inputTokens = usage?.usage?.input_tokens;\n break;\n }\n case \"content_block_start\": {\n const block = frame.data.content_block as {\n type: string;\n id?: string;\n name?: string;\n };\n if (block.type === \"tool_use\" && block.id && block.name) {\n toolBlocks.set(frame.data.index as number, {\n id: block.id,\n name: block.name,\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const delta = frame.data.delta as { type: string; text?: string; partial_json?: string };\n if (delta.type === \"text_delta\" && delta.text) {\n yield { type: \"delta\", content: delta.text };\n } else if (delta.type === \"input_json_delta\" && delta.partial_json) {\n const block = toolBlocks.get(frame.data.index as number);\n if (block) block.json += delta.partial_json;\n }\n break;\n }\n case \"content_block_stop\": {\n const block = toolBlocks.get(frame.data.index as number);\n if (block) {\n let args = \"{}\";\n if (block.json.length > 0) {\n try {\n args = block.json;\n JSON.parse(args); // validate before handing off\n } catch {\n args = \"{}\";\n }\n }\n yield {\n type: \"tool_call\",\n id: block.id,\n name: block.name,\n arguments: args,\n };\n toolBlocks.delete(frame.data.index as number);\n }\n break;\n }\n case \"message_delta\": {\n const usage = frame.data.usage as { output_tokens?: number };\n if (usage?.output_tokens !== undefined) outputTokens = usage.output_tokens;\n break;\n }\n case \"message_stop\":\n if (inputTokens !== undefined || outputTokens !== undefined) {\n this.onUsage?.({\n promptTokens: inputTokens ?? 0,\n completionTokens: outputTokens ?? 0,\n });\n }\n finished = true;\n break;\n case \"error\": {\n const error = frame.data.error as { message?: string } | undefined;\n yield {\n type: \"error\",\n error: new Error(\n `Claude stream error: ${error?.message ?? JSON.stringify(frame.data)}`,\n ),\n };\n finished = true;\n break;\n }\n }\n if (finished) break;\n }\n } finally {\n this.streams.delete(controller);\n }\n\n yield { type: \"done\" };\n }\n}\n\n/** Anthropic messages: leading system messages become `system`; the rest map to wire roles. */\nfunction mapMessages(messages: LLMMessage[]): { system: string; wire: unknown[] } {\n const system: string[] = [];\n const wire: unknown[] = [];\n for (const message of messages) {\n switch (message.role) {\n case \"system\":\n system.push(message.content);\n break;\n case \"user\":\n wire.push({ role: \"user\", content: message.content });\n break;\n case \"assistant\": {\n const blocks: unknown[] = [];\n if (message.content) blocks.push({ type: \"text\", text: message.content });\n for (const call of message.toolCalls ?? []) {\n let input: unknown = {};\n try {\n input = JSON.parse(call.arguments);\n } catch {\n input = {};\n }\n blocks.push({ type: \"tool_use\", id: call.id, name: call.name, input });\n }\n wire.push({ role: \"assistant\", content: blocks });\n break;\n }\n case \"tool\":\n wire.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: message.toolCallId,\n content: message.content,\n },\n ],\n });\n break;\n }\n }\n return { system: system.join(\"\\n\\n\"), wire };\n}\n\n/**\n * Parse the Anthropic SSE stream into `{ event, data }` frames. Unlike the\n * OpenAI-compatible streamer, the `event:` line matters \u2014 it distinguishes\n * text deltas from tool-argument deltas. Bounded by the idle timeout.\n */\nasync function* readClaudeSSE(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n onTiming: LLMStreamTimingCallback | undefined,\n idleTimeoutMs: number,\n): AsyncGenerator<ClaudeEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let firstEvent = false;\n\n const readWithTimeout = (): Promise<Awaited<ReturnType<typeof reader.read>>> => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n return new Promise((resolve, reject) => {\n const cleanup = () => {\n if (timer !== undefined) clearTimeout(timer);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = () => {\n cleanup();\n reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n };\n reader.read().then(\n (result) => {\n cleanup();\n resolve(result);\n },\n (error) => {\n cleanup();\n reject(error);\n },\n );\n timer = setTimeout(() => {\n cleanup();\n void reader.cancel().catch(() => {});\n reject(\n new Error(\n `Claude stream idle for ${idleTimeoutMs}ms \u2014 no data received; aborting the stalled stream`,\n ),\n );\n }, idleTimeoutMs);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n };\n\n while (true) {\n if (signal.aborted) {\n throw new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n const { done, value } = await readWithTimeout();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const frames = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = frames.pop() ?? \"\";\n for (const frame of frames) {\n if (!firstEvent) {\n firstEvent = true;\n onTiming?.(\"first-chunk\");\n }\n let event = \"\";\n const dataLines: string[] = [];\n for (const line of frame.split(/\\r?\\n/)) {\n if (line.startsWith(\"event:\")) event = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) dataLines.push(line.slice(5).trimStart());\n }\n if (dataLines.length === 0) continue;\n try {\n yield { event, data: JSON.parse(dataLines.join(\"\\n\")) as Record<string, unknown> };\n } catch {\n // Ignore malformed frames.\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ClaudeLLM", "__name", "options", "controller", "request", "system", "wire", "mapMessages", "response", "tool", "body", "toolBlocks", "inputTokens", "outputTokens", "finished", "frame", "readClaudeSSE", "block", "delta", "args", "usage", "error", "messages", "message", "blocks", "call", "input", "signal", "onTiming", "idleTimeoutMs", "reader", "decoder", "buffer", "firstEvent", "readWithTimeout", "timer", "resolve", "reject", "cleanup", "onAbort", "result", "done", "value", "frames", "event", "dataLines", "line"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/providers/llm/adapters/claude/index.ts"],
|
|
4
|
+
"sourcesContent": ["export { ClaudeLLM } from \"./claude\";\nexport type { ClaudeOptions } from \"./claude\";\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,aAAAA,MAAiB",
|
|
6
|
+
"names": ["ClaudeLLM"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var o=Object.defineProperty;var a=(i,e)=>o(i,"name",{value:e,configurable:!0});import{openAICompatibleStream as r}from"../openai-compatible.js";class n{static{a(this,"DeepSeekLLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;toolMode;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("DeepSeekLLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"deepseek-chat",this.baseUrl=(e.baseUrl??"https://api.deepseek.com").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage,this.toolMode=e.toolMode}stop(){for(const e of this.streams)e.abort()}async*stream(e){const t=new AbortController;this.streams.add(t);try{yield*r({baseUrl:this.baseUrl,apiKey:this.apiKey,model:this.model,fetchImpl:this.fetchImpl,request:e,signal:t.signal,extraBody:{thinking:{type:"disabled"}},label:"DeepSeek",onTiming:this.onTiming,idleTimeoutMs:this.idleTimeoutMs,onUsage:this.onUsage,toolMode:this.toolMode})}finally{this.streams.delete(t)}}}export{n as DeepSeekLLM};
|
|
2
2
|
//# sourceMappingURL=deepseek.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/providers/llm/adapters/deepseek/deepseek.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "+
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n ToolMode,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\nimport { openAICompatibleStream } from \"../openai-compatible\";\n\nexport interface DeepSeekOptions {\n apiKey: string;\n /** Defaults to `deepseek-chat`. */\n model?: string;\n /** Defaults to `https://api.deepseek.com`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n /**\n * Default tool encoding for requests that don't set `toolMode` (the\n * request's `toolMode` wins). For models whose endpoints lack native tool\n * calling.\n */\n toolMode?: ToolMode;\n}\n\n/**\n * DeepSeek LLM adapter (OpenAI-compatible chat completions over SSE).\n */\nexport class DeepSeekLLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly toolMode: ToolMode | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: DeepSeekOptions) {\n if (!options.apiKey) {\n throw new Error(\"DeepSeekLLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"deepseek-chat\";\n this.baseUrl = (options.baseUrl ?? \"https://api.deepseek.com\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n this.toolMode = options.toolMode;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n // Multiple generations can stream concurrently (e.g. delegated\n // sub-agents); each gets its own controller, and stop() aborts them all.\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n yield* openAICompatibleStream({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n model: this.model,\n fetchImpl: this.fetchImpl,\n request,\n signal: controller.signal,\n // Reasoning models default to enabled thinking; disable it so the\n // adapter behaves uniformly on deepseek-chat.\n extraBody: { thinking: { type: \"disabled\" } },\n label: \"DeepSeek\",\n onTiming: this.onTiming,\n idleTimeoutMs: this.idleTimeoutMs,\n onUsage: this.onUsage,\n toolMode: this.toolMode,\n });\n } finally {\n this.streams.delete(controller);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "+EASA,OAAS,0BAAAA,MAA8B,uBA+BhC,MAAMC,CAA2B,CAxCxC,MAwCwC,CAAAC,EAAA,oBACrB,OACA,MACA,QACA,UACA,SACA,cACA,QACA,SACA,QAAU,IAAI,IAE/B,YAAYC,EAA0B,CACpC,GAAI,CAACA,EAAQ,OACX,MAAM,IAAI,MAAM,gCAAgC,EAElD,KAAK,OAASA,EAAQ,OACtB,KAAK,MAAQA,EAAQ,OAAS,gBAC9B,KAAK,SAAWA,EAAQ,SAAW,4BAA4B,QAAQ,OAAQ,EAAE,EACjF,KAAK,UAAYA,EAAQ,OAAS,MAClC,KAAK,SAAWA,EAAQ,SACxB,KAAK,cAAgBA,EAAQ,eAAiB,IAC9C,KAAK,QAAUA,EAAQ,QACvB,KAAK,SAAWA,EAAQ,QAC1B,CAGA,MAAa,CACX,UAAWC,KAAc,KAAK,QAASA,EAAW,MAAM,CAC1D,CAEA,MAAO,OAAOC,EAA+C,CAG3D,MAAMD,EAAa,IAAI,gBACvB,KAAK,QAAQ,IAAIA,CAAU,EAE3B,GAAI,CACF,MAAOJ,EAAuB,CAC5B,QAAS,KAAK,QACd,OAAQ,KAAK,OACb,MAAO,KAAK,MACZ,UAAW,KAAK,UAChB,QAAAK,EACA,OAAQD,EAAW,OAGnB,UAAW,CAAE,SAAU,CAAE,KAAM,UAAW,CAAE,EAC5C,MAAO,WACP,SAAU,KAAK,SACf,cAAe,KAAK,cACpB,QAAS,KAAK,QACd,SAAU,KAAK,QACjB,CAAC,CACH,QAAE,CACA,KAAK,QAAQ,OAAOA,CAAU,CAChC,CACF,CACF",
|
|
6
|
+
"names": ["openAICompatibleStream", "DeepSeekLLM", "__name", "options", "controller", "request"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{DeepSeekLLM as
|
|
1
|
+
import{DeepSeekLLM as r}from"./deepseek/deepseek.js";import{OpenRouterLLM as p}from"./openrouter/openrouter.js";import{OpenAILLM as f}from"./openai/openai.js";import{ClaudeLLM as x}from"./claude/claude.js";export{x as ClaudeLLM,r as DeepSeekLLM,f as OpenAILLM,p as OpenRouterLLM};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/providers/llm/adapters/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { DeepSeekLLM } from \"./deepseek/deepseek\";\n"],
|
|
5
|
-
"mappings": "AAAA,OAAS,eAAAA,MAAmB",
|
|
6
|
-
"names": ["DeepSeekLLM"]
|
|
4
|
+
"sourcesContent": ["export { DeepSeekLLM } from \"./deepseek/deepseek\";\nexport { OpenRouterLLM } from \"./openrouter/openrouter\";\nexport { OpenAILLM } from \"./openai/openai\";\nexport { ClaudeLLM } from \"./claude/claude\";\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,eAAAA,MAAmB,sBAC5B,OAAS,iBAAAC,MAAqB,0BAC9B,OAAS,aAAAC,MAAiB,kBAC1B,OAAS,aAAAC,MAAiB",
|
|
6
|
+
"names": ["DeepSeekLLM", "OpenRouterLLM", "OpenAILLM", "ClaudeLLM"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/providers/llm/adapters/openai/index.ts"],
|
|
4
|
+
"sourcesContent": ["export { OpenAILLM } from \"./openai\";\nexport type { OpenAIOptions } from \"./openai\";\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,aAAAA,MAAiB",
|
|
6
|
+
"names": ["OpenAILLM"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var a=Object.defineProperty;var o=(i,e)=>a(i,"name",{value:e,configurable:!0});import{openAICompatibleStream as r}from"../openai-compatible.js";class s{static{o(this,"OpenAILLM")}apiKey;model;baseUrl;fetchImpl;onTiming;idleTimeoutMs;onUsage;toolMode;streams=new Set;constructor(e){if(!e.apiKey)throw new Error("OpenAILLM requires an apiKey");this.apiKey=e.apiKey,this.model=e.model??"gpt-4o-mini",this.baseUrl=(e.baseUrl??"https://api.openai.com/v1").replace(/\/+$/,""),this.fetchImpl=e.fetch??fetch,this.onTiming=e.onTiming,this.idleTimeoutMs=e.idleTimeoutMs??8e3,this.onUsage=e.onUsage,this.toolMode=e.toolMode}stop(){for(const e of this.streams)e.abort()}async*stream(e){const t=new AbortController;this.streams.add(t);try{yield*r({baseUrl:this.baseUrl,apiKey:this.apiKey,model:this.model,fetchImpl:this.fetchImpl,request:e,signal:t.signal,label:"OpenAI",onTiming:this.onTiming,idleTimeoutMs:this.idleTimeoutMs,onUsage:this.onUsage,toolMode:this.toolMode})}finally{this.streams.delete(t)}}}export{s as OpenAILLM};
|
|
2
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/providers/llm/adapters/openai/openai.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n LLM,\n LLMEvent,\n LLMRequest,\n LLMStreamTimingCallback,\n LLMUsageCallback,\n ToolMode,\n} from \"../../types\";\nimport type { FetchLike } from \"../../../shared\";\nimport { openAICompatibleStream } from \"../openai-compatible\";\n\nexport interface OpenAIOptions {\n apiKey: string;\n /** Defaults to `gpt-4o-mini`. */\n model?: string;\n /** Defaults to `https://api.openai.com/v1`. */\n baseUrl?: string;\n /** Injectable fetch implementation, mainly for tests. */\n fetch?: FetchLike;\n /** Provider-timeline hook: request-start / headers / first-chunk. */\n onTiming?: LLMStreamTimingCallback;\n /**\n * Abort a stream that delivers no data for this long (default 8000ms) \u2014\n * protects against provider connections that go silent after the model\n * already produced its output. Raise it for providers with slow TTFT.\n */\n idleTimeoutMs?: number;\n /** Called with the provider-reported token usage (when included). */\n onUsage?: LLMUsageCallback;\n /**\n * Default tool encoding for requests that don't set `toolMode` (the\n * request's `toolMode` wins). For models whose endpoints lack native tool\n * calling.\n */\n toolMode?: ToolMode;\n}\n\n/**\n * OpenAI LLM adapter (OpenAI-compatible chat completions over SSE).\n */\nexport class OpenAILLM implements LLM {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly onTiming: LLMStreamTimingCallback | undefined;\n private readonly idleTimeoutMs: number;\n private readonly onUsage: LLMUsageCallback | undefined;\n private readonly toolMode: ToolMode | undefined;\n private readonly streams = new Set<AbortController>();\n\n constructor(options: OpenAIOptions) {\n if (!options.apiKey) {\n throw new Error(\"OpenAILLM requires an apiKey\");\n }\n this.apiKey = options.apiKey;\n this.model = options.model ?? \"gpt-4o-mini\";\n this.baseUrl = (options.baseUrl ?? \"https://api.openai.com/v1\").replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? fetch;\n this.onTiming = options.onTiming;\n this.idleTimeoutMs = options.idleTimeoutMs ?? 8_000;\n this.onUsage = options.onUsage;\n this.toolMode = options.toolMode;\n }\n\n /** Cancel every in-flight stream (parallel sub-generations included). */\n stop(): void {\n for (const controller of this.streams) controller.abort();\n }\n\n async *stream(request: LLMRequest): AsyncGenerator<LLMEvent> {\n // Multiple generations can stream concurrently (e.g. delegated\n // sub-agents); each gets its own controller, and stop() aborts them all.\n const controller = new AbortController();\n this.streams.add(controller);\n\n try {\n yield* openAICompatibleStream({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n model: this.model,\n fetchImpl: this.fetchImpl,\n request,\n signal: controller.signal,\n label: \"OpenAI\",\n onTiming: this.onTiming,\n idleTimeoutMs: this.idleTimeoutMs,\n onUsage: this.onUsage,\n toolMode: this.toolMode,\n });\n } finally {\n this.streams.delete(controller);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "+EASA,OAAS,0BAAAA,MAA8B,uBA+BhC,MAAMC,CAAyB,CAxCtC,MAwCsC,CAAAC,EAAA,kBACnB,OACA,MACA,QACA,UACA,SACA,cACA,QACA,SACA,QAAU,IAAI,IAE/B,YAAYC,EAAwB,CAClC,GAAI,CAACA,EAAQ,OACX,MAAM,IAAI,MAAM,8BAA8B,EAEhD,KAAK,OAASA,EAAQ,OACtB,KAAK,MAAQA,EAAQ,OAAS,cAC9B,KAAK,SAAWA,EAAQ,SAAW,6BAA6B,QAAQ,OAAQ,EAAE,EAClF,KAAK,UAAYA,EAAQ,OAAS,MAClC,KAAK,SAAWA,EAAQ,SACxB,KAAK,cAAgBA,EAAQ,eAAiB,IAC9C,KAAK,QAAUA,EAAQ,QACvB,KAAK,SAAWA,EAAQ,QAC1B,CAGA,MAAa,CACX,UAAWC,KAAc,KAAK,QAASA,EAAW,MAAM,CAC1D,CAEA,MAAO,OAAOC,EAA+C,CAG3D,MAAMD,EAAa,IAAI,gBACvB,KAAK,QAAQ,IAAIA,CAAU,EAE3B,GAAI,CACF,MAAOJ,EAAuB,CAC5B,QAAS,KAAK,QACd,OAAQ,KAAK,OACb,MAAO,KAAK,MACZ,UAAW,KAAK,UAChB,QAAAK,EACA,OAAQD,EAAW,OACnB,MAAO,SACP,SAAU,KAAK,SACf,cAAe,KAAK,cACpB,QAAS,KAAK,QACd,SAAU,KAAK,QACjB,CAAC,CACH,QAAE,CACA,KAAK,QAAQ,OAAOA,CAAU,CAChC,CACF,CACF",
|
|
6
|
+
"names": ["openAICompatibleStream", "OpenAILLM", "__name", "options", "controller", "request"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var U=Object.defineProperty;var d=(r,n)=>U(r,"name",{value:n,configurable:!0});function I(r){return{type:"object",properties:{answer:{type:"string",description:"Your spoken reply when no tool call is needed."},calls:{type:"array",description:"The tool calls to execute, when the request needs tools.",items:{type:"object",properties:{name:{type:"string",enum:r.map(n=>n.name)},arguments:{description:"The arguments for the named tool, per its schema.",oneOf:r.map(n=>n.parameters??{type:"object"})}},required:["name","arguments"],additionalProperties:!1}}}}}d(I,"buildEnvelopeSchema");function W(r){return`When the user's request requires a tool, respond with ONLY valid JSON matching this schema, with no prose and no markdown fences:
|
|
2
|
+
`+JSON.stringify(I(r))+`
|
|
3
|
+
The JSON must be either {"answer": "..."} or {"calls": [{"name": "...", "arguments": {...}}]}. When no tool is needed, respond in plain conversational text with no JSON.`}d(W,"promptedEnvelopeInstruction");function j(r){const n=r.trim();return n.startsWith("{")||n.startsWith("[")||/^```(?:json)?/i.test(n)}d(j,"looksLikeJsonAttempt");function P(r){const n=r.replace(/```(?:json)?/gi,"").replace(/^[^{]*/,"").replace(/[^}]*$/,"");if(n.length===0)return null;const e=n.indexOf("{"),a=n.lastIndexOf("}");return e===-1||a===-1||a<=e?null:n.slice(e,a+1)}d(P,"extractEnvelope");function Y(){const r="<thinking>",n="</thinking>";let e="",a=!1;const x=d((o,i)=>{const f=Math.min(o.length,i.length-1);for(let l=f;l>=1;l--)if(i.startsWith(o.slice(-l)))return l;return 0},"prefixTail");return{push(o){let i="",f="";for(e+=o;;){if(a){const c=e.indexOf(n);if(c!==-1){f+=e.slice(0,c),e=e.slice(c+n.length),a=!1;continue}const b=x(e,n);return f+=e.slice(0,e.length-b),e=e.slice(e.length-b),{text:i,reasoning:f}}const l=e.indexOf(r);if(l!==-1){i+=e.slice(0,l),e=e.slice(l+r.length),a=!0;continue}const p=x(e,r);return i+=e.slice(0,e.length-p),e=e.slice(e.length-p),{text:i,reasoning:f}}},flush(){let o="",i="";return a?i=e:e.length>0&&!r.startsWith(e)&&(o=e),e="",a=!1,{text:o,reasoning:i}}}}d(Y,"inlineThinking");function B(r){return`You have access to the following tools. When the user's request requires one, respond with ONLY the tool-call JSON envelope shown in the request \u2014 no prose, no markdown, no tool-call syntax. When no tool is needed, reply conversationally in plain text \u2014 no JSON at all.
|
|
4
|
+
|
|
5
|
+
Available tools:
|
|
6
|
+
`+r.map(e=>`- ${e.name}: ${e.description}`).join(`
|
|
7
|
+
`)}d(B,"buildToolContract");async function*G(r){const{baseUrl:n,apiKey:e,model:a,fetchImpl:x,request:o,signal:i,extraHeaders:f,extraBody:l,label:p,onTiming:c,idleTimeoutMs:b,onUsage:w}=r;c?.("request-start");const m=o.toolMode??r.toolMode??"native",u=m!=="native"&&(o.tools?.length??0)>0,g=u?B(o.tools):null,A=o.messages.findIndex(t=>t.role!=="system"),N=A===-1?o.messages.length:A,C=[];o.messages.forEach((t,s,L)=>{s===N&&g!==null&&C.push({role:"system",content:g});const y={role:t.role,content:t.content};t.name&&(y.name=t.name),t.toolCallId&&(y.tool_call_id=t.toolCallId),t.toolCalls&&(y.tool_calls=t.toolCalls.map(O=>({id:O.id,type:"function",function:{name:O.name,arguments:O.arguments}}))),m==="prompted"&&u&&s===L.length-1&&(y.content=`${t.content}
|
|
8
|
+
|
|
9
|
+
${W(o.tools)}`),C.push(y)}),N===o.messages.length&&g!==null&&C.push({role:"system",content:g});const T=await x(`${n}/chat/completions`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e}`,...f},body:JSON.stringify({model:a,messages:C,...!u&&o.tools&&o.tools.length>0?{tools:o.tools.map(t=>({type:"function",function:t}))}:{},...u&&m==="envelope"?{response_format:{type:"json_schema",json_schema:{name:"tool_envelope",strict:!1,schema:I(o.tools)}}}:{},stream:!0,temperature:o.temperature,max_tokens:o.maxTokens,stream_options:{include_usage:!0},...l}),signal:i});if(!T.ok){const t=await T.text();throw new Error(`${p} request failed (${T.status}): ${t}`)}if(!T.body)throw new Error(`${p} returned an empty body`);c?.("headers");const _=new Map;let M=!1,v=0,J=!1,q=!1,k="";const D=Y();for await(const t of F(T.body,i,c,b,p)){const s=t.choices?.[0];if(t.error){yield{type:"error",error:new Error(`${p} provider aborted the stream: ${t.error.message??JSON.stringify(t.error)}`)};break}if(t.usage&&(t.usage.prompt_tokens??0)>0&&(J=!0,v=0,w?.({promptTokens:t.usage.prompt_tokens??0,completionTokens:t.usage.completion_tokens??0})),!s)continue;const L=s.delta,y=D.push(L?.content??""),$=(L?.reasoning??L?.reasoning_content??"")+y.reasoning;u?k+=y.text:(y.text.length>0||$.length>0)&&(yield{type:"delta",content:y.text,...$.length>0?{reasoning:$}:{}});for(const h of L?.tool_calls??[]){const R=h.index??0,S=_.get(R)??{id:"",name:"",arguments:""};h.id&&(S.id=h.id),h.function?.name&&(S.name+=h.function.name),h.function?.arguments&&(S.arguments+=h.function.arguments),_.set(R,S)}if(s.finish_reason==="tool_calls"&&!q){for(const h of _.values())yield{type:"tool_call",id:h.id,name:h.name,arguments:h.arguments};q=!0,M=!0}else if(s.finish_reason==="stop")M=!0;else if(s.finish_reason==="error"||s.finish_reason==="content_filter"){yield{type:"error",error:new Error(`${p} stream finished with "${s.finish_reason}"`+(_.size>0?"":" and produced no output"))};break}if(M&&(J||(v===0&&(v=Date.now()),Date.now()-v>500)))break}const E=D.flush();if(E.text&&(u?k+=E.text:yield{type:"delta",content:E.text}),u){let t;try{t=JSON.parse(k)}catch{const s=P(k);if(s!==null)try{t=JSON.parse(s)}catch{t=void 0}if(t===void 0)try{t=JSON.parse(`{${k}`)}catch{t=void 0}}if(t===void 0)if(m==="prompted"&&!j(k)){const s=k.trim();s.length>0&&(yield{type:"delta",content:s})}else yield{type:"error",error:new Error(`${p} ${m} tool mode: model did not return a JSON envelope (${k.slice(0,120)})`)};else{typeof t.answer=="string"&&t.answer.length>0&&(yield{type:"delta",content:t.answer});for(const s of t.calls??[])typeof s.name=="string"&&(yield{type:"tool_call",id:crypto.randomUUID(),name:s.name,arguments:JSON.stringify(s.arguments??{})})}}yield{type:"done"}}d(G,"openAICompatibleStream");async function*F(r,n,e,a=8e3,x="LLM"){const o=r.getReader(),i=new TextDecoder;let f="",l=!1;const p=d(()=>{let c;return new Promise((b,w)=>{const m=d(()=>{c!==void 0&&clearTimeout(c),n.removeEventListener("abort",u)},"cleanup"),u=d(()=>{m(),w(new DOMException("The operation was aborted.","AbortError"))},"onAbort");o.read().then(g=>{m(),b(g)},g=>{m(),w(g)}),c=setTimeout(()=>{m(),o.cancel().catch(()=>{}),w(new Error(`${x} stream idle for ${a}ms \u2014 no data received; aborting the stalled stream`))},a),n.addEventListener("abort",u,{once:!0})})},"readWithTimeout");for(;;){if(n.aborted)throw new DOMException("The operation was aborted.","AbortError");const{done:c,value:b}=await p();if(c)break;f+=i.decode(b,{stream:!0});const w=f.split(/\r?\n\r?\n/);f=w.pop()??"";for(const m of w)for(const u of m.split(/\r?\n/)){if(!u.startsWith("data:"))continue;const g=u.slice(5).trim();if(g==="[DONE]")return;l||(l=!0,e?.("first-chunk"));try{yield JSON.parse(g)}catch{}}}}d(F,"parseSSE");export{G as openAICompatibleStream};
|
|
10
|
+
//# sourceMappingURL=openai-compatible.js.map
|