@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,693 +0,0 @@
|
|
|
1
|
-
# Session Management
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The `@falai/agent` framework provides **automatic session management** through the `SessionManager` class, eliminating the need for manual session creation, persistence, and state management. Sessions are automatically created, loaded, and saved, allowing developers to focus on building conversation logic rather than managing session lifecycle.
|
|
6
|
-
|
|
7
|
-
## Core Design Principles
|
|
8
|
-
|
|
9
|
-
### 1. 🎯 Agent-Level Schema-First Data Extraction
|
|
10
|
-
|
|
11
|
-
Define what data to collect upfront using JSON Schema at the agent level, then extract it reliably across all routes:
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
// Define your agent-level data contract
|
|
15
|
-
interface TravelData {
|
|
16
|
-
destination: string;
|
|
17
|
-
departureDate: string;
|
|
18
|
-
passengers: number;
|
|
19
|
-
cabinClass: "economy" | "business" | "first";
|
|
20
|
-
hotelPreference?: string;
|
|
21
|
-
budgetRange?: string;
|
|
22
|
-
specialRequests?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Agent with centralized schema
|
|
26
|
-
const agent = new Agent<{}, TravelData>({
|
|
27
|
-
name: "Travel Agent",
|
|
28
|
-
provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
|
|
29
|
-
|
|
30
|
-
// Agent-level schema defines all possible data fields
|
|
31
|
-
schema: {
|
|
32
|
-
type: "object",
|
|
33
|
-
properties: {
|
|
34
|
-
destination: { type: "string" },
|
|
35
|
-
departureDate: { type: "string" },
|
|
36
|
-
passengers: { type: "number", minimum: 1, maximum: 9 },
|
|
37
|
-
cabinClass: {
|
|
38
|
-
type: "string",
|
|
39
|
-
enum: ["economy", "business", "first"],
|
|
40
|
-
default: "economy",
|
|
41
|
-
},
|
|
42
|
-
hotelPreference: { type: "string" },
|
|
43
|
-
budgetRange: { type: "string" },
|
|
44
|
-
specialRequests: { type: "string" }
|
|
45
|
-
},
|
|
46
|
-
required: ["destination", "departureDate", "passengers"],
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// Routes specify required fields instead of schemas
|
|
51
|
-
const flightRoute = agent.createRoute({
|
|
52
|
-
title: "Book Flight",
|
|
53
|
-
description: "Help user book a flight",
|
|
54
|
-
requiredFields: ["destination", "departureDate", "passengers", "cabinClass"],
|
|
55
|
-
optionalFields: ["specialRequests"]
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const hotelRoute = agent.createRoute({
|
|
59
|
-
title: "Book Hotel",
|
|
60
|
-
description: "Help user book accommodation",
|
|
61
|
-
requiredFields: ["destination", "departureDate", "hotelPreference"],
|
|
62
|
-
optionalFields: ["budgetRange", "specialRequests"]
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Why?** Agent-level schema-first extraction provides:
|
|
67
|
-
|
|
68
|
-
- **Type Safety** - Full TypeScript types from definition to extraction across all routes
|
|
69
|
-
- **Reliability** - Provider-enforced schemas, not prompt-based parsing
|
|
70
|
-
- **Predictability** - Same data structure every time, shared across routes
|
|
71
|
-
- **Efficiency** - Extract multiple fields in one LLM call
|
|
72
|
-
- **Cross-Route Data Sharing** - Data collected by any route is available to all routes
|
|
73
|
-
- **Route Completion** - Routes complete when their required fields are satisfied
|
|
74
|
-
|
|
75
|
-
### 2. 🤖 Automatic Session Management
|
|
76
|
-
|
|
77
|
-
Sessions are automatically managed through the `SessionManager` class integrated into every `Agent`:
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// Server-side: Agent with automatic session management and agent-level data
|
|
81
|
-
const agent = new Agent<{}, TravelData>({
|
|
82
|
-
name: "Travel Agent",
|
|
83
|
-
provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
|
|
84
|
-
persistence: { adapter: new PrismaAdapter({ prisma }) },
|
|
85
|
-
sessionId: "user-123", // Automatically loads or creates this session
|
|
86
|
-
|
|
87
|
-
// Agent-level schema
|
|
88
|
-
schema: { /* comprehensive travel data schema */ }
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Simple conversation - no manual session management
|
|
92
|
-
const response1 = await agent.respond("I want to book a flight to Paris");
|
|
93
|
-
console.log(agent.session.id); // Session ID
|
|
94
|
-
console.log(agent.session.getData<TravelData>()); // Agent-level collected data
|
|
95
|
-
|
|
96
|
-
// Continue conversation - session automatically maintained
|
|
97
|
-
const response2 = await agent.respond("Make that Tokyo instead");
|
|
98
|
-
// Session automatically updated with new data in agent-level structure
|
|
99
|
-
|
|
100
|
-
// Switch to hotel booking - data is shared
|
|
101
|
-
const response3 = await agent.respond("Also book me a hotel in Tokyo");
|
|
102
|
-
// Hotel route can access destination data collected by flight route
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**SessionManager API:**
|
|
106
|
-
|
|
107
|
-
The `SessionManager` provides a clean API for session operations with comprehensive error handling:
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
// Access the session manager
|
|
111
|
-
const sessionManager = agent.session;
|
|
112
|
-
|
|
113
|
-
// Get or create session (works for existing, new, or auto-generated IDs)
|
|
114
|
-
await sessionManager.getOrCreate("user-123");
|
|
115
|
-
await sessionManager.getOrCreate(); // Auto-generates ID
|
|
116
|
-
|
|
117
|
-
// History management with error handling
|
|
118
|
-
try {
|
|
119
|
-
await sessionManager.addMessage("user", "Hello");
|
|
120
|
-
await sessionManager.addMessage("assistant", "Hi there!");
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error("Failed to add message to history:", error);
|
|
123
|
-
// Message will be rolled back automatically
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const history = sessionManager.getHistory();
|
|
127
|
-
sessionManager.clearHistory();
|
|
128
|
-
|
|
129
|
-
// Data access with synchronization
|
|
130
|
-
const data = sessionManager.getData<FlightData>();
|
|
131
|
-
await sessionManager.setData({ destination: "Paris" });
|
|
132
|
-
|
|
133
|
-
// Session operations
|
|
134
|
-
await sessionManager.save(); // Manual save (auto-saves on addMessage)
|
|
135
|
-
await sessionManager.delete();
|
|
136
|
-
const newSession = await sessionManager.reset(true); // Preserve history
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Agent-Session Data Synchronization
|
|
140
|
-
|
|
141
|
-
The framework ensures bidirectional synchronization between agent collected data and session data:
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
// Agent data updates automatically sync with session
|
|
145
|
-
const agent = new Agent<{}, BookingData>({
|
|
146
|
-
sessionId: "user-123",
|
|
147
|
-
// ... other config
|
|
148
|
-
});
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Session Resume: Pre-Set Route and Step
|
|
152
|
-
|
|
153
|
-
When a session is created (or restored from persistence) with `currentRoute` and optionally `currentStep` already set, the framework honors that position on the first interaction — as long as the conversation history contains **no user messages**.
|
|
154
|
-
|
|
155
|
-
This is useful for:
|
|
156
|
-
|
|
157
|
-
- **Resuming from persistence**: A session loaded from a database already has route/step state. The first system message picks up where it left off.
|
|
158
|
-
- **Programmatic placement**: Starting a user at a specific point in the flow without AI routing.
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
import { createSession } from "@falai/agent";
|
|
162
|
-
|
|
163
|
-
// Create a session pre-positioned at a specific route and step
|
|
164
|
-
const session = createSession<MyData>({
|
|
165
|
-
id: "user-456",
|
|
166
|
-
currentRoute: {
|
|
167
|
-
id: "onboarding_route",
|
|
168
|
-
title: "Onboarding",
|
|
169
|
-
},
|
|
170
|
-
currentStep: {
|
|
171
|
-
id: "ask_email",
|
|
172
|
-
description: "Collect user email",
|
|
173
|
-
},
|
|
174
|
-
data: { name: "Alice" }, // Pre-populated data
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// First call with a system message — route/step are honored, no AI routing
|
|
178
|
-
const response = await agent.respond({
|
|
179
|
-
history: [
|
|
180
|
-
{ role: "system", content: "Resume the onboarding flow for this user." },
|
|
181
|
-
],
|
|
182
|
-
session,
|
|
183
|
-
});
|
|
184
|
-
// → Agent stays on "Onboarding" route, "ask_email" step
|
|
185
|
-
|
|
186
|
-
// If the first message is from a user, normal AI routing applies
|
|
187
|
-
const response2 = await agent.respond({
|
|
188
|
-
history: [
|
|
189
|
-
{ role: "user", content: "I need help with billing" },
|
|
190
|
-
],
|
|
191
|
-
session,
|
|
192
|
-
});
|
|
193
|
-
// → AI evaluates intent and may switch to a different route
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Rules:**
|
|
197
|
-
|
|
198
|
-
- If `currentRoute` is set and there are **no user messages** in history → pre-set route (and step) are honored
|
|
199
|
-
- If `currentRoute` is set but there **is a user message** → normal AI routing runs (user intent takes priority)
|
|
200
|
-
- If `currentStep` is set but not found in the route → falls back to resolving from the route's initial step
|
|
201
|
-
- If `currentRoute` is set but not found among available routes → falls back to normal AI routing
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
// Update agent data - automatically syncs with session
|
|
205
|
-
await agent.updateCollectedData({
|
|
206
|
-
destination: "Tokyo",
|
|
207
|
-
passengers: 2
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Session data is automatically updated
|
|
211
|
-
const sessionData = agent.session.getData<BookingData>();
|
|
212
|
-
console.log(sessionData.destination); // "Tokyo"
|
|
213
|
-
|
|
214
|
-
// Update session data - automatically syncs with agent
|
|
215
|
-
await agent.session.setData({
|
|
216
|
-
checkInDate: "2025-03-15"
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// Agent data is automatically updated
|
|
220
|
-
const agentData = agent.getCollectedData();
|
|
221
|
-
console.log(agentData.checkInDate); // "2025-03-15"
|
|
222
|
-
|
|
223
|
-
} catch (error) {
|
|
224
|
-
console.error("Data synchronization failed:", error);
|
|
225
|
-
// Both agent and session data remain in consistent state
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Error Handling in Data Synchronization
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
class SessionManager<TData> {
|
|
233
|
-
async setData(data: Partial<TData>): Promise<void> {
|
|
234
|
-
const previousData = { ...this.session.data };
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
// Validate data if schema is available
|
|
238
|
-
if (this.schema) {
|
|
239
|
-
this.validateData(data);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Update session data
|
|
243
|
-
this.session.data = { ...this.session.data, ...data };
|
|
244
|
-
|
|
245
|
-
// Sync with agent collected data
|
|
246
|
-
if (this.agent) {
|
|
247
|
-
await this.agent.updateCollectedData(data);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Persist changes
|
|
251
|
-
await this.save();
|
|
252
|
-
|
|
253
|
-
} catch (error) {
|
|
254
|
-
// Rollback session data on any failure
|
|
255
|
-
this.session.data = previousData;
|
|
256
|
-
|
|
257
|
-
console.error("Session data update failed, rolled back:", error);
|
|
258
|
-
throw new Error(`Data synchronization failed: ${error.message}`);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
async addMessage(role: "user" | "assistant", content: string): Promise<void> {
|
|
263
|
-
const message: HistoryItem = {
|
|
264
|
-
role,
|
|
265
|
-
content,
|
|
266
|
-
timestamp: new Date().toISOString()
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
// Add to session history
|
|
271
|
-
this.session.history.push(message);
|
|
272
|
-
|
|
273
|
-
// Persist immediately for reliability
|
|
274
|
-
await this.save();
|
|
275
|
-
|
|
276
|
-
} catch (error) {
|
|
277
|
-
// Remove message from history on persistence failure
|
|
278
|
-
this.session.history.pop();
|
|
279
|
-
|
|
280
|
-
console.error("Failed to persist message:", error);
|
|
281
|
-
throw new Error(`Message persistence failed: ${error.message}`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### Chat Method with Proper Error Handling
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
class Agent<TContext, TData> {
|
|
291
|
-
async chat(message: string, sessionId?: string): Promise<AgentResponse<TData>> {
|
|
292
|
-
try {
|
|
293
|
-
// Ensure session is loaded
|
|
294
|
-
if (!this.session || this.session.id !== sessionId) {
|
|
295
|
-
await this.loadSession(sessionId);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Add user message to history BEFORE processing
|
|
299
|
-
await this.session.addMessage("user", message);
|
|
300
|
-
|
|
301
|
-
// Process the message
|
|
302
|
-
const response = await this.respond({
|
|
303
|
-
message,
|
|
304
|
-
sessionId: this.session.id
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// Add assistant response to history
|
|
308
|
-
if (response.message) {
|
|
309
|
-
await this.session.addMessage("assistant", response.message);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return response;
|
|
313
|
-
|
|
314
|
-
} catch (error) {
|
|
315
|
-
console.error("Chat method failed:", error);
|
|
316
|
-
|
|
317
|
-
// Try to remove the user message if response failed
|
|
318
|
-
try {
|
|
319
|
-
const history = this.session.getHistory();
|
|
320
|
-
if (history.length > 0 && history[history.length - 1].role === "user") {
|
|
321
|
-
await this.session.removeLastMessage();
|
|
322
|
-
}
|
|
323
|
-
} catch (rollbackError) {
|
|
324
|
-
console.error("Failed to rollback user message:", rollbackError);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
throw new Error(`Chat failed: ${error.message}`);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
**Why?** Automatic session management provides:
|
|
334
|
-
|
|
335
|
-
- **Zero Boilerplate** - No manual session creation or persistence code
|
|
336
|
-
- **Server-Friendly** - Perfect for stateless server environments
|
|
337
|
-
- **Always-on Routing** - Users can change their mind mid-conversation
|
|
338
|
-
- **Context Awareness** - Router sees current progress and collected data
|
|
339
|
-
- **Data Persistence** - Collected data automatically saved and restored
|
|
340
|
-
- **History Management** - Conversation history automatically maintained
|
|
341
|
-
- **Session Tracking** - Easy session identification for client/server communication
|
|
342
|
-
|
|
343
|
-
### 3. 🔧 Code-Based Step Logic + AI-Driven Transitions
|
|
344
|
-
|
|
345
|
-
Use TypeScript functions for deterministic flow control AND text conditions for AI-driven step selection:
|
|
346
|
-
|
|
347
|
-
```typescript
|
|
348
|
-
// Step with smart bypassing based on collected data
|
|
349
|
-
const askDestination = route.initialStep.nextStep({
|
|
350
|
-
id: "ask_destination", // Optional: custom step ID
|
|
351
|
-
prompt: "Ask where they want to fly",
|
|
352
|
-
collect: ["destination"],
|
|
353
|
-
skipIf: (data) => !!data.destination, // Code-based condition!
|
|
354
|
-
condition: "Customer hasn't specified destination yet", // Text condition for AI
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
const askDate = askDestination.nextStep({
|
|
358
|
-
id: "ask_date", // Optional: custom step ID for easier tracking
|
|
359
|
-
prompt: "Ask about travel dates",
|
|
360
|
-
collect: ["departureDate"],
|
|
361
|
-
skipIf: (data) => !!data.departureDate,
|
|
362
|
-
requires: ["destination"], // Prerequisites
|
|
363
|
-
condition: "Destination confirmed, need travel dates now",
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**Custom Step IDs:**
|
|
369
|
-
|
|
370
|
-
You can optionally provide custom IDs for steps to make them easier to track and reference:
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
const confirmBooking = askDate.nextStep({
|
|
374
|
-
id: "confirm_booking", // ✅ Custom ID instead of auto-generated
|
|
375
|
-
prompt: "Confirm all booking details",
|
|
376
|
-
requires: ["destination", "departureDate", "passengers"],
|
|
377
|
-
});
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
If you don't provide an ID, one is automatically generated from the route ID and step description.
|
|
381
|
-
|
|
382
|
-
**Why?** Code-based logic provides:
|
|
383
|
-
|
|
384
|
-
- **Predictability** - No fuzzy LLM interpretation of conditions
|
|
385
|
-
- **Performance** - No extra LLM calls for condition checking
|
|
386
|
-
- **Debugging** - Clear logic flow you can trace
|
|
387
|
-
- **Type Safety** - Full TypeScript support for data validation
|
|
388
|
-
- **Custom IDs** - Easier tracking and debugging with meaningful step identifiers
|
|
389
|
-
|
|
390
|
-
**How Step Transitions Work:**
|
|
391
|
-
|
|
392
|
-
1. **Code filters first**: `skipIf` and `requires` filter out invalid steps deterministically
|
|
393
|
-
2. **AI selects best step**: From valid candidates, AI evaluates text conditions to choose optimal step
|
|
394
|
-
3. **Combined decision**: Single AI call handles both route selection AND step selection (no extra calls!)
|
|
395
|
-
4. **Completion detection**: When all steps are skipped and `END_ROUTE` is reached, route is marked complete
|
|
396
|
-
|
|
397
|
-
```typescript
|
|
398
|
-
// The AI sees:
|
|
399
|
-
// "Available steps: askDate, confirmBooking
|
|
400
|
-
// - askDate: Destination confirmed, need travel dates now
|
|
401
|
-
// - confirmBooking: All required info collected, ready to book
|
|
402
|
-
// Current data: {destination: 'Paris', departureDate: '2025-01-15'}
|
|
403
|
-
//
|
|
404
|
-
// → AI selects 'confirmBooking' based on context"
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### 4. 🛠️ Tools with Data Access
|
|
408
|
-
|
|
409
|
-
Tools execute with full context including collected data:
|
|
410
|
-
|
|
411
|
-
```typescript
|
|
412
|
-
import { Tool } from "@falai/agent";
|
|
413
|
-
|
|
414
|
-
const searchFlights: Tool<Context, [], void, FlightData> = {
|
|
415
|
-
id: "search_flights",
|
|
416
|
-
description: "Search for available flights based on collected data",
|
|
417
|
-
parameters: {
|
|
418
|
-
type: "object",
|
|
419
|
-
properties: {},
|
|
420
|
-
},
|
|
421
|
-
handler: async (toolContext) => {
|
|
422
|
-
const { data, context, history } = toolContext;
|
|
423
|
-
|
|
424
|
-
// Access collected data directly
|
|
425
|
-
if (!data.destination || !data.departureDate) {
|
|
426
|
-
return { data: undefined };
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Enrich collected data
|
|
430
|
-
return {
|
|
431
|
-
data: undefined,
|
|
432
|
-
dataUpdate: {
|
|
433
|
-
destinationCode: await lookupAirportCode(data.destination),
|
|
434
|
-
departureDateParsed: parseDate(data.departureDate),
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
},
|
|
438
|
-
};
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
**Why?** Tools with data access enable:
|
|
442
|
-
|
|
443
|
-
- **Data Enrichment** - Tools can validate and enhance collected data
|
|
444
|
-
- **Computed Fields** - Calculate derived values from collected data
|
|
445
|
-
- **Conditional Execution** - Tools decide what to do based on data step
|
|
446
|
-
- **Action Flags** - Tools can set flags for subsequent operations
|
|
447
|
-
|
|
448
|
-
### 5. 🎭 Always-On Routing
|
|
449
|
-
|
|
450
|
-
Routing happens every turn, allowing users to change direction:
|
|
451
|
-
|
|
452
|
-
```typescript
|
|
453
|
-
// User starts booking a flight
|
|
454
|
-
const response1 = await agent.respond({
|
|
455
|
-
history: [
|
|
456
|
-
{
|
|
457
|
-
role: "user",
|
|
458
|
-
content: "I want to fly to Paris",
|
|
459
|
-
},
|
|
460
|
-
],
|
|
461
|
-
session,
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
// User changes mind mid-conversation
|
|
465
|
-
const response2 = await agent.respond({
|
|
466
|
-
history: [
|
|
467
|
-
...previousHistory,
|
|
468
|
-
{
|
|
469
|
-
role: "user",
|
|
470
|
-
content: "Actually, make that Tokyo instead",
|
|
471
|
-
},
|
|
472
|
-
],
|
|
473
|
-
session: response1.session, // Router sees context and switches appropriately
|
|
474
|
-
});
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
**Why?** Always-on routing provides:
|
|
478
|
-
|
|
479
|
-
- **User Control** - Users can change their mind naturally
|
|
480
|
-
- **Context Awareness** - Router considers current progress
|
|
481
|
-
- **Graceful Transitions** - Smooth handling of intent changes
|
|
482
|
-
- **No Dead Ends** - Always a valid next step
|
|
483
|
-
|
|
484
|
-
### 6. 🔄 Three-Phase Pipeline
|
|
485
|
-
|
|
486
|
-
Clean separation of concerns in every response:
|
|
487
|
-
|
|
488
|
-
```
|
|
489
|
-
1. PREPARATION → 2. ROUTING → 3. RESPONSE
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
**Phase 1: Preparation**
|
|
493
|
-
|
|
494
|
-
- Execute tools if current step has `tool`
|
|
495
|
-
- Update context with tool results
|
|
496
|
-
- Enrich collected data if tools return `dataUpdate`
|
|
497
|
-
|
|
498
|
-
**Phase 2: Routing**
|
|
499
|
-
|
|
500
|
-
- Build dynamic routing schema (scores for all routes 0-100)
|
|
501
|
-
- Include session context in routing prompt
|
|
502
|
-
- AI selects best route based on current step
|
|
503
|
-
- Update session if route changed
|
|
504
|
-
|
|
505
|
-
**Phase 3: Response**
|
|
506
|
-
|
|
507
|
-
- Determine next step using `skipIf` and `requires`
|
|
508
|
-
- Build response schema including current step's `collect` fields
|
|
509
|
-
- Generate message with schema-enforced data extraction
|
|
510
|
-
- Update session with newly collected data
|
|
511
|
-
|
|
512
|
-
**Why?** This architecture enables:
|
|
513
|
-
|
|
514
|
-
- **Efficiency** - 1-2 LLM calls per turn vs 3-5 in condition-heavy approaches
|
|
515
|
-
- **Reliability** - Tools execute before AI sees the conversation
|
|
516
|
-
- **Flexibility** - Always-on routing handles any user direction
|
|
517
|
-
- **Type Safety** - Schemas ensure consistent data structures
|
|
518
|
-
|
|
519
|
-
### 7. 📦 Enhanced Lifecycle Hooks
|
|
520
|
-
|
|
521
|
-
Hooks for validation, enrichment, and persistence:
|
|
522
|
-
|
|
523
|
-
```typescript
|
|
524
|
-
const agent = new Agent({
|
|
525
|
-
// ... other options
|
|
526
|
-
hooks: {
|
|
527
|
-
// Refresh context before each response
|
|
528
|
-
beforeRespond: async (ctx) => {
|
|
529
|
-
return await loadFreshContext(ctx.userId);
|
|
530
|
-
},
|
|
531
|
-
|
|
532
|
-
// Persist context updates
|
|
533
|
-
onContextUpdate: async (newCtx, oldCtx) => {
|
|
534
|
-
await saveContext(newCtx);
|
|
535
|
-
},
|
|
536
|
-
|
|
537
|
-
// Validate and enrich collected data
|
|
538
|
-
onDataUpdate: async (data, previous) => {
|
|
539
|
-
// Normalize data
|
|
540
|
-
if (data.passengers < 1) data.passengers = 1;
|
|
541
|
-
|
|
542
|
-
// Auto-trigger actions
|
|
543
|
-
if (hasAllRequires(data)) {
|
|
544
|
-
data.shouldSearchFlights = true;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
return data;
|
|
548
|
-
},
|
|
549
|
-
},
|
|
550
|
-
});
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
**Why?** Lifecycle hooks provide:
|
|
554
|
-
|
|
555
|
-
- **Data Validation** - Ensure collected data meets business rules
|
|
556
|
-
- **Enrichment** - Add computed fields or normalize values
|
|
557
|
-
- **Persistence** - Save/restore conversation step
|
|
558
|
-
- **Integration** - Connect with external systems
|
|
559
|
-
|
|
560
|
-
## Comparison with Other Approaches
|
|
561
|
-
|
|
562
|
-
### @falai/agent vs Traditional Step Machines
|
|
563
|
-
|
|
564
|
-
| Aspect | @falai/agent (Data-Driven) | Traditional Step Machines |
|
|
565
|
-
| ------------------- | -------------------------- | ------------------------------------- |
|
|
566
|
-
| **Step Logic** | Code-based (`skipIf`) | Manual condition checking |
|
|
567
|
-
| **Data Collection** | Schema-driven extraction | Manual parsing |
|
|
568
|
-
| **Type Safety** | Full TypeScript | Often runtime validation |
|
|
569
|
-
| **LLM Calls/Turn** | 1-2 (routing + response) | 3-5 (conditions + routing + response) |
|
|
570
|
-
| **Validation** | Code + schemas | Manual implementation |
|
|
571
|
-
| **Routing** | Always-on, context-aware | Route-only, rigid |
|
|
572
|
-
|
|
573
|
-
### @falai/agent vs OpenAI Function Calling
|
|
574
|
-
|
|
575
|
-
| Aspect | @falai/agent | OpenAI Functions |
|
|
576
|
-
| ------------------ | ------------------------ | ----------------------------- |
|
|
577
|
-
| **Tool Execution** | Automatic (step-driven) | AI-decided |
|
|
578
|
-
| **Flow Control** | Code-based step logic | AI inference |
|
|
579
|
-
| **Determinism** | High - code-driven flow | Low - AI may vary |
|
|
580
|
-
| **Data Handling** | Structured schemas | Unstructured function results |
|
|
581
|
-
| **Type Safety** | Full TypeScript | Runtime type checking |
|
|
582
|
-
| **Use Case** | Structured conversations | Flexible, open-ended tasks |
|
|
583
|
-
|
|
584
|
-
## When to Use @falai/agent
|
|
585
|
-
|
|
586
|
-
✅ **Great for:**
|
|
587
|
-
|
|
588
|
-
- **Data Collection Flows** - Booking, onboarding, forms, surveys
|
|
589
|
-
- **Multi-Step Processes** - Complex workflows with clear progression
|
|
590
|
-
- **Type-Safe Applications** - When data structure matters
|
|
591
|
-
- **Predictable Conversations** - Structured, goal-oriented interactions
|
|
592
|
-
- **Session-Based Apps** - Conversations that span multiple turns
|
|
593
|
-
|
|
594
|
-
❌ **Not ideal for:**
|
|
595
|
-
|
|
596
|
-
- **Open-Ended Chat** - General conversation without clear goals
|
|
597
|
-
- **Creative Tasks** - Brainstorming, writing, ideation
|
|
598
|
-
- **Simple Q&A** - Stepless question-answering (use stepless routes!)
|
|
599
|
-
- **Rapid Prototyping** - When you need maximum flexibility
|
|
600
|
-
|
|
601
|
-
## Architecture Patterns
|
|
602
|
-
|
|
603
|
-
### Stepful Routes (Data Collection)
|
|
604
|
-
|
|
605
|
-
For structured data collecting with step management:
|
|
606
|
-
|
|
607
|
-
```typescript
|
|
608
|
-
interface BookingData {
|
|
609
|
-
destination: string;
|
|
610
|
-
dates: string;
|
|
611
|
-
passengers: number;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
const bookingRoute = agent.createRoute<BookingData>({
|
|
615
|
-
title: "Flight Booking",
|
|
616
|
-
schema: {
|
|
617
|
-
/* schema for all fields */
|
|
618
|
-
},
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
bookingRoute.initialStep
|
|
622
|
-
.nextStep({
|
|
623
|
-
prompt: "Ask destination",
|
|
624
|
-
collect: ["destination"],
|
|
625
|
-
skipIf: (data) => !!data.destination,
|
|
626
|
-
})
|
|
627
|
-
.nextStep({
|
|
628
|
-
tool: enrichDestination, // Validates and enriches
|
|
629
|
-
requires: ["destination"],
|
|
630
|
-
})
|
|
631
|
-
.nextStep({
|
|
632
|
-
prompt: "Ask dates",
|
|
633
|
-
collect: ["dates"],
|
|
634
|
-
skipIf: (data) => !!data.dates,
|
|
635
|
-
});
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### Stepless Routes (Q&A)
|
|
639
|
-
|
|
640
|
-
For simple question-answering without step:
|
|
641
|
-
|
|
642
|
-
```typescript
|
|
643
|
-
const qnaRoute = agent.createRoute({
|
|
644
|
-
title: "Company Q&A",
|
|
645
|
-
when: ["User asks about company"],
|
|
646
|
-
// NO schema - stepless!
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
// Just use initial step
|
|
650
|
-
qnaRoute.initialStep.prompt = "Answer from knowledge base";
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
### Mixed Architecture
|
|
654
|
-
|
|
655
|
-
Combine both patterns in one agent:
|
|
656
|
-
|
|
657
|
-
```typescript
|
|
658
|
-
// Q&A routes (stepless)
|
|
659
|
-
const companyInfoRoute = agent.createRoute({
|
|
660
|
-
/* no schema */
|
|
661
|
-
});
|
|
662
|
-
const productInfoRoute = agent.createRoute({
|
|
663
|
-
/* no schema */
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
// Booking routes (stepful)
|
|
667
|
-
const bookingRoute = agent.createRoute<BookingData>({
|
|
668
|
-
/* with schema */
|
|
669
|
-
});
|
|
670
|
-
const supportRoute = agent.createRoute<SupportData>({
|
|
671
|
-
/* with schema */
|
|
672
|
-
});
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
## Design Influences
|
|
676
|
-
|
|
677
|
-
This framework draws inspiration from:
|
|
678
|
-
|
|
679
|
-
1. **Schema-First APIs** - JSON Schema for data contracts
|
|
680
|
-
2. **Step Machines** - Explicit step modeling for predictability
|
|
681
|
-
3. **TypeScript** - Full type safety throughout
|
|
682
|
-
4. **Functional Programming** - Pure functions for step logic
|
|
683
|
-
5. **React Hooks** - Lifecycle patterns for extensibility
|
|
684
|
-
|
|
685
|
-
## Further Reading
|
|
686
|
-
|
|
687
|
-
- [Getting Started Guide](../../guides/getting-started/README.md) - Build your first agent
|
|
688
|
-
- [Context Management](./context-management.md) - Context providers and updates
|
|
689
|
-
- [API Reference](../../api/README.md) - Complete API documentation
|
|
690
|
-
|
|
691
|
-
---
|
|
692
|
-
|
|
693
|
-
**Questions?** Open an issue or discussion on [GitHub](https://github.com/falai-dev/agent).
|