@falai/agent 2.2.3 → 2.4.1
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 -96
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +184 -1183
- 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 +13 -27
- 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 +1 -3
- 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 +21 -11
- 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 -96
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +177 -1175
- 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 +13 -27
- package/dist/core/SignalEvaluator.js.map +1 -1
- package/dist/core/SignalProcessor.d.ts.map +1 -1
- package/dist/core/SignalProcessor.js +1 -3
- 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 +21 -11
- 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 +3 -1
- 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 +18 -8
- 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 +241 -1465
- 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 +14 -30
- package/src/core/SignalProcessor.ts +1 -4
- 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 +23 -11
- 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
|
@@ -25,7 +25,9 @@ import type {
|
|
|
25
25
|
MessageData,
|
|
26
26
|
SessionStatus,
|
|
27
27
|
PersistenceAdapter,
|
|
28
|
+
SessionUpdateOptions,
|
|
28
29
|
} from "../types";
|
|
30
|
+
import { SessionConflictError } from "../types/errors";
|
|
29
31
|
import { createSessionId } from "../utils";
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -133,11 +135,18 @@ export class PostgreSQLAdapter<TData = Record<string, unknown>> implements Persi
|
|
|
133
135
|
message_count INTEGER DEFAULT 0,
|
|
134
136
|
last_message_at TIMESTAMP,
|
|
135
137
|
completed_at TIMESTAMP,
|
|
138
|
+
version INTEGER,
|
|
136
139
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
137
140
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
138
141
|
)
|
|
139
142
|
`);
|
|
140
143
|
|
|
144
|
+
// Migration: add the optimistic-concurrency version column to tables
|
|
145
|
+
// created by pre-2.4 versions
|
|
146
|
+
await this.client.query(`
|
|
147
|
+
ALTER TABLE ${sessionTable} ADD COLUMN IF NOT EXISTS version INTEGER
|
|
148
|
+
`);
|
|
149
|
+
|
|
141
150
|
await this.client.query(`
|
|
142
151
|
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON ${sessionTable}(user_id);
|
|
143
152
|
CREATE INDEX IF NOT EXISTS idx_sessions_status ON ${sessionTable}(status);
|
|
@@ -187,9 +196,9 @@ class PostgreSQLSessionRepository<TData = Record<string, unknown>>
|
|
|
187
196
|
const now = new Date();
|
|
188
197
|
|
|
189
198
|
const result = await this.client.query<SessionData<TData>>(
|
|
190
|
-
`INSERT INTO ${this.tableName}
|
|
191
|
-
(id, user_id, agent_name, status, collected_data, message_count, created_at, updated_at)
|
|
192
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
199
|
+
`INSERT INTO ${this.tableName}
|
|
200
|
+
(id, user_id, agent_name, status, collected_data, message_count, version, created_at, updated_at)
|
|
201
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
193
202
|
RETURNING *`,
|
|
194
203
|
[
|
|
195
204
|
id,
|
|
@@ -198,6 +207,7 @@ class PostgreSQLSessionRepository<TData = Record<string, unknown>>
|
|
|
198
207
|
data.status || "active",
|
|
199
208
|
JSON.stringify(data.collectedData || {}),
|
|
200
209
|
data.messageCount || 0,
|
|
210
|
+
data.version ?? 1,
|
|
201
211
|
now,
|
|
202
212
|
now,
|
|
203
213
|
]
|
|
@@ -244,7 +254,8 @@ class PostgreSQLSessionRepository<TData = Record<string, unknown>>
|
|
|
244
254
|
|
|
245
255
|
async update(
|
|
246
256
|
id: string,
|
|
247
|
-
data: Partial<Omit<SessionData<TData>, "id" | "createdAt"
|
|
257
|
+
data: Partial<Omit<SessionData<TData>, "id" | "createdAt">>,
|
|
258
|
+
options?: SessionUpdateOptions
|
|
248
259
|
): Promise<SessionData<TData> | null> {
|
|
249
260
|
const fields: string[] = [];
|
|
250
261
|
const values: unknown[] = [];
|
|
@@ -282,10 +293,39 @@ class PostgreSQLSessionRepository<TData = Record<string, unknown>>
|
|
|
282
293
|
fields.push(`updated_at = $${paramIndex++}`);
|
|
283
294
|
values.push(new Date());
|
|
284
295
|
|
|
296
|
+
if (options?.expectedVersion !== undefined) {
|
|
297
|
+
const expectedVersion = options.expectedVersion;
|
|
298
|
+
|
|
299
|
+
// Compare-and-swap in a single statement: rows without a stored version
|
|
300
|
+
// (pre-2.4) are accepted and adopt expectedVersion as their base
|
|
301
|
+
fields.push(`version = COALESCE(version, $${paramIndex++}) + 1`);
|
|
302
|
+
values.push(expectedVersion);
|
|
303
|
+
|
|
304
|
+
const idParam = paramIndex++;
|
|
305
|
+
values.push(id);
|
|
306
|
+
const versionParam = paramIndex++;
|
|
307
|
+
values.push(expectedVersion);
|
|
308
|
+
|
|
309
|
+
const result = await this.client.query<SessionData<TData>>(
|
|
310
|
+
`UPDATE ${this.tableName}
|
|
311
|
+
SET ${fields.join(", ")}
|
|
312
|
+
WHERE id = $${idParam} AND (version IS NULL OR version = $${versionParam})
|
|
313
|
+
RETURNING *`,
|
|
314
|
+
values
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
if (result.rows[0]) return result.rows[0];
|
|
318
|
+
|
|
319
|
+
const existing = await this.findById(id);
|
|
320
|
+
if (!existing) return null;
|
|
321
|
+
throw new SessionConflictError(id, expectedVersion, existing.version);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
fields.push(`version = COALESCE(version, 0) + 1`);
|
|
285
325
|
values.push(id);
|
|
286
326
|
|
|
287
327
|
const result = await this.client.query<SessionData<TData>>(
|
|
288
|
-
`UPDATE ${this.tableName}
|
|
328
|
+
`UPDATE ${this.tableName}
|
|
289
329
|
SET ${fields.join(", ")}
|
|
290
330
|
WHERE id = $${paramIndex}
|
|
291
331
|
RETURNING *`,
|
|
@@ -14,7 +14,9 @@ import type {
|
|
|
14
14
|
MessageRole,
|
|
15
15
|
Event,
|
|
16
16
|
CreateSessionData,
|
|
17
|
+
SessionUpdateOptions,
|
|
17
18
|
} from "../types";
|
|
19
|
+
import { SessionConflictError } from "../types/errors";
|
|
18
20
|
import { logger } from '../utils'
|
|
19
21
|
import { createSessionId } from '../utils';
|
|
20
22
|
|
|
@@ -202,6 +204,13 @@ class PrismaSessionRepository<TData = Record<string, unknown>>
|
|
|
202
204
|
private prisma: PrismaClient;
|
|
203
205
|
private tableName: string;
|
|
204
206
|
private fieldMap: Partial<Record<keyof SessionData<TData>, string>>;
|
|
207
|
+
/**
|
|
208
|
+
* Whether the user's Prisma model has a `version` column. Unknown until the
|
|
209
|
+
* first write; when Prisma rejects the field, writes fall back to omitting
|
|
210
|
+
* it so models without the column keep working (optimistic locking is then
|
|
211
|
+
* inactive — add `version Int?` to the model to enable it).
|
|
212
|
+
*/
|
|
213
|
+
private versionSupported?: boolean;
|
|
205
214
|
|
|
206
215
|
constructor(
|
|
207
216
|
prismaClient: PrismaClient,
|
|
@@ -213,6 +222,34 @@ class PrismaSessionRepository<TData = Record<string, unknown>>
|
|
|
213
222
|
this.fieldMap = fieldMappings || {};
|
|
214
223
|
}
|
|
215
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Run a write that includes the `version` field, retrying without it once
|
|
227
|
+
* if the model evidently lacks the column. The outcome is remembered.
|
|
228
|
+
*/
|
|
229
|
+
private async writeWithVersionFallback<T>(
|
|
230
|
+
write: (includeVersion: boolean) => Promise<T>
|
|
231
|
+
): Promise<T> {
|
|
232
|
+
if (this.versionSupported === false) {
|
|
233
|
+
return write(false);
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
const result = await write(true);
|
|
237
|
+
this.versionSupported = true;
|
|
238
|
+
return result;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
const versionField = this.fieldMap.version || "version";
|
|
241
|
+
if (
|
|
242
|
+
this.versionSupported === undefined &&
|
|
243
|
+
error instanceof Error &&
|
|
244
|
+
error.message.includes(versionField)
|
|
245
|
+
) {
|
|
246
|
+
this.versionSupported = false;
|
|
247
|
+
return write(false);
|
|
248
|
+
}
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
216
253
|
/**
|
|
217
254
|
* Map our standard field names to custom schema field names
|
|
218
255
|
*/
|
|
@@ -254,6 +291,7 @@ class PrismaSessionRepository<TData = Record<string, unknown>>
|
|
|
254
291
|
messageCount: unmapped.messageCount as number | undefined,
|
|
255
292
|
lastMessageAt: unmapped.lastMessageAt as Date | undefined,
|
|
256
293
|
completedAt: unmapped.completedAt as Date | undefined,
|
|
294
|
+
version: (unmapped.version as number | null) ?? undefined,
|
|
257
295
|
createdAt: unmapped.createdAt as Date,
|
|
258
296
|
updatedAt: unmapped.updatedAt as Date,
|
|
259
297
|
};
|
|
@@ -264,14 +302,14 @@ class PrismaSessionRepository<TData = Record<string, unknown>>
|
|
|
264
302
|
}
|
|
265
303
|
|
|
266
304
|
async create(data: CreateSessionData<TData>): Promise<SessionData<TData>> {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
data: mapped
|
|
305
|
+
const id = data.id || createSessionId();
|
|
306
|
+
const result = await this.writeWithVersionFallback((includeVersion) => {
|
|
307
|
+
const mapped = this.mapFields(
|
|
308
|
+
includeVersion
|
|
309
|
+
? { ...data, id, version: data.version ?? 1 }
|
|
310
|
+
: { ...data, id }
|
|
311
|
+
);
|
|
312
|
+
return this.getModel().create({ data: mapped });
|
|
275
313
|
});
|
|
276
314
|
return this.unmapFields(result);
|
|
277
315
|
}
|
|
@@ -314,15 +352,43 @@ class PrismaSessionRepository<TData = Record<string, unknown>>
|
|
|
314
352
|
|
|
315
353
|
async update(
|
|
316
354
|
id: string,
|
|
317
|
-
data: Partial<Omit<SessionData<TData>, "id" | "createdAt"
|
|
355
|
+
data: Partial<Omit<SessionData<TData>, "id" | "createdAt">>,
|
|
356
|
+
options?: SessionUpdateOptions
|
|
318
357
|
): Promise<SessionData<TData> | null> {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
358
|
+
// Read-check-write: the Prisma model is user-defined, so we cannot emit a
|
|
359
|
+
// conditional UPDATE generically. Add `version Int?` to your Prisma model
|
|
360
|
+
// for optimistic locking to be effective.
|
|
361
|
+
const existing = await this.findById(id);
|
|
362
|
+
if (!existing) return null;
|
|
363
|
+
|
|
364
|
+
if (
|
|
365
|
+
options?.expectedVersion !== undefined &&
|
|
366
|
+
existing.version !== undefined &&
|
|
367
|
+
existing.version !== options.expectedVersion
|
|
368
|
+
) {
|
|
369
|
+
throw new SessionConflictError(
|
|
370
|
+
id,
|
|
371
|
+
options.expectedVersion,
|
|
372
|
+
existing.version
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const result = await this.writeWithVersionFallback((includeVersion) => {
|
|
377
|
+
const mapped = this.mapFields(
|
|
378
|
+
includeVersion
|
|
379
|
+
? {
|
|
380
|
+
...(data as Record<string, unknown>),
|
|
381
|
+
version: (existing.version ?? options?.expectedVersion ?? 0) + 1,
|
|
382
|
+
}
|
|
383
|
+
: { ...(data as Record<string, unknown>) }
|
|
384
|
+
);
|
|
385
|
+
return this.getModel().update({
|
|
386
|
+
where: { [this.fieldMap.id || "id"]: id },
|
|
387
|
+
data: {
|
|
388
|
+
...mapped,
|
|
389
|
+
[this.fieldMap.updatedAt || "updatedAt"]: new Date(),
|
|
390
|
+
},
|
|
391
|
+
});
|
|
326
392
|
});
|
|
327
393
|
return this.unmapFields(result);
|
|
328
394
|
}
|
|
@@ -11,7 +11,9 @@ import type {
|
|
|
11
11
|
SessionRepository,
|
|
12
12
|
SessionStatus,
|
|
13
13
|
CollectedStateData,
|
|
14
|
+
SessionUpdateOptions,
|
|
14
15
|
} from "../types";
|
|
16
|
+
import { SessionConflictError } from "../types/errors";
|
|
15
17
|
import { createSessionId, logger } from "../utils";
|
|
16
18
|
|
|
17
19
|
/**
|
|
@@ -139,6 +141,7 @@ class RedisSessionRepository<TData = Record<string, unknown>>
|
|
|
139
141
|
updatedAt: now,
|
|
140
142
|
status: data.status || "active",
|
|
141
143
|
messageCount: data.messageCount || 0,
|
|
144
|
+
version: data.version ?? 1,
|
|
142
145
|
};
|
|
143
146
|
|
|
144
147
|
await this.redis.setex(this.getKey(id), this.ttl, JSON.stringify(session));
|
|
@@ -201,14 +204,29 @@ class RedisSessionRepository<TData = Record<string, unknown>>
|
|
|
201
204
|
|
|
202
205
|
async update(
|
|
203
206
|
id: string,
|
|
204
|
-
data: Partial<Omit<SessionData<TData>, "id" | "createdAt"
|
|
207
|
+
data: Partial<Omit<SessionData<TData>, "id" | "createdAt">>,
|
|
208
|
+
options?: SessionUpdateOptions
|
|
205
209
|
): Promise<SessionData<TData> | null> {
|
|
206
210
|
const existing = await this.findById(id);
|
|
207
211
|
if (!existing) return null;
|
|
208
212
|
|
|
213
|
+
// Check-then-set on the stored JSON — not fully atomic (no WATCH/MULTI)
|
|
214
|
+
if (
|
|
215
|
+
options?.expectedVersion !== undefined &&
|
|
216
|
+
existing.version !== undefined &&
|
|
217
|
+
existing.version !== options.expectedVersion
|
|
218
|
+
) {
|
|
219
|
+
throw new SessionConflictError(
|
|
220
|
+
id,
|
|
221
|
+
options.expectedVersion,
|
|
222
|
+
existing.version
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
209
226
|
const updated: SessionData<TData> = {
|
|
210
227
|
...existing,
|
|
211
228
|
...data,
|
|
229
|
+
version: (existing.version ?? options?.expectedVersion ?? 0) + 1,
|
|
212
230
|
updatedAt: new Date(),
|
|
213
231
|
};
|
|
214
232
|
|
|
@@ -29,7 +29,9 @@ import type {
|
|
|
29
29
|
PersistenceAdapter,
|
|
30
30
|
CollectedStateData,
|
|
31
31
|
CreateSessionData,
|
|
32
|
+
SessionUpdateOptions,
|
|
32
33
|
} from "../types";
|
|
34
|
+
import { SessionConflictError } from "../types/errors";
|
|
33
35
|
import { createSessionId } from "../utils";
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -125,11 +127,21 @@ export class SQLiteAdapter<TData = Record<string, unknown>> implements Persisten
|
|
|
125
127
|
message_count INTEGER DEFAULT 0,
|
|
126
128
|
last_message_at TEXT,
|
|
127
129
|
completed_at TEXT,
|
|
130
|
+
version INTEGER,
|
|
128
131
|
created_at TEXT NOT NULL,
|
|
129
132
|
updated_at TEXT NOT NULL
|
|
130
133
|
)
|
|
131
134
|
`);
|
|
132
135
|
|
|
136
|
+
// Migration: add the optimistic-concurrency version column to tables
|
|
137
|
+
// created by pre-2.4 versions
|
|
138
|
+
const sessionColumns = this.db
|
|
139
|
+
.prepare(`PRAGMA table_info(${sessionTable})`)
|
|
140
|
+
.all();
|
|
141
|
+
if (!sessionColumns.some((column) => column.name === "version")) {
|
|
142
|
+
this.db.exec(`ALTER TABLE ${sessionTable} ADD COLUMN version INTEGER`);
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
// Create indexes for sessions
|
|
134
146
|
this.db.exec(`
|
|
135
147
|
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON ${sessionTable}(user_id);
|
|
@@ -183,14 +195,15 @@ class SQLiteSessionRepository<TData = Record<string, unknown>>
|
|
|
183
195
|
id,
|
|
184
196
|
status: data.status || "active",
|
|
185
197
|
messageCount: data.messageCount || 0,
|
|
198
|
+
version: data.version ?? 1,
|
|
186
199
|
createdAt: now,
|
|
187
200
|
updatedAt: now,
|
|
188
201
|
};
|
|
189
202
|
|
|
190
203
|
const stmt = this.db.prepare(`
|
|
191
|
-
INSERT INTO ${this.tableName}
|
|
192
|
-
(id, user_id, agent_name, status, collected_data, message_count, created_at, updated_at)
|
|
193
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
204
|
+
INSERT INTO ${this.tableName}
|
|
205
|
+
(id, user_id, agent_name, status, collected_data, message_count, version, created_at, updated_at)
|
|
206
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
194
207
|
`);
|
|
195
208
|
|
|
196
209
|
stmt.run(
|
|
@@ -200,6 +213,7 @@ class SQLiteSessionRepository<TData = Record<string, unknown>>
|
|
|
200
213
|
session.status,
|
|
201
214
|
JSON.stringify(data.collectedData || {}),
|
|
202
215
|
session.messageCount,
|
|
216
|
+
session.version,
|
|
203
217
|
now.toISOString(),
|
|
204
218
|
now.toISOString()
|
|
205
219
|
);
|
|
@@ -239,7 +253,8 @@ class SQLiteSessionRepository<TData = Record<string, unknown>>
|
|
|
239
253
|
|
|
240
254
|
async update(
|
|
241
255
|
id: string,
|
|
242
|
-
data: Partial<Omit<SessionData<TData>, "id" | "createdAt"
|
|
256
|
+
data: Partial<Omit<SessionData<TData>, "id" | "createdAt">>,
|
|
257
|
+
options?: SessionUpdateOptions
|
|
243
258
|
): Promise<SessionData<TData> | null> {
|
|
244
259
|
const fields: string[] = [];
|
|
245
260
|
const values: unknown[] = [];
|
|
@@ -276,10 +291,36 @@ class SQLiteSessionRepository<TData = Record<string, unknown>>
|
|
|
276
291
|
fields.push("updated_at = ?");
|
|
277
292
|
values.push(new Date().toISOString());
|
|
278
293
|
|
|
294
|
+
if (options?.expectedVersion !== undefined) {
|
|
295
|
+
const expectedVersion = options.expectedVersion;
|
|
296
|
+
|
|
297
|
+
// Compare-and-swap in a single statement: rows without a stored version
|
|
298
|
+
// (pre-2.4) are accepted and adopt expectedVersion as their base
|
|
299
|
+
fields.push("version = COALESCE(version, ?) + 1");
|
|
300
|
+
values.push(expectedVersion);
|
|
301
|
+
values.push(id, expectedVersion);
|
|
302
|
+
|
|
303
|
+
const stmt = this.db.prepare(
|
|
304
|
+
`UPDATE ${this.tableName}
|
|
305
|
+
SET ${fields.join(", ")}
|
|
306
|
+
WHERE id = ? AND (version IS NULL OR version = ?)`
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
const result = stmt.run(...values);
|
|
310
|
+
if (result.changes === 0) {
|
|
311
|
+
const existing = await this.findById(id);
|
|
312
|
+
if (!existing) return null;
|
|
313
|
+
throw new SessionConflictError(id, expectedVersion, existing.version);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return await this.findById(id);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
fields.push("version = COALESCE(version, 0) + 1");
|
|
279
320
|
values.push(id);
|
|
280
321
|
|
|
281
322
|
const stmt = this.db.prepare(
|
|
282
|
-
`UPDATE ${this.tableName}
|
|
323
|
+
`UPDATE ${this.tableName}
|
|
283
324
|
SET ${fields.join(", ")}
|
|
284
325
|
WHERE id = ?`
|
|
285
326
|
);
|
|
@@ -358,6 +399,7 @@ class SQLiteSessionRepository<TData = Record<string, unknown>>
|
|
|
358
399
|
completedAt: row.completed_at
|
|
359
400
|
? new Date(row.completed_at as string)
|
|
360
401
|
: undefined,
|
|
402
|
+
version: (row.version as number | null) ?? undefined,
|
|
361
403
|
createdAt: new Date(row.created_at as string),
|
|
362
404
|
updatedAt: new Date(row.updated_at as string),
|
|
363
405
|
};
|