@falai/agent 1.2.8 → 2.0.0
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 +40 -886
- package/dist/adapters/MemoryAdapter.js +2 -2
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.js +2 -2
- package/dist/adapters/MongoAdapter.js.map +1 -1
- package/dist/adapters/OpenSearchAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenSearchAdapter.js +9 -7
- package/dist/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts +14 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +25 -9
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.js +5 -5
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.js +2 -2
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts +17 -0
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +30 -11
- package/dist/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +2 -2
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +2 -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 +9 -7
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +14 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +25 -9
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +5 -5
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +2 -2
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +17 -0
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +30 -11
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/constants/index.d.ts +0 -9
- package/dist/cjs/constants/index.d.ts.map +1 -1
- package/dist/cjs/constants/index.js +2 -11
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/core/Agent.d.ts +119 -153
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +471 -324
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/AutoChainExecutor.d.ts +107 -0
- package/dist/cjs/core/AutoChainExecutor.d.ts.map +1 -0
- package/dist/cjs/core/AutoChainExecutor.js +297 -0
- package/dist/cjs/core/AutoChainExecutor.js.map +1 -0
- package/dist/cjs/core/BranchEvaluator.d.ts +54 -0
- package/dist/cjs/core/BranchEvaluator.d.ts.map +1 -0
- package/dist/cjs/core/BranchEvaluator.js +130 -0
- package/dist/cjs/core/BranchEvaluator.js.map +1 -0
- package/dist/cjs/core/DirectiveBus.d.ts +88 -0
- package/dist/cjs/core/DirectiveBus.d.ts.map +1 -0
- package/dist/cjs/core/DirectiveBus.js +196 -0
- package/dist/cjs/core/DirectiveBus.js.map +1 -0
- package/dist/cjs/core/DirectiveChainTracker.d.ts +49 -0
- package/dist/cjs/core/DirectiveChainTracker.d.ts.map +1 -0
- package/dist/cjs/core/DirectiveChainTracker.js +121 -0
- package/dist/cjs/core/DirectiveChainTracker.js.map +1 -0
- package/dist/cjs/core/Flow.d.ts +186 -0
- package/dist/cjs/core/Flow.d.ts.map +1 -0
- package/dist/cjs/core/Flow.js +550 -0
- package/dist/cjs/core/Flow.js.map +1 -0
- package/dist/cjs/core/FlowRouter.d.ts +182 -0
- package/dist/cjs/core/FlowRouter.d.ts.map +1 -0
- package/dist/cjs/core/{RoutingEngine.js → FlowRouter.js} +323 -306
- package/dist/cjs/core/FlowRouter.js.map +1 -0
- package/dist/cjs/core/PersistenceManager.d.ts +2 -2
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +7 -7
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +21 -8
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/core/PromptComposer.js +182 -105
- package/dist/cjs/core/PromptComposer.js.map +1 -1
- package/dist/cjs/core/PromptSectionCache.d.ts +1 -1
- package/dist/cjs/core/PromptSectionCache.js +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts +18 -8
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +38 -36
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/ResponseModal.d.ts +73 -56
- package/dist/cjs/core/ResponseModal.d.ts.map +1 -1
- package/dist/cjs/core/ResponseModal.js +1191 -1014
- package/dist/cjs/core/ResponseModal.js.map +1 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +124 -26
- package/dist/cjs/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/core/ResponsePipeline.js +509 -136
- package/dist/cjs/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/core/SignalEvaluator.d.ts +86 -0
- package/dist/cjs/core/SignalEvaluator.d.ts.map +1 -0
- package/dist/cjs/core/SignalEvaluator.js +333 -0
- package/dist/cjs/core/SignalEvaluator.js.map +1 -0
- package/dist/cjs/core/SignalProcessor.d.ts +152 -0
- package/dist/cjs/core/SignalProcessor.d.ts.map +1 -0
- package/dist/cjs/core/SignalProcessor.js +562 -0
- package/dist/cjs/core/SignalProcessor.js.map +1 -0
- package/dist/cjs/core/Step.d.ts +43 -32
- package/dist/cjs/core/Step.d.ts.map +1 -1
- package/dist/cjs/core/Step.js +221 -126
- package/dist/cjs/core/Step.js.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts +2 -2
- package/dist/cjs/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/cjs/core/StreamingToolExecutor.js.map +1 -1
- package/dist/cjs/core/ToolManager.d.ts +44 -13
- package/dist/cjs/core/ToolManager.d.ts.map +1 -1
- package/dist/cjs/core/ToolManager.js +174 -91
- package/dist/cjs/core/ToolManager.js.map +1 -1
- package/dist/cjs/core/createAgent.d.ts +35 -0
- package/dist/cjs/core/createAgent.d.ts.map +1 -0
- package/dist/cjs/core/createAgent.js +39 -0
- package/dist/cjs/core/createAgent.js.map +1 -0
- package/dist/cjs/core/flow-namespace.d.ts +49 -0
- package/dist/cjs/core/flow-namespace.d.ts.map +1 -0
- package/dist/cjs/core/flow-namespace.js +171 -0
- package/dist/cjs/core/flow-namespace.js.map +1 -0
- package/dist/cjs/index.d.ts +11 -14
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +18 -22
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +183 -54
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js +0 -6
- package/dist/cjs/types/agent.js.map +1 -1
- package/dist/cjs/types/ai.d.ts +3 -3
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +15 -0
- package/dist/cjs/types/errors.d.ts.map +1 -0
- package/dist/cjs/types/errors.js +22 -0
- package/dist/cjs/types/errors.js.map +1 -0
- package/dist/cjs/types/flow.d.ts +513 -0
- package/dist/cjs/types/flow.d.ts.map +1 -0
- package/dist/cjs/types/{route.js → flow.js} +2 -2
- package/dist/cjs/types/flow.js.map +1 -0
- package/dist/cjs/types/index.d.ts +7 -6
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +6 -2
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/persistence.d.ts +11 -7
- package/dist/cjs/types/persistence.d.ts.map +1 -1
- package/dist/cjs/types/routing.d.ts +1 -1
- package/dist/cjs/types/routing.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +24 -23
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/signals.d.ts +248 -0
- package/dist/cjs/types/signals.d.ts.map +1 -0
- package/dist/cjs/types/signals.js +11 -0
- package/dist/cjs/types/signals.js.map +1 -0
- package/dist/cjs/types/template.d.ts +2 -8
- package/dist/cjs/types/template.d.ts.map +1 -1
- package/dist/cjs/types/tool.d.ts +36 -29
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/types/tool.js +1 -1
- package/dist/cjs/types/tool.js.map +1 -1
- package/dist/cjs/utils/condition.d.ts +7 -1
- package/dist/cjs/utils/condition.d.ts.map +1 -1
- package/dist/cjs/utils/condition.js.map +1 -1
- package/dist/cjs/utils/id.d.ts +13 -5
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +24 -10
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +2 -2
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +7 -3
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/session.d.ts +44 -5
- package/dist/cjs/utils/session.d.ts.map +1 -1
- package/dist/cjs/utils/session.js +197 -38
- package/dist/cjs/utils/session.js.map +1 -1
- package/dist/constants/index.d.ts +0 -9
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +3 -9
- package/dist/constants/index.js.map +1 -1
- package/dist/core/Agent.d.ts +119 -153
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +472 -325
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/AutoChainExecutor.d.ts +107 -0
- package/dist/core/AutoChainExecutor.d.ts.map +1 -0
- package/dist/core/AutoChainExecutor.js +293 -0
- package/dist/core/AutoChainExecutor.js.map +1 -0
- package/dist/core/BranchEvaluator.d.ts +54 -0
- package/dist/core/BranchEvaluator.d.ts.map +1 -0
- package/dist/core/BranchEvaluator.js +126 -0
- package/dist/core/BranchEvaluator.js.map +1 -0
- package/dist/core/DirectiveBus.d.ts +88 -0
- package/dist/core/DirectiveBus.d.ts.map +1 -0
- package/dist/core/DirectiveBus.js +192 -0
- package/dist/core/DirectiveBus.js.map +1 -0
- package/dist/core/DirectiveChainTracker.d.ts +49 -0
- package/dist/core/DirectiveChainTracker.d.ts.map +1 -0
- package/dist/core/DirectiveChainTracker.js +117 -0
- package/dist/core/DirectiveChainTracker.js.map +1 -0
- package/dist/core/Flow.d.ts +186 -0
- package/dist/core/Flow.d.ts.map +1 -0
- package/dist/core/Flow.js +546 -0
- package/dist/core/Flow.js.map +1 -0
- package/dist/core/FlowRouter.d.ts +182 -0
- package/dist/core/FlowRouter.d.ts.map +1 -0
- package/dist/core/{RoutingEngine.js → FlowRouter.js} +322 -305
- package/dist/core/FlowRouter.js.map +1 -0
- package/dist/core/PersistenceManager.d.ts +2 -2
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +7 -7
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +21 -8
- package/dist/core/PromptComposer.d.ts.map +1 -1
- package/dist/core/PromptComposer.js +183 -106
- package/dist/core/PromptComposer.js.map +1 -1
- package/dist/core/PromptSectionCache.d.ts +1 -1
- package/dist/core/PromptSectionCache.js +1 -1
- package/dist/core/ResponseEngine.d.ts +18 -8
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +38 -36
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/ResponseModal.d.ts +73 -56
- package/dist/core/ResponseModal.d.ts.map +1 -1
- package/dist/core/ResponseModal.js +1193 -1016
- package/dist/core/ResponseModal.js.map +1 -1
- package/dist/core/ResponsePipeline.d.ts +124 -26
- package/dist/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/core/ResponsePipeline.js +509 -137
- package/dist/core/ResponsePipeline.js.map +1 -1
- package/dist/core/SignalEvaluator.d.ts +86 -0
- package/dist/core/SignalEvaluator.d.ts.map +1 -0
- package/dist/core/SignalEvaluator.js +326 -0
- package/dist/core/SignalEvaluator.js.map +1 -0
- package/dist/core/SignalProcessor.d.ts +152 -0
- package/dist/core/SignalProcessor.d.ts.map +1 -0
- package/dist/core/SignalProcessor.js +555 -0
- package/dist/core/SignalProcessor.js.map +1 -0
- package/dist/core/Step.d.ts +43 -32
- package/dist/core/Step.d.ts.map +1 -1
- package/dist/core/Step.js +220 -126
- package/dist/core/Step.js.map +1 -1
- package/dist/core/StreamingToolExecutor.d.ts +2 -2
- package/dist/core/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/core/StreamingToolExecutor.js.map +1 -1
- package/dist/core/ToolManager.d.ts +44 -13
- package/dist/core/ToolManager.d.ts.map +1 -1
- package/dist/core/ToolManager.js +174 -91
- package/dist/core/ToolManager.js.map +1 -1
- package/dist/core/createAgent.d.ts +35 -0
- package/dist/core/createAgent.d.ts.map +1 -0
- package/dist/core/createAgent.js +36 -0
- package/dist/core/createAgent.js.map +1 -0
- package/dist/core/flow-namespace.d.ts +49 -0
- package/dist/core/flow-namespace.d.ts.map +1 -0
- package/dist/core/flow-namespace.js +168 -0
- package/dist/core/flow-namespace.js.map +1 -0
- package/dist/index.d.ts +11 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -12
- package/dist/index.js.map +1 -1
- package/dist/types/agent.d.ts +183 -54
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js +0 -6
- package/dist/types/agent.js.map +1 -1
- package/dist/types/ai.d.ts +3 -3
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +18 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/flow.d.ts +513 -0
- package/dist/types/flow.d.ts.map +1 -0
- package/dist/types/flow.js +5 -0
- package/dist/types/flow.js.map +1 -0
- package/dist/types/index.d.ts +7 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/persistence.d.ts +11 -7
- package/dist/types/persistence.d.ts.map +1 -1
- package/dist/types/routing.d.ts +1 -1
- package/dist/types/routing.d.ts.map +1 -1
- package/dist/types/session.d.ts +24 -23
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/signals.d.ts +248 -0
- package/dist/types/signals.d.ts.map +1 -0
- package/dist/types/signals.js +10 -0
- package/dist/types/signals.js.map +1 -0
- package/dist/types/template.d.ts +2 -8
- package/dist/types/template.d.ts.map +1 -1
- package/dist/types/tool.d.ts +36 -29
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/tool.js +1 -1
- package/dist/types/tool.js.map +1 -1
- package/dist/utils/condition.d.ts +7 -1
- package/dist/utils/condition.d.ts.map +1 -1
- package/dist/utils/condition.js.map +1 -1
- package/dist/utils/id.d.ts +13 -5
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +22 -9
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/session.d.ts +44 -5
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +193 -37
- package/dist/utils/session.js.map +1 -1
- package/docs/README.md +15 -202
- package/docs/concepts/architecture.md +281 -0
- package/docs/concepts/directives.md +400 -0
- package/docs/concepts/pipeline.md +399 -0
- package/docs/guides/branching.md +263 -0
- package/docs/guides/compaction.md +163 -0
- package/docs/guides/conditions.md +167 -0
- package/docs/guides/error-handling.md +176 -0
- package/docs/guides/flow-control.md +409 -0
- package/docs/guides/instructions.md +210 -0
- package/docs/guides/persistence.md +182 -0
- package/docs/guides/streaming.md +137 -0
- package/docs/migration/README.md +15 -0
- package/docs/migration/route-to-flow.md +560 -0
- package/docs/migration/v1-to-v2.md +909 -0
- package/docs/reference/adapters.md +481 -0
- package/docs/reference/branches.md +241 -0
- package/docs/reference/create-agent.md +186 -0
- package/docs/reference/directive.md +243 -0
- package/docs/reference/errors.md +122 -0
- package/docs/reference/flow.md +238 -0
- package/docs/reference/instruction.md +177 -0
- package/docs/reference/pre-directive.md +131 -0
- package/docs/reference/providers.md +227 -0
- package/docs/reference/signals.md +356 -0
- package/docs/reference/step.md +339 -0
- package/docs/reference/tool.md +269 -0
- package/docs/start/01-install.md +81 -0
- package/docs/start/02-first-agent.md +196 -0
- package/docs/start/03-collect-data.md +222 -0
- package/docs/start/04-add-tools.md +276 -0
- package/docs/start/05-go-to-production.md +216 -0
- package/examples/01-quickstart.ts +20 -0
- package/examples/02-data-extraction.ts +90 -0
- package/examples/03-tools.ts +136 -0
- package/examples/04-instructions.ts +100 -0
- package/examples/05-branching.ts +140 -0
- package/examples/06-flow-control.ts +103 -0
- package/examples/07-streaming.ts +69 -0
- package/examples/08-persistence.ts +98 -0
- package/examples/09-signals.ts +144 -0
- package/examples/tsconfig.json +30 -0
- package/package.json +2 -1
- package/src/adapters/MemoryAdapter.ts +3 -3
- package/src/adapters/MongoAdapter.ts +3 -3
- package/src/adapters/OpenSearchAdapter.ts +10 -8
- package/src/adapters/PostgreSQLAdapter.ts +26 -10
- package/src/adapters/PrismaAdapter.ts +6 -6
- package/src/adapters/RedisAdapter.ts +3 -3
- package/src/adapters/SQLiteAdapter.ts +31 -12
- package/src/constants/index.ts +2 -10
- package/src/core/Agent.ts +585 -374
- package/src/core/AutoChainExecutor.ts +440 -0
- package/src/core/BranchEvaluator.ts +167 -0
- package/src/core/DirectiveBus.ts +248 -0
- package/src/core/DirectiveChainTracker.ts +144 -0
- package/src/core/Flow.ts +666 -0
- package/src/core/{RoutingEngine.ts → FlowRouter.ts} +385 -365
- package/src/core/PersistenceManager.ts +8 -8
- package/src/core/PromptComposer.ts +209 -140
- package/src/core/PromptSectionCache.ts +1 -1
- package/src/core/ResponseEngine.ts +61 -46
- package/src/core/ResponseModal.ts +1453 -1240
- package/src/core/ResponsePipeline.ts +655 -175
- package/src/core/SignalEvaluator.ts +420 -0
- package/src/core/SignalProcessor.ts +723 -0
- package/src/core/Step.ts +279 -176
- package/src/core/StreamingToolExecutor.ts +4 -4
- package/src/core/ToolManager.ts +200 -97
- package/src/core/createAgent.ts +40 -0
- package/src/core/flow-namespace.ts +219 -0
- package/src/index.ts +42 -36
- package/src/types/agent.ts +182 -53
- package/src/types/ai.ts +3 -3
- package/src/types/errors.ts +18 -0
- package/src/types/flow.ts +590 -0
- package/src/types/index.ts +43 -16
- package/src/types/persistence.ts +12 -8
- package/src/types/routing.ts +1 -1
- package/src/types/session.ts +26 -23
- package/src/types/signals.ts +321 -0
- package/src/types/template.ts +3 -11
- package/src/types/tool.ts +50 -42
- package/src/utils/condition.ts +13 -4
- package/src/utils/id.ts +27 -9
- package/src/utils/index.ts +6 -2
- package/src/utils/session.ts +238 -42
- package/dist/cjs/core/BatchExecutor.d.ts +0 -359
- package/dist/cjs/core/BatchExecutor.d.ts.map +0 -1
- package/dist/cjs/core/BatchExecutor.js +0 -861
- package/dist/cjs/core/BatchExecutor.js.map +0 -1
- package/dist/cjs/core/BatchPromptBuilder.d.ts +0 -89
- package/dist/cjs/core/BatchPromptBuilder.d.ts.map +0 -1
- package/dist/cjs/core/BatchPromptBuilder.js +0 -223
- package/dist/cjs/core/BatchPromptBuilder.js.map +0 -1
- package/dist/cjs/core/Route.d.ts +0 -180
- package/dist/cjs/core/Route.d.ts.map +0 -1
- package/dist/cjs/core/Route.js +0 -542
- package/dist/cjs/core/Route.js.map +0 -1
- package/dist/cjs/core/RoutingEngine.d.ts +0 -185
- package/dist/cjs/core/RoutingEngine.d.ts.map +0 -1
- package/dist/cjs/core/RoutingEngine.js.map +0 -1
- package/dist/cjs/types/route.d.ts +0 -336
- package/dist/cjs/types/route.d.ts.map +0 -1
- package/dist/cjs/types/route.js.map +0 -1
- package/dist/core/BatchExecutor.d.ts +0 -359
- package/dist/core/BatchExecutor.d.ts.map +0 -1
- package/dist/core/BatchExecutor.js +0 -856
- package/dist/core/BatchExecutor.js.map +0 -1
- package/dist/core/BatchPromptBuilder.d.ts +0 -89
- package/dist/core/BatchPromptBuilder.d.ts.map +0 -1
- package/dist/core/BatchPromptBuilder.js +0 -219
- package/dist/core/BatchPromptBuilder.js.map +0 -1
- package/dist/core/Route.d.ts +0 -180
- package/dist/core/Route.d.ts.map +0 -1
- package/dist/core/Route.js +0 -538
- package/dist/core/Route.js.map +0 -1
- package/dist/core/RoutingEngine.d.ts +0 -185
- package/dist/core/RoutingEngine.d.ts.map +0 -1
- package/dist/core/RoutingEngine.js.map +0 -1
- package/dist/types/route.d.ts +0 -336
- package/dist/types/route.d.ts.map +0 -1
- package/dist/types/route.js +0 -5
- package/dist/types/route.js.map +0 -1
- package/docs/CONTRIBUTING.md +0 -521
- package/docs/api/README.md +0 -3299
- package/docs/api/overview.md +0 -1410
- package/docs/architecture/data-extraction-flow.md +0 -360
- package/docs/architecture/multi-step-execution.md +0 -277
- package/docs/core/agent/README.md +0 -938
- package/docs/core/agent/context-management.md +0 -796
- package/docs/core/agent/rules-and-prohibitions.md +0 -113
- package/docs/core/agent/session-management.md +0 -693
- package/docs/core/ai-integration/prompt-composition.md +0 -355
- package/docs/core/ai-integration/providers.md +0 -515
- package/docs/core/ai-integration/response-processing.md +0 -433
- package/docs/core/conversation-flows/data-collection.md +0 -772
- package/docs/core/conversation-flows/route-dsl.md +0 -509
- package/docs/core/conversation-flows/routes.md +0 -249
- package/docs/core/conversation-flows/step-transitions.md +0 -731
- package/docs/core/conversation-flows/steps.md +0 -268
- package/docs/core/error-handling.md +0 -830
- package/docs/core/persistence/adapters.md +0 -255
- package/docs/core/persistence/session-storage.md +0 -656
- package/docs/core/routing/intelligent-routing.md +0 -470
- package/docs/core/tools/enhanced-tool.md +0 -186
- package/docs/core/tools/streaming-execution.md +0 -161
- package/docs/core/tools/tool-definition.md +0 -970
- package/docs/core/tools/tool-scoping.md +0 -819
- package/docs/guides/advanced-patterns/publishing.md +0 -186
- package/docs/guides/context-compaction.md +0 -96
- package/docs/guides/error-handling-patterns.md +0 -578
- package/docs/guides/getting-started/README.md +0 -795
- package/docs/guides/migration/README.md +0 -101
- package/docs/guides/migration/flexible-routing-conditions.md +0 -375
- package/docs/guides/migration/multi-step-execution.md +0 -393
- package/docs/guides/migration/response-modal-refactor.md +0 -518
- package/docs/guides/prompt-optimization.md +0 -164
- package/examples/advanced-patterns/context-compaction.ts +0 -223
- package/examples/advanced-patterns/knowledge-based-agent.ts +0 -735
- package/examples/advanced-patterns/persistent-onboarding.ts +0 -728
- package/examples/advanced-patterns/route-lifecycle-hooks.ts +0 -556
- package/examples/advanced-patterns/streaming-responses.ts +0 -656
- package/examples/ai-providers/anthropic-integration.ts +0 -388
- package/examples/ai-providers/openai-integration.ts +0 -228
- package/examples/condition-patterns/function-only-conditions.ts +0 -365
- package/examples/condition-patterns/mixed-array-conditions.ts +0 -477
- package/examples/condition-patterns/route-skipif-patterns.ts +0 -468
- package/examples/condition-patterns/step-skipif-patterns.ts +0 -0
- package/examples/condition-patterns/string-only-conditions.ts +0 -296
- package/examples/conversation-flows/completion-transitions.ts +0 -318
- package/examples/core-concepts/basic-agent.ts +0 -503
- package/examples/core-concepts/modern-streaming-api.ts +0 -309
- package/examples/core-concepts/schema-driven-extraction.ts +0 -332
- package/examples/core-concepts/session-management.ts +0 -494
- package/examples/integrations/database-integration.ts +0 -631
- package/examples/integrations/healthcare-integration.ts +0 -595
- package/examples/integrations/search-integration.ts +0 -530
- package/examples/integrations/server-session-management.ts +0 -307
- package/examples/persistence/custom-adapter.ts +0 -526
- package/examples/persistence/database-persistence.ts +0 -583
- package/examples/persistence/memory-sessions.ts +0 -495
- package/examples/persistence/prisma-schema.example.prisma +0 -74
- package/examples/persistence/redis-persistence.ts +0 -488
- package/examples/tools/basic-tools.ts +0 -765
- package/examples/tools/data-enrichment-tools.ts +0 -593
- package/examples/tools/enhanced-tool-metadata.ts +0 -268
- package/examples/tools/streaming-tool-execution.ts +0 -283
- package/src/core/BatchExecutor.ts +0 -1187
- package/src/core/BatchPromptBuilder.ts +0 -299
- package/src/core/Route.ts +0 -678
- package/src/types/route.ts +0 -392
package/dist/core/Agent.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core Agent implementation
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { NotImplementedError } from "../types/errors";
|
|
5
|
+
import { SignalProcessor } from "./SignalProcessor";
|
|
6
|
+
import { SignalEvaluator } from "./SignalEvaluator";
|
|
7
|
+
import { mergeCollected, enterFlow, enterStep, completeCurrentFlow, logger, LoggerLevel, generateSignalId, } from "../utils";
|
|
8
|
+
import { Flow } from "./Flow";
|
|
9
|
+
import { FlowConfigurationError as StepFlowConfigurationError } from "./Step";
|
|
7
10
|
import { PersistenceManager } from "./PersistenceManager";
|
|
8
11
|
import { SessionManager } from "./SessionManager";
|
|
9
|
-
import {
|
|
12
|
+
import { FlowRouter } from "./FlowRouter";
|
|
10
13
|
import { PromptSectionCache } from "./PromptSectionCache";
|
|
11
14
|
import { ResponseModal } from "./ResponseModal";
|
|
12
15
|
import { ToolManager } from "./ToolManager";
|
|
@@ -22,14 +25,14 @@ class DataValidationError extends Error {
|
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
25
|
-
* Error thrown when
|
|
28
|
+
* Error thrown when flow configuration is invalid
|
|
26
29
|
*/
|
|
27
|
-
class
|
|
28
|
-
constructor(
|
|
29
|
-
super(message || `
|
|
30
|
-
this.
|
|
30
|
+
class FlowConfigurationError extends Error {
|
|
31
|
+
constructor(flowTitle, invalidFields, message) {
|
|
32
|
+
super(message || `Flow configuration error in '${flowTitle}'`);
|
|
33
|
+
this.flowTitle = flowTitle;
|
|
31
34
|
this.invalidFields = invalidFields;
|
|
32
|
-
this.name = "
|
|
35
|
+
this.name = "FlowConfigurationError";
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
/**
|
|
@@ -40,13 +43,75 @@ export class Agent {
|
|
|
40
43
|
constructor(options) {
|
|
41
44
|
this.options = options;
|
|
42
45
|
this._terms = [];
|
|
43
|
-
this.
|
|
46
|
+
this._instructions = [];
|
|
44
47
|
this._tools = [];
|
|
45
|
-
this.
|
|
46
|
-
this._rules = [];
|
|
47
|
-
this._prohibitions = [];
|
|
48
|
+
this._flows = [];
|
|
48
49
|
this._knowledgeBase = {};
|
|
49
50
|
this._collectedData = {};
|
|
51
|
+
this.maxAutoStepsPerTurn = options.maxAutoStepsPerTurn ?? 10;
|
|
52
|
+
this.maxDirectiveChain = options.maxDirectiveChain ?? 10;
|
|
53
|
+
// Validate routerMode reservation — only 'ai' is supported in v2.0
|
|
54
|
+
if (options.routerMode !== undefined && options.routerMode !== 'ai') {
|
|
55
|
+
throw new NotImplementedError(`[NotImplementedError] routerMode "${String(options.routerMode)}" is not implemented: only "ai" is supported in v2.0. ` +
|
|
56
|
+
`Set routerMode to "ai" or omit the option.`);
|
|
57
|
+
}
|
|
58
|
+
// ─── Signal construction-time validation (Requirements 1.4, 1.5, 1.6, 1.9, 2.3) ───
|
|
59
|
+
const rawSignals = options.signals ?? [];
|
|
60
|
+
// Auto-generate stable ids for entries without `id`
|
|
61
|
+
for (let i = 0; i < rawSignals.length; i++) {
|
|
62
|
+
if (!rawSignals[i].id) {
|
|
63
|
+
rawSignals[i] = {
|
|
64
|
+
...rawSignals[i],
|
|
65
|
+
id: generateSignalId(rawSignals[i].title, rawSignals[i].description, i),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Validate unique ids (Requirement 1.4)
|
|
70
|
+
const idCounts = new Map();
|
|
71
|
+
for (const signal of rawSignals) {
|
|
72
|
+
const id = signal.id;
|
|
73
|
+
idCounts.set(id, (idCounts.get(id) ?? 0) + 1);
|
|
74
|
+
}
|
|
75
|
+
const duplicateIds = [...idCounts.entries()]
|
|
76
|
+
.filter(([, count]) => count > 1)
|
|
77
|
+
.map(([id]) => id);
|
|
78
|
+
if (duplicateIds.length > 0) {
|
|
79
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Duplicate signal ids: ${duplicateIds.join(', ')}. ` +
|
|
80
|
+
`Each signal must have a unique id.`);
|
|
81
|
+
}
|
|
82
|
+
// Validate signalBatchSize (positive integer when set)
|
|
83
|
+
if (options.signalBatchSize !== undefined) {
|
|
84
|
+
if (!Number.isInteger(options.signalBatchSize) ||
|
|
85
|
+
options.signalBatchSize <= 0) {
|
|
86
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] signalBatchSize must be a positive integer, got: ${options.signalBatchSize}.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Validate each signal's configuration
|
|
90
|
+
for (const signal of rawSignals) {
|
|
91
|
+
// Requirement 1.5: cooldown without cooldownMs → debug warning, treat as 'always'
|
|
92
|
+
if (signal.behavior === 'cooldown' && signal.cooldownMs == null) {
|
|
93
|
+
logger.debug(`[Agent] Signal "${signal.id}" has behavior 'cooldown' but no cooldownMs. Treating as 'always'.`);
|
|
94
|
+
signal.behavior = 'always';
|
|
95
|
+
}
|
|
96
|
+
// Requirement 1.9: validate extract schema is a JSON Schema object
|
|
97
|
+
if (signal.extract !== undefined) {
|
|
98
|
+
if (signal.extract === null ||
|
|
99
|
+
typeof signal.extract !== 'object' ||
|
|
100
|
+
Array.isArray(signal.extract)) {
|
|
101
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Signal "${signal.id}" has an invalid extract schema. ` +
|
|
102
|
+
`Expected a JSON Schema object, got: ${typeof signal.extract}.`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
this._signals = rawSignals;
|
|
107
|
+
// Requirement 2.3: Only instantiate SignalProcessor when signals are present
|
|
108
|
+
if (rawSignals.length > 0) {
|
|
109
|
+
const evaluator = new SignalEvaluator(options.provider);
|
|
110
|
+
this.signalProcessor = new SignalProcessor(rawSignals, options.provider, evaluator, { batchSize: options.signalBatchSize ?? 10 });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.signalProcessor = undefined;
|
|
114
|
+
}
|
|
50
115
|
// Set log level based on debug option
|
|
51
116
|
if (options.debug) {
|
|
52
117
|
logger.setLevel(LoggerLevel.DEBUG);
|
|
@@ -78,10 +143,10 @@ export class Agent {
|
|
|
78
143
|
this._currentSession = options.session;
|
|
79
144
|
// Initialize prompt section cache
|
|
80
145
|
this._promptSectionCache = new PromptSectionCache(options.promptCache);
|
|
81
|
-
// Initialize
|
|
82
|
-
this._routingEngine = new
|
|
83
|
-
|
|
84
|
-
|
|
146
|
+
// Initialize flow router
|
|
147
|
+
this._routingEngine = new FlowRouter({
|
|
148
|
+
flowSwitchMargin: options.flowSwitchMargin,
|
|
149
|
+
onFlowSwitch: () => this.invalidateFlowSections(),
|
|
85
150
|
promptSectionCache: this._promptSectionCache,
|
|
86
151
|
});
|
|
87
152
|
// Initialize ResponseModal for handling all response generation
|
|
@@ -119,28 +184,25 @@ export class Agent {
|
|
|
119
184
|
this.createTerm(term);
|
|
120
185
|
});
|
|
121
186
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
187
|
+
// Initialize instructions (new unified form)
|
|
188
|
+
if (options.instructions) {
|
|
189
|
+
options.instructions.forEach((instruction) => {
|
|
190
|
+
this.createInstruction(instruction);
|
|
125
191
|
});
|
|
126
192
|
}
|
|
127
193
|
if (options.tools) {
|
|
128
194
|
options.tools.forEach((tool) => {
|
|
129
|
-
this.
|
|
195
|
+
this.addTool(tool);
|
|
130
196
|
});
|
|
131
197
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
if (options.prohibitions) {
|
|
137
|
-
this._prohibitions = [...options.prohibitions];
|
|
138
|
-
}
|
|
139
|
-
if (options.routes) {
|
|
140
|
-
options.routes.forEach((routeOptions) => {
|
|
141
|
-
this.createRoute(routeOptions);
|
|
198
|
+
if (options.flows) {
|
|
199
|
+
options.flows.forEach((flowOptions) => {
|
|
200
|
+
this.createFlow(flowOptions);
|
|
142
201
|
});
|
|
143
202
|
}
|
|
203
|
+
// Validate deferred branch `then` string references against the flow registry.
|
|
204
|
+
// This catches strings that don't match a local step id AND don't match any flow id/title.
|
|
205
|
+
this.validateBranchReferences();
|
|
144
206
|
// Initialize knowledge base
|
|
145
207
|
if (options.knowledgeBase) {
|
|
146
208
|
this._knowledgeBase = { ...options.knowledgeBase };
|
|
@@ -196,6 +258,66 @@ export class Agent {
|
|
|
196
258
|
}
|
|
197
259
|
logger.debug("[Agent] Schema validation passed");
|
|
198
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Walk every flow's steps and resolve deferred string `then` values in branches
|
|
263
|
+
* against the agent's flow registry. Strings that match neither a local step id
|
|
264
|
+
* nor any flow id/title throw FlowConfigurationError.
|
|
265
|
+
* @private
|
|
266
|
+
*/
|
|
267
|
+
validateBranchReferences() {
|
|
268
|
+
for (const flow of this._flows) {
|
|
269
|
+
this.validateFlowBranchReferences(flow);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Validate branch `then` string references for a single flow against the agent's
|
|
274
|
+
* flow registry. Throws FlowConfigurationError for unresolved references.
|
|
275
|
+
* @private
|
|
276
|
+
*/
|
|
277
|
+
validateFlowBranchReferences(flow) {
|
|
278
|
+
const steps = flow.getAllSteps();
|
|
279
|
+
const localStepIds = new Set(steps.map(s => s.id));
|
|
280
|
+
for (const step of steps) {
|
|
281
|
+
if (!step.branches)
|
|
282
|
+
continue;
|
|
283
|
+
for (const entry of step.branches) {
|
|
284
|
+
if (typeof entry.then !== 'string')
|
|
285
|
+
continue;
|
|
286
|
+
// Already matches a local step id — no deferred resolution needed
|
|
287
|
+
if (localStepIds.has(entry.then))
|
|
288
|
+
continue;
|
|
289
|
+
// Check against the agent's flow registry (id or title)
|
|
290
|
+
const matchesFlow = this._flows.some(f => f.id === entry.then || f.title === entry.then);
|
|
291
|
+
if (!matchesFlow) {
|
|
292
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Unresolved branch target: "${entry.then}" in ${flow.id}.${step.id} does not match any step in the flow or any flow in the agent. ` +
|
|
293
|
+
`Fix the branch "then" value to reference a valid step id or flow id/title.`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Validate that every step's `collect` fields in a flow reference valid keys
|
|
300
|
+
* from the agent-level schema. Throws FlowConfigurationError at construction
|
|
301
|
+
* time if any collect field is not a valid schema key.
|
|
302
|
+
*
|
|
303
|
+
* This enforces Requirement 14.5: generic inference is preserved AND every
|
|
304
|
+
* `collect` field reference is a valid key of the inferred TData.
|
|
305
|
+
* @private
|
|
306
|
+
*/
|
|
307
|
+
validateFlowCollectFields(flow) {
|
|
308
|
+
const schemaKeys = Object.keys(this._schema.properties);
|
|
309
|
+
const schemaKeySet = new Set(schemaKeys);
|
|
310
|
+
const steps = flow.getAllSteps();
|
|
311
|
+
for (const step of steps) {
|
|
312
|
+
if (!step.collect || step.collect.length === 0)
|
|
313
|
+
continue;
|
|
314
|
+
const invalidFields = step.collect.filter(field => !schemaKeySet.has(String(field)));
|
|
315
|
+
if (invalidFields.length > 0) {
|
|
316
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Step "${step.id}" in flow "${flow.title}" references invalid collect fields: ${invalidFields.map(f => String(f)).join(', ')}. ` +
|
|
317
|
+
`Must be valid keys from agent schema. Available fields: ${schemaKeys.join(', ')}.`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
199
321
|
/**
|
|
200
322
|
* Validate data against the agent-level schema
|
|
201
323
|
*/
|
|
@@ -266,7 +388,7 @@ export class Agent {
|
|
|
266
388
|
const validation = this.validateData(updates);
|
|
267
389
|
if (!validation.valid) {
|
|
268
390
|
const errorMessages = validation.errors.map(e => e.message).join(', ');
|
|
269
|
-
throw new DataValidationError(validation.errors, `Data validation failed: ${errorMessages}
|
|
391
|
+
throw new DataValidationError(validation.errors, `[DataValidationError] Data validation failed: fields [${errorMessages}] did not pass schema validation. Fix the offending values to match the declared schema.`);
|
|
270
392
|
}
|
|
271
393
|
// Log warnings if any
|
|
272
394
|
if (validation.warnings.length > 0) {
|
|
@@ -311,16 +433,16 @@ export class Agent {
|
|
|
311
433
|
this.options.name = value;
|
|
312
434
|
}
|
|
313
435
|
/**
|
|
314
|
-
* Get agent
|
|
436
|
+
* Get agent persona
|
|
315
437
|
*/
|
|
316
|
-
get
|
|
317
|
-
return this.options.
|
|
438
|
+
get persona() {
|
|
439
|
+
return this.options.persona;
|
|
318
440
|
}
|
|
319
441
|
/**
|
|
320
|
-
* Set agent
|
|
442
|
+
* Set agent persona
|
|
321
443
|
*/
|
|
322
|
-
set
|
|
323
|
-
this.options.
|
|
444
|
+
set persona(value) {
|
|
445
|
+
this.options.persona = value;
|
|
324
446
|
}
|
|
325
447
|
/**
|
|
326
448
|
* Get agent goal
|
|
@@ -334,30 +456,6 @@ export class Agent {
|
|
|
334
456
|
set goal(value) {
|
|
335
457
|
this.options.goal = value;
|
|
336
458
|
}
|
|
337
|
-
/**
|
|
338
|
-
* Get agent identity
|
|
339
|
-
*/
|
|
340
|
-
get identity() {
|
|
341
|
-
return this.options.identity;
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Set agent identity
|
|
345
|
-
*/
|
|
346
|
-
set identity(value) {
|
|
347
|
-
this.options.identity = value;
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Get agent personality
|
|
351
|
-
*/
|
|
352
|
-
get personality() {
|
|
353
|
-
return this.options.personality;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Set agent personality
|
|
357
|
-
*/
|
|
358
|
-
set personality(value) {
|
|
359
|
-
this.options.personality = value;
|
|
360
|
-
}
|
|
361
459
|
/**
|
|
362
460
|
* Get whether debug mode is enabled
|
|
363
461
|
*/
|
|
@@ -384,29 +482,17 @@ export class Agent {
|
|
|
384
482
|
this.options.provider = value;
|
|
385
483
|
}
|
|
386
484
|
/**
|
|
387
|
-
* Get the
|
|
388
|
-
*/
|
|
389
|
-
get compositionMode() {
|
|
390
|
-
return this.options.compositionMode ?? CompositionMode.FLUID;
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Set the composition mode
|
|
394
|
-
*/
|
|
395
|
-
set compositionMode(value) {
|
|
396
|
-
this.options.compositionMode = value;
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Get the route switch margin
|
|
485
|
+
* Get the flow switch margin
|
|
400
486
|
* @default 15
|
|
401
487
|
*/
|
|
402
|
-
get
|
|
403
|
-
return this.options.
|
|
488
|
+
get flowSwitchMargin() {
|
|
489
|
+
return this.options.flowSwitchMargin ?? 15;
|
|
404
490
|
}
|
|
405
491
|
/**
|
|
406
|
-
* Set the
|
|
492
|
+
* Set the flow switch margin
|
|
407
493
|
*/
|
|
408
|
-
set
|
|
409
|
-
this.options.
|
|
494
|
+
set flowSwitchMargin(value) {
|
|
495
|
+
this.options.flowSwitchMargin = value;
|
|
410
496
|
}
|
|
411
497
|
/**
|
|
412
498
|
* Get the prompt section cache instance
|
|
@@ -414,19 +500,6 @@ export class Agent {
|
|
|
414
500
|
get promptSectionCache() {
|
|
415
501
|
return this._promptSectionCache;
|
|
416
502
|
}
|
|
417
|
-
/**
|
|
418
|
-
* Get the maximum steps per batch
|
|
419
|
-
* @default 1
|
|
420
|
-
*/
|
|
421
|
-
get maxStepsPerBatch() {
|
|
422
|
-
return this.options.maxStepsPerBatch ?? 1;
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Set the maximum steps per batch
|
|
426
|
-
*/
|
|
427
|
-
set maxStepsPerBatch(value) {
|
|
428
|
-
this.options.maxStepsPerBatch = value;
|
|
429
|
-
}
|
|
430
503
|
/**
|
|
431
504
|
* Get all terms
|
|
432
505
|
*/
|
|
@@ -434,10 +507,10 @@ export class Agent {
|
|
|
434
507
|
return [...this._terms];
|
|
435
508
|
}
|
|
436
509
|
/**
|
|
437
|
-
* Get all
|
|
510
|
+
* Get all instructions
|
|
438
511
|
*/
|
|
439
|
-
get
|
|
440
|
-
return [...this.
|
|
512
|
+
get instructions() {
|
|
513
|
+
return [...this._instructions];
|
|
441
514
|
}
|
|
442
515
|
/**
|
|
443
516
|
* Get all tools
|
|
@@ -446,34 +519,10 @@ export class Agent {
|
|
|
446
519
|
return [...this._tools];
|
|
447
520
|
}
|
|
448
521
|
/**
|
|
449
|
-
* Get all
|
|
450
|
-
*/
|
|
451
|
-
get routes() {
|
|
452
|
-
return [...this._routes];
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Get agent-level rules
|
|
456
|
-
*/
|
|
457
|
-
get rules() {
|
|
458
|
-
return [...this._rules];
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Set agent-level rules
|
|
462
|
-
*/
|
|
463
|
-
set rules(value) {
|
|
464
|
-
this._rules = [...value];
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Get agent-level prohibitions
|
|
522
|
+
* Get all flows
|
|
468
523
|
*/
|
|
469
|
-
get
|
|
470
|
-
return [...this.
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Set agent-level prohibitions
|
|
474
|
-
*/
|
|
475
|
-
set prohibitions(value) {
|
|
476
|
-
this._prohibitions = [...value];
|
|
524
|
+
get flows() {
|
|
525
|
+
return [...this._flows];
|
|
477
526
|
}
|
|
478
527
|
/**
|
|
479
528
|
* Get current schema
|
|
@@ -490,6 +539,13 @@ export class Agent {
|
|
|
490
539
|
}
|
|
491
540
|
this._schema = value;
|
|
492
541
|
}
|
|
542
|
+
/**
|
|
543
|
+
* Get the configured signals.
|
|
544
|
+
*/
|
|
545
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
546
|
+
get signals() {
|
|
547
|
+
return this._signals;
|
|
548
|
+
}
|
|
493
549
|
/**
|
|
494
550
|
* Get the agent's knowledge base
|
|
495
551
|
*/
|
|
@@ -516,98 +572,38 @@ export class Agent {
|
|
|
516
572
|
this._currentSession = value;
|
|
517
573
|
this._promptSectionCache.invalidateAll();
|
|
518
574
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
575
|
+
/**
|
|
576
|
+
* Get all flows
|
|
577
|
+
*/
|
|
578
|
+
getFlows() {
|
|
579
|
+
return this.flows;
|
|
580
|
+
}
|
|
522
581
|
/**
|
|
523
582
|
* Get all terms
|
|
524
|
-
* @deprecated Use `agent.terms` instead
|
|
525
583
|
*/
|
|
526
584
|
getTerms() {
|
|
527
585
|
return this.terms;
|
|
528
586
|
}
|
|
529
587
|
/**
|
|
530
588
|
* Get all tools
|
|
531
|
-
* @deprecated Use `agent.tools` instead
|
|
532
589
|
*/
|
|
533
590
|
getTools() {
|
|
534
591
|
return this.tools;
|
|
535
592
|
}
|
|
536
593
|
/**
|
|
537
|
-
* Get all
|
|
538
|
-
* @deprecated Use `agent.guidelines` instead
|
|
594
|
+
* Get all instructions
|
|
539
595
|
*/
|
|
540
|
-
|
|
541
|
-
return this.
|
|
596
|
+
getInstructions() {
|
|
597
|
+
return this.instructions;
|
|
542
598
|
}
|
|
543
599
|
/**
|
|
544
|
-
*
|
|
545
|
-
*
|
|
600
|
+
* Invalidate flow-dependent prompt cache sections.
|
|
601
|
+
* Called automatically when the active flow changes.
|
|
546
602
|
*/
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
* Get agent-level rules
|
|
552
|
-
* @deprecated Use `agent.rules` instead
|
|
553
|
-
*/
|
|
554
|
-
getRules() {
|
|
555
|
-
return this.rules;
|
|
556
|
-
}
|
|
557
|
-
/**
|
|
558
|
-
* Get agent-level prohibitions
|
|
559
|
-
* @deprecated Use `agent.prohibitions` instead
|
|
560
|
-
*/
|
|
561
|
-
getProhibitions() {
|
|
562
|
-
return this.prohibitions;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Get current schema
|
|
566
|
-
* @deprecated Use `agent.schema` instead
|
|
567
|
-
*/
|
|
568
|
-
getSchema() {
|
|
569
|
-
return this.schema;
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* Get the agent's knowledge base
|
|
573
|
-
* @deprecated Use `agent.knowledgeBase` instead
|
|
574
|
-
*/
|
|
575
|
-
getKnowledgeBase() {
|
|
576
|
-
return this.knowledgeBase;
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Get the current session (if set)
|
|
580
|
-
* @deprecated Use `agent.currentSession` instead
|
|
581
|
-
*/
|
|
582
|
-
getCurrentSession() {
|
|
583
|
-
return this.currentSession;
|
|
584
|
-
}
|
|
585
|
-
/**
|
|
586
|
-
* Set the current session for convenience methods
|
|
587
|
-
* @deprecated Use `agent.currentSession = session` instead
|
|
588
|
-
* @param session - Session step to use for subsequent calls
|
|
589
|
-
*/
|
|
590
|
-
setCurrentSession(session) {
|
|
591
|
-
this.currentSession = session;
|
|
592
|
-
this._promptSectionCache.invalidateAll();
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Clear the current session
|
|
596
|
-
* @deprecated Use `agent.currentSession = undefined` instead
|
|
597
|
-
*/
|
|
598
|
-
clearCurrentSession() {
|
|
599
|
-
this._currentSession = undefined;
|
|
600
|
-
this._promptSectionCache.invalidateAll();
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Invalidate route-dependent prompt cache sections.
|
|
604
|
-
* Called automatically when the active route changes.
|
|
605
|
-
*/
|
|
606
|
-
invalidateRouteSections() {
|
|
607
|
-
this._promptSectionCache.invalidate('activeRoutes');
|
|
608
|
-
this._promptSectionCache.invalidate('routeRules');
|
|
609
|
-
this._promptSectionCache.invalidate('routeProhibitions');
|
|
610
|
-
this._promptSectionCache.invalidate('routeKnowledgeBase');
|
|
603
|
+
invalidateFlowSections() {
|
|
604
|
+
this._promptSectionCache.invalidate('activeFlows');
|
|
605
|
+
this._promptSectionCache.invalidate('flowKnowledgeBase');
|
|
606
|
+
this._promptSectionCache.invalidate('instructionsFlow');
|
|
611
607
|
}
|
|
612
608
|
/**
|
|
613
609
|
* Get the persistence manager (if configured)
|
|
@@ -631,28 +627,32 @@ export class Agent {
|
|
|
631
627
|
// Core methods
|
|
632
628
|
// ---------------------------------------------------------------------------
|
|
633
629
|
/**
|
|
634
|
-
* Create a new
|
|
630
|
+
* Create a new flow (journey) using agent-level data type
|
|
635
631
|
*/
|
|
636
|
-
|
|
632
|
+
createFlow(options) {
|
|
637
633
|
// Validate that requiredFields exist in agent schema
|
|
638
634
|
if (options.requiredFields && this._schema?.properties) {
|
|
639
635
|
const invalidRequiredFields = options.requiredFields.filter(field => !(String(field) in this._schema.properties));
|
|
640
636
|
if (invalidRequiredFields.length > 0) {
|
|
641
|
-
throw new
|
|
642
|
-
`
|
|
637
|
+
throw new FlowConfigurationError(options.title, invalidRequiredFields.map(f => String(f)), `[FlowConfigurationError] Invalid required fields in flow "${options.title}": [${invalidRequiredFields.join(', ')}] are not declared in the agent schema. ` +
|
|
638
|
+
`Use valid schema keys. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`);
|
|
643
639
|
}
|
|
644
640
|
}
|
|
645
641
|
// Validate that optionalFields exist in agent schema
|
|
646
642
|
if (options.optionalFields && this._schema?.properties) {
|
|
647
643
|
const invalidOptionalFields = options.optionalFields.filter(field => !(String(field) in this._schema.properties));
|
|
648
644
|
if (invalidOptionalFields.length > 0) {
|
|
649
|
-
throw new
|
|
650
|
-
`
|
|
645
|
+
throw new FlowConfigurationError(options.title, invalidOptionalFields.map(f => String(f)), `[FlowConfigurationError] Invalid optional fields in flow "${options.title}": [${invalidOptionalFields.join(', ')}] are not declared in the agent schema. ` +
|
|
646
|
+
`Use valid schema keys. Available fields: ${Object.keys(this._schema.properties).join(', ')}.`);
|
|
651
647
|
}
|
|
652
648
|
}
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
649
|
+
const flow = new Flow(options, this);
|
|
650
|
+
// Validate that step collect fields reference valid schema keys
|
|
651
|
+
if (this._schema?.properties) {
|
|
652
|
+
this.validateFlowCollectFields(flow);
|
|
653
|
+
}
|
|
654
|
+
this._flows.push(flow);
|
|
655
|
+
return flow;
|
|
656
656
|
}
|
|
657
657
|
/**
|
|
658
658
|
* Create a domain term for the glossary
|
|
@@ -662,20 +662,22 @@ export class Agent {
|
|
|
662
662
|
return this;
|
|
663
663
|
}
|
|
664
664
|
/**
|
|
665
|
-
* Create
|
|
665
|
+
* Create an instruction (unified behavioral primitive).
|
|
666
666
|
*/
|
|
667
|
-
|
|
668
|
-
const
|
|
669
|
-
...
|
|
670
|
-
|
|
671
|
-
|
|
667
|
+
createInstruction(instruction) {
|
|
668
|
+
const instructionWithId = {
|
|
669
|
+
...instruction,
|
|
670
|
+
kind: instruction.kind || 'should',
|
|
671
|
+
id: instruction.id || `instruction_${this._instructions.length}`,
|
|
672
|
+
enabled: instruction.enabled !== false, // Default to true
|
|
672
673
|
};
|
|
673
|
-
this.
|
|
674
|
+
this._instructions.push(instructionWithId);
|
|
675
|
+
this._promptSectionCache.invalidate('instructionsGlobal');
|
|
674
676
|
return this;
|
|
675
677
|
}
|
|
676
678
|
/**
|
|
677
679
|
* Add a tool to the agent using the unified Tool interface
|
|
678
|
-
* Creates and adds the tool to agent scope in one operation
|
|
680
|
+
* Creates and adds the tool to agent scope in one operation
|
|
679
681
|
*/
|
|
680
682
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
681
683
|
addTool(tool) {
|
|
@@ -688,20 +690,6 @@ export class Agent {
|
|
|
688
690
|
logger.debug(`[Agent] Added tool to agent scope: ${tool.id}`);
|
|
689
691
|
return this;
|
|
690
692
|
}
|
|
691
|
-
/**
|
|
692
|
-
* Register a tool at the agent level (legacy method for backward compatibility)
|
|
693
|
-
* @deprecated Use addTool() with Tool interface instead
|
|
694
|
-
*/
|
|
695
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
696
|
-
createTool(tool) {
|
|
697
|
-
// Validate tool before adding
|
|
698
|
-
if (!tool || !tool.id || !tool.handler) {
|
|
699
|
-
throw new Error('Invalid tool: must have id and handler properties');
|
|
700
|
-
}
|
|
701
|
-
this._tools.push(tool);
|
|
702
|
-
logger.debug(`[Agent] Created tool (legacy): ${tool.id}`);
|
|
703
|
-
return this;
|
|
704
|
-
}
|
|
705
693
|
/**
|
|
706
694
|
* Register multiple tools at the agent level
|
|
707
695
|
*/
|
|
@@ -719,7 +707,7 @@ export class Agent {
|
|
|
719
707
|
}
|
|
720
708
|
/**
|
|
721
709
|
* Update the agent's context
|
|
722
|
-
* Triggers both agent-level and
|
|
710
|
+
* Triggers both agent-level and flow-specific onContextUpdate lifecycle hooks if configured
|
|
723
711
|
*/
|
|
724
712
|
async updateContext(updates) {
|
|
725
713
|
const previousContext = this._context;
|
|
@@ -728,12 +716,12 @@ export class Agent {
|
|
|
728
716
|
...this._context,
|
|
729
717
|
...updates,
|
|
730
718
|
};
|
|
731
|
-
// Trigger
|
|
732
|
-
if (this._currentSession?.
|
|
733
|
-
const
|
|
734
|
-
if (
|
|
719
|
+
// Trigger flow-specific lifecycle hook if configured and session has current flow
|
|
720
|
+
if (this._currentSession?.currentFlow) {
|
|
721
|
+
const currentFlow = this._flows.find((r) => r.id === this._currentSession.currentFlow?.id);
|
|
722
|
+
if (currentFlow?.hooks?.onContextUpdate &&
|
|
735
723
|
previousContext !== undefined) {
|
|
736
|
-
await
|
|
724
|
+
await currentFlow.handleContextUpdate(this._context, previousContext);
|
|
737
725
|
}
|
|
738
726
|
}
|
|
739
727
|
// Trigger agent-level lifecycle hook if configured
|
|
@@ -743,10 +731,11 @@ export class Agent {
|
|
|
743
731
|
// Invalidate context-dependent prompt cache sections
|
|
744
732
|
this._promptSectionCache.invalidate('agentMeta');
|
|
745
733
|
this._promptSectionCache.invalidate('knowledgeBase');
|
|
734
|
+
this._promptSectionCache.invalidate('instructionsGlobal');
|
|
746
735
|
}
|
|
747
736
|
/**
|
|
748
737
|
* Update collected data in session with lifecycle hook support
|
|
749
|
-
* Triggers both agent-level and
|
|
738
|
+
* Triggers both agent-level and flow-specific onDataUpdate lifecycle hooks if configured
|
|
750
739
|
* @internal
|
|
751
740
|
*/
|
|
752
741
|
async updateData(session, dataUpdate) {
|
|
@@ -756,11 +745,11 @@ export class Agent {
|
|
|
756
745
|
...session.data,
|
|
757
746
|
...dataUpdate,
|
|
758
747
|
};
|
|
759
|
-
// Trigger
|
|
760
|
-
if (session.
|
|
761
|
-
const
|
|
762
|
-
if (
|
|
763
|
-
newCollected = await
|
|
748
|
+
// Trigger flow-specific lifecycle hook if configured and session has a current flow
|
|
749
|
+
if (session.currentFlow) {
|
|
750
|
+
const currentFlow = this._flows.find((r) => r.id === session.currentFlow?.id);
|
|
751
|
+
if (currentFlow?.hooks?.onDataUpdate) {
|
|
752
|
+
newCollected = await currentFlow.handleDataUpdate(newCollected, previousCollected);
|
|
764
753
|
}
|
|
765
754
|
}
|
|
766
755
|
// Trigger agent-level lifecycle hook if configured
|
|
@@ -805,10 +794,10 @@ export class Agent {
|
|
|
805
794
|
return this.options;
|
|
806
795
|
}
|
|
807
796
|
/**
|
|
808
|
-
* Get
|
|
797
|
+
* Get flow router
|
|
809
798
|
* @internal Used by ResponseModal
|
|
810
799
|
*/
|
|
811
|
-
|
|
800
|
+
getFlowRouter() {
|
|
812
801
|
return this._routingEngine;
|
|
813
802
|
}
|
|
814
803
|
/**
|
|
@@ -818,51 +807,11 @@ export class Agent {
|
|
|
818
807
|
getUpdateDataMethod() {
|
|
819
808
|
return this.updateData.bind(this);
|
|
820
809
|
}
|
|
821
|
-
/**
|
|
822
|
-
* Evaluate and match active guidelines based on their conditions
|
|
823
|
-
* Returns guidelines that should be active given the current context
|
|
824
|
-
*/
|
|
825
|
-
async evaluateGuidelines(context, session, history) {
|
|
826
|
-
const templateContext = { context, session, history, data: session?.data };
|
|
827
|
-
const evaluator = createConditionEvaluator(templateContext);
|
|
828
|
-
const matches = [];
|
|
829
|
-
for (const guideline of this._guidelines) {
|
|
830
|
-
// Skip disabled guidelines
|
|
831
|
-
if (guideline.enabled === false) {
|
|
832
|
-
continue;
|
|
833
|
-
}
|
|
834
|
-
if (guideline.condition) {
|
|
835
|
-
const evaluation = await evaluator.evaluateCondition(guideline.condition, 'AND');
|
|
836
|
-
// Include guideline if:
|
|
837
|
-
// 1. No programmatic conditions (only strings) - always active
|
|
838
|
-
// 2. Programmatic conditions evaluate to true
|
|
839
|
-
if (!evaluation.hasProgrammaticConditions || evaluation.programmaticResult) {
|
|
840
|
-
const rationale = evaluation.aiContextStrings.length > 0
|
|
841
|
-
? `Condition met: ${evaluation.aiContextStrings.join(" AND ")}`
|
|
842
|
-
: evaluation.hasProgrammaticConditions
|
|
843
|
-
? "Programmatic condition evaluated to true"
|
|
844
|
-
: "Always active (no conditions)";
|
|
845
|
-
matches.push({
|
|
846
|
-
guideline,
|
|
847
|
-
rationale
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
else {
|
|
852
|
-
// No condition means always active
|
|
853
|
-
matches.push({
|
|
854
|
-
guideline,
|
|
855
|
-
rationale: "Always active (no conditions)"
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
return matches;
|
|
860
|
-
}
|
|
861
810
|
/**
|
|
862
811
|
* Execute a prepare or finalize function/tool
|
|
863
812
|
* @internal Used by ResponseModal
|
|
864
813
|
*/
|
|
865
|
-
async executePrepareFinalize(prepareOrFinalize, context, data,
|
|
814
|
+
async executePrepareFinalize(prepareOrFinalize, context, data, flow, step) {
|
|
866
815
|
if (!prepareOrFinalize)
|
|
867
816
|
return;
|
|
868
817
|
if (typeof prepareOrFinalize === "function") {
|
|
@@ -874,7 +823,7 @@ export class Agent {
|
|
|
874
823
|
let tool;
|
|
875
824
|
if (typeof prepareOrFinalize === "string") {
|
|
876
825
|
// Tool ID - use ToolManager to find it across all scopes
|
|
877
|
-
tool = this.tool.find(prepareOrFinalize, undefined, step,
|
|
826
|
+
tool = this.tool.find(prepareOrFinalize, undefined, step, flow);
|
|
878
827
|
}
|
|
879
828
|
else {
|
|
880
829
|
// Tool object - validate it has required properties
|
|
@@ -921,7 +870,6 @@ export class Agent {
|
|
|
921
870
|
}
|
|
922
871
|
/**
|
|
923
872
|
* Get collected data from current session or agent-level collected data
|
|
924
|
-
* @param routeId - Optional route ID to get data for (uses current route if not provided)
|
|
925
873
|
* @returns The collected data from the current session or agent-level data
|
|
926
874
|
*/
|
|
927
875
|
getData() {
|
|
@@ -929,64 +877,263 @@ export class Agent {
|
|
|
929
877
|
this.syncSessionDataToCollectedData();
|
|
930
878
|
// If we have a current session, use session data
|
|
931
879
|
if (this._currentSession) {
|
|
932
|
-
// With agent-level data, all
|
|
933
|
-
// No need for
|
|
880
|
+
// With agent-level data, all flows share the same data structure
|
|
881
|
+
// No need for flow-specific data access
|
|
934
882
|
return (this._currentSession.data) || {};
|
|
935
883
|
}
|
|
936
884
|
// Otherwise, return agent-level collected data
|
|
937
885
|
return this.getCollectedData();
|
|
938
886
|
}
|
|
939
887
|
/**
|
|
940
|
-
*
|
|
941
|
-
* Sets
|
|
888
|
+
* Dispatch a directive (or a flow shorthand) into a session.
|
|
889
|
+
* Sets `pendingDirective` on the session without triggering a `respond()` call.
|
|
890
|
+
* The directive will be applied at the start of the next turn.
|
|
891
|
+
*
|
|
892
|
+
* String form desugars to `{ goTo: target }`.
|
|
942
893
|
*
|
|
943
|
-
* @param
|
|
944
|
-
* @param session - Session
|
|
945
|
-
* @
|
|
946
|
-
*
|
|
894
|
+
* @param target - Flow ID/title string (desugars to `{ goTo: target }`) or a full Directive
|
|
895
|
+
* @param session - Session to update (uses current session if not provided)
|
|
896
|
+
* @returns Updated session with `pendingDirective` set
|
|
897
|
+
*
|
|
898
|
+
* @throws FlowConfigurationError if the string target doesn't match any flow
|
|
899
|
+
* @throws FlowConfigurationError if the directive fails validation
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* // String shorthand — desugars to { goTo: 'Feedback' }
|
|
903
|
+
* const updated = await agent.dispatch('Feedback', session);
|
|
947
904
|
*
|
|
948
905
|
* @example
|
|
949
|
-
* //
|
|
950
|
-
*
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
* }
|
|
955
|
-
*/
|
|
956
|
-
async nextStepRoute(routeIdOrTitle, session, condition, history) {
|
|
906
|
+
* // Full directive
|
|
907
|
+
* const updated = await agent.dispatch({ goTo: 'Billing', reply: 'Transferring you now.' }, session);
|
|
908
|
+
*/
|
|
909
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
910
|
+
async dispatch(target, session) {
|
|
957
911
|
const targetSession = session || this._currentSession;
|
|
958
912
|
if (!targetSession) {
|
|
959
|
-
throw new Error("No session provided and no current session available. Please provide a session to
|
|
960
|
-
}
|
|
961
|
-
//
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
913
|
+
throw new Error("No session provided and no current session available. Please provide a session to dispatch into.");
|
|
914
|
+
}
|
|
915
|
+
// Desugar string form to { goTo: target }
|
|
916
|
+
const directive = typeof target === 'string'
|
|
917
|
+
? { goTo: target }
|
|
918
|
+
: target;
|
|
919
|
+
// Validate the directive: check for multiple position fields, empty goTo, etc.
|
|
920
|
+
this.validateDirective(directive);
|
|
921
|
+
// If goTo is a string, validate it references a known flow
|
|
922
|
+
if (typeof directive.goTo === 'string') {
|
|
923
|
+
const flowTarget = directive.goTo;
|
|
924
|
+
const matchesFlow = this._flows.some(f => f.id === flowTarget || f.title === flowTarget);
|
|
925
|
+
if (!matchesFlow) {
|
|
926
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
927
|
+
`Available flows: ${this._flows.map(f => f.title).join(', ')}.`);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
else if (directive.goTo && typeof directive.goTo === 'object' && directive.goTo.flow) {
|
|
931
|
+
const flowTarget = directive.goTo.flow;
|
|
932
|
+
const matchesFlow = this._flows.some(f => f.id === flowTarget || f.title === flowTarget);
|
|
933
|
+
if (!matchesFlow) {
|
|
934
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Unknown flow: "${flowTarget}" does not match any flow id or title. ` +
|
|
935
|
+
`Available flows: ${this._flows.map(f => f.title).join(', ')}.`);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
// Strip PreDirective-only fields before storing
|
|
939
|
+
const stripped = this.stripPreDirectiveFields(directive);
|
|
940
|
+
// Set pendingDirective on the session without applying it
|
|
975
941
|
const updatedSession = {
|
|
976
942
|
...targetSession,
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
943
|
+
pendingDirective: stripped,
|
|
944
|
+
metadata: {
|
|
945
|
+
...targetSession.metadata,
|
|
946
|
+
lastUpdatedAt: new Date(),
|
|
981
947
|
},
|
|
982
948
|
};
|
|
983
|
-
// Update current session if
|
|
949
|
+
// Update current session in place if no explicit session was passed
|
|
984
950
|
if (!session && this._currentSession) {
|
|
985
951
|
this._currentSession = updatedSession;
|
|
986
952
|
}
|
|
987
|
-
logger.debug(`[Agent]
|
|
953
|
+
logger.debug(`[Agent] Dispatched directive: pendingDirective set on session ${updatedSession.id}`);
|
|
954
|
+
return updatedSession;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Apply a directive synchronously to a session without invoking `respond()`.
|
|
958
|
+
* Performs in-place application: updates flow/step position, merges state writes.
|
|
959
|
+
*
|
|
960
|
+
* This is the synchronous counterpart to `dispatch` — it applies immediately
|
|
961
|
+
* rather than deferring to the next turn.
|
|
962
|
+
*
|
|
963
|
+
* @param directive - The directive to apply
|
|
964
|
+
* @param session - The session to apply the directive to
|
|
965
|
+
* @returns The updated session with the directive applied
|
|
966
|
+
*/
|
|
967
|
+
applyDirective(directive, session) {
|
|
968
|
+
// Validate the directive
|
|
969
|
+
this.validateDirective(directive);
|
|
970
|
+
let updatedSession = { ...session };
|
|
971
|
+
const now = new Date();
|
|
972
|
+
// Apply state writes
|
|
973
|
+
if (directive.contextUpdate) {
|
|
974
|
+
// Context updates are applied to the agent, not the session
|
|
975
|
+
this._context = {
|
|
976
|
+
...this._context,
|
|
977
|
+
...directive.contextUpdate,
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
if (directive.dataUpdate) {
|
|
981
|
+
updatedSession = {
|
|
982
|
+
...updatedSession,
|
|
983
|
+
data: {
|
|
984
|
+
...updatedSession.data,
|
|
985
|
+
...directive.dataUpdate,
|
|
986
|
+
},
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
// Apply position control
|
|
990
|
+
if (directive.goTo) {
|
|
991
|
+
const flowTarget = typeof directive.goTo === 'string'
|
|
992
|
+
? directive.goTo
|
|
993
|
+
: directive.goTo.flow;
|
|
994
|
+
if (flowTarget) {
|
|
995
|
+
const targetFlow = this._flows.find(f => f.id === flowTarget || f.title === flowTarget);
|
|
996
|
+
if (targetFlow) {
|
|
997
|
+
// Merge goTo.data if present
|
|
998
|
+
if (typeof directive.goTo === 'object' && directive.goTo.data) {
|
|
999
|
+
updatedSession = {
|
|
1000
|
+
...updatedSession,
|
|
1001
|
+
data: {
|
|
1002
|
+
...updatedSession.data,
|
|
1003
|
+
...directive.goTo.data,
|
|
1004
|
+
},
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
updatedSession = enterFlow(updatedSession, targetFlow.id, targetFlow.title);
|
|
1008
|
+
// If a specific step is targeted
|
|
1009
|
+
if (typeof directive.goTo === 'object' && directive.goTo.step) {
|
|
1010
|
+
updatedSession = enterStep(updatedSession, directive.goTo.step);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
else if (directive.goToStep) {
|
|
1016
|
+
const stepTarget = typeof directive.goToStep === 'string'
|
|
1017
|
+
? directive.goToStep
|
|
1018
|
+
: directive.goToStep.step;
|
|
1019
|
+
// Merge goToStep.data if present
|
|
1020
|
+
if (typeof directive.goToStep === 'object' && directive.goToStep.data) {
|
|
1021
|
+
updatedSession = {
|
|
1022
|
+
...updatedSession,
|
|
1023
|
+
data: {
|
|
1024
|
+
...updatedSession.data,
|
|
1025
|
+
...directive.goToStep.data,
|
|
1026
|
+
},
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
updatedSession = enterStep(updatedSession, stepTarget);
|
|
1030
|
+
}
|
|
1031
|
+
else if (directive.complete) {
|
|
1032
|
+
updatedSession = completeCurrentFlow(updatedSession);
|
|
1033
|
+
// If complete carries a chained directive, set it as pendingDirective
|
|
1034
|
+
if (typeof directive.complete === 'object' && directive.complete.next) {
|
|
1035
|
+
updatedSession = {
|
|
1036
|
+
...updatedSession,
|
|
1037
|
+
pendingDirective: directive.complete.next,
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
else if (directive.abort) {
|
|
1042
|
+
const clearSession = typeof directive.abort === 'object'
|
|
1043
|
+
? directive.abort.clearSession !== false
|
|
1044
|
+
: true;
|
|
1045
|
+
if (clearSession) {
|
|
1046
|
+
updatedSession = {
|
|
1047
|
+
...updatedSession,
|
|
1048
|
+
currentFlow: undefined,
|
|
1049
|
+
currentStep: undefined,
|
|
1050
|
+
data: {},
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
updatedSession = {
|
|
1055
|
+
...updatedSession,
|
|
1056
|
+
currentFlow: undefined,
|
|
1057
|
+
currentStep: undefined,
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
else if (directive.reset) {
|
|
1062
|
+
const currentFlowId = updatedSession.currentFlow?.id;
|
|
1063
|
+
const currentFlowTitle = updatedSession.currentFlow?.title;
|
|
1064
|
+
if (currentFlowId && currentFlowTitle) {
|
|
1065
|
+
// Clear data if requested
|
|
1066
|
+
if (typeof directive.reset === 'object' && directive.reset.clearData) {
|
|
1067
|
+
const currentFlow = this._flows.find(f => f.id === currentFlowId);
|
|
1068
|
+
if (currentFlow) {
|
|
1069
|
+
const ownedFields = [
|
|
1070
|
+
...(currentFlow.requiredFields || []),
|
|
1071
|
+
...(currentFlow.optionalFields || []),
|
|
1072
|
+
];
|
|
1073
|
+
updatedSession = completeCurrentFlow(updatedSession, { clearOwnedFields: ownedFields });
|
|
1074
|
+
// Re-enter the same flow
|
|
1075
|
+
updatedSession = enterFlow(updatedSession, currentFlowId, currentFlowTitle);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
else {
|
|
1079
|
+
// Re-enter the flow from the beginning (or specified step)
|
|
1080
|
+
updatedSession = enterFlow(updatedSession, currentFlowId, currentFlowTitle);
|
|
1081
|
+
}
|
|
1082
|
+
// If a specific step is targeted for reset
|
|
1083
|
+
if (typeof directive.reset === 'object' && directive.reset.step) {
|
|
1084
|
+
updatedSession = enterStep(updatedSession, directive.reset.step);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
// Update metadata
|
|
1089
|
+
updatedSession = {
|
|
1090
|
+
...updatedSession,
|
|
1091
|
+
metadata: {
|
|
1092
|
+
...updatedSession.metadata,
|
|
1093
|
+
lastUpdatedAt: now,
|
|
1094
|
+
},
|
|
1095
|
+
};
|
|
988
1096
|
return updatedSession;
|
|
989
1097
|
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Validate a directive for structural correctness.
|
|
1100
|
+
* Throws FlowConfigurationError for invalid combinations.
|
|
1101
|
+
* @private
|
|
1102
|
+
*/
|
|
1103
|
+
validateDirective(directive) {
|
|
1104
|
+
// Check for multiple position fields
|
|
1105
|
+
const positionFields = ['goTo', 'goToStep', 'complete', 'abort', 'reset'];
|
|
1106
|
+
const setPositionFields = positionFields.filter(field => directive[field] !== undefined);
|
|
1107
|
+
if (setPositionFields.length > 1) {
|
|
1108
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Multiple position fields: a Directive may set at most one position field. ` +
|
|
1109
|
+
`Found: ${setPositionFields.join(', ')}. Remove all but one.`);
|
|
1110
|
+
}
|
|
1111
|
+
// Check for empty goTo object
|
|
1112
|
+
if (directive.goTo && typeof directive.goTo === 'object') {
|
|
1113
|
+
const goToObj = directive.goTo;
|
|
1114
|
+
if (!goToObj.flow && !goToObj.step) {
|
|
1115
|
+
throw new StepFlowConfigurationError(`[FlowConfigurationError] Empty goTo: "goTo" requires at least a "flow" field. ` +
|
|
1116
|
+
`Provide { goTo: { flow: '<id>' } } or use the string shorthand { goTo: '<id>' }.`);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Strip PreDirective-only fields (appendPrompt, injectTools, halt) from a directive.
|
|
1122
|
+
* These fields are transient (one-turn lifetime) and must not be persisted.
|
|
1123
|
+
* @private
|
|
1124
|
+
*/
|
|
1125
|
+
stripPreDirectiveFields(directive) {
|
|
1126
|
+
const raw = directive;
|
|
1127
|
+
if (!raw.appendPrompt && !raw.injectTools && raw.halt === undefined) {
|
|
1128
|
+
return directive;
|
|
1129
|
+
}
|
|
1130
|
+
const { appendPrompt, injectTools, halt, ...rest } = raw;
|
|
1131
|
+
if (appendPrompt || injectTools || halt !== undefined) {
|
|
1132
|
+
logger.debug(`[Agent] Stripped PreDirective-only fields before storing pendingDirective: ` +
|
|
1133
|
+
`${[appendPrompt && 'appendPrompt', injectTools && 'injectTools', halt !== undefined && 'halt'].filter(Boolean).join(', ')}`);
|
|
1134
|
+
}
|
|
1135
|
+
return rest;
|
|
1136
|
+
}
|
|
990
1137
|
/**
|
|
991
1138
|
* Simplified respond method using SessionManager
|
|
992
1139
|
* Automatically manages conversation history through the session
|