@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
|
@@ -1,796 +0,0 @@
|
|
|
1
|
-
# Context & Session Management
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The `@falai/agent` framework provides **automatic session management** through the integrated `SessionManager` class, tracking conversation progress, collected data, and user intent across multiple turns. This enables sophisticated data-driven conversations with zero boilerplate code.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🎯 Automatic Session Management
|
|
10
|
-
|
|
11
|
-
The `SessionManager` automatically tracks four key aspects of a conversation:
|
|
12
|
-
|
|
13
|
-
1. **Current Route** - Which conversation flow the user is in
|
|
14
|
-
2. **Current Step** - Where in the flow they currently are
|
|
15
|
-
3. **Agent-Level Data** - Centralized structured data collected across all routes
|
|
16
|
-
4. **Conversation History** - Complete message history within the session
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
// Define your agent-level data extraction type
|
|
20
|
-
interface TravelData {
|
|
21
|
-
destination: string;
|
|
22
|
-
departureDate: string;
|
|
23
|
-
passengers: number;
|
|
24
|
-
cabinClass: "economy" | "business" | "first";
|
|
25
|
-
hotelPreference?: string;
|
|
26
|
-
budgetRange?: string;
|
|
27
|
-
specialRequests?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Agent with automatic session management and agent-level schema
|
|
31
|
-
const agent = new Agent<{}, TravelData>({
|
|
32
|
-
name: "Travel Agent",
|
|
33
|
-
provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
|
|
34
|
-
persistence: { adapter: new PrismaAdapter({ prisma }) },
|
|
35
|
-
sessionId: "user-123", // Automatically loads or creates session
|
|
36
|
-
|
|
37
|
-
// Agent-level schema for all data collection
|
|
38
|
-
schema: {
|
|
39
|
-
type: "object",
|
|
40
|
-
properties: {
|
|
41
|
-
destination: { type: "string" },
|
|
42
|
-
departureDate: { type: "string", format: "date" },
|
|
43
|
-
passengers: { type: "number", minimum: 1, maximum: 9 },
|
|
44
|
-
cabinClass: { type: "string", enum: ["economy", "business", "first"] },
|
|
45
|
-
hotelPreference: { type: "string" },
|
|
46
|
-
budgetRange: { type: "string" },
|
|
47
|
-
specialRequests: { type: "string" }
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Simple conversation - session managed automatically
|
|
53
|
-
const response = await agent.respond("I want to book a flight to Paris");
|
|
54
|
-
|
|
55
|
-
// Access session information
|
|
56
|
-
console.log(agent.session.id); // "user-123"
|
|
57
|
-
console.log(agent.session.getData<TravelData>()); // { destination: "Paris", ... }
|
|
58
|
-
console.log(agent.session.getHistory()); // Conversation history
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Benefits of Automatic Session Management:**
|
|
62
|
-
|
|
63
|
-
- **Zero Boilerplate** - No manual session creation or persistence code
|
|
64
|
-
- **Always-On Routing** - Users can change their mind mid-conversation
|
|
65
|
-
- **Data Persistence** - Collected data automatically saved and restored
|
|
66
|
-
- **Context Awareness** - Router sees current progress and collected data
|
|
67
|
-
- **History Management** - Conversation history automatically maintained
|
|
68
|
-
- **Server-Friendly** - Perfect for stateless server environments
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## 🔄 SessionManager API
|
|
73
|
-
|
|
74
|
-
### Session Operations
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
// Access the session manager
|
|
78
|
-
const sessionManager = agent.session;
|
|
79
|
-
|
|
80
|
-
// Get or create session (works for existing, new, or auto-generated IDs)
|
|
81
|
-
await sessionManager.getOrCreate("user-123");
|
|
82
|
-
await sessionManager.getOrCreate(); // Auto-generates ID
|
|
83
|
-
|
|
84
|
-
// Agent-level data management
|
|
85
|
-
const data = sessionManager.getData<TravelData>();
|
|
86
|
-
await sessionManager.setData({
|
|
87
|
-
destination: "Paris",
|
|
88
|
-
departureDate: "2025-10-15",
|
|
89
|
-
passengers: 2,
|
|
90
|
-
cabinClass: "economy"
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// History management
|
|
94
|
-
await sessionManager.addMessage("user", "I want to book a flight");
|
|
95
|
-
await sessionManager.addMessage("assistant", "Where would you like to go?");
|
|
96
|
-
const history = sessionManager.getHistory();
|
|
97
|
-
sessionManager.clearHistory();
|
|
98
|
-
|
|
99
|
-
// Session operations
|
|
100
|
-
await sessionManager.save(); // Manual save (auto-saves on addMessage)
|
|
101
|
-
await sessionManager.delete();
|
|
102
|
-
const newSession = await sessionManager.reset(true); // Preserve history
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Session Step Structure
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
interface SessionState<TData = unknown> {
|
|
109
|
-
currentRoute?: {
|
|
110
|
-
id: string;
|
|
111
|
-
title: string;
|
|
112
|
-
enteredAt: Date;
|
|
113
|
-
};
|
|
114
|
-
currentStep?: {
|
|
115
|
-
id: string;
|
|
116
|
-
description?: string;
|
|
117
|
-
enteredAt: Date;
|
|
118
|
-
};
|
|
119
|
-
data: Partial<TData>; // Data collected so far
|
|
120
|
-
routeHistory: Array<{
|
|
121
|
-
routeId: string;
|
|
122
|
-
routeTitle: string;
|
|
123
|
-
enteredAt: Date;
|
|
124
|
-
exitedAt?: Date;
|
|
125
|
-
}>;
|
|
126
|
-
metadata?: Record<string, unknown>;
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## 🔄 Enhanced Lifecycle Hooks
|
|
131
|
-
|
|
132
|
-
### Context Hooks (Traditional Context Management)
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
const agent = new Agent({
|
|
136
|
-
// ... other options
|
|
137
|
-
hooks: {
|
|
138
|
-
// Refresh context before each response
|
|
139
|
-
beforeRespond: async (currentContext) => {
|
|
140
|
-
const freshData = await loadUserData(currentContext.userId);
|
|
141
|
-
return { ...currentContext, ...freshData };
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
// Persist context updates
|
|
145
|
-
onContextUpdate: async (newContext, previousContext) => {
|
|
146
|
-
await saveUserData(newContext.userId, newContext);
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
// Agent-level data validation and enrichment
|
|
150
|
-
onDataUpdate: async (data, previousData) => {
|
|
151
|
-
// Normalize passenger count
|
|
152
|
-
if (data.passengers < 1) data.passengers = 1;
|
|
153
|
-
if (data.passengers > 9) data.passengers = 9;
|
|
154
|
-
|
|
155
|
-
// Enrich with computed fields using agent-level data
|
|
156
|
-
if (data.destination && !data.destinationCode) {
|
|
157
|
-
data.destinationCode = await lookupAirportCode(data.destination);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Auto-set budget range based on cabin class
|
|
161
|
-
if (data.cabinClass && !data.budgetRange) {
|
|
162
|
-
data.budgetRange = data.cabinClass === 'first' ? 'premium' :
|
|
163
|
-
data.cabinClass === 'business' ? 'high' : 'standard';
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Auto-trigger actions when we have complete booking data
|
|
167
|
-
if (data.destination && data.departureDate && data.passengers) {
|
|
168
|
-
data.shouldSearchFlights = true;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return data;
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Context Provider Pattern
|
|
178
|
-
|
|
179
|
-
For always-fresh context from external sources:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
const agent = new Agent({
|
|
183
|
-
// ... other options
|
|
184
|
-
contextProvider: async () => {
|
|
185
|
-
// Load fresh context for each response
|
|
186
|
-
return await loadFullContextFromDatabase();
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## 📊 Data Extraction Pipeline
|
|
192
|
-
|
|
193
|
-
Schema-first data extraction with intelligent step progression:
|
|
194
|
-
|
|
195
|
-
### 1. Define Your Data Schema
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
interface FlightData {
|
|
199
|
-
destination: string;
|
|
200
|
-
destinationCode?: string; // Enriched by tools
|
|
201
|
-
departureDate: string;
|
|
202
|
-
departureDateParsed?: string; // Enriched by tools
|
|
203
|
-
passengers: number;
|
|
204
|
-
cabinClass: "economy" | "business" | "first";
|
|
205
|
-
shouldSearchFlights?: boolean; // Action flag
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const route = agent.createRoute<FlightData>({
|
|
209
|
-
title: "Book Flight",
|
|
210
|
-
schema: {
|
|
211
|
-
type: "object",
|
|
212
|
-
properties: {
|
|
213
|
-
destination: { type: "string" },
|
|
214
|
-
departureDate: { type: "string" },
|
|
215
|
-
passengers: { type: "number", minimum: 1, maximum: 9 },
|
|
216
|
-
cabinClass: {
|
|
217
|
-
type: "string",
|
|
218
|
-
enum: ["economy", "business", "first"],
|
|
219
|
-
default: "economy",
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
required: ["destination", "departureDate", "passengers"],
|
|
223
|
-
},
|
|
224
|
-
initialData: {
|
|
225
|
-
cabinClass: "economy", // Pre-populate defaults
|
|
226
|
-
},
|
|
227
|
-
});
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### 2. Create Smart Step Machines
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
// Step with code-based logic (no fuzzy LLM conditions!)
|
|
234
|
-
const askDestination = route.initialStep.nextStep({
|
|
235
|
-
prompt: "Ask where they want to fly",
|
|
236
|
-
collect: ["destination"],
|
|
237
|
-
skipIf: (data) => !!data.destination, // Skip if already have destination
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
const enrichDestination = askDestination.nextStep({
|
|
241
|
-
tool: lookupAirportCode, // Tool executes automatically
|
|
242
|
-
requires: ["destination"], // Prerequisites
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
const askDates = enrichDestination.nextStep({
|
|
246
|
-
prompt: "Ask about travel dates",
|
|
247
|
-
collect: ["departureDate"],
|
|
248
|
-
skipIf: (data) => !!data.departureDate,
|
|
249
|
-
requires: ["destination"], // Must have destination first
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const validateDate = askDates.nextStep({
|
|
253
|
-
tool: parseAndValidateDate,
|
|
254
|
-
requires: ["departureDate"],
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
const askPassengers = validateDate.nextStep({
|
|
258
|
-
prompt: "How many passengers?",
|
|
259
|
-
collect: ["passengers"],
|
|
260
|
-
skipIf: (data) => !!data.passengers,
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
const searchFlights = askPassengers.nextStep({
|
|
264
|
-
tool: searchFlightAPI,
|
|
265
|
-
// Triggered when shouldSearchFlights flag is set by hook
|
|
266
|
-
});
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### 3. Tools Access Collected data
|
|
270
|
-
|
|
271
|
-
```typescript
|
|
272
|
-
const searchFlights: Tool<Context, [], void, FlightData> = {
|
|
273
|
-
id: "search_flights",
|
|
274
|
-
description: "Search for available flights based on collected data",
|
|
275
|
-
parameters: {
|
|
276
|
-
type: "object",
|
|
277
|
-
properties: {},
|
|
278
|
-
},
|
|
279
|
-
handler: async (toolContext) => {
|
|
280
|
-
// Access collected data directly (no LLM extraction needed!)
|
|
281
|
-
if (!toolContext.data.destination || !toolContext.data.departureDate) {
|
|
282
|
-
return { data: undefined };
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const flights = await searchFlightAPI(
|
|
286
|
-
toolContext.data.destination,
|
|
287
|
-
toolContext.data.departureDate
|
|
288
|
-
);
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
data: undefined,
|
|
292
|
-
contextUpdate: { availableFlights: flights },
|
|
293
|
-
dataUpdate: {
|
|
294
|
-
shouldSearchFlights: false, // Clear the flag
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
},
|
|
298
|
-
};
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### 4. Lifecycle Hooks for Validation & Enrichment
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
const agent = new Agent({
|
|
305
|
-
// ... other options
|
|
306
|
-
hooks: {
|
|
307
|
-
onDataUpdate: async (data, previous) => {
|
|
308
|
-
// Normalize data
|
|
309
|
-
if (data.passengers < 1) data.passengers = 1;
|
|
310
|
-
if (data.passengers > 9) data.passengers = 9;
|
|
311
|
-
|
|
312
|
-
// Enrich data
|
|
313
|
-
if (data.destination && !data.destinationCode) {
|
|
314
|
-
data.destinationCode = await lookupAirportCode(data.destination);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Auto-trigger actions
|
|
318
|
-
if (hasAllRequires(data) && !data.shouldSearchFlights) {
|
|
319
|
-
data.shouldSearchFlights = true;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
return data;
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
## 🎯 Always-On Routing with Context
|
|
329
|
-
|
|
330
|
-
Routing happens every turn with full session context:
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
// User starts booking a flight
|
|
334
|
-
const response1 = await agent.respond({
|
|
335
|
-
history: [
|
|
336
|
-
{
|
|
337
|
-
role: "user",
|
|
338
|
-
content: "I want to fly to Paris tomorrow with 2 people",
|
|
339
|
-
},
|
|
340
|
-
],
|
|
341
|
-
session,
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
// User changes mind mid-conversation
|
|
345
|
-
const response2 = await agent.respond({
|
|
346
|
-
history: [
|
|
347
|
-
...previousHistory,
|
|
348
|
-
{
|
|
349
|
-
role: "user",
|
|
350
|
-
content: "Actually, make that Tokyo instead",
|
|
351
|
-
},
|
|
352
|
-
],
|
|
353
|
-
session: response1.session, // Router sees context and switches appropriately
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// Router understands:
|
|
357
|
-
// - Current route: "Book Flight"
|
|
358
|
-
// - Current step: "ask_passengers"
|
|
359
|
-
// - Collected data: { destination: "Paris", departureDate: "tomorrow", passengers: 2 }
|
|
360
|
-
// - User intent: "Tokyo instead" → switches to new destination
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## 📋 Multi-Turn Conversation Patterns
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
import { Agent, type ContextLifecycleHooks } from "@falai/agent";
|
|
367
|
-
|
|
368
|
-
// Define hooks
|
|
369
|
-
const hooks: ContextLifecycleHooks<MyContext> = {
|
|
370
|
-
// Load fresh context before each response
|
|
371
|
-
beforeRespond: async (currentContext) => {
|
|
372
|
-
return await database.loadContext(sessionId);
|
|
373
|
-
},
|
|
374
|
-
|
|
375
|
-
// Persist context after updates
|
|
376
|
-
onContextUpdate: async (newContext, previousContext) => {
|
|
377
|
-
await database.saveContext(sessionId, newContext);
|
|
378
|
-
},
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
// Create agent with hooks
|
|
382
|
-
const agent = new Agent({
|
|
383
|
-
name: "Bot",
|
|
384
|
-
provider: provider,
|
|
385
|
-
context: initialContext,
|
|
386
|
-
hooks, // 🔑 Enable persistence
|
|
387
|
-
});
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**How it works:**
|
|
391
|
-
|
|
392
|
-
1. `beforeRespond` fetches fresh context from your database before `respond()` is called
|
|
393
|
-
2. Tools can update context using `toolContext.updateContext()` or returning `{ contextUpdate }`
|
|
394
|
-
3. `onContextUpdate` automatically persists changes to your database
|
|
395
|
-
4. Next request creates a new agent, `beforeRespond` loads the updated context
|
|
396
|
-
|
|
397
|
-
---
|
|
398
|
-
|
|
399
|
-
## 🔧 Tool Context Updates
|
|
400
|
-
|
|
401
|
-
Tools can update context in **two ways**:
|
|
402
|
-
|
|
403
|
-
### Option A: Return `contextUpdate`
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
const saveName: Tool<MyContext, [name: string], boolean> = {
|
|
407
|
-
id: "save_name",
|
|
408
|
-
description: "Save the user's name to context",
|
|
409
|
-
parameters: {
|
|
410
|
-
type: "object",
|
|
411
|
-
properties: {
|
|
412
|
-
name: { type: "string", description: "The user's name" },
|
|
413
|
-
},
|
|
414
|
-
required: ["name"],
|
|
415
|
-
},
|
|
416
|
-
handler: async (toolContext, args) => {
|
|
417
|
-
return {
|
|
418
|
-
data: true,
|
|
419
|
-
contextUpdate: {
|
|
420
|
-
userName: args.name,
|
|
421
|
-
updatedAt: new Date(),
|
|
422
|
-
},
|
|
423
|
-
};
|
|
424
|
-
},
|
|
425
|
-
};
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
**Pros:**
|
|
429
|
-
|
|
430
|
-
- Declarative and functional
|
|
431
|
-
- Easy to test
|
|
432
|
-
- Context update is part of the result
|
|
433
|
-
|
|
434
|
-
### Option B: Call `updateContext()` directly
|
|
435
|
-
|
|
436
|
-
```typescript
|
|
437
|
-
const saveName: Tool<MyContext, [name: string], boolean> = {
|
|
438
|
-
id: "save_name",
|
|
439
|
-
description: "Save the user's name to context using direct update",
|
|
440
|
-
parameters: {
|
|
441
|
-
type: "object",
|
|
442
|
-
properties: {
|
|
443
|
-
name: { type: "string", description: "The user's name" },
|
|
444
|
-
},
|
|
445
|
-
required: ["name"],
|
|
446
|
-
},
|
|
447
|
-
handler: async (toolContext, args) => {
|
|
448
|
-
await toolContext.updateContext({
|
|
449
|
-
userName: args.name,
|
|
450
|
-
updatedAt: new Date(),
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
return { data: true };
|
|
454
|
-
},
|
|
455
|
-
};
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
**Pros:**
|
|
459
|
-
|
|
460
|
-
- More imperative and direct
|
|
461
|
-
- Can update context at any point in the tool
|
|
462
|
-
- Useful for complex logic
|
|
463
|
-
|
|
464
|
-
**Both approaches trigger the `onContextUpdate` hook automatically.**
|
|
465
|
-
|
|
466
|
-
---
|
|
467
|
-
|
|
468
|
-
## 🌐 Context Provider Pattern
|
|
469
|
-
|
|
470
|
-
For scenarios where context is **always loaded from an external source**, use the `contextProvider` pattern:
|
|
471
|
-
|
|
472
|
-
```typescript
|
|
473
|
-
const agent = new Agent({
|
|
474
|
-
name: "Bot",
|
|
475
|
-
provider: provider,
|
|
476
|
-
|
|
477
|
-
// Instead of static context:
|
|
478
|
-
contextProvider: async () => {
|
|
479
|
-
// Fetch context fresh on every respond() call
|
|
480
|
-
return await database.loadContext(sessionId);
|
|
481
|
-
},
|
|
482
|
-
|
|
483
|
-
hooks: {
|
|
484
|
-
// Still persist updates
|
|
485
|
-
onContextUpdate: async (newContext) => {
|
|
486
|
-
await database.saveContext(sessionId, newContext);
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
**When to use:**
|
|
493
|
-
|
|
494
|
-
- Context is always loaded from a database/cache
|
|
495
|
-
- You never have a static starting context
|
|
496
|
-
- You want guaranteed fresh data on every request
|
|
497
|
-
|
|
498
|
-
**Difference from `beforeRespond`:**
|
|
499
|
-
|
|
500
|
-
- `contextProvider`: **Replaces** the context entirely
|
|
501
|
-
- `beforeRespond`: **Updates** the existing context (can access previous step)
|
|
502
|
-
|
|
503
|
-
---
|
|
504
|
-
|
|
505
|
-
## 🎯 Complete Example: Multi-Turn Onboarding
|
|
506
|
-
|
|
507
|
-
```typescript
|
|
508
|
-
import { Agent, type Tool } from "@falai/agent";
|
|
509
|
-
|
|
510
|
-
interface OnboardingContext {
|
|
511
|
-
sessionId: string;
|
|
512
|
-
userId: string;
|
|
513
|
-
businessName?: string;
|
|
514
|
-
industry?: string;
|
|
515
|
-
completedSteps: string[];
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Database simulation
|
|
519
|
-
const db = {
|
|
520
|
-
async loadSession(sessionId: string) {
|
|
521
|
-
return await database.findSession(sessionId);
|
|
522
|
-
},
|
|
523
|
-
async saveSession(sessionId: string, data: Partial<OnboardingContext>) {
|
|
524
|
-
await database.updateSession(sessionId, data);
|
|
525
|
-
},
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
// Factory function for creating agents
|
|
529
|
-
async function createOnboardingAgent(sessionId: string) {
|
|
530
|
-
const session = await db.loadSession(sessionId);
|
|
531
|
-
|
|
532
|
-
const agent = new Agent<OnboardingContext>({
|
|
533
|
-
name: "OnboardingBot",
|
|
534
|
-
provider: provider,
|
|
535
|
-
context: {
|
|
536
|
-
sessionId,
|
|
537
|
-
userId: session.userId,
|
|
538
|
-
businessName: session.businessName,
|
|
539
|
-
industry: session.industry,
|
|
540
|
-
completedSteps: session.completedSteps || [],
|
|
541
|
-
},
|
|
542
|
-
hooks: {
|
|
543
|
-
// Load fresh context before responding
|
|
544
|
-
beforeRespond: async (current) => {
|
|
545
|
-
const fresh = await db.loadSession(sessionId);
|
|
546
|
-
return { ...current, ...fresh };
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
// Persist context after updates
|
|
550
|
-
onContextUpdate: async (newContext) => {
|
|
551
|
-
await db.saveSession(sessionId, {
|
|
552
|
-
businessName: newContext.businessName,
|
|
553
|
-
industry: newContext.industry,
|
|
554
|
-
completedSteps: newContext.completedSteps,
|
|
555
|
-
});
|
|
556
|
-
},
|
|
557
|
-
},
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
// Define tools with context updates
|
|
561
|
-
const saveBusinessName: Tool<OnboardingContext, [name: string], boolean> = {
|
|
562
|
-
id: "save_business_name",
|
|
563
|
-
description: "Save the business name and mark step as completed",
|
|
564
|
-
parameters: {
|
|
565
|
-
type: "object",
|
|
566
|
-
properties: {
|
|
567
|
-
name: { type: "string", description: "The business name" },
|
|
568
|
-
},
|
|
569
|
-
required: ["name"],
|
|
570
|
-
},
|
|
571
|
-
handler: async (toolContext, args) => {
|
|
572
|
-
return {
|
|
573
|
-
data: true,
|
|
574
|
-
contextUpdate: {
|
|
575
|
-
businessName: args.name,
|
|
576
|
-
completedSteps: [
|
|
577
|
-
...toolContext.context.completedSteps,
|
|
578
|
-
"business_name",
|
|
579
|
-
],
|
|
580
|
-
},
|
|
581
|
-
};
|
|
582
|
-
},
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
const saveIndustry: Tool<OnboardingContext, [industry: string], boolean> = {
|
|
586
|
-
id: "save_industry",
|
|
587
|
-
description: "Save the industry and mark step as completed",
|
|
588
|
-
parameters: {
|
|
589
|
-
type: "object",
|
|
590
|
-
properties: {
|
|
591
|
-
industry: { type: "string", description: "The business industry" },
|
|
592
|
-
},
|
|
593
|
-
required: ["industry"],
|
|
594
|
-
},
|
|
595
|
-
handler: async (toolContext, args) => {
|
|
596
|
-
// Alternative: use updateContext directly
|
|
597
|
-
await toolContext.updateContext({
|
|
598
|
-
industry: args.industry,
|
|
599
|
-
completedSteps: [...toolContext.context.completedSteps, "industry"],
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
return { data: true };
|
|
603
|
-
},
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
// Build conversation routes...
|
|
607
|
-
const route = agent.createRoute({ title: "Onboarding" });
|
|
608
|
-
// ...
|
|
609
|
-
|
|
610
|
-
return agent;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Usage across multiple turns
|
|
614
|
-
async function handleUserMessage(sessionId: string, message: string) {
|
|
615
|
-
// Recreate agent for each turn (context is loaded fresh)
|
|
616
|
-
const agent = await createOnboardingAgent(sessionId);
|
|
617
|
-
|
|
618
|
-
const response = await agent.respond({
|
|
619
|
-
history: [
|
|
620
|
-
{
|
|
621
|
-
role: "user",
|
|
622
|
-
content: message,
|
|
623
|
-
},
|
|
624
|
-
],
|
|
625
|
-
});
|
|
626
|
-
|
|
627
|
-
return response.message;
|
|
628
|
-
}
|
|
629
|
-
```
|
|
630
|
-
|
|
631
|
-
---
|
|
632
|
-
|
|
633
|
-
## 📋 Best Practices
|
|
634
|
-
|
|
635
|
-
### ✅ DO
|
|
636
|
-
|
|
637
|
-
- **Recreate agents** for each request in multi-turn conversations
|
|
638
|
-
- **Use lifecycle hooks** to integrate with your database
|
|
639
|
-
- **Store context** in your database/cache (Redis, PostgreSQL, etc.)
|
|
640
|
-
- **Load fresh context** via `beforeRespond` or `contextProvider`
|
|
641
|
-
- **Test persistence** by simulating multiple turns
|
|
642
|
-
- **Handle errors** in hooks gracefully (fallback to current context)
|
|
643
|
-
|
|
644
|
-
### ❌ DON'T
|
|
645
|
-
|
|
646
|
-
- **Cache agent instances** across requests (context gets stale)
|
|
647
|
-
- **Mutate context directly** without using `updateContext()` or `contextUpdate`
|
|
648
|
-
- **Rely on in-memory step** for multi-turn conversations
|
|
649
|
-
- **Forget to handle** `onContextUpdate` failures (could lose data)
|
|
650
|
-
- **Mix** `context` and `contextProvider` (will throw an error)
|
|
651
|
-
|
|
652
|
-
---
|
|
653
|
-
|
|
654
|
-
## 🔍 Debugging Context Issues
|
|
655
|
-
|
|
656
|
-
### Problem: Context updates aren't persisting
|
|
657
|
-
|
|
658
|
-
**Check:**
|
|
659
|
-
|
|
660
|
-
1. Are you using `onContextUpdate` hook?
|
|
661
|
-
2. Is your database save actually working?
|
|
662
|
-
3. Are you recreating the agent with fresh context each turn?
|
|
663
|
-
|
|
664
|
-
```typescript
|
|
665
|
-
// Debug your hooks
|
|
666
|
-
hooks: {
|
|
667
|
-
beforeRespond: async (current) => {
|
|
668
|
-
console.log("📥 Loading context:", current);
|
|
669
|
-
const fresh = await db.load(sessionId);
|
|
670
|
-
console.log("✅ Loaded fresh:", fresh);
|
|
671
|
-
return fresh;
|
|
672
|
-
},
|
|
673
|
-
|
|
674
|
-
onContextUpdate: async (newContext) => {
|
|
675
|
-
console.log("💾 Saving context:", newContext);
|
|
676
|
-
await db.save(sessionId, newContext);
|
|
677
|
-
console.log("✅ Saved successfully");
|
|
678
|
-
},
|
|
679
|
-
},
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
### Problem: Context is null/undefined
|
|
683
|
-
|
|
684
|
-
**Check:**
|
|
685
|
-
|
|
686
|
-
1. Did you provide either `context` or `contextProvider`?
|
|
687
|
-
2. Is your `contextProvider` returning valid data?
|
|
688
|
-
3. Is `beforeRespond` returning valid context?
|
|
689
|
-
|
|
690
|
-
```typescript
|
|
691
|
-
// Validate your contextProvider
|
|
692
|
-
contextProvider: async () => {
|
|
693
|
-
const ctx = await db.load(sessionId);
|
|
694
|
-
if (!ctx) {
|
|
695
|
-
console.error("❌ Context not found!");
|
|
696
|
-
throw new Error("Session not found");
|
|
697
|
-
}
|
|
698
|
-
return ctx;
|
|
699
|
-
},
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Problem: Tools not updating context
|
|
703
|
-
|
|
704
|
-
**Check:**
|
|
705
|
-
|
|
706
|
-
1. Are you returning `{ contextUpdate }` or calling `toolContext.updateContext()`?
|
|
707
|
-
2. Is `onContextUpdate` being called? (Add console.log)
|
|
708
|
-
3. Are your tools being executed at all?
|
|
709
|
-
|
|
710
|
-
---
|
|
711
|
-
|
|
712
|
-
## 🚀 Advanced Patterns
|
|
713
|
-
|
|
714
|
-
### Pattern: Context Versioning
|
|
715
|
-
|
|
716
|
-
```typescript
|
|
717
|
-
interface VersionedContext extends MyContext {
|
|
718
|
-
version: number;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
hooks: {
|
|
722
|
-
onContextUpdate: async (newContext) => {
|
|
723
|
-
await db.save(sessionId, {
|
|
724
|
-
...newContext,
|
|
725
|
-
version: newContext.version + 1,
|
|
726
|
-
});
|
|
727
|
-
},
|
|
728
|
-
|
|
729
|
-
beforeRespond: async (current) => {
|
|
730
|
-
const fresh = await db.load(sessionId);
|
|
731
|
-
if (fresh.version > current.version) {
|
|
732
|
-
console.log("⚠️ Context changed by another request!");
|
|
733
|
-
}
|
|
734
|
-
return fresh;
|
|
735
|
-
},
|
|
736
|
-
},
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
### Pattern: Selective Persistence
|
|
740
|
-
|
|
741
|
-
```typescript
|
|
742
|
-
// Only persist specific fields
|
|
743
|
-
hooks: {
|
|
744
|
-
onContextUpdate: async (newContext) => {
|
|
745
|
-
// Don't persist temporary/computed fields
|
|
746
|
-
const { tempData, ...persistable } = newContext;
|
|
747
|
-
await db.save(sessionId, persistable);
|
|
748
|
-
},
|
|
749
|
-
},
|
|
750
|
-
```
|
|
751
|
-
|
|
752
|
-
### Pattern: Multi-User Context
|
|
753
|
-
|
|
754
|
-
```typescript
|
|
755
|
-
interface MultiUserContext {
|
|
756
|
-
conversationId: string;
|
|
757
|
-
participants: Map<string, UserData>;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
hooks: {
|
|
761
|
-
beforeRespond: async (current) => {
|
|
762
|
-
// Load all participant data
|
|
763
|
-
const conversation = await db.loadConversation(conversationId);
|
|
764
|
-
return {
|
|
765
|
-
conversationId,
|
|
766
|
-
participants: new Map(conversation.participants),
|
|
767
|
-
};
|
|
768
|
-
},
|
|
769
|
-
},
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
---
|
|
773
|
-
|
|
774
|
-
## 📚 Related Resources
|
|
775
|
-
|
|
776
|
-
- [Complete Example: Persistent Onboarding](../../../examples/advanced-patterns/persistent-onboarding.ts)
|
|
777
|
-
- [API Reference: AgentOptions](../../api/overview.md#agentoptions)
|
|
778
|
-
- [API Reference: ContextLifecycleHooks](../../api/overview.md#contextlifecyclehooks)
|
|
779
|
-
- [Getting Started](../../guides/getting-started/README.md)
|
|
780
|
-
|
|
781
|
-
---
|
|
782
|
-
|
|
783
|
-
## 🆘 Need Help?
|
|
784
|
-
|
|
785
|
-
If you're still having issues:
|
|
786
|
-
|
|
787
|
-
1. Check the [examples](../../../examples/) for working implementations
|
|
788
|
-
2. Review the [API Reference](../../api/README.md) for detailed type information
|
|
789
|
-
3. Open an issue on GitHub with your use case
|
|
790
|
-
|
|
791
|
-
**Remember:** The key to persistent conversations is:
|
|
792
|
-
|
|
793
|
-
1. **Recreate agents** each turn
|
|
794
|
-
2. **Load fresh context** via hooks/provider
|
|
795
|
-
3. **Persist updates** via `onContextUpdate`
|
|
796
|
-
4. **Never cache** agent instances across requests
|