@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
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Branches"
|
|
3
|
+
description: "Explicit source-local forks declared on a step, evaluated in order with code-first short-circuit."
|
|
4
|
+
type: reference
|
|
5
|
+
order: 8
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Branches
|
|
9
|
+
|
|
10
|
+
> **Where this is introduced:** [Branching](../guides/branching.md)
|
|
11
|
+
|
|
12
|
+
A **branch** is an explicit, source-local fork: from this step, here are the possible next steps and how each one is chosen. `step.branches` is an array of `BranchEntry` evaluated in declaration order — the first entry whose conditions pass wins, and its `then` resolves to a step id, a flow id, or a full `Directive`.
|
|
13
|
+
|
|
14
|
+
Branches sit between code and AI. Use `if` (a function predicate) to skip LLM evaluation when the choice is purely a function of `data` and `context`. Use `when` (an AI-evaluated string) for choices that need intent classification. Combine both when both must agree — `if` runs first, free; `when` is only evaluated if `if` passes, saving tokens.
|
|
15
|
+
|
|
16
|
+
Branches resolve **after** the step's post-LLM phase (tool execution, `finalize`) and **before** linear successor selection. They coexist with the implicit-fork pattern (multiple successor steps each carrying their own `step.when`); when `branches` is absent or no entry matches, resolution falls through to that path unchanged.
|
|
17
|
+
|
|
18
|
+
## Signature
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
interface BranchEntry<TContext = unknown, TData = unknown> {
|
|
22
|
+
/** AI-evaluated condition. String or array of strings (AND semantics). */
|
|
23
|
+
when?: string | string[];
|
|
24
|
+
|
|
25
|
+
/** Code predicate. Function or array of functions (AND semantics). */
|
|
26
|
+
if?:
|
|
27
|
+
| BranchPredicate<TContext, TData>
|
|
28
|
+
| BranchPredicate<TContext, TData>[];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Where to go when this entry matches.
|
|
32
|
+
* - String matching a step id in the current flow → enter that step.
|
|
33
|
+
* - String matching a flow id/title → treated as { goTo: <string> }.
|
|
34
|
+
* - Directive object → applied directly.
|
|
35
|
+
*/
|
|
36
|
+
then: string | Directive<TContext, TData>;
|
|
37
|
+
|
|
38
|
+
/** Optional label for event traces and flow visualization. */
|
|
39
|
+
label?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type BranchMap<TContext = unknown, TData = unknown> =
|
|
43
|
+
Array<BranchEntry<TContext, TData>>;
|
|
44
|
+
|
|
45
|
+
type BranchPredicate<TContext = unknown, TData = unknown> = (
|
|
46
|
+
ctx: BranchPredicateContext<TContext, TData>,
|
|
47
|
+
) => boolean | Promise<boolean>;
|
|
48
|
+
|
|
49
|
+
interface BranchPredicateContext<TContext = unknown, TData = unknown> {
|
|
50
|
+
/** Collected data (partial — null-check fields not in `requires`). */
|
|
51
|
+
data: Partial<TData>;
|
|
52
|
+
/** Agent-level context. */
|
|
53
|
+
context: TContext;
|
|
54
|
+
/** Full session state. */
|
|
55
|
+
session: SessionState<TData>;
|
|
56
|
+
/** Conversation history as events. */
|
|
57
|
+
history: Event[];
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Fields
|
|
62
|
+
|
|
63
|
+
### `BranchEntry`
|
|
64
|
+
|
|
65
|
+
| Field | Type | Required | Default | Notes |
|
|
66
|
+
|-------|------|----------|---------|-------|
|
|
67
|
+
| `when` | `string \| string[]` | no | — | AI-evaluated condition. Reuses the same machinery as `step.when`. Only evaluated if `if` passes (or is absent). Costs LLM tokens. |
|
|
68
|
+
| `if` | `BranchPredicate \| BranchPredicate[]` | no | — | Code predicate. Free to evaluate. When both `when` and `if` are set, `if` runs first; `when` is only evaluated if all `if` predicates pass. |
|
|
69
|
+
| `then` | `string \| Directive` | yes | — | Target. See [Resolution of `then`](#resolution-of-then) below. |
|
|
70
|
+
| `label` | `string` | no | — | Optional label surfaced in event traces and flow visualization. |
|
|
71
|
+
|
|
72
|
+
An entry with neither `when` nor `if` is an unconditional fallback and is only legal as the **last** entry in the array.
|
|
73
|
+
|
|
74
|
+
### `BranchMap`
|
|
75
|
+
|
|
76
|
+
A `BranchMap` is just `Array<BranchEntry>`. Entries are evaluated top-to-bottom; the first match wins. There is no separate object-syntax form — keeping the shape an array means declaration order and source position are the same thing.
|
|
77
|
+
|
|
78
|
+
### `BranchPredicateContext`
|
|
79
|
+
|
|
80
|
+
| Field | Type | Notes |
|
|
81
|
+
|-------|------|-------|
|
|
82
|
+
| `data` | `Partial<TData>` | Collected data so far. Predicates must null-check any field not declared in the source step's `requires`. Fields covered by `requires` are guaranteed present when the predicate runs. |
|
|
83
|
+
| `context` | `TContext` | Agent-level context (user, env, services). |
|
|
84
|
+
| `session` | `SessionState<TData>` | Full session state — current flow, current step, history. |
|
|
85
|
+
| `history` | `Event[]` | Conversation history as events (read-only). |
|
|
86
|
+
|
|
87
|
+
## Resolution
|
|
88
|
+
|
|
89
|
+
### Order
|
|
90
|
+
|
|
91
|
+
For each entry in declaration order:
|
|
92
|
+
|
|
93
|
+
1. If the entry has neither `when` nor `if`, it matches unconditionally (only legal as the last entry).
|
|
94
|
+
2. If `if` is set, evaluate every predicate. If any returns falsy, skip the entry — `when` is **not** evaluated.
|
|
95
|
+
3. If `when` is set, evaluate the AI condition. If it returns falsy, skip the entry.
|
|
96
|
+
4. Otherwise the entry matches; return its `then`.
|
|
97
|
+
|
|
98
|
+
If no entry matches, branches return `undefined` and resolution falls through to linear `nextStep` / AI step selection. This is the same fall-through used when `branches` is omitted entirely.
|
|
99
|
+
|
|
100
|
+
The code-first ordering is deliberate: `if` is free, `when` costs tokens. Running `if` first short-circuits the AI call when the predicate already disqualifies the entry.
|
|
101
|
+
|
|
102
|
+
### Resolution of `then`
|
|
103
|
+
|
|
104
|
+
`then` accepts three forms, resolved in this order:
|
|
105
|
+
|
|
106
|
+
1. **String matching a step id in the current flow** → enter that step directly.
|
|
107
|
+
2. **String matching a flow id or title** → treated as `applyDirective({ goTo: then })`.
|
|
108
|
+
3. **`Directive` object** → applied via `applyDirective(then)`.
|
|
109
|
+
|
|
110
|
+
When a string matches both a local step id and a flow id (rare), the local step wins — step ids are scoped to the current flow.
|
|
111
|
+
|
|
112
|
+
A bare string **never** resolves to a step in another flow, even if that step id is globally unique. To target a step in a different flow, use the `Directive` form: `then: { goToStep: { step: 'foo', flow: 'OtherFlow' } }`. This keeps the string lookup unambiguous and makes cross-flow intent explicit at the call site.
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### 1. Code-only fork (zero LLM cost)
|
|
117
|
+
|
|
118
|
+
A routing step that picks a path based purely on collected data. Combined with `auto: true`, the entire decision happens without an LLM call.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
flow({
|
|
122
|
+
id: "plan_routing",
|
|
123
|
+
steps: [
|
|
124
|
+
{
|
|
125
|
+
id: "route_by_plan",
|
|
126
|
+
auto: true,
|
|
127
|
+
branches: [
|
|
128
|
+
{ if: ({ data }) => data.plan === "enterprise", then: "enterprise_path", label: "enterprise" },
|
|
129
|
+
{ if: ({ data }) => data.plan === "pro", then: "pro_path", label: "pro" },
|
|
130
|
+
{ then: "free_path" }, // unconditional fallback (last entry)
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
{ id: "enterprise_path", prompt: "A specialist will reach out." },
|
|
134
|
+
{ id: "pro_path", prompt: "Set up your pro account." },
|
|
135
|
+
{ id: "free_path", prompt: "Welcome to the free tier." },
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 2. Mixed targets (step id, flow id, full Directive)
|
|
141
|
+
|
|
142
|
+
One branch step covering local navigation, cross-flow handoff, cross-flow step targeting, and completion in a single source-local list.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
flow({
|
|
146
|
+
id: "router",
|
|
147
|
+
steps: [
|
|
148
|
+
{
|
|
149
|
+
id: "classify",
|
|
150
|
+
prompt: "How can I help?",
|
|
151
|
+
branches: [
|
|
152
|
+
// Step id in the current flow.
|
|
153
|
+
{ if: ({ data }) => data.tier === "enterprise", then: "enterprise_path" },
|
|
154
|
+
|
|
155
|
+
// Flow id — sugar for { goTo: "CancellationFlow" }.
|
|
156
|
+
{ when: "user wants to cancel", then: "CancellationFlow" },
|
|
157
|
+
|
|
158
|
+
// Full Directive — cross-flow with data carry.
|
|
159
|
+
{
|
|
160
|
+
when: "user is asking about a refund",
|
|
161
|
+
then: { goTo: { flow: "Refund", data: { source: "classify" } } },
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// Cross-flow step reference (Directive required for cross-flow steps).
|
|
165
|
+
{
|
|
166
|
+
if: ({ data }) => data.escalate === true,
|
|
167
|
+
then: { goToStep: { step: "priority_intake", flow: "Escalation" } },
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Directive with a non-position field (state write + completion).
|
|
171
|
+
{ if: ({ data }) => data.shouldComplete === true, then: { complete: true } },
|
|
172
|
+
|
|
173
|
+
// Unconditional fallback.
|
|
174
|
+
{ then: "default_path" },
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{ id: "enterprise_path", prompt: "..." },
|
|
178
|
+
{ id: "default_path", prompt: "..." },
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 3. Combined `if` + `when` (token-saving short-circuit)
|
|
184
|
+
|
|
185
|
+
When both fields are set on the same entry, `if` runs first. `when` is only evaluated if `if` passes — so the LLM call only happens when the predicate hasn't already disqualified the branch.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
flow({
|
|
189
|
+
id: "pricing",
|
|
190
|
+
steps: [
|
|
191
|
+
{
|
|
192
|
+
id: "pricing_routing",
|
|
193
|
+
branches: [
|
|
194
|
+
{
|
|
195
|
+
// Free predicate runs first; AI condition only fires when it passes.
|
|
196
|
+
if: ({ data, context }) =>
|
|
197
|
+
data.country === "US" && context.featureFlags.enableUsPricing,
|
|
198
|
+
when: "user is asking about pricing",
|
|
199
|
+
then: "us_pricing",
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
when: "user is asking about pricing",
|
|
203
|
+
then: "global_pricing",
|
|
204
|
+
},
|
|
205
|
+
{ then: "general_help" }, // fallback
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
{ id: "us_pricing", prompt: "Here is US pricing." },
|
|
209
|
+
{ id: "global_pricing", prompt: "Here is global pricing." },
|
|
210
|
+
{ id: "general_help", prompt: "I can help with that." },
|
|
211
|
+
],
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Errors
|
|
216
|
+
|
|
217
|
+
Misuse of `branches` surfaces as `FlowConfigurationError` at flow construction or at first evaluation:
|
|
218
|
+
|
|
219
|
+
- **Empty array.** `branches: []` is rejected — it signals a missing target.
|
|
220
|
+
- **Unreachable fallback.** A non-last entry with neither `when` nor `if` is rejected (later entries would never run).
|
|
221
|
+
- **Unknown step id.** A `then` string that matches neither a step in the current flow nor any flow id throws when first evaluated.
|
|
222
|
+
- **Malformed Directive.** A `then` Directive with multiple position fields set, or an empty `goTo: {}`, fails the same `flow.validate(directive)` rules that apply to all directives.
|
|
223
|
+
|
|
224
|
+
A `BranchPredicate` that throws or rejects is caught by the resolver, logged at `ERROR`, and treated as a falsy result for that entry — resolution proceeds to the next entry. Branch predicate errors never corrupt the session; the worst case degrades to fall-through (linear / AI step selection).
|
|
225
|
+
|
|
226
|
+
## Coexistence with implicit forks
|
|
227
|
+
|
|
228
|
+
The implicit-fork pattern (multiple successor steps each carrying their own `step.when`) is unchanged in v2. Both forms are first-class:
|
|
229
|
+
|
|
230
|
+
- **Implicit** — fork by listing multiple steps with their own `when`. Reads as a linear flow that occasionally skips. Use when the fork is incidental.
|
|
231
|
+
- **Explicit (`branches`)** — fork declared at the source step, all paths visible in one list. Reads as "this step is a routing point with N options." Use when the fork is the point.
|
|
232
|
+
|
|
233
|
+
When both are present on the same step, branches take precedence: if a branch entry matches, the linear chain is bypassed. If branches return `undefined`, the linear chain runs.
|
|
234
|
+
|
|
235
|
+
## Related
|
|
236
|
+
|
|
237
|
+
- [Branching](../guides/branching.md) — the guide that introduces this primitive end-to-end.
|
|
238
|
+
- [Step](./step.md) — where the `branches` field lives.
|
|
239
|
+
- [Directive](./directive.md) — the flat shape `then` accepts as its third form.
|
|
240
|
+
- [Conditions](../guides/conditions.md) — the `when` (AI) vs `if` (code) split shared with `Step` and `Flow`.
|
|
241
|
+
- [Turn pipeline](../concepts/pipeline.md) — where branch resolution sits in the per-turn sequence.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "createAgent"
|
|
3
|
+
description: "Factory function that constructs an Agent from a single options object."
|
|
4
|
+
type: reference
|
|
5
|
+
order: 1
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# createAgent
|
|
9
|
+
|
|
10
|
+
> **Where this is introduced:** [Your first agent](../start/02-first-agent.md)
|
|
11
|
+
|
|
12
|
+
`createAgent` is the level-1 entry point for constructing an `Agent`. It is
|
|
13
|
+
syntactic sugar over `new Agent(options)` and accepts the same `AgentOptions`
|
|
14
|
+
shape. Generic inference flows from `schema` through every `flows[].steps[].collect`
|
|
15
|
+
reference, so the type of `session.data` and tool handler arguments is derived
|
|
16
|
+
once and propagates everywhere.
|
|
17
|
+
|
|
18
|
+
## Signature
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
function createAgent<TContext = unknown, TData = unknown>(
|
|
22
|
+
options: AgentOptions<TContext, TData>
|
|
23
|
+
): Agent<TContext, TData>;
|
|
24
|
+
|
|
25
|
+
interface AgentOptions<TContext = unknown, TData = unknown> {
|
|
26
|
+
name: string;
|
|
27
|
+
goal?: string;
|
|
28
|
+
persona?: Template<TContext>;
|
|
29
|
+
debug?: boolean;
|
|
30
|
+
context?: TContext;
|
|
31
|
+
contextProvider?: ContextProvider<TContext>;
|
|
32
|
+
hooks?: ContextLifecycleHooks<TContext, TData>;
|
|
33
|
+
provider: AiProvider;
|
|
34
|
+
schema?: StructuredSchema;
|
|
35
|
+
initialData?: Partial<TData>;
|
|
36
|
+
terms?: Term<TContext, TData>[];
|
|
37
|
+
instructions?: Instruction<TContext, TData>[];
|
|
38
|
+
tools?: Tool<TContext, TData, unknown>[];
|
|
39
|
+
flows?: FlowOptions<TContext, TData>[];
|
|
40
|
+
signals?: Signal<TContext, TData, unknown>[];
|
|
41
|
+
signalBatchSize?: number;
|
|
42
|
+
persistence?: PersistenceConfig<TData>;
|
|
43
|
+
knowledgeBase?: Record<string, unknown>;
|
|
44
|
+
flowSwitchMargin?: number;
|
|
45
|
+
maxAutoStepsPerTurn?: number;
|
|
46
|
+
maxDirectiveChain?: number;
|
|
47
|
+
compaction?: AgentCompactionConfig;
|
|
48
|
+
promptCache?: PromptCacheConfig;
|
|
49
|
+
routerMode?: 'ai';
|
|
50
|
+
sessionId?: string;
|
|
51
|
+
session?: SessionState;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Fields
|
|
56
|
+
|
|
57
|
+
| Field | Type | Required | Default | Notes |
|
|
58
|
+
|-------|------|----------|---------|-------|
|
|
59
|
+
| `name` | `string` | yes | — | Display name surfaced in logs and prompt sections. |
|
|
60
|
+
| `goal` | `string` | no | — | One-line objective rendered into the system prompt. |
|
|
61
|
+
| `persona` | `Template<TContext>` | no | — | Who the agent is and how it communicates — role, tone, and self-concept. Rendered into the system prompt. |
|
|
62
|
+
| `provider` | `AiProvider` | yes | — | Strategy instance: `GeminiProvider`, `OpenAIProvider`, `AnthropicProvider`, or `OpenRouterProvider`. |
|
|
63
|
+
| `schema` | `StructuredSchema` | no | — | Single source of truth for `TData`. Every `collect` key in every step must reference a property defined here. |
|
|
64
|
+
| `initialData` | `Partial<TData>` | no | — | Pre-populates `session.data` when the agent is constructed. |
|
|
65
|
+
| `flows` | `FlowOptions<TContext, TData>[]` | no | `[]` | Conversation flows. May also be added later via `agent.createFlow(...)`. |
|
|
66
|
+
| `tools` | `Tool<TContext, TData, unknown>[]` | no | `[]` | Agent-scoped tools. Each tool's `Tool.id` must be unique. |
|
|
67
|
+
| `instructions` | `Instruction<TContext, TData>[]` | no | `[]` | Behavioral statements discriminated by `kind: 'must' \| 'never' \| 'should'`. Scoped at agent, flow, or step level. |
|
|
68
|
+
| `terms` | `Term<TContext, TData>[]` | no | `[]` | Domain glossary entries inlined into the prompt. |
|
|
69
|
+
| `signals` | `Signal<TContext, TData, unknown>[]` | no | `[]` | Typed event detectors that run before/after the LLM turn. |
|
|
70
|
+
| `signalBatchSize` | `number` | no | `10` | Maximum signals per batched classifier call. Throws `FlowConfigurationError` if not a positive integer. |
|
|
71
|
+
| `context` | `TContext` | no | — | Static ambient data (user info, env, etc.) available to every hook and tool. |
|
|
72
|
+
| `contextProvider` | `ContextProvider<TContext>` | no | — | Async context loader. Use instead of `context` when ambient data must be fetched per turn. |
|
|
73
|
+
| `hooks` | `ContextLifecycleHooks<TContext, TData>` | no | — | `beforeRespond`, `onContextUpdate`, `onDataUpdate` — fire around every turn. |
|
|
74
|
+
| `persistence` | `PersistenceConfig<TData>` | no | in-memory | Session storage. Omit for `MemoryAdapter`. |
|
|
75
|
+
| `knowledgeBase` | `Record<string, unknown>` | no | — | Arbitrary JSON inlined into the prompt as background knowledge. |
|
|
76
|
+
| `flowSwitchMargin` | `number` | no | `15` | Margin (0–100) the best alternative flow must exceed the current flow's score by before switching. Higher values make the agent stickier. |
|
|
77
|
+
| `maxAutoStepsPerTurn` | `number` | no | `10` | Cap on consecutive `auto: true` steps per turn. Throws `FlowConfigurationError` when exceeded. |
|
|
78
|
+
| `maxDirectiveChain` | `number` | no | `10` | Cap on chained directives per turn (e.g., `goTo` → `onEnter` emits `goTo` → …). Throws `FlowConfigurationError` when exceeded. |
|
|
79
|
+
| `compaction` | `AgentCompactionConfig` | no | — | History compaction config: `maxTokens`, `compactionThreshold`, `preserveRecentCount`, `maxToolResultChars`. |
|
|
80
|
+
| `promptCache` | `PromptCacheConfig` | no | `{ enabled: true }` | Controls prompt-section memoization across turns. |
|
|
81
|
+
| `debug` | `boolean` | no | `false` | Enables `loglevel` debug output. |
|
|
82
|
+
| `routerMode` | `'ai'` | no | `'ai'` | Reserved for future router strategies. Any non-`'ai'` value throws `NotImplementedError` at construction. |
|
|
83
|
+
| `sessionId` | `string` | no | — | Auto-loads the session with this id from the configured adapter. |
|
|
84
|
+
| `session` | `SessionState` | no | — | Pre-built session passed in for convenience methods. |
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
### Minimal agent
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { createAgent, GeminiProvider } from '@falai/agent';
|
|
92
|
+
|
|
93
|
+
const agent = createAgent({
|
|
94
|
+
name: 'Greeter',
|
|
95
|
+
provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
|
|
96
|
+
schema: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: { name: { type: 'string' } },
|
|
99
|
+
},
|
|
100
|
+
flows: [
|
|
101
|
+
{
|
|
102
|
+
title: 'Greet',
|
|
103
|
+
steps: [
|
|
104
|
+
{ id: 'ask_name', prompt: 'Ask for the user\'s name.', collect: ['name'] },
|
|
105
|
+
{ id: 'greet', prompt: 'Greet them by name.', requires: ['name'] },
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const response = await agent.respond('Hi, I\'m Ada.');
|
|
112
|
+
console.log(response.message);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Tools, instructions, and persistence
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { createAgent, GeminiProvider, MemoryAdapter } from '@falai/agent';
|
|
119
|
+
|
|
120
|
+
const agent = createAgent({
|
|
121
|
+
name: 'BookingBot',
|
|
122
|
+
persona: 'Concise concierge. Always confirms dates before booking.',
|
|
123
|
+
provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! }),
|
|
124
|
+
schema: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
city: { type: 'string' },
|
|
128
|
+
checkIn: { type: 'string' },
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
instructions: [
|
|
132
|
+
{ kind: 'must', prompt: 'Validate dates are in the future.' },
|
|
133
|
+
{ kind: 'never', prompt: 'Promise rates you have not looked up.' },
|
|
134
|
+
],
|
|
135
|
+
tools: [
|
|
136
|
+
{
|
|
137
|
+
id: 'book_hotel',
|
|
138
|
+
description: 'Book a hotel for the collected city and date.',
|
|
139
|
+
parameters: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
city: { type: 'string' },
|
|
143
|
+
checkIn: { type: 'string' },
|
|
144
|
+
},
|
|
145
|
+
required: ['city', 'checkIn'],
|
|
146
|
+
},
|
|
147
|
+
handler: async (ctx, args) => {
|
|
148
|
+
const ref = await reserve(args.city, args.checkIn);
|
|
149
|
+
return { content: `Booked ${ref}.` };
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
flows: [
|
|
154
|
+
{
|
|
155
|
+
title: 'Book',
|
|
156
|
+
requiredFields: ['city', 'checkIn'],
|
|
157
|
+
steps: [
|
|
158
|
+
{ id: 'ask', prompt: 'Collect city and check-in date.', collect: ['city', 'checkIn'] },
|
|
159
|
+
{ id: 'confirm', prompt: 'Confirm and call book_hotel.', requires: ['city', 'checkIn'] },
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
persistence: { adapter: new MemoryAdapter() },
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Errors
|
|
168
|
+
|
|
169
|
+
`createAgent` runs the same construction-time validation as `new Agent(...)`.
|
|
170
|
+
The following typed errors may be thrown:
|
|
171
|
+
|
|
172
|
+
- `FlowConfigurationError` — duplicate flow ids or titles, duplicate signal ids, duplicate tool ids, invalid `signalBatchSize`, invalid signal `extract` schema, a step's `collect` references a key not defined in `schema`, a flow's `requiredFields`/`optionalFields` references an unknown schema key, or an unresolvable branch `then` target.
|
|
173
|
+
- `NotImplementedError` — `routerMode` set to anything other than `'ai'`.
|
|
174
|
+
|
|
175
|
+
Validation errors during a turn (not construction) — `DataValidationError`,
|
|
176
|
+
`ToolExecutionError`, `ResponseGenerationError` — surface from
|
|
177
|
+
`agent.respond(...)` and are documented on [Errors](./errors.md).
|
|
178
|
+
|
|
179
|
+
## Related
|
|
180
|
+
|
|
181
|
+
- [Architecture](../concepts/architecture.md) — the seven primitives and how they fit together
|
|
182
|
+
- [Your first agent](../start/02-first-agent.md) — the tutorial that introduces `createAgent`
|
|
183
|
+
- [Flow](./flow.md) — the `flows[]` entry shape
|
|
184
|
+
- [Tool](./tool.md) — the `tools[]` entry shape
|
|
185
|
+
- [Instruction](./instruction.md) — the `instructions[]` entry shape
|
|
186
|
+
- [Errors](./errors.md) — typed error classes thrown at construction and at runtime
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Directive"
|
|
3
|
+
description: "Flat shape returned by tools and hooks to write state, redirect the conversation, or speak verbatim."
|
|
4
|
+
type: reference
|
|
5
|
+
order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Directive
|
|
9
|
+
|
|
10
|
+
> **Where this is introduced:** [Directives](../concepts/directives.md)
|
|
11
|
+
|
|
12
|
+
A `Directive<TContext, TData>` is the single shape any tool, hook, or branch returns when it wants to write state, change position, or speak verbatim. It is a **flat object literal** — not a discriminated union, not a class, not a builder. Every field is optional. Every directive is plain JSON-serializable data (PreDirective adds non-serializable extensions; see [PreDirective](./pre-directive.md)).
|
|
13
|
+
|
|
14
|
+
A directive carries up to four orthogonal payloads:
|
|
15
|
+
|
|
16
|
+
- **One position field** — `goTo`, `goToStep`, `complete`, `abort`, or `reset`. Where to send the conversation. Mutually exclusive: at most one per directive.
|
|
17
|
+
- **State writes** — `dataUpdate` and/or `contextUpdate`. Shallow-merged into `session.data` and `session.context` before the next phase runs.
|
|
18
|
+
- **A verbatim reply** — `reply`. The literal assistant utterance, bypassing the LLM.
|
|
19
|
+
- **Per-position observability** — `reason` strings inside the object forms of position fields, surfaced in event traces and the directive chain log.
|
|
20
|
+
|
|
21
|
+
Multiple directives emitted during the same turn are collected onto the per-turn bus and merged by Algorithm 4 (see [Merge rules](#merge-rules) below).
|
|
22
|
+
|
|
23
|
+
## Signature
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
interface Directive<TContext = unknown, TData = unknown> {
|
|
27
|
+
// ── Position fields (mutually exclusive: at most one) ────────────
|
|
28
|
+
goTo?:
|
|
29
|
+
| string
|
|
30
|
+
| {
|
|
31
|
+
flow?: string;
|
|
32
|
+
step?: string;
|
|
33
|
+
data?: Partial<TData>;
|
|
34
|
+
reason?: string;
|
|
35
|
+
carry?: "preserve" | "reset";
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
goToStep?:
|
|
39
|
+
| string
|
|
40
|
+
| { step: string; flow?: string; data?: Partial<TData>; reason?: string };
|
|
41
|
+
|
|
42
|
+
complete?:
|
|
43
|
+
| true
|
|
44
|
+
| { next?: Directive<TContext, TData>; reason?: string };
|
|
45
|
+
|
|
46
|
+
abort?:
|
|
47
|
+
| string
|
|
48
|
+
| { reason: string; clearSession?: boolean };
|
|
49
|
+
|
|
50
|
+
reset?:
|
|
51
|
+
| true
|
|
52
|
+
| { step?: string; clearData?: boolean; reason?: string };
|
|
53
|
+
|
|
54
|
+
// ── Verbatim utterance ───────────────────────────────────────────
|
|
55
|
+
reply?: string;
|
|
56
|
+
|
|
57
|
+
// ── State writes (shallow-merged, both phases) ───────────────────
|
|
58
|
+
contextUpdate?: Partial<TContext>;
|
|
59
|
+
dataUpdate?: Partial<TData>;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Fields
|
|
64
|
+
|
|
65
|
+
### Position fields
|
|
66
|
+
|
|
67
|
+
Exactly **zero or one** position field may be set per directive. Setting two or more is a runtime configuration error (see [Errors](#errors)). When zero are set, the directive is purely a state write or a verbatim reply.
|
|
68
|
+
|
|
69
|
+
| Field | Shorthand | Object form | Notes |
|
|
70
|
+
|-------|-----------|-------------|-------|
|
|
71
|
+
| `goTo` | `string` (flow id / title) | `{ flow?, step?, data?, reason?, carry? }` | Jump to another flow. The string form is sugar for `{ flow: <string> }`. `carry: 'reset'` clears the destination flow's `requiredFields`/`optionalFields` on entry; `carry: 'preserve'` (default) preserves them. `data` is shallow-merged into `session.data` before entry. |
|
|
72
|
+
| `goToStep` | `string` (step id in the current flow) | `{ step, flow?, data?, reason? }` | Jump to a step. The bare string form targets the current flow only — for cross-flow steps, use the object form with `flow`. |
|
|
73
|
+
| `complete` | `true` | `{ next?, reason? }` | Mark the current flow complete. `next` is a chained `Directive` applied immediately after completion (e.g. transition to a follow-up flow). Equivalent to satisfying all `requiredFields`. |
|
|
74
|
+
| `abort` | `string` (reason) | `{ reason, clearSession? }` | End the conversation. The string form is sugar for `{ reason: <string> }`. When `clearSession: true`, the session is cleared at the next persistence write. `reply` cannot co-exist with `abort` — an aborted conversation cannot deliver a reply. |
|
|
75
|
+
| `reset` | `true` | `{ step?, clearData?, reason? }` | Restart the current flow. `step` re-enters at a specific step (default: initial). `clearData: true` clears every field declared in the flow's `requiredFields` and `optionalFields`. |
|
|
76
|
+
|
|
77
|
+
Each object form carries an optional `reason: string`. The reason is **observability-only** — it appears in the per-turn directive chain log and `AgentResponse.directiveChain` so traces are self-explaining, and it is stored on the corresponding event so post-mortems can read it. It does not influence routing, merging, or any pipeline decision.
|
|
78
|
+
|
|
79
|
+
### State writes
|
|
80
|
+
|
|
81
|
+
| Field | Type | Phase | Notes |
|
|
82
|
+
|-------|------|-------|-------|
|
|
83
|
+
| `dataUpdate` | `Partial<TData>` | both | Shallow-merged into `session.data`. Triggers `flow.hooks.onDataUpdate` and `Agent` data hooks. Across multiple emitters this turn, key collisions resolve last-write-wins. |
|
|
84
|
+
| `contextUpdate` | `Partial<TContext>` | both | Shallow-merged into `session.context`. Triggers `flow.hooks.onContextUpdate` and `Agent` context hooks. Last-write-wins on key collision. |
|
|
85
|
+
|
|
86
|
+
Shallow-merge means each top-level key is replaced wholesale. To update a nested object, read it from `data`/`context`, merge in code, and write back the full sub-object. Deep merge is intentionally not provided — it would silently disagree with TypeScript's `Partial<>` shape.
|
|
87
|
+
|
|
88
|
+
### `reply`
|
|
89
|
+
|
|
90
|
+
`reply: string` is the verbatim assistant utterance. When set, the LLM call is skipped this turn and the string is emitted as the assistant message exactly as written. Templating is not applied — `reply` is the rendered output.
|
|
91
|
+
|
|
92
|
+
`reply` co-validates with two fields:
|
|
93
|
+
|
|
94
|
+
- **`abort`** — co-existence is rejected at validation. Aborted conversations cannot deliver a reply.
|
|
95
|
+
- **`halt`** (PreDirective only) — when both are set, `reply` becomes the assistant output and the turn ends with `stoppedReason: 'reply'`. When `halt` is set without `reply`, the turn ends with `stoppedReason: 'halt'` and an empty assistant message.
|
|
96
|
+
|
|
97
|
+
Across multiple emitters this turn, `reply` is **last-wins** — the most recent emission overrides earlier ones, with a `DEBUG` log when more than one emitter set it.
|
|
98
|
+
|
|
99
|
+
## Merge rules
|
|
100
|
+
|
|
101
|
+
Directives emitted during one turn — by tools (return value or `ctx.dispatch`), prepare/finalize hooks, onEnter/onComplete hooks, and signal handlers — are collected onto a per-phase bus and merged into a single applied directive. The bus runs in two phases (pre-LLM and post-LLM); merge rules are identical for both.
|
|
102
|
+
|
|
103
|
+
| Field group | Merge rule |
|
|
104
|
+
|-------------|-----------|
|
|
105
|
+
| Position fields (`goTo`, `goToStep`, `complete`, `abort`, `reset`) | **Winner-takes-all by precedence:** `abort > complete > goTo / goToStep > reset`. Among entries of the same precedence, last emission wins. A `DEBUG` log records all losers. |
|
|
106
|
+
| `reply` | **Last-wins.** Most recent non-empty `reply` overrides earlier ones. `DEBUG` log when more than one was set. |
|
|
107
|
+
| `dataUpdate`, `contextUpdate` | **Shallow-merged across all emitters.** Last-write-wins on key collision. Always applied — never overridden by position fields. |
|
|
108
|
+
| `appendPrompt` (PreDirective) | **Concatenated** in emission order. |
|
|
109
|
+
| `injectTools` (PreDirective) | **Concatenated, then deduped by `Tool.id`** (last definition wins). |
|
|
110
|
+
| `halt` (PreDirective) | **Logical-OR.** Any emitter setting `halt: true` halts the turn. |
|
|
111
|
+
|
|
112
|
+
The full algorithm is implemented by `flow.merge(a, b)`. See [`flow` namespace](#flow-namespace) below.
|
|
113
|
+
|
|
114
|
+
> Branches **do not** participate in this bus. When a branch's `then` resolves to a `Directive`, it is applied via `applyDirective` directly, bypassing merge. The bus winner (if any) wins over branch evaluation: if the post-LLM bus produced a position field, branches don't run on that turn. See [Branches](./branches.md).
|
|
115
|
+
|
|
116
|
+
## `flow` namespace
|
|
117
|
+
|
|
118
|
+
The `flow` namespace exports three runtime helpers for working with directives. There are no constructor builders — directives are plain object literals.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { flow } from "@falai/agent";
|
|
122
|
+
|
|
123
|
+
flow.isDirective(x); // type guard
|
|
124
|
+
flow.merge(a, b); // Algorithm 4 merge of two directives
|
|
125
|
+
flow.validate(d); // throws FlowConfigurationError on invalid shape
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
| Helper | Signature | Notes |
|
|
129
|
+
|--------|-----------|-------|
|
|
130
|
+
| `flow.isDirective` | `(x: unknown) => x is Directive` | Structural type guard. Returns `true` for any non-null, non-array object. Filters out primitives, null/undefined, arrays, and functions. |
|
|
131
|
+
| `flow.merge` | `<T extends Directive>(a: T, b: T) => T` | Merges by Algorithm 4. Position field uses precedence (b wins on tie). `reply` is last-wins. State writes shallow-merge. PreDirective fields concatenate / dedupe / OR per the table above. |
|
|
132
|
+
| `flow.validate` | `(d: Directive) => void` | Throws `FlowConfigurationError` for: multiple position fields set; `goTo` set as an empty object `{}`; `reply` co-existing with `abort`. |
|
|
133
|
+
|
|
134
|
+
## Examples
|
|
135
|
+
|
|
136
|
+
### 1. Simple `goTo`
|
|
137
|
+
|
|
138
|
+
A finalize hook redirects to a follow-up flow when a flag flips on the response.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import type { Directive } from "@falai/agent";
|
|
142
|
+
|
|
143
|
+
const step = {
|
|
144
|
+
id: "summary",
|
|
145
|
+
prompt: "Summarize the request.",
|
|
146
|
+
hooks: {
|
|
147
|
+
finalize: ({ data }): Directive | void => {
|
|
148
|
+
if (data.escalate) {
|
|
149
|
+
return { goTo: "Escalation", reason: "summary marked escalate=true" };
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 2. `complete` with `dataUpdate`
|
|
157
|
+
|
|
158
|
+
A booking tool finalizes its work and writes back the booking id while marking the flow done in one declarative result.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import type { Tool, Directive } from "@falai/agent";
|
|
162
|
+
|
|
163
|
+
export const bookHotel: Tool = {
|
|
164
|
+
id: "book_hotel",
|
|
165
|
+
description: "Reserve the collected dates.",
|
|
166
|
+
async handler(ctx) {
|
|
167
|
+
const id = await api.book(ctx.data);
|
|
168
|
+
const directive: Directive = {
|
|
169
|
+
complete: { reason: "reservation confirmed" },
|
|
170
|
+
dataUpdate: { bookingId: id, bookedAt: new Date().toISOString() },
|
|
171
|
+
};
|
|
172
|
+
return { data: { id }, directive };
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 3. `abort`
|
|
178
|
+
|
|
179
|
+
A permission tool halts the conversation when the caller cannot proceed. Note that `reply` cannot accompany `abort`; the abort reason itself is what's recorded.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import type { Tool, Directive } from "@falai/agent";
|
|
183
|
+
|
|
184
|
+
export const verifyAccess: Tool = {
|
|
185
|
+
id: "verify_access",
|
|
186
|
+
isReadOnly: () => true,
|
|
187
|
+
async handler(ctx) {
|
|
188
|
+
const allowed = await acl.check(ctx.context.userId);
|
|
189
|
+
if (!allowed) {
|
|
190
|
+
const directive: Directive = {
|
|
191
|
+
abort: { reason: "caller is not on the allow-list", clearSession: true },
|
|
192
|
+
};
|
|
193
|
+
return { data: { allowed: false }, directive };
|
|
194
|
+
}
|
|
195
|
+
return { data: { allowed: true } };
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 4. `reply` only — speak verbatim, write nothing
|
|
201
|
+
|
|
202
|
+
A finalize hook emits a confirmation utterance without changing position or writing state. The LLM call this turn is skipped; the literal string is the assistant message.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import type { Directive } from "@falai/agent";
|
|
206
|
+
|
|
207
|
+
const step = {
|
|
208
|
+
id: "confirm_handoff",
|
|
209
|
+
hooks: {
|
|
210
|
+
finalize: ({ data }): Directive | void => {
|
|
211
|
+
if (data.handoffReady) {
|
|
212
|
+
return { reply: "Connecting you with a specialist now." };
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Errors
|
|
220
|
+
|
|
221
|
+
`flow.validate(directive)` and the per-turn merge stage throw `FlowConfigurationError` for the following invariants. See [Errors](./errors.md) for the format contract.
|
|
222
|
+
|
|
223
|
+
| Cause | Message shape |
|
|
224
|
+
|-------|---------------|
|
|
225
|
+
| Multiple position fields set on one directive | `[FlowConfigurationError] Invalid directive: multiple position fields set (...). A directive may have at most one position field. Remove the extras.` |
|
|
226
|
+
| `goTo` set as an empty object `{}` | `[FlowConfigurationError] Invalid directive: goTo is set as an empty object. goTo requires a flow id or title. Provide { flow: "<id>" } or use the string shorthand.` |
|
|
227
|
+
| `reply` co-existing with `abort` | `[FlowConfigurationError] Invalid directive: reply cannot co-exist with abort. An aborted conversation cannot deliver a reply. Remove one of the fields.` |
|
|
228
|
+
|
|
229
|
+
Two related runtime behaviors are notable but **not** thrown errors:
|
|
230
|
+
|
|
231
|
+
- Returning a `PreDirective` (with `appendPrompt` / `injectTools` / `halt`) from a post-LLM hook (`finalize`, `onComplete`) drops those three fields with a `DEBUG` log; the remaining `Directive` portion is honored.
|
|
232
|
+
- A `goTo` / `goToStep` referencing an unknown flow or step throws `FlowConfigurationError` at apply time, not at validation time — the validator does not have the agent's flow registry.
|
|
233
|
+
|
|
234
|
+
## Related
|
|
235
|
+
|
|
236
|
+
- [Directives](../concepts/directives.md) — the mental model and inheritance chain `Directive → PreDirective → SignalDirective`.
|
|
237
|
+
- [Turn pipeline](../concepts/pipeline.md) — when the bus runs, and where merge sits in the per-turn sequence.
|
|
238
|
+
- [Flow control](../guides/flow-control.md) — recipes for redirecting, completing, aborting, or replying from tools and hooks.
|
|
239
|
+
- [PreDirective](./pre-directive.md) — pre-LLM extension adding `appendPrompt`, `injectTools`, `halt`.
|
|
240
|
+
- [Signals](./signals.md) — `SignalDirective` extends `PreDirective` for signal handlers.
|
|
241
|
+
- [Tool](./tool.md) — `ctx.dispatch(directive)` and `ToolResult.directive`.
|
|
242
|
+
- [Branches](./branches.md) — `then: Directive` as a branch target (note: branches bypass the bus).
|
|
243
|
+
- [Errors](./errors.md) — `FlowConfigurationError` format contract.
|