@falai/agent 2.2.4 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/adapters/MemoryAdapter.d.ts.map +1 -1
- package/dist/adapters/MemoryAdapter.js +10 -1
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.d.ts.map +1 -1
- package/dist/adapters/MongoAdapter.js +33 -2
- package/dist/adapters/MongoAdapter.js.map +1 -1
- package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenSearchAdapter.js +15 -1
- package/dist/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +35 -5
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.d.ts.map +1 -1
- package/dist/adapters/PrismaAdapter.js +58 -15
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.d.ts.map +1 -1
- package/dist/adapters/RedisAdapter.js +10 -1
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +38 -6
- package/dist/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +10 -1
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +33 -2
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js +15 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +35 -5
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +58 -15
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +10 -1
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +38 -6
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/core/Agent.d.ts +28 -18
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +58 -68
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.js +14 -20
- package/dist/cjs/core/AutoChainExecutor.js.map +1 -1
- package/dist/cjs/core/BranchEvaluator.d.ts +4 -3
- package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -1
- package/dist/cjs/core/BranchEvaluator.js +18 -23
- package/dist/cjs/core/BranchEvaluator.js.map +1 -1
- package/dist/cjs/core/Flow.d.ts +2 -1
- package/dist/cjs/core/Flow.d.ts.map +1 -1
- package/dist/cjs/core/Flow.js +10 -3
- package/dist/cjs/core/Flow.js.map +1 -1
- package/dist/cjs/core/FlowRouter.d.ts +1 -0
- package/dist/cjs/core/FlowRouter.d.ts.map +1 -1
- package/dist/cjs/core/FlowRouter.js +28 -5
- package/dist/cjs/core/FlowRouter.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +3 -0
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +57 -5
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/core/PromptComposer.js +24 -10
- package/dist/cjs/core/PromptComposer.js.map +1 -1
- package/dist/cjs/core/ResponseGenerationError.d.ts +30 -0
- package/dist/cjs/core/ResponseGenerationError.d.ts.map +1 -0
- package/dist/cjs/core/ResponseGenerationError.js +37 -0
- package/dist/cjs/core/ResponseGenerationError.js.map +1 -0
- package/dist/cjs/core/ResponseModal.d.ts +43 -102
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +178 -1194
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +58 -152
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/core/ResponsePipeline.js +408 -457
- package/dist/cjs/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/core/SessionFinalizer.d.ts +34 -0
- package/dist/cjs/core/SessionFinalizer.d.ts.map +1 -0
- package/dist/cjs/core/SessionFinalizer.js +61 -0
- package/dist/cjs/core/SessionFinalizer.js.map +1 -0
- package/dist/cjs/core/SessionManager.d.ts +1 -1
- package/dist/cjs/core/SessionManager.d.ts.map +1 -1
- package/dist/cjs/core/SessionManager.js +18 -7
- package/dist/cjs/core/SessionManager.js.map +1 -1
- package/dist/cjs/core/SignalCoordinator.d.ts +103 -0
- package/dist/cjs/core/SignalCoordinator.d.ts.map +1 -0
- package/dist/cjs/core/SignalCoordinator.js +207 -0
- package/dist/cjs/core/SignalCoordinator.js.map +1 -0
- package/dist/cjs/core/SignalEvaluator.d.ts +2 -2
- package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -1
- package/dist/cjs/core/SignalEvaluator.js +11 -26
- package/dist/cjs/core/SignalEvaluator.js.map +1 -1
- package/dist/cjs/core/SignalProcessor.d.ts.map +1 -1
- package/dist/cjs/core/SignalProcessor.js +28 -11
- package/dist/cjs/core/SignalProcessor.js.map +1 -1
- package/dist/cjs/core/Step.d.ts +3 -1
- package/dist/cjs/core/Step.d.ts.map +1 -1
- package/dist/cjs/core/Step.js +10 -3
- package/dist/cjs/core/Step.js.map +1 -1
- package/dist/cjs/core/StepLifecycle.d.ts +33 -0
- package/dist/cjs/core/StepLifecycle.d.ts.map +1 -0
- package/dist/cjs/core/StepLifecycle.js +97 -0
- package/dist/cjs/core/StepLifecycle.js.map +1 -0
- package/dist/cjs/core/ToolLoopExecutor.d.ts +104 -0
- package/dist/cjs/core/ToolLoopExecutor.d.ts.map +1 -0
- package/dist/cjs/core/ToolLoopExecutor.js +391 -0
- package/dist/cjs/core/ToolLoopExecutor.js.map +1 -0
- package/dist/cjs/core/ToolManager.d.ts +1 -1
- package/dist/cjs/core/ToolManager.d.ts.map +1 -1
- package/dist/cjs/core/ToolManager.js.map +1 -1
- package/dist/cjs/index.d.ts +4 -5
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -6
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts +2 -0
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +28 -56
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.d.ts +25 -21
- package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.js +48 -407
- package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +2 -0
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +27 -56
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +129 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.js +485 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -0
- package/dist/cjs/providers/OpenAIProvider.d.ts +9 -28
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +23 -417
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts +10 -27
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +28 -417
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/providers/errorClassification.d.ts +61 -0
- package/dist/cjs/providers/errorClassification.d.ts.map +1 -0
- package/dist/cjs/providers/errorClassification.js +123 -0
- package/dist/cjs/providers/errorClassification.js.map +1 -0
- package/dist/cjs/providers/index.d.ts +4 -0
- package/dist/cjs/providers/index.d.ts.map +1 -1
- package/dist/cjs/providers/index.js +7 -1
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +2 -1
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +20 -0
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +33 -0
- package/dist/cjs/types/errors.d.ts.map +1 -1
- package/dist/cjs/types/errors.js +37 -1
- package/dist/cjs/types/errors.js.map +1 -1
- package/dist/cjs/types/flow.d.ts +10 -5
- package/dist/cjs/types/flow.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +1 -1
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +5 -4
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +3 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/persistence.d.ts +43 -2
- package/dist/cjs/types/persistence.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +8 -0
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/signals.d.ts +18 -2
- package/dist/cjs/types/signals.d.ts.map +1 -1
- package/dist/cjs/types/template.d.ts +3 -1
- package/dist/cjs/types/template.d.ts.map +1 -1
- package/dist/cjs/types/tool.d.ts +4 -4
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/utils/condition.d.ts +19 -0
- package/dist/cjs/utils/condition.d.ts.map +1 -1
- package/dist/cjs/utils/condition.js +86 -15
- package/dist/cjs/utils/condition.js.map +1 -1
- package/dist/cjs/utils/session.d.ts +1 -0
- package/dist/cjs/utils/session.d.ts.map +1 -1
- package/dist/cjs/utils/session.js +1 -0
- package/dist/cjs/utils/session.js.map +1 -1
- package/dist/core/Agent.d.ts +28 -18
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +58 -68
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/AutoChainExecutor.d.ts.map +1 -1
- package/dist/core/AutoChainExecutor.js +14 -20
- package/dist/core/AutoChainExecutor.js.map +1 -1
- package/dist/core/BranchEvaluator.d.ts +4 -3
- package/dist/core/BranchEvaluator.d.ts.map +1 -1
- package/dist/core/BranchEvaluator.js +18 -23
- package/dist/core/BranchEvaluator.js.map +1 -1
- package/dist/core/Flow.d.ts +2 -1
- package/dist/core/Flow.d.ts.map +1 -1
- package/dist/core/Flow.js +10 -3
- package/dist/core/Flow.js.map +1 -1
- package/dist/core/FlowRouter.d.ts +1 -0
- package/dist/core/FlowRouter.d.ts.map +1 -1
- package/dist/core/FlowRouter.js +28 -5
- package/dist/core/FlowRouter.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +3 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +58 -6
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts.map +1 -1
- package/dist/core/PromptComposer.js +24 -10
- package/dist/core/PromptComposer.js.map +1 -1
- package/dist/core/ResponseGenerationError.d.ts +30 -0
- package/dist/core/ResponseGenerationError.d.ts.map +1 -0
- package/dist/core/ResponseGenerationError.js +33 -0
- package/dist/core/ResponseGenerationError.js.map +1 -0
- package/dist/core/ResponseModal.d.ts +43 -102
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +171 -1186
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/ResponsePipeline.d.ts +58 -152
- package/dist/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/core/ResponsePipeline.js +409 -458
- package/dist/core/ResponsePipeline.js.map +1 -1
- package/dist/core/SessionFinalizer.d.ts +34 -0
- package/dist/core/SessionFinalizer.d.ts.map +1 -0
- package/dist/core/SessionFinalizer.js +57 -0
- package/dist/core/SessionFinalizer.js.map +1 -0
- package/dist/core/SessionManager.d.ts +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +18 -7
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SignalCoordinator.d.ts +103 -0
- package/dist/core/SignalCoordinator.d.ts.map +1 -0
- package/dist/core/SignalCoordinator.js +203 -0
- package/dist/core/SignalCoordinator.js.map +1 -0
- package/dist/core/SignalEvaluator.d.ts +2 -2
- package/dist/core/SignalEvaluator.d.ts.map +1 -1
- package/dist/core/SignalEvaluator.js +11 -26
- package/dist/core/SignalEvaluator.js.map +1 -1
- package/dist/core/SignalProcessor.d.ts.map +1 -1
- package/dist/core/SignalProcessor.js +28 -11
- package/dist/core/SignalProcessor.js.map +1 -1
- package/dist/core/Step.d.ts +3 -1
- package/dist/core/Step.d.ts.map +1 -1
- package/dist/core/Step.js +10 -3
- package/dist/core/Step.js.map +1 -1
- package/dist/core/StepLifecycle.d.ts +33 -0
- package/dist/core/StepLifecycle.d.ts.map +1 -0
- package/dist/core/StepLifecycle.js +93 -0
- package/dist/core/StepLifecycle.js.map +1 -0
- package/dist/core/ToolLoopExecutor.d.ts +104 -0
- package/dist/core/ToolLoopExecutor.d.ts.map +1 -0
- package/dist/core/ToolLoopExecutor.js +387 -0
- package/dist/core/ToolLoopExecutor.js.map +1 -0
- package/dist/core/ToolManager.d.ts +1 -1
- package/dist/core/ToolManager.d.ts.map +1 -1
- package/dist/core/ToolManager.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +2 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +22 -50
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/DeepSeekProvider.d.ts +25 -21
- package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/DeepSeekProvider.js +49 -408
- package/dist/providers/DeepSeekProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +2 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +21 -50
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.d.ts +129 -0
- package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/dist/providers/OpenAICompatibleProvider.js +481 -0
- package/dist/providers/OpenAICompatibleProvider.js.map +1 -0
- package/dist/providers/OpenAIProvider.d.ts +9 -28
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +23 -417
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +10 -27
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +28 -417
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/providers/errorClassification.d.ts +61 -0
- package/dist/providers/errorClassification.d.ts.map +1 -0
- package/dist/providers/errorClassification.js +116 -0
- package/dist/providers/errorClassification.js.map +1 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/types/agent.d.ts +2 -1
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +20 -0
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/errors.d.ts +33 -0
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +34 -0
- package/dist/types/errors.js.map +1 -1
- package/dist/types/flow.d.ts +10 -5
- package/dist/types/flow.d.ts.map +1 -1
- package/dist/types/history.d.ts +1 -1
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/persistence.d.ts +43 -2
- package/dist/types/persistence.d.ts.map +1 -1
- package/dist/types/session.d.ts +8 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/signals.d.ts +18 -2
- package/dist/types/signals.d.ts.map +1 -1
- package/dist/types/template.d.ts +3 -1
- package/dist/types/template.d.ts.map +1 -1
- package/dist/types/tool.d.ts +4 -4
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/condition.d.ts +19 -0
- package/dist/utils/condition.d.ts.map +1 -1
- package/dist/utils/condition.js +84 -15
- package/dist/utils/condition.js.map +1 -1
- package/dist/utils/session.d.ts +1 -0
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +1 -0
- package/dist/utils/session.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/guides/branching.md +1 -1
- package/docs/guides/compaction.md +12 -5
- package/docs/guides/conditions.md +15 -2
- package/docs/guides/error-handling.md +59 -9
- package/docs/guides/instructions.md +2 -2
- package/docs/guides/persistence.md +69 -2
- package/docs/guides/streaming.md +2 -0
- package/docs/migration/README.md +5 -1
- package/docs/migration/v2-3-to-v2-4.md +316 -0
- package/docs/reference/adapters.md +55 -7
- package/docs/reference/branches.md +2 -2
- package/docs/reference/create-agent.md +3 -3
- package/docs/reference/errors.md +66 -1
- package/docs/reference/flow.md +1 -1
- package/docs/reference/instruction.md +4 -4
- package/docs/reference/providers.md +100 -3
- package/docs/reference/signals.md +14 -3
- package/docs/reference/step.md +2 -2
- package/docs/reference/tool.md +3 -1
- package/docs/start/05-go-to-production.md +3 -0
- package/package.json +1 -1
- package/src/adapters/MemoryAdapter.ts +15 -1
- package/src/adapters/MongoAdapter.ts +41 -2
- package/src/adapters/OpenSearchAdapter.ts +24 -1
- package/src/adapters/PostgreSQLAdapter.ts +45 -5
- package/src/adapters/PrismaAdapter.ts +82 -16
- package/src/adapters/RedisAdapter.ts +19 -1
- package/src/adapters/SQLiteAdapter.ts +47 -5
- package/src/core/Agent.ts +70 -85
- package/src/core/AutoChainExecutor.ts +27 -57
- package/src/core/BranchEvaluator.ts +24 -30
- package/src/core/Flow.ts +10 -3
- package/src/core/FlowRouter.ts +36 -4
- package/src/core/PersistenceManager.ts +79 -10
- package/src/core/PromptComposer.ts +25 -12
- package/src/core/ResponseGenerationError.ts +56 -0
- package/src/core/ResponseModal.ts +233 -1482
- package/src/core/ResponsePipeline.ts +492 -662
- package/src/core/SessionFinalizer.ts +78 -0
- package/src/core/SessionManager.ts +21 -9
- package/src/core/SignalCoordinator.ts +263 -0
- package/src/core/SignalEvaluator.ts +12 -29
- package/src/core/SignalProcessor.ts +34 -11
- package/src/core/Step.ts +11 -3
- package/src/core/StepLifecycle.ts +139 -0
- package/src/core/ToolLoopExecutor.ts +492 -0
- package/src/core/ToolManager.ts +2 -1
- package/src/index.ts +7 -5
- package/src/providers/AnthropicProvider.ts +30 -72
- package/src/providers/DeepSeekProvider.ts +74 -586
- package/src/providers/GeminiProvider.ts +29 -70
- package/src/providers/OpenAICompatibleProvider.ts +738 -0
- package/src/providers/OpenAIProvider.ts +29 -602
- package/src/providers/OpenRouterProvider.ts +38 -596
- package/src/providers/errorClassification.ts +172 -0
- package/src/providers/index.ts +13 -0
- package/src/types/agent.ts +2 -1
- package/src/types/ai.ts +22 -0
- package/src/types/errors.ts +57 -0
- package/src/types/flow.ts +10 -5
- package/src/types/history.ts +1 -2
- package/src/types/index.ts +5 -1
- package/src/types/persistence.ts +50 -2
- package/src/types/session.ts +9 -0
- package/src/types/signals.ts +20 -2
- package/src/types/template.ts +3 -1
- package/src/types/tool.ts +10 -10
- package/src/utils/condition.ts +115 -18
- package/src/utils/session.ts +2 -0
|
@@ -4,24 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import OpenAI from "openai";
|
|
7
|
-
import type { ChatCompletionCreateParamsNonStreaming } from "openai/resources/chat/completions";
|
|
8
|
-
import { FunctionParameters } from "openai/resources/shared.mjs";
|
|
9
7
|
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
StructuredSchema,
|
|
17
|
-
} from "../types";
|
|
18
|
-
import type { HistoryItem } from "../types/history";
|
|
19
|
-
import { withTimeoutAndRetry, logger } from "../utils";
|
|
20
|
-
|
|
21
|
-
const DEFAULT_RETRY_CONFIG = {
|
|
22
|
-
timeout: 60000,
|
|
23
|
-
retries: 3,
|
|
24
|
-
};
|
|
8
|
+
import type { ProviderCapabilities } from "../types/ai";
|
|
9
|
+
import type { ErrorClassificationOptions } from "./errorClassification";
|
|
10
|
+
import {
|
|
11
|
+
OpenAICompatibleProvider,
|
|
12
|
+
type OpenAICompatibleRequestConfig,
|
|
13
|
+
} from "./OpenAICompatibleProvider";
|
|
25
14
|
|
|
26
15
|
/**
|
|
27
16
|
* Configuration options for OpenRouter provider
|
|
@@ -39,9 +28,7 @@ export interface OpenRouterProviderOptions {
|
|
|
39
28
|
/** Optional app name for OpenRouter rankings */
|
|
40
29
|
siteName?: string;
|
|
41
30
|
/** Default parameters - uses ChatCompletionCreateParamsNonStreaming from openai package */
|
|
42
|
-
config?:
|
|
43
|
-
Omit<ChatCompletionCreateParamsNonStreaming, "model" | "messages">
|
|
44
|
-
>;
|
|
31
|
+
config?: OpenAICompatibleRequestConfig;
|
|
45
32
|
/** Retry configuration */
|
|
46
33
|
retryConfig?: {
|
|
47
34
|
timeout?: number;
|
|
@@ -49,96 +36,35 @@ export interface OpenRouterProviderOptions {
|
|
|
49
36
|
};
|
|
50
37
|
}
|
|
51
38
|
|
|
52
|
-
/**
|
|
53
|
-
* Type guard for errors with status/code properties
|
|
54
|
-
*/
|
|
55
|
-
interface ErrorWithStatus {
|
|
56
|
-
status?: number;
|
|
57
|
-
code?: string;
|
|
58
|
-
message?: string;
|
|
59
|
-
type?: string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Type guard to check if error is ErrorWithStatus
|
|
64
|
-
*/
|
|
65
|
-
function isErrorWithStatus(error: unknown): error is ErrorWithStatus {
|
|
66
|
-
return (
|
|
67
|
-
typeof error === "object" &&
|
|
68
|
-
error !== null &&
|
|
69
|
-
("status" in error || "code" in error || "message" in error)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Safely extract error message
|
|
75
|
-
*/
|
|
76
|
-
function getErrorMessage(error: unknown): string {
|
|
77
|
-
if (error instanceof Error) {
|
|
78
|
-
return error.message;
|
|
79
|
-
}
|
|
80
|
-
if (isErrorWithStatus(error) && error.message) {
|
|
81
|
-
return error.message;
|
|
82
|
-
}
|
|
83
|
-
return String(error);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Determines if an error should trigger backup model usage
|
|
88
|
-
*/
|
|
89
|
-
const shouldUseBackupModel = (error: unknown): boolean => {
|
|
90
|
-
if (!isErrorWithStatus(error)) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Server errors
|
|
95
|
-
if (error.status === 500 || error.status === 503) {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Rate limiting
|
|
100
|
-
if (error.status === 429) {
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Model not available or overloaded
|
|
105
|
-
if (error.code === "model_not_found" || error.code === "model_overloaded") {
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const message = getErrorMessage(error);
|
|
110
|
-
if (
|
|
111
|
-
message.includes("overloaded") ||
|
|
112
|
-
message.includes("unavailable") ||
|
|
113
|
-
message.includes("internal error") ||
|
|
114
|
-
message.includes("Internal error") ||
|
|
115
|
-
message.includes("capacity")
|
|
116
|
-
) {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return false;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
39
|
/**
|
|
124
40
|
* OpenRouter provider implementation
|
|
125
41
|
* Provides access to multiple AI models through OpenRouter's unified API
|
|
126
42
|
*/
|
|
127
|
-
export class OpenRouterProvider
|
|
43
|
+
export class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
128
44
|
public readonly name = "openrouter";
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
45
|
+
public readonly capabilities: ProviderCapabilities = {
|
|
46
|
+
supportsTools: true,
|
|
47
|
+
supportsNativeJsonSchema: true,
|
|
48
|
+
supportsStreaming: true,
|
|
49
|
+
supportsStreamingToolCalls: true,
|
|
50
|
+
supportsPromptCaching: false,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
protected readonly logLabel = "OPENROUTER";
|
|
54
|
+
protected readonly displayName = "OpenRouter";
|
|
55
|
+
|
|
56
|
+
/** OpenRouter additionally reports capacity issues in error messages */
|
|
57
|
+
protected override readonly classificationOptions: ErrorClassificationOptions =
|
|
58
|
+
{
|
|
59
|
+
overloadedCodes: ["model_not_found", "model_overloaded"],
|
|
60
|
+
overloadedMessages: ["capacity"],
|
|
61
|
+
};
|
|
136
62
|
|
|
137
63
|
constructor(options: OpenRouterProviderOptions) {
|
|
138
64
|
const {
|
|
139
65
|
apiKey,
|
|
140
66
|
model,
|
|
141
|
-
backupModels
|
|
67
|
+
backupModels,
|
|
142
68
|
siteUrl,
|
|
143
69
|
siteName,
|
|
144
70
|
config,
|
|
@@ -154,503 +80,19 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
154
80
|
}
|
|
155
81
|
|
|
156
82
|
// Initialize OpenAI client with OpenRouter base URL
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
this.primaryModel = model;
|
|
167
|
-
this.backupModels = backupModels;
|
|
168
|
-
this.config = config;
|
|
169
|
-
this.retryConfig = {
|
|
170
|
-
timeout: retryConfig?.timeout || DEFAULT_RETRY_CONFIG.timeout,
|
|
171
|
-
retries: retryConfig?.retries || DEFAULT_RETRY_CONFIG.retries,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Build OpenRouter-formatted messages from HistoryItem[] array.
|
|
177
|
-
* OpenRouter uses OpenAI-compatible format.
|
|
178
|
-
*/
|
|
179
|
-
private buildOpenRouterMessages(history: HistoryItem[]): Array<unknown> {
|
|
180
|
-
const messages: Array<unknown> = [];
|
|
181
|
-
|
|
182
|
-
for (const item of history) {
|
|
183
|
-
switch (item.role) {
|
|
184
|
-
case "system":
|
|
185
|
-
messages.push({ role: "system", content: item.content });
|
|
186
|
-
break;
|
|
187
|
-
case "user":
|
|
188
|
-
messages.push({ role: "user", content: item.content });
|
|
189
|
-
break;
|
|
190
|
-
case "assistant":
|
|
191
|
-
if (item.tool_calls && item.tool_calls.length > 0) {
|
|
192
|
-
messages.push({
|
|
193
|
-
role: "assistant",
|
|
194
|
-
content: item.content || null,
|
|
195
|
-
tool_calls: item.tool_calls.map(tc => ({
|
|
196
|
-
id: tc.id,
|
|
197
|
-
type: "function",
|
|
198
|
-
function: {
|
|
199
|
-
name: tc.name,
|
|
200
|
-
arguments: JSON.stringify(tc.arguments),
|
|
201
|
-
},
|
|
202
|
-
})),
|
|
203
|
-
});
|
|
204
|
-
} else {
|
|
205
|
-
messages.push({ role: "assistant", content: item.content || "" });
|
|
206
|
-
}
|
|
207
|
-
break;
|
|
208
|
-
case "tool":
|
|
209
|
-
messages.push({
|
|
210
|
-
role: "tool",
|
|
211
|
-
tool_call_id: item.tool_call_id,
|
|
212
|
-
content: typeof item.content === "string" ? item.content : JSON.stringify(item.content),
|
|
213
|
-
});
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return messages;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Adapt common schema format to OpenRouter's format.
|
|
223
|
-
* OpenRouter is OpenAI-compatible and uses standard JSON Schema.
|
|
224
|
-
*
|
|
225
|
-
* @private
|
|
226
|
-
*/
|
|
227
|
-
private adaptSchemaForOpenRouter(
|
|
228
|
-
schema: StructuredSchema
|
|
229
|
-
): Record<string, unknown> {
|
|
230
|
-
// OpenRouter is OpenAI-compatible and uses standard JSON Schema
|
|
231
|
-
// Our StructuredSchema is already JSON Schema compatible
|
|
232
|
-
return schema as Record<string, unknown>;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
async generateMessage<
|
|
236
|
-
TContext = unknown,
|
|
237
|
-
TStructured = AgentStructuredResponse
|
|
238
|
-
>(
|
|
239
|
-
input: GenerateMessageInput<TContext>
|
|
240
|
-
): Promise<GenerateMessageOutput<TStructured>> {
|
|
241
|
-
return this.generateWithBackup<TContext, TStructured>(input);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async *generateMessageStream<
|
|
245
|
-
TContext = unknown,
|
|
246
|
-
TStructured = AgentStructuredResponse
|
|
247
|
-
>(
|
|
248
|
-
input: GenerateMessageInput<TContext>
|
|
249
|
-
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
250
|
-
yield* this.generateStreamWithBackup<TContext, TStructured>(input);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private async generateWithBackup<
|
|
254
|
-
TContext = unknown,
|
|
255
|
-
TStructured = AgentStructuredResponse
|
|
256
|
-
>(
|
|
257
|
-
input: GenerateMessageInput<TContext>
|
|
258
|
-
): Promise<GenerateMessageOutput<TStructured>> {
|
|
259
|
-
// Try primary model first
|
|
260
|
-
try {
|
|
261
|
-
return await this.generateWithModel(this.primaryModel, input);
|
|
262
|
-
} catch (primaryError: unknown) {
|
|
263
|
-
const primaryErrMsg = getErrorMessage(primaryError);
|
|
264
|
-
logger.warn(
|
|
265
|
-
`[OPENROUTER] Primary model ${this.primaryModel} failed: ${primaryErrMsg}`
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
if (!shouldUseBackupModel(primaryError)) {
|
|
269
|
-
throw primaryError;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
logger.debug(`[OPENROUTER] Trying backup models`);
|
|
273
|
-
|
|
274
|
-
let lastBackupError: unknown = primaryError;
|
|
275
|
-
|
|
276
|
-
for (let i = 0; i < this.backupModels.length; i++) {
|
|
277
|
-
const backupModel = this.backupModels[i];
|
|
278
|
-
logger.debug(
|
|
279
|
-
`[OPENROUTER] Trying backup model ${i + 1}/${this.backupModels.length
|
|
280
|
-
}: ${backupModel}`
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
try {
|
|
284
|
-
const result = await this.generateWithModel(backupModel, input);
|
|
285
|
-
logger.debug(`[OPENROUTER] Backup model ${backupModel} succeeded`);
|
|
286
|
-
return result as GenerateMessageOutput<TStructured>;
|
|
287
|
-
} catch (backupError: unknown) {
|
|
288
|
-
const backupErrMsg = getErrorMessage(backupError);
|
|
289
|
-
logger.warn(
|
|
290
|
-
`[OPENROUTER] Backup model ${backupModel} failed: ${backupErrMsg}`
|
|
291
|
-
);
|
|
292
|
-
lastBackupError = backupError;
|
|
293
|
-
|
|
294
|
-
if (
|
|
295
|
-
!shouldUseBackupModel(backupError) &&
|
|
296
|
-
i < this.backupModels.length - 1
|
|
297
|
-
) {
|
|
298
|
-
logger.debug(
|
|
299
|
-
`[OPENROUTER] Backup model error doesn't qualify for further attempts`
|
|
300
|
-
);
|
|
301
|
-
break;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const lastBackupErrMsg = getErrorMessage(lastBackupError);
|
|
307
|
-
logger.error(
|
|
308
|
-
`[OPENROUTER] All models failed. Primary: ${primaryErrMsg}, Last backup: ${lastBackupErrMsg}`
|
|
309
|
-
);
|
|
310
|
-
throw lastBackupError;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private async generateWithModel<
|
|
315
|
-
TContext = unknown,
|
|
316
|
-
TStructured = AgentStructuredResponse
|
|
317
|
-
>(
|
|
318
|
-
model: string,
|
|
319
|
-
input: GenerateMessageInput<TContext>
|
|
320
|
-
): Promise<GenerateMessageOutput<TStructured>> {
|
|
321
|
-
const operation = async (): Promise<GenerateMessageOutput> => {
|
|
322
|
-
const historyMessages = this.buildOpenRouterMessages(input.history);
|
|
323
|
-
historyMessages.push({ role: "user", content: input.prompt });
|
|
324
|
-
|
|
325
|
-
const params: ChatCompletionCreateParamsNonStreaming = {
|
|
326
|
-
model,
|
|
327
|
-
messages: historyMessages as ChatCompletionCreateParamsNonStreaming["messages"],
|
|
328
|
-
...this.config,
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// Override with input parameters if provided
|
|
332
|
-
if (input.parameters?.maxOutputTokens !== undefined) {
|
|
333
|
-
params.max_tokens = input.parameters.maxOutputTokens;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Add tools if provided
|
|
337
|
-
if (input.tools && input.tools.length > 0) {
|
|
338
|
-
params.tools = input.tools.map((tool) => ({
|
|
339
|
-
type: "function" as const,
|
|
340
|
-
function: {
|
|
341
|
-
name: tool.name || tool.id,
|
|
342
|
-
description: tool.description,
|
|
343
|
-
parameters: tool.parameters as FunctionParameters, // JSON schema
|
|
344
|
-
},
|
|
345
|
-
}));
|
|
346
|
-
params.tool_choice = "auto";
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Use structured output API if JSON schema is provided
|
|
350
|
-
if (input.parameters?.jsonSchema) {
|
|
351
|
-
const response = await this.client.responses.parse({
|
|
352
|
-
model,
|
|
353
|
-
instructions: input.prompt,
|
|
354
|
-
input: "",
|
|
355
|
-
reasoning: {
|
|
356
|
-
effort: input.parameters?.reasoning?.effort || "low",
|
|
357
|
-
},
|
|
358
|
-
text: {
|
|
359
|
-
format: {
|
|
360
|
-
type: "json_schema",
|
|
361
|
-
name: input.parameters?.schemaName || "structured_output",
|
|
362
|
-
// Adapt common schema format to OpenRouter's format
|
|
363
|
-
schema: this.adaptSchemaForOpenRouter(
|
|
364
|
-
input.parameters.jsonSchema
|
|
365
|
-
),
|
|
366
|
-
},
|
|
367
|
-
},
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
if (!response.output_parsed) {
|
|
371
|
-
throw new Error("No parsed output returned from OpenRouter");
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
const structured = response.output_parsed as AgentStructuredResponse;
|
|
375
|
-
const message = structured.message;
|
|
376
|
-
|
|
377
|
-
return {
|
|
378
|
-
message,
|
|
379
|
-
metadata: {
|
|
380
|
-
model: response.model,
|
|
381
|
-
tokensUsed: response.usage?.total_tokens,
|
|
382
|
-
promptTokens: response.usage?.input_tokens,
|
|
383
|
-
completionTokens: response.usage?.output_tokens,
|
|
384
|
-
},
|
|
385
|
-
structured,
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// Fall back to regular chat completions API if no schema provided
|
|
390
|
-
const response = await this.client.chat.completions.create(params);
|
|
391
|
-
|
|
392
|
-
const message = response.choices[0]?.message?.content || "";
|
|
393
|
-
|
|
394
|
-
let toolCalls: Array<{
|
|
395
|
-
toolName: string;
|
|
396
|
-
arguments: Record<string, unknown>;
|
|
397
|
-
}> = [];
|
|
398
|
-
if (response.choices?.[0]?.message?.tool_calls) {
|
|
399
|
-
toolCalls = response.choices[0].message.tool_calls
|
|
400
|
-
.filter((toolCall) => toolCall.type === "function")
|
|
401
|
-
.map((toolCall) => {
|
|
402
|
-
let toolCallArguments: Record<string, unknown> = {};
|
|
403
|
-
try {
|
|
404
|
-
toolCallArguments = JSON.parse(
|
|
405
|
-
toolCall.function.arguments
|
|
406
|
-
) as Record<string, unknown>;
|
|
407
|
-
} catch (error) {
|
|
408
|
-
logger.warn(
|
|
409
|
-
`[OPENROUTER] Failed to parse tool call arguments: ${getErrorMessage(
|
|
410
|
-
error
|
|
411
|
-
)}`
|
|
412
|
-
);
|
|
413
|
-
toolCallArguments = {};
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
toolName: toolCall.function.name,
|
|
417
|
-
arguments: toolCallArguments,
|
|
418
|
-
};
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Only throw error if we have no text AND no function calls
|
|
423
|
-
if (!message && toolCalls.length === 0) {
|
|
424
|
-
throw new Error("No response from OpenRouter");
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
message,
|
|
429
|
-
metadata: {
|
|
430
|
-
model: response.model,
|
|
431
|
-
finishReason: response.choices[0]?.finish_reason,
|
|
432
|
-
tokensUsed: response.usage?.total_tokens,
|
|
433
|
-
promptTokens: response.usage?.prompt_tokens,
|
|
434
|
-
completionTokens: response.usage?.completion_tokens,
|
|
83
|
+
super({
|
|
84
|
+
client: new OpenAI({
|
|
85
|
+
apiKey,
|
|
86
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
87
|
+
defaultHeaders: {
|
|
88
|
+
"HTTP-Referer": siteUrl || "",
|
|
89
|
+
"X-Title": siteName || "",
|
|
435
90
|
},
|
|
436
|
-
|
|
437
|
-
toolCalls.length > 0
|
|
438
|
-
? ({ message, toolCalls } as AgentStructuredResponse)
|
|
439
|
-
: undefined,
|
|
440
|
-
};
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
return withTimeoutAndRetry(
|
|
444
|
-
operation,
|
|
445
|
-
this.retryConfig.timeout,
|
|
446
|
-
this.retryConfig.retries,
|
|
447
|
-
`OpenRouter ${model}`
|
|
448
|
-
) as Promise<GenerateMessageOutput<TStructured>>;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
private async *generateStreamWithBackup<
|
|
452
|
-
TContext = unknown,
|
|
453
|
-
TStructured = AgentStructuredResponse
|
|
454
|
-
>(
|
|
455
|
-
input: GenerateMessageInput<TContext>
|
|
456
|
-
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
457
|
-
// Try primary model first
|
|
458
|
-
try {
|
|
459
|
-
yield* this.generateStreamWithModel(this.primaryModel, input);
|
|
460
|
-
} catch (primaryError: unknown) {
|
|
461
|
-
const primaryErrMsg = getErrorMessage(primaryError);
|
|
462
|
-
logger.warn(
|
|
463
|
-
`[OPENROUTER] Primary model ${this.primaryModel} failed: ${primaryErrMsg}`
|
|
464
|
-
);
|
|
465
|
-
|
|
466
|
-
if (!shouldUseBackupModel(primaryError)) {
|
|
467
|
-
throw primaryError;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
logger.debug(`[OPENROUTER] Trying backup models for streaming`);
|
|
471
|
-
|
|
472
|
-
let lastBackupError: unknown = primaryError;
|
|
473
|
-
|
|
474
|
-
for (let i = 0; i < this.backupModels.length; i++) {
|
|
475
|
-
const backupModel = this.backupModels[i];
|
|
476
|
-
logger.debug(
|
|
477
|
-
`[OPENROUTER] Trying backup model ${i + 1}/${this.backupModels.length
|
|
478
|
-
}: ${backupModel}`
|
|
479
|
-
);
|
|
480
|
-
|
|
481
|
-
try {
|
|
482
|
-
yield* this.generateStreamWithModel(backupModel, input);
|
|
483
|
-
logger.debug(`[OPENROUTER] Backup model ${backupModel} succeeded`);
|
|
484
|
-
return;
|
|
485
|
-
} catch (backupError: unknown) {
|
|
486
|
-
const backupErrMsg = getErrorMessage(backupError);
|
|
487
|
-
logger.warn(
|
|
488
|
-
`[OPENROUTER] Backup model ${backupModel} failed: ${backupErrMsg}`
|
|
489
|
-
);
|
|
490
|
-
lastBackupError = backupError;
|
|
491
|
-
|
|
492
|
-
if (
|
|
493
|
-
!shouldUseBackupModel(backupError) &&
|
|
494
|
-
i < this.backupModels.length - 1
|
|
495
|
-
) {
|
|
496
|
-
logger.debug(
|
|
497
|
-
`[OPENROUTER] Backup model error doesn't qualify for further attempts`
|
|
498
|
-
);
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
const lastBackupErrMsg = getErrorMessage(lastBackupError);
|
|
505
|
-
logger.error(
|
|
506
|
-
`[OPENROUTER] All models failed. Primary: ${primaryErrMsg}, Last backup: ${lastBackupErrMsg}`
|
|
507
|
-
);
|
|
508
|
-
throw lastBackupError;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
private async *generateStreamWithModel<
|
|
513
|
-
TContext = unknown,
|
|
514
|
-
TStructured = AgentStructuredResponse
|
|
515
|
-
>(
|
|
516
|
-
model: string,
|
|
517
|
-
input: GenerateMessageInput<TContext>
|
|
518
|
-
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
519
|
-
const historyMessages = this.buildOpenRouterMessages(input.history);
|
|
520
|
-
historyMessages.push({ role: "user" as const, content: input.prompt });
|
|
521
|
-
|
|
522
|
-
const params = {
|
|
523
|
-
...this.config,
|
|
91
|
+
}),
|
|
524
92
|
model,
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
// Override with input parameters if provided
|
|
530
|
-
if (input.parameters?.maxOutputTokens !== undefined) {
|
|
531
|
-
params.max_tokens = input.parameters.maxOutputTokens;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// Add tools if provided
|
|
535
|
-
if (input.tools && input.tools.length > 0) {
|
|
536
|
-
params.tools = input.tools.map((tool) => ({
|
|
537
|
-
type: "function" as const,
|
|
538
|
-
function: {
|
|
539
|
-
name: tool.name || tool.id,
|
|
540
|
-
description: tool.description,
|
|
541
|
-
parameters: tool.parameters as FunctionParameters, // JSON schema
|
|
542
|
-
},
|
|
543
|
-
}));
|
|
544
|
-
params.tool_choice = "auto";
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// Streaming path does not support responses.parse; if schema present,
|
|
548
|
-
// request JSON object and parse at the end.
|
|
549
|
-
if (input.parameters?.jsonSchema) {
|
|
550
|
-
params.response_format = { type: "json_object" };
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const stream = await this.client.chat.completions.create(params);
|
|
554
|
-
|
|
555
|
-
let accumulated = "";
|
|
556
|
-
let currentModel = model;
|
|
557
|
-
let finishReason: string | undefined;
|
|
558
|
-
let promptTokens: number | undefined;
|
|
559
|
-
let completionTokens: number | undefined;
|
|
560
|
-
let totalTokens: number | undefined;
|
|
561
|
-
const toolCalls: Array<{
|
|
562
|
-
toolName: string;
|
|
563
|
-
arguments: Record<string, unknown>;
|
|
564
|
-
}> = [];
|
|
565
|
-
|
|
566
|
-
for await (const chunk of stream) {
|
|
567
|
-
currentModel = chunk.model;
|
|
568
|
-
const delta = chunk.choices[0]?.delta?.content || "";
|
|
569
|
-
|
|
570
|
-
// Extract tool calls from delta
|
|
571
|
-
if (chunk.choices[0]?.delta?.tool_calls) {
|
|
572
|
-
for (const toolCall of chunk.choices[0].delta.tool_calls) {
|
|
573
|
-
if (toolCall.function) {
|
|
574
|
-
let toolCallArguments: Record<string, unknown> = {};
|
|
575
|
-
try {
|
|
576
|
-
toolCallArguments = toolCall.function.arguments
|
|
577
|
-
? (JSON.parse(toolCall.function.arguments) as Record<
|
|
578
|
-
string,
|
|
579
|
-
unknown
|
|
580
|
-
>)
|
|
581
|
-
: {};
|
|
582
|
-
} catch (error) {
|
|
583
|
-
logger.warn(
|
|
584
|
-
`[OPENROUTER] Failed to parse tool call arguments in stream: ${getErrorMessage(
|
|
585
|
-
error
|
|
586
|
-
)}`
|
|
587
|
-
);
|
|
588
|
-
toolCallArguments = {};
|
|
589
|
-
}
|
|
590
|
-
toolCalls.push({
|
|
591
|
-
toolName: toolCall.function.name || "",
|
|
592
|
-
arguments: toolCallArguments,
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
if (delta) {
|
|
599
|
-
accumulated += delta;
|
|
600
|
-
yield {
|
|
601
|
-
delta,
|
|
602
|
-
accumulated,
|
|
603
|
-
done: false,
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
if (chunk.choices[0]?.finish_reason) {
|
|
608
|
-
finishReason = chunk.choices[0].finish_reason;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// OpenRouter may include usage in the final chunk
|
|
612
|
-
if (chunk.usage) {
|
|
613
|
-
promptTokens = chunk.usage.prompt_tokens;
|
|
614
|
-
completionTokens = chunk.usage.completion_tokens;
|
|
615
|
-
totalTokens = chunk.usage.total_tokens;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// Parse JSON response if schema was provided
|
|
620
|
-
let structured: TStructured | undefined;
|
|
621
|
-
if (input.parameters?.jsonSchema && accumulated) {
|
|
622
|
-
try {
|
|
623
|
-
structured = JSON.parse(accumulated) as TStructured;
|
|
624
|
-
} catch (error) {
|
|
625
|
-
logger.warn(
|
|
626
|
-
"[OPENROUTER] Failed to parse JSON response in stream:",
|
|
627
|
-
error
|
|
628
|
-
);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// If tools were used, include them in structured response
|
|
633
|
-
if (toolCalls.length > 0) {
|
|
634
|
-
structured = {
|
|
635
|
-
...(structured || {}),
|
|
636
|
-
message: (structured as AgentStructuredResponse | undefined)?.message || accumulated,
|
|
637
|
-
toolCalls,
|
|
638
|
-
} as TStructured;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Yield final chunk
|
|
642
|
-
yield {
|
|
643
|
-
delta: "",
|
|
644
|
-
accumulated,
|
|
645
|
-
done: true,
|
|
646
|
-
metadata: {
|
|
647
|
-
model: currentModel,
|
|
648
|
-
finishReason,
|
|
649
|
-
tokensUsed: totalTokens,
|
|
650
|
-
promptTokens,
|
|
651
|
-
completionTokens,
|
|
652
|
-
},
|
|
653
|
-
structured,
|
|
654
|
-
};
|
|
93
|
+
backupModels,
|
|
94
|
+
config,
|
|
95
|
+
retryConfig,
|
|
96
|
+
});
|
|
655
97
|
}
|
|
656
98
|
}
|