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