@falai/agent 3.4.5 → 4.0.0-alpha.2
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 +41 -34
- package/dist/cjs/core/Agent.d.ts +22 -378
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +104 -1178
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
- package/dist/cjs/core/CompactionEngine.js +5 -3
- package/dist/cjs/core/CompactionEngine.js.map +1 -1
- package/dist/cjs/core/FlowSpec.d.ts +136 -0
- package/dist/cjs/core/FlowSpec.d.ts.map +1 -0
- package/dist/cjs/core/FlowSpec.js +522 -0
- package/dist/cjs/core/FlowSpec.js.map +1 -0
- package/dist/cjs/core/Migrate.d.ts +38 -0
- package/dist/cjs/core/Migrate.d.ts.map +1 -0
- package/dist/cjs/core/Migrate.js +270 -0
- package/dist/cjs/core/Migrate.js.map +1 -0
- package/dist/cjs/core/Prompt.d.ts +54 -0
- package/dist/cjs/core/Prompt.d.ts.map +1 -0
- package/dist/cjs/core/Prompt.js +143 -0
- package/dist/cjs/core/Prompt.js.map +1 -0
- package/dist/cjs/core/Runner.d.ts +160 -0
- package/dist/cjs/core/Runner.d.ts.map +1 -0
- package/dist/cjs/core/Runner.js +1131 -0
- package/dist/cjs/core/Runner.js.map +1 -0
- package/dist/cjs/core/Speak.d.ts +37 -0
- package/dist/cjs/core/Speak.d.ts.map +1 -0
- package/dist/cjs/core/Speak.js +364 -0
- package/dist/cjs/core/Speak.js.map +1 -0
- package/dist/cjs/core/Understand.d.ts +28 -0
- package/dist/cjs/core/Understand.d.ts.map +1 -0
- package/dist/cjs/core/Understand.js +353 -0
- package/dist/cjs/core/Understand.js.map +1 -0
- package/dist/cjs/core/contracts.d.ts +122 -0
- package/dist/cjs/core/contracts.d.ts.map +1 -0
- package/dist/cjs/core/contracts.js +11 -0
- package/dist/cjs/core/contracts.js.map +1 -0
- package/dist/cjs/core/falai.d.ts +57 -0
- package/dist/cjs/core/falai.d.ts.map +1 -0
- package/dist/cjs/core/falai.js +43 -0
- package/dist/cjs/core/falai.js.map +1 -0
- package/dist/cjs/core/predicate.d.ts +9 -0
- package/dist/cjs/core/predicate.d.ts.map +1 -0
- package/dist/cjs/core/predicate.js +58 -0
- package/dist/cjs/core/predicate.js.map +1 -0
- package/dist/cjs/index.d.ts +26 -31
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +46 -68
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/persistence/MemoryStore.d.ts +15 -0
- package/dist/cjs/persistence/MemoryStore.d.ts.map +1 -0
- package/dist/cjs/persistence/MemoryStore.js +39 -0
- package/dist/cjs/persistence/MemoryStore.js.map +1 -0
- package/dist/cjs/persistence/MongoStore.d.ts +42 -0
- package/dist/cjs/persistence/MongoStore.d.ts.map +1 -0
- package/dist/cjs/persistence/MongoStore.js +60 -0
- package/dist/cjs/persistence/MongoStore.js.map +1 -0
- package/dist/cjs/persistence/OpenSearchStore.d.ts +86 -0
- package/dist/cjs/persistence/OpenSearchStore.d.ts.map +1 -0
- package/dist/cjs/persistence/OpenSearchStore.js +120 -0
- package/dist/cjs/persistence/OpenSearchStore.js.map +1 -0
- package/dist/cjs/persistence/PostgresStore.d.ts +41 -0
- package/dist/cjs/persistence/PostgresStore.d.ts.map +1 -0
- package/dist/cjs/persistence/PostgresStore.js +58 -0
- package/dist/cjs/persistence/PostgresStore.js.map +1 -0
- package/dist/cjs/persistence/PrismaStore.d.ts +65 -0
- package/dist/cjs/persistence/PrismaStore.d.ts.map +1 -0
- package/dist/cjs/persistence/PrismaStore.js +95 -0
- package/dist/cjs/persistence/PrismaStore.js.map +1 -0
- package/dist/cjs/persistence/RedisStore.d.ts +34 -0
- package/dist/cjs/persistence/RedisStore.d.ts.map +1 -0
- package/dist/cjs/persistence/RedisStore.js +61 -0
- package/dist/cjs/persistence/RedisStore.js.map +1 -0
- package/dist/cjs/persistence/SQLiteStore.d.ts +45 -0
- package/dist/cjs/persistence/SQLiteStore.d.ts.map +1 -0
- package/dist/cjs/persistence/SQLiteStore.js +74 -0
- package/dist/cjs/persistence/SQLiteStore.js.map +1 -0
- package/dist/cjs/persistence/sessionRow.d.ts +14 -0
- package/dist/cjs/persistence/sessionRow.d.ts.map +1 -0
- package/dist/cjs/persistence/sessionRow.js +50 -0
- package/dist/cjs/persistence/sessionRow.js.map +1 -0
- package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.js +8 -3
- package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +4 -3
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +4 -3
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts +4 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAICompatibleProvider.js +2 -0
- package/dist/cjs/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +2 -4
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.d.ts +11 -6
- package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.js +33 -10
- package/dist/cjs/providers/ProviderAdapter.js.map +1 -1
- package/dist/cjs/providers/ZaiProvider.d.ts +6 -4
- package/dist/cjs/providers/ZaiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/ZaiProvider.js +6 -4
- package/dist/cjs/providers/ZaiProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +153 -383
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js +1 -1
- package/dist/cjs/types/ai.d.ts +32 -1
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/compaction.d.ts +3 -1
- package/dist/cjs/types/compaction.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +9 -12
- package/dist/cjs/types/errors.d.ts.map +1 -1
- package/dist/cjs/types/errors.js +14 -17
- package/dist/cjs/types/errors.js.map +1 -1
- package/dist/cjs/types/flow.d.ts +265 -513
- package/dist/cjs/types/flow.d.ts.map +1 -1
- package/dist/cjs/types/flow.js +7 -1
- package/dist/cjs/types/flow.js.map +1 -1
- package/dist/cjs/types/history.d.ts +7 -18
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/history.js.map +1 -1
- package/dist/cjs/types/index.d.ts +9 -15
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +4 -14
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/session.d.ts +94 -64
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/session.js +5 -1
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/cjs/types/tool.d.ts +37 -207
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/types/tool.js +5 -14
- package/dist/cjs/types/tool.js.map +1 -1
- package/dist/cjs/utils/clock.d.ts +28 -0
- package/dist/cjs/utils/clock.d.ts.map +1 -0
- package/dist/cjs/utils/clock.js +64 -0
- package/dist/cjs/utils/clock.js.map +1 -0
- package/dist/cjs/utils/duration.d.ts +11 -0
- package/dist/cjs/utils/duration.d.ts.map +1 -0
- package/dist/cjs/utils/duration.js +31 -0
- package/dist/cjs/utils/duration.js.map +1 -0
- package/dist/cjs/utils/history.d.ts +4 -1
- package/dist/cjs/utils/history.d.ts.map +1 -1
- package/dist/cjs/utils/history.js +2 -2
- package/dist/cjs/utils/history.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +4 -10
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +14 -61
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/json.d.ts +2 -0
- package/dist/cjs/utils/json.d.ts.map +1 -1
- package/dist/cjs/utils/json.js +5 -0
- package/dist/cjs/utils/json.js.map +1 -1
- package/dist/cjs/utils/outcomes.d.ts +48 -0
- package/dist/cjs/utils/outcomes.d.ts.map +1 -0
- package/dist/cjs/utils/outcomes.js +51 -0
- package/dist/cjs/utils/outcomes.js.map +1 -0
- package/dist/cjs/utils/schema.d.ts +50 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -0
- package/dist/cjs/utils/schema.js +138 -0
- package/dist/cjs/utils/schema.js.map +1 -0
- package/dist/cjs/utils/streamingMessage.d.ts +3 -2
- package/dist/cjs/utils/streamingMessage.d.ts.map +1 -1
- package/dist/cjs/utils/streamingMessage.js +38 -4
- package/dist/cjs/utils/streamingMessage.js.map +1 -1
- package/dist/cjs/utils/template.d.ts +13 -149
- package/dist/cjs/utils/template.d.ts.map +1 -1
- package/dist/cjs/utils/template.js +31 -363
- package/dist/cjs/utils/template.js.map +1 -1
- package/dist/cjs/utils/usage.d.ts +19 -0
- package/dist/cjs/utils/usage.d.ts.map +1 -0
- package/dist/cjs/utils/usage.js +35 -0
- package/dist/cjs/utils/usage.js.map +1 -0
- package/dist/core/Agent.d.ts +22 -378
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +107 -1181
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/CompactionEngine.d.ts.map +1 -1
- package/dist/core/CompactionEngine.js +5 -3
- package/dist/core/CompactionEngine.js.map +1 -1
- package/dist/core/FlowSpec.d.ts +136 -0
- package/dist/core/FlowSpec.d.ts.map +1 -0
- package/dist/core/FlowSpec.js +516 -0
- package/dist/core/FlowSpec.js.map +1 -0
- package/dist/core/Migrate.d.ts +38 -0
- package/dist/core/Migrate.d.ts.map +1 -0
- package/dist/core/Migrate.js +264 -0
- package/dist/core/Migrate.js.map +1 -0
- package/dist/core/Prompt.d.ts +54 -0
- package/dist/core/Prompt.d.ts.map +1 -0
- package/dist/core/Prompt.js +133 -0
- package/dist/core/Prompt.js.map +1 -0
- package/dist/core/Runner.d.ts +160 -0
- package/dist/core/Runner.d.ts.map +1 -0
- package/dist/core/Runner.js +1127 -0
- package/dist/core/Runner.js.map +1 -0
- package/dist/core/Speak.d.ts +37 -0
- package/dist/core/Speak.d.ts.map +1 -0
- package/dist/core/Speak.js +360 -0
- package/dist/core/Speak.js.map +1 -0
- package/dist/core/Understand.d.ts +28 -0
- package/dist/core/Understand.d.ts.map +1 -0
- package/dist/core/Understand.js +349 -0
- package/dist/core/Understand.js.map +1 -0
- package/dist/core/contracts.d.ts +122 -0
- package/dist/core/contracts.d.ts.map +1 -0
- package/dist/core/contracts.js +10 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/falai.d.ts +57 -0
- package/dist/core/falai.d.ts.map +1 -0
- package/dist/core/falai.js +40 -0
- package/dist/core/falai.js.map +1 -0
- package/dist/core/predicate.d.ts +9 -0
- package/dist/core/predicate.d.ts.map +1 -0
- package/dist/core/predicate.js +54 -0
- package/dist/core/predicate.js.map +1 -0
- package/dist/index.d.ts +26 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -24
- package/dist/index.js.map +1 -1
- package/dist/persistence/MemoryStore.d.ts +15 -0
- package/dist/persistence/MemoryStore.d.ts.map +1 -0
- package/dist/persistence/MemoryStore.js +35 -0
- package/dist/persistence/MemoryStore.js.map +1 -0
- package/dist/persistence/MongoStore.d.ts +42 -0
- package/dist/persistence/MongoStore.d.ts.map +1 -0
- package/dist/persistence/MongoStore.js +56 -0
- package/dist/persistence/MongoStore.js.map +1 -0
- package/dist/persistence/OpenSearchStore.d.ts +86 -0
- package/dist/persistence/OpenSearchStore.d.ts.map +1 -0
- package/dist/persistence/OpenSearchStore.js +116 -0
- package/dist/persistence/OpenSearchStore.js.map +1 -0
- package/dist/persistence/PostgresStore.d.ts +41 -0
- package/dist/persistence/PostgresStore.d.ts.map +1 -0
- package/dist/persistence/PostgresStore.js +54 -0
- package/dist/persistence/PostgresStore.js.map +1 -0
- package/dist/persistence/PrismaStore.d.ts +65 -0
- package/dist/persistence/PrismaStore.d.ts.map +1 -0
- package/dist/persistence/PrismaStore.js +91 -0
- package/dist/persistence/PrismaStore.js.map +1 -0
- package/dist/persistence/RedisStore.d.ts +34 -0
- package/dist/persistence/RedisStore.d.ts.map +1 -0
- package/dist/persistence/RedisStore.js +57 -0
- package/dist/persistence/RedisStore.js.map +1 -0
- package/dist/persistence/SQLiteStore.d.ts +45 -0
- package/dist/persistence/SQLiteStore.d.ts.map +1 -0
- package/dist/persistence/SQLiteStore.js +70 -0
- package/dist/persistence/SQLiteStore.js.map +1 -0
- package/dist/persistence/sessionRow.d.ts +14 -0
- package/dist/persistence/sessionRow.d.ts.map +1 -0
- package/dist/persistence/sessionRow.js +45 -0
- package/dist/persistence/sessionRow.js.map +1 -0
- package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/DeepSeekProvider.js +8 -3
- package/dist/providers/DeepSeekProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +4 -3
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +4 -3
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.d.ts +4 -0
- package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -1
- package/dist/providers/OpenAICompatibleProvider.js +2 -0
- package/dist/providers/OpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +2 -4
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/providers/ProviderAdapter.d.ts +11 -6
- package/dist/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/providers/ProviderAdapter.js +34 -11
- package/dist/providers/ProviderAdapter.js.map +1 -1
- package/dist/providers/ZaiProvider.d.ts +6 -4
- package/dist/providers/ZaiProvider.d.ts.map +1 -1
- package/dist/providers/ZaiProvider.js +6 -4
- package/dist/providers/ZaiProvider.js.map +1 -1
- package/dist/types/agent.d.ts +153 -383
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js +1 -1
- package/dist/types/ai.d.ts +32 -1
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/compaction.d.ts +3 -1
- package/dist/types/compaction.d.ts.map +1 -1
- package/dist/types/errors.d.ts +9 -12
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +12 -15
- package/dist/types/errors.js.map +1 -1
- package/dist/types/flow.d.ts +265 -513
- package/dist/types/flow.d.ts.map +1 -1
- package/dist/types/flow.js +7 -1
- package/dist/types/flow.js.map +1 -1
- package/dist/types/history.d.ts +7 -18
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/history.js.map +1 -1
- package/dist/types/index.d.ts +9 -15
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -7
- package/dist/types/index.js.map +1 -1
- package/dist/types/session.d.ts +94 -64
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +5 -1
- package/dist/types/session.js.map +1 -1
- package/dist/types/tool.d.ts +37 -207
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/tool.js +6 -13
- package/dist/types/tool.js.map +1 -1
- package/dist/utils/clock.d.ts +28 -0
- package/dist/utils/clock.d.ts.map +1 -0
- package/dist/utils/clock.js +59 -0
- package/dist/utils/clock.js.map +1 -0
- package/dist/utils/duration.d.ts +11 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +26 -0
- package/dist/utils/duration.js.map +1 -0
- package/dist/utils/history.d.ts +4 -1
- package/dist/utils/history.d.ts.map +1 -1
- package/dist/utils/history.js +2 -2
- package/dist/utils/history.js.map +1 -1
- package/dist/utils/index.d.ts +4 -10
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -21
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/json.d.ts +2 -0
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js +4 -0
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/outcomes.d.ts +48 -0
- package/dist/utils/outcomes.d.ts.map +1 -0
- package/dist/utils/outcomes.js +48 -0
- package/dist/utils/outcomes.js.map +1 -0
- package/dist/utils/schema.d.ts +50 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +129 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/streamingMessage.d.ts +3 -2
- package/dist/utils/streamingMessage.d.ts.map +1 -1
- package/dist/utils/streamingMessage.js +38 -4
- package/dist/utils/streamingMessage.js.map +1 -1
- package/dist/utils/template.d.ts +13 -149
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +28 -355
- package/dist/utils/template.js.map +1 -1
- package/dist/utils/usage.d.ts +19 -0
- package/dist/utils/usage.d.ts.map +1 -0
- package/dist/utils/usage.js +31 -0
- package/dist/utils/usage.js.map +1 -0
- package/docs/README.md +37 -19
- package/docs/concepts/architecture.md +117 -239
- package/docs/concepts/collection.md +170 -0
- package/docs/concepts/pipeline.md +132 -378
- package/docs/concepts/runs-and-waits.md +192 -0
- package/docs/guides/actions-and-events.md +276 -0
- package/docs/guides/branching.md +119 -208
- package/docs/guides/compaction.md +63 -158
- package/docs/guides/conditions.md +164 -128
- package/docs/guides/error-handling.md +168 -164
- package/docs/guides/flow-control.md +210 -349
- package/docs/guides/flows-from-json.md +224 -0
- package/docs/guides/instructions.md +125 -161
- package/docs/guides/persistence.md +182 -206
- package/docs/guides/streaming.md +50 -114
- package/docs/guides/testing.md +284 -0
- package/docs/guides/triggers.md +401 -0
- package/docs/migration/README.md +8 -15
- package/docs/migration/v1-to-v2.md +1 -1
- package/docs/migration/v2-3-to-v2-4.md +2 -2
- package/docs/migration/v2-6-to-v2-7.md +4 -4
- package/docs/migration/v3-to-v4.md +452 -0
- package/docs/reference/actions-events-conditions.md +396 -0
- package/docs/reference/agent.md +244 -0
- package/docs/reference/branches.md +75 -203
- package/docs/reference/errors.md +188 -144
- package/docs/reference/fields.md +125 -0
- package/docs/reference/flow-spec.md +248 -0
- package/docs/reference/flow.md +104 -192
- package/docs/reference/instruction.md +83 -137
- package/docs/reference/outcomes.md +273 -0
- package/docs/reference/providers.md +525 -302
- package/docs/reference/session.md +210 -0
- package/docs/reference/step.md +194 -312
- package/docs/reference/stores.md +496 -0
- package/docs/reference/tool.md +162 -231
- package/docs/reference/trigger.md +180 -0
- package/docs/rfc/v4-one-flow.md +477 -0
- package/docs/start/01-install.md +59 -44
- package/docs/start/02-first-agent.md +97 -147
- package/docs/start/03-collect-data.md +78 -183
- package/docs/start/04-add-tools.md +159 -227
- package/docs/start/05-go-to-production.md +167 -164
- package/examples/01-quickstart.ts +26 -16
- package/examples/02-fields.ts +75 -0
- package/examples/03-tools.ts +79 -119
- package/examples/04-instructions.ts +60 -87
- package/examples/05-branches.ts +78 -0
- package/examples/06-triggers-and-waits.ts +148 -0
- package/examples/07-streaming.ts +34 -60
- package/examples/08-store-and-migration.ts +97 -0
- package/examples/09-flows-from-json.ts +107 -0
- package/package.json +9 -6
- package/src/core/Agent.ts +116 -1512
- package/src/core/CompactionEngine.ts +7 -4
- package/src/core/FlowSpec.ts +712 -0
- package/src/core/Migrate.ts +256 -0
- package/src/core/Prompt.ts +156 -0
- package/src/core/Runner.ts +1181 -0
- package/src/core/Speak.ts +451 -0
- package/src/core/Understand.ts +422 -0
- package/src/core/contracts.ts +111 -0
- package/src/core/falai.ts +86 -0
- package/src/core/predicate.ts +56 -0
- package/src/index.ts +119 -147
- package/src/persistence/MemoryStore.ts +37 -0
- package/src/persistence/MongoStore.ts +89 -0
- package/src/persistence/OpenSearchStore.ts +153 -0
- package/src/persistence/PostgresStore.ts +89 -0
- package/src/persistence/PrismaStore.ts +127 -0
- package/src/persistence/RedisStore.ts +90 -0
- package/src/persistence/SQLiteStore.ts +103 -0
- package/src/persistence/sessionRow.ts +45 -0
- package/src/providers/DeepSeekProvider.ts +8 -3
- package/src/providers/GeminiProvider.ts +4 -3
- package/src/providers/OpenAICompatibleProvider.ts +6 -0
- package/src/providers/OpenRouterProvider.ts +2 -4
- package/src/providers/ProviderAdapter.ts +46 -13
- package/src/providers/ZaiProvider.ts +6 -4
- package/src/types/agent.ts +124 -397
- package/src/types/ai.ts +33 -1
- package/src/types/compaction.ts +3 -1
- package/src/types/errors.ts +13 -16
- package/src/types/flow.ts +249 -550
- package/src/types/history.ts +7 -20
- package/src/types/index.ts +87 -139
- package/src/types/session.ts +135 -70
- package/src/types/tool.ts +42 -267
- package/src/utils/clock.ts +70 -0
- package/src/utils/duration.ts +33 -0
- package/src/utils/history.ts +3 -2
- package/src/utils/index.ts +8 -66
- package/src/utils/json.ts +5 -0
- package/src/utils/outcomes.ts +56 -0
- package/src/utils/schema.ts +145 -0
- package/src/utils/streamingMessage.ts +34 -4
- package/src/utils/template.ts +32 -423
- package/src/utils/usage.ts +37 -0
- package/dist/adapters/MemoryAdapter.d.ts +0 -47
- package/dist/adapters/MemoryAdapter.d.ts.map +0 -1
- package/dist/adapters/MemoryAdapter.js +0 -204
- package/dist/adapters/MemoryAdapter.js.map +0 -1
- package/dist/adapters/MongoAdapter.d.ts +0 -97
- package/dist/adapters/MongoAdapter.d.ts.map +0 -1
- package/dist/adapters/MongoAdapter.js +0 -196
- package/dist/adapters/MongoAdapter.js.map +0 -1
- package/dist/adapters/OpenSearchAdapter.d.ts +0 -169
- package/dist/adapters/OpenSearchAdapter.d.ts.map +0 -1
- package/dist/adapters/OpenSearchAdapter.js +0 -471
- package/dist/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/adapters/PostgreSQLAdapter.d.ts +0 -85
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +0 -1
- package/dist/adapters/PostgreSQLAdapter.js +0 -308
- package/dist/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/adapters/PrismaAdapter.d.ts +0 -115
- package/dist/adapters/PrismaAdapter.d.ts.map +0 -1
- package/dist/adapters/PrismaAdapter.js +0 -406
- package/dist/adapters/PrismaAdapter.js.map +0 -1
- package/dist/adapters/RedisAdapter.d.ts +0 -72
- package/dist/adapters/RedisAdapter.d.ts.map +0 -1
- package/dist/adapters/RedisAdapter.js +0 -286
- package/dist/adapters/RedisAdapter.js.map +0 -1
- package/dist/adapters/SQLiteAdapter.d.ts +0 -86
- package/dist/adapters/SQLiteAdapter.d.ts.map +0 -1
- package/dist/adapters/SQLiteAdapter.js +0 -337
- package/dist/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -17
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -11
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/sessionRow.d.ts +0 -22
- package/dist/adapters/sessionRow.d.ts.map +0 -1
- package/dist/adapters/sessionRow.js +0 -48
- package/dist/adapters/sessionRow.js.map +0 -1
- package/dist/cjs/adapters/MemoryAdapter.d.ts +0 -47
- package/dist/cjs/adapters/MemoryAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/MemoryAdapter.js +0 -208
- package/dist/cjs/adapters/MemoryAdapter.js.map +0 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts +0 -97
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/MongoAdapter.js +0 -200
- package/dist/cjs/adapters/MongoAdapter.js.map +0 -1
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts +0 -169
- package/dist/cjs/adapters/OpenSearchAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js +0 -475
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +0 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +0 -85
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +0 -312
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +0 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts +0 -115
- package/dist/cjs/adapters/PrismaAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/PrismaAdapter.js +0 -410
- package/dist/cjs/adapters/PrismaAdapter.js.map +0 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts +0 -72
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/RedisAdapter.js +0 -290
- package/dist/cjs/adapters/RedisAdapter.js.map +0 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +0 -86
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +0 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +0 -341
- package/dist/cjs/adapters/SQLiteAdapter.js.map +0 -1
- package/dist/cjs/adapters/index.d.ts +0 -17
- package/dist/cjs/adapters/index.d.ts.map +0 -1
- package/dist/cjs/adapters/index.js +0 -21
- package/dist/cjs/adapters/index.js.map +0 -1
- package/dist/cjs/adapters/sessionRow.d.ts +0 -22
- package/dist/cjs/adapters/sessionRow.d.ts.map +0 -1
- package/dist/cjs/adapters/sessionRow.js +0 -52
- package/dist/cjs/adapters/sessionRow.js.map +0 -1
- package/dist/cjs/constants/index.d.ts +0 -1
- package/dist/cjs/constants/index.d.ts.map +0 -1
- package/dist/cjs/constants/index.js +0 -4
- package/dist/cjs/constants/index.js.map +0 -1
- package/dist/cjs/core/AutoChainExecutor.d.ts +0 -97
- package/dist/cjs/core/AutoChainExecutor.d.ts.map +0 -1
- package/dist/cjs/core/AutoChainExecutor.js +0 -288
- package/dist/cjs/core/AutoChainExecutor.js.map +0 -1
- package/dist/cjs/core/BranchEvaluator.d.ts +0 -55
- package/dist/cjs/core/BranchEvaluator.d.ts.map +0 -1
- package/dist/cjs/core/BranchEvaluator.js +0 -125
- package/dist/cjs/core/BranchEvaluator.js.map +0 -1
- package/dist/cjs/core/DirectiveChainTracker.d.ts +0 -49
- package/dist/cjs/core/DirectiveChainTracker.d.ts.map +0 -1
- package/dist/cjs/core/DirectiveChainTracker.js +0 -121
- package/dist/cjs/core/DirectiveChainTracker.js.map +0 -1
- package/dist/cjs/core/Events.d.ts +0 -26
- package/dist/cjs/core/Events.d.ts.map +0 -1
- package/dist/cjs/core/Events.js +0 -144
- package/dist/cjs/core/Events.js.map +0 -1
- package/dist/cjs/core/Flow.d.ts +0 -183
- package/dist/cjs/core/Flow.d.ts.map +0 -1
- package/dist/cjs/core/Flow.js +0 -551
- package/dist/cjs/core/Flow.js.map +0 -1
- package/dist/cjs/core/FlowRouter.d.ts +0 -183
- package/dist/cjs/core/FlowRouter.d.ts.map +0 -1
- package/dist/cjs/core/FlowRouter.js +0 -1047
- package/dist/cjs/core/FlowRouter.js.map +0 -1
- package/dist/cjs/core/PersistenceManager.d.ts +0 -114
- package/dist/cjs/core/PersistenceManager.d.ts.map +0 -1
- package/dist/cjs/core/PersistenceManager.js +0 -336
- package/dist/cjs/core/PersistenceManager.js.map +0 -1
- package/dist/cjs/core/PromptComposer.d.ts +0 -47
- package/dist/cjs/core/PromptComposer.d.ts.map +0 -1
- package/dist/cjs/core/PromptComposer.js +0 -397
- package/dist/cjs/core/PromptComposer.js.map +0 -1
- package/dist/cjs/core/PromptSectionCache.d.ts +0 -48
- package/dist/cjs/core/PromptSectionCache.d.ts.map +0 -1
- package/dist/cjs/core/PromptSectionCache.js +0 -108
- package/dist/cjs/core/PromptSectionCache.js.map +0 -1
- package/dist/cjs/core/ResponseEngine.d.ts +0 -43
- package/dist/cjs/core/ResponseEngine.d.ts.map +0 -1
- package/dist/cjs/core/ResponseEngine.js +0 -235
- package/dist/cjs/core/ResponseEngine.js.map +0 -1
- package/dist/cjs/core/ResponseGenerationError.d.ts +0 -30
- package/dist/cjs/core/ResponseGenerationError.d.ts.map +0 -1
- package/dist/cjs/core/ResponseGenerationError.js +0 -35
- package/dist/cjs/core/ResponseGenerationError.js.map +0 -1
- package/dist/cjs/core/ResponseModal.d.ts +0 -305
- package/dist/cjs/core/ResponseModal.d.ts.map +0 -1
- package/dist/cjs/core/ResponseModal.js +0 -1414
- package/dist/cjs/core/ResponseModal.js.map +0 -1
- package/dist/cjs/core/ResponsePipeline.d.ts +0 -220
- package/dist/cjs/core/ResponsePipeline.d.ts.map +0 -1
- package/dist/cjs/core/ResponsePipeline.js +0 -1040
- package/dist/cjs/core/ResponsePipeline.js.map +0 -1
- package/dist/cjs/core/SessionFinalizer.d.ts +0 -34
- package/dist/cjs/core/SessionFinalizer.d.ts.map +0 -1
- package/dist/cjs/core/SessionFinalizer.js +0 -88
- package/dist/cjs/core/SessionFinalizer.js.map +0 -1
- package/dist/cjs/core/SessionManager.d.ts +0 -112
- package/dist/cjs/core/SessionManager.d.ts.map +0 -1
- package/dist/cjs/core/SessionManager.js +0 -308
- package/dist/cjs/core/SessionManager.js.map +0 -1
- package/dist/cjs/core/SignalCoordinator.d.ts +0 -103
- package/dist/cjs/core/SignalCoordinator.d.ts.map +0 -1
- package/dist/cjs/core/SignalCoordinator.js +0 -207
- package/dist/cjs/core/SignalCoordinator.js.map +0 -1
- package/dist/cjs/core/SignalEvaluator.d.ts +0 -86
- package/dist/cjs/core/SignalEvaluator.d.ts.map +0 -1
- package/dist/cjs/core/SignalEvaluator.js +0 -319
- package/dist/cjs/core/SignalEvaluator.js.map +0 -1
- package/dist/cjs/core/SignalProcessor.d.ts +0 -152
- package/dist/cjs/core/SignalProcessor.d.ts.map +0 -1
- package/dist/cjs/core/SignalProcessor.js +0 -505
- package/dist/cjs/core/SignalProcessor.js.map +0 -1
- package/dist/cjs/core/Step.d.ts +0 -184
- package/dist/cjs/core/Step.d.ts.map +0 -1
- package/dist/cjs/core/Step.js +0 -599
- package/dist/cjs/core/Step.js.map +0 -1
- package/dist/cjs/core/StepLifecycle.d.ts +0 -43
- package/dist/cjs/core/StepLifecycle.d.ts.map +0 -1
- package/dist/cjs/core/StepLifecycle.js +0 -180
- package/dist/cjs/core/StepLifecycle.js.map +0 -1
- package/dist/cjs/core/StreamingToolExecutor.d.ts +0 -142
- package/dist/cjs/core/StreamingToolExecutor.d.ts.map +0 -1
- package/dist/cjs/core/StreamingToolExecutor.js +0 -490
- package/dist/cjs/core/StreamingToolExecutor.js.map +0 -1
- package/dist/cjs/core/ToolLoopExecutor.d.ts +0 -133
- package/dist/cjs/core/ToolLoopExecutor.d.ts.map +0 -1
- package/dist/cjs/core/ToolLoopExecutor.js +0 -568
- package/dist/cjs/core/ToolLoopExecutor.js.map +0 -1
- package/dist/cjs/core/ToolManager.d.ts +0 -250
- package/dist/cjs/core/ToolManager.d.ts.map +0 -1
- package/dist/cjs/core/ToolManager.js +0 -1104
- package/dist/cjs/core/ToolManager.js.map +0 -1
- package/dist/cjs/core/createAgent.d.ts +0 -35
- package/dist/cjs/core/createAgent.d.ts.map +0 -1
- package/dist/cjs/core/createAgent.js +0 -39
- package/dist/cjs/core/createAgent.js.map +0 -1
- package/dist/cjs/core/flow-namespace.d.ts +0 -64
- package/dist/cjs/core/flow-namespace.d.ts.map +0 -1
- package/dist/cjs/core/flow-namespace.js +0 -182
- package/dist/cjs/core/flow-namespace.js.map +0 -1
- package/dist/cjs/core/toolGates.d.ts +0 -24
- package/dist/cjs/core/toolGates.d.ts.map +0 -1
- package/dist/cjs/core/toolGates.js +0 -52
- package/dist/cjs/core/toolGates.js.map +0 -1
- package/dist/cjs/types/persistence.d.ts +0 -254
- package/dist/cjs/types/persistence.d.ts.map +0 -1
- package/dist/cjs/types/persistence.js +0 -7
- package/dist/cjs/types/persistence.js.map +0 -1
- package/dist/cjs/types/prompt-cache.d.ts +0 -15
- package/dist/cjs/types/prompt-cache.d.ts.map +0 -1
- package/dist/cjs/types/prompt-cache.js +0 -6
- package/dist/cjs/types/prompt-cache.js.map +0 -1
- package/dist/cjs/types/signals.d.ts +0 -263
- package/dist/cjs/types/signals.d.ts.map +0 -1
- package/dist/cjs/types/signals.js +0 -11
- package/dist/cjs/types/signals.js.map +0 -1
- package/dist/cjs/types/template.d.ts +0 -84
- package/dist/cjs/types/template.d.ts.map +0 -1
- package/dist/cjs/types/template.js +0 -3
- package/dist/cjs/types/template.js.map +0 -1
- package/dist/cjs/utils/condition.d.ts +0 -63
- package/dist/cjs/utils/condition.d.ts.map +0 -1
- package/dist/cjs/utils/condition.js +0 -239
- package/dist/cjs/utils/condition.js.map +0 -1
- package/dist/cjs/utils/event.d.ts +0 -6
- package/dist/cjs/utils/event.d.ts.map +0 -1
- package/dist/cjs/utils/event.js +0 -20
- package/dist/cjs/utils/event.js.map +0 -1
- package/dist/cjs/utils/id.d.ts +0 -33
- package/dist/cjs/utils/id.d.ts.map +0 -1
- package/dist/cjs/utils/id.js +0 -84
- package/dist/cjs/utils/id.js.map +0 -1
- package/dist/cjs/utils/serialize.d.ts +0 -36
- package/dist/cjs/utils/serialize.d.ts.map +0 -1
- package/dist/cjs/utils/serialize.js +0 -77
- package/dist/cjs/utils/serialize.js.map +0 -1
- package/dist/cjs/utils/session.d.ts +0 -124
- package/dist/cjs/utils/session.d.ts.map +0 -1
- package/dist/cjs/utils/session.js +0 -396
- package/dist/cjs/utils/session.js.map +0 -1
- package/dist/constants/index.d.ts +0 -2
- package/dist/constants/index.d.ts.map +0 -1
- package/dist/constants/index.js +0 -4
- package/dist/constants/index.js.map +0 -1
- package/dist/core/AutoChainExecutor.d.ts +0 -97
- package/dist/core/AutoChainExecutor.d.ts.map +0 -1
- package/dist/core/AutoChainExecutor.js +0 -284
- package/dist/core/AutoChainExecutor.js.map +0 -1
- package/dist/core/BranchEvaluator.d.ts +0 -55
- package/dist/core/BranchEvaluator.d.ts.map +0 -1
- package/dist/core/BranchEvaluator.js +0 -121
- package/dist/core/BranchEvaluator.js.map +0 -1
- package/dist/core/DirectiveChainTracker.d.ts +0 -49
- package/dist/core/DirectiveChainTracker.d.ts.map +0 -1
- package/dist/core/DirectiveChainTracker.js +0 -117
- package/dist/core/DirectiveChainTracker.js.map +0 -1
- package/dist/core/Events.d.ts +0 -26
- package/dist/core/Events.d.ts.map +0 -1
- package/dist/core/Events.js +0 -137
- package/dist/core/Events.js.map +0 -1
- package/dist/core/Flow.d.ts +0 -183
- package/dist/core/Flow.d.ts.map +0 -1
- package/dist/core/Flow.js +0 -547
- package/dist/core/Flow.js.map +0 -1
- package/dist/core/FlowRouter.d.ts +0 -183
- package/dist/core/FlowRouter.d.ts.map +0 -1
- package/dist/core/FlowRouter.js +0 -1043
- package/dist/core/FlowRouter.js.map +0 -1
- package/dist/core/PersistenceManager.d.ts +0 -114
- package/dist/core/PersistenceManager.d.ts.map +0 -1
- package/dist/core/PersistenceManager.js +0 -332
- package/dist/core/PersistenceManager.js.map +0 -1
- package/dist/core/PromptComposer.d.ts +0 -47
- package/dist/core/PromptComposer.d.ts.map +0 -1
- package/dist/core/PromptComposer.js +0 -393
- package/dist/core/PromptComposer.js.map +0 -1
- package/dist/core/PromptSectionCache.d.ts +0 -48
- package/dist/core/PromptSectionCache.d.ts.map +0 -1
- package/dist/core/PromptSectionCache.js +0 -104
- package/dist/core/PromptSectionCache.js.map +0 -1
- package/dist/core/ResponseEngine.d.ts +0 -43
- package/dist/core/ResponseEngine.d.ts.map +0 -1
- package/dist/core/ResponseEngine.js +0 -231
- package/dist/core/ResponseEngine.js.map +0 -1
- package/dist/core/ResponseGenerationError.d.ts +0 -30
- package/dist/core/ResponseGenerationError.d.ts.map +0 -1
- package/dist/core/ResponseGenerationError.js +0 -31
- package/dist/core/ResponseGenerationError.js.map +0 -1
- package/dist/core/ResponseModal.d.ts +0 -305
- package/dist/core/ResponseModal.d.ts.map +0 -1
- package/dist/core/ResponseModal.js +0 -1410
- package/dist/core/ResponseModal.js.map +0 -1
- package/dist/core/ResponsePipeline.d.ts +0 -220
- package/dist/core/ResponsePipeline.d.ts.map +0 -1
- package/dist/core/ResponsePipeline.js +0 -1035
- package/dist/core/ResponsePipeline.js.map +0 -1
- package/dist/core/SessionFinalizer.d.ts +0 -34
- package/dist/core/SessionFinalizer.d.ts.map +0 -1
- package/dist/core/SessionFinalizer.js +0 -84
- package/dist/core/SessionFinalizer.js.map +0 -1
- package/dist/core/SessionManager.d.ts +0 -112
- package/dist/core/SessionManager.d.ts.map +0 -1
- package/dist/core/SessionManager.js +0 -301
- package/dist/core/SessionManager.js.map +0 -1
- package/dist/core/SignalCoordinator.d.ts +0 -103
- package/dist/core/SignalCoordinator.d.ts.map +0 -1
- package/dist/core/SignalCoordinator.js +0 -203
- package/dist/core/SignalCoordinator.js.map +0 -1
- package/dist/core/SignalEvaluator.d.ts +0 -86
- package/dist/core/SignalEvaluator.d.ts.map +0 -1
- package/dist/core/SignalEvaluator.js +0 -312
- package/dist/core/SignalEvaluator.js.map +0 -1
- package/dist/core/SignalProcessor.d.ts +0 -152
- package/dist/core/SignalProcessor.d.ts.map +0 -1
- package/dist/core/SignalProcessor.js +0 -498
- package/dist/core/SignalProcessor.js.map +0 -1
- package/dist/core/Step.d.ts +0 -184
- package/dist/core/Step.d.ts.map +0 -1
- package/dist/core/Step.js +0 -594
- package/dist/core/Step.js.map +0 -1
- package/dist/core/StepLifecycle.d.ts +0 -43
- package/dist/core/StepLifecycle.d.ts.map +0 -1
- package/dist/core/StepLifecycle.js +0 -176
- package/dist/core/StepLifecycle.js.map +0 -1
- package/dist/core/StreamingToolExecutor.d.ts +0 -142
- package/dist/core/StreamingToolExecutor.d.ts.map +0 -1
- package/dist/core/StreamingToolExecutor.js +0 -483
- package/dist/core/StreamingToolExecutor.js.map +0 -1
- package/dist/core/ToolLoopExecutor.d.ts +0 -133
- package/dist/core/ToolLoopExecutor.d.ts.map +0 -1
- package/dist/core/ToolLoopExecutor.js +0 -564
- package/dist/core/ToolLoopExecutor.js.map +0 -1
- package/dist/core/ToolManager.d.ts +0 -250
- package/dist/core/ToolManager.d.ts.map +0 -1
- package/dist/core/ToolManager.js +0 -1098
- package/dist/core/ToolManager.js.map +0 -1
- package/dist/core/createAgent.d.ts +0 -35
- package/dist/core/createAgent.d.ts.map +0 -1
- package/dist/core/createAgent.js +0 -36
- package/dist/core/createAgent.js.map +0 -1
- package/dist/core/flow-namespace.d.ts +0 -64
- package/dist/core/flow-namespace.d.ts.map +0 -1
- package/dist/core/flow-namespace.js +0 -179
- package/dist/core/flow-namespace.js.map +0 -1
- package/dist/core/toolGates.d.ts +0 -24
- package/dist/core/toolGates.d.ts.map +0 -1
- package/dist/core/toolGates.js +0 -49
- package/dist/core/toolGates.js.map +0 -1
- package/dist/types/persistence.d.ts +0 -254
- package/dist/types/persistence.d.ts.map +0 -1
- package/dist/types/persistence.js +0 -6
- package/dist/types/persistence.js.map +0 -1
- package/dist/types/prompt-cache.d.ts +0 -15
- package/dist/types/prompt-cache.d.ts.map +0 -1
- package/dist/types/prompt-cache.js +0 -5
- package/dist/types/prompt-cache.js.map +0 -1
- package/dist/types/signals.d.ts +0 -263
- package/dist/types/signals.d.ts.map +0 -1
- package/dist/types/signals.js +0 -10
- package/dist/types/signals.js.map +0 -1
- package/dist/types/template.d.ts +0 -84
- package/dist/types/template.d.ts.map +0 -1
- package/dist/types/template.js +0 -2
- package/dist/types/template.js.map +0 -1
- package/dist/utils/condition.d.ts +0 -63
- package/dist/utils/condition.d.ts.map +0 -1
- package/dist/utils/condition.js +0 -230
- package/dist/utils/condition.js.map +0 -1
- package/dist/utils/event.d.ts +0 -6
- package/dist/utils/event.d.ts.map +0 -1
- package/dist/utils/event.js +0 -17
- package/dist/utils/event.js.map +0 -1
- package/dist/utils/id.d.ts +0 -33
- package/dist/utils/id.d.ts.map +0 -1
- package/dist/utils/id.js +0 -77
- package/dist/utils/id.js.map +0 -1
- package/dist/utils/serialize.d.ts +0 -36
- package/dist/utils/serialize.d.ts.map +0 -1
- package/dist/utils/serialize.js +0 -72
- package/dist/utils/serialize.js.map +0 -1
- package/dist/utils/session.d.ts +0 -124
- package/dist/utils/session.d.ts.map +0 -1
- package/dist/utils/session.js +0 -379
- package/dist/utils/session.js.map +0 -1
- package/docs/concepts/directives.md +0 -369
- package/docs/reference/adapters.md +0 -543
- package/docs/reference/create-agent.md +0 -216
- package/docs/reference/directive.md +0 -242
- package/docs/reference/signals.md +0 -368
- package/examples/02-data-extraction.ts +0 -90
- package/examples/05-branching.ts +0 -140
- package/examples/06-flow-control.ts +0 -103
- package/examples/08-persistence.ts +0 -98
- package/examples/09-signals.ts +0 -144
- package/src/adapters/MemoryAdapter.ts +0 -281
- package/src/adapters/MongoAdapter.ts +0 -341
- package/src/adapters/OpenSearchAdapter.ts +0 -693
- package/src/adapters/PostgreSQLAdapter.ts +0 -487
- package/src/adapters/PrismaAdapter.ts +0 -617
- package/src/adapters/RedisAdapter.ts +0 -439
- package/src/adapters/SQLiteAdapter.ts +0 -496
- package/src/adapters/index.ts +0 -43
- package/src/adapters/sessionRow.ts +0 -57
- package/src/constants/index.ts +0 -2
- package/src/core/AutoChainExecutor.ts +0 -397
- package/src/core/BranchEvaluator.ts +0 -161
- package/src/core/DirectiveChainTracker.ts +0 -144
- package/src/core/Events.ts +0 -164
- package/src/core/Flow.ts +0 -665
- package/src/core/FlowRouter.ts +0 -1540
- package/src/core/PersistenceManager.ts +0 -446
- package/src/core/PromptComposer.ts +0 -448
- package/src/core/PromptSectionCache.ts +0 -125
- package/src/core/ResponseEngine.ts +0 -338
- package/src/core/ResponseGenerationError.ts +0 -53
- package/src/core/ResponseModal.ts +0 -1902
- package/src/core/ResponsePipeline.ts +0 -1404
- package/src/core/SessionFinalizer.ts +0 -108
- package/src/core/SessionManager.ts +0 -372
- package/src/core/SignalCoordinator.ts +0 -263
- package/src/core/SignalEvaluator.ts +0 -404
- package/src/core/SignalProcessor.ts +0 -663
- package/src/core/Step.ts +0 -782
- package/src/core/StepLifecycle.ts +0 -242
- package/src/core/StreamingToolExecutor.ts +0 -609
- package/src/core/ToolLoopExecutor.ts +0 -749
- package/src/core/ToolManager.ts +0 -1379
- package/src/core/createAgent.ts +0 -40
- package/src/core/flow-namespace.ts +0 -227
- package/src/core/toolGates.ts +0 -72
- package/src/types/persistence.ts +0 -303
- package/src/types/prompt-cache.ts +0 -17
- package/src/types/signals.ts +0 -338
- package/src/types/template.ts +0 -98
- package/src/utils/condition.ts +0 -296
- package/src/utils/event.ts +0 -16
- package/src/utils/id.ts +0 -91
- package/src/utils/serialize.ts +0 -86
- package/src/utils/session.ts +0 -501
package/docs/guides/streaming.md
CHANGED
|
@@ -1,149 +1,85 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Streaming"
|
|
3
|
-
description: "
|
|
3
|
+
description: "turnStream: the reply arrives as text deltas, the full turn result arrives last, and everything else works exactly as in turn()."
|
|
4
4
|
type: guide
|
|
5
|
-
order:
|
|
5
|
+
order: 9
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Streaming
|
|
9
9
|
|
|
10
|
-
`agent.
|
|
10
|
+
`agent.turnStream()` is `agent.turn()` that yields the reply while the model writes it.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
```ts
|
|
13
|
+
import { falai, GeminiProvider } from "@falai/agent";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
`respondStream` takes the same `RespondParams` as `respond` — `history`, optional `session`, optional `contextOverride`, optional `signal` — and returns an async iterable of chunks.
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
const stream = agent.respondStream({
|
|
20
|
-
history: [{ role: "user", content: "Book me a hotel in Lisbon." }],
|
|
15
|
+
const f = falai().fields({
|
|
16
|
+
nome: { type: "string", ask: "Pergunte o nome." },
|
|
21
17
|
});
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// ...metadata fields, populated on the final chunk
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
`delta` is the new token(s); concatenating every `delta` reproduces the final reply unless a post-phase signal replaces the message on the terminal chunk. `accumulated` is the authoritative running total — useful when your renderer needs the full string each tick (e.g., a Markdown view that re-parses on every update). `done` flips to `true` exactly once, on the terminal chunk.
|
|
40
|
-
|
|
41
|
-
## Render incrementally
|
|
42
|
-
|
|
43
|
-
The simplest renderer prints every `delta` as it arrives and clears the line on `done`:
|
|
19
|
+
const agent = f.agent({
|
|
20
|
+
name: "Ana",
|
|
21
|
+
provider: new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY ?? "", model: "gemini-2.5-flash" }),
|
|
22
|
+
flows: [
|
|
23
|
+
f.flow({
|
|
24
|
+
id: "boas-vindas",
|
|
25
|
+
name: "Boas-vindas",
|
|
26
|
+
on: [{ message: [] }],
|
|
27
|
+
steps: [{ id: "nome", collect: ["nome"] }],
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
});
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (chunk.delta) {
|
|
32
|
+
for await (const chunk of agent.turnStream({ sessionId: "demo", message: "oi, sou o Rui" })) {
|
|
33
|
+
if ("delta" in chunk) {
|
|
48
34
|
process.stdout.write(chunk.delta);
|
|
35
|
+
continue;
|
|
49
36
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
For a UI, push the latest `accumulated` into your component state. React, Solid, Svelte — they all re-render off whichever value you give them, and `accumulated` is the cheapest to consume because it never requires the renderer to track partial state.
|
|
57
|
-
|
|
58
|
-
A common rendering rule of thumb:
|
|
59
|
-
|
|
60
|
-
- Plain text view → append `delta`.
|
|
61
|
-
- Markdown view that re-parses each frame → bind to `accumulated`.
|
|
62
|
-
- Server-Sent Events transport → forward `{ delta, done }` per chunk; let the client reassemble.
|
|
63
|
-
|
|
64
|
-
## Surface tool calls in flight
|
|
65
|
-
|
|
66
|
-
Streaming works through tool calls transparently. When the LLM emits a tool call mid-reply, `respondStream` runs the tool, then resumes streaming the post-tool tokens — the consumer never sees the call boundary in the text. What you do get is a quiet gap while the tool executes, which is the right moment to show a "thinking" indicator.
|
|
67
|
-
|
|
68
|
-
Detect the gap by watching for empty `delta` chunks after some text has already arrived, or — more robustly — toggle the indicator off as soon as the first non-empty `delta` lands:
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
let thinking = true;
|
|
72
|
-
let firstToken = true;
|
|
73
|
-
|
|
74
|
-
for await (const chunk of agent.respondStream({ history })) {
|
|
75
|
-
if (chunk.delta) {
|
|
76
|
-
if (firstToken) {
|
|
77
|
-
thinking = false;
|
|
78
|
-
firstToken = false;
|
|
79
|
-
ui.hideSpinner();
|
|
80
|
-
}
|
|
81
|
-
ui.appendText(chunk.delta);
|
|
82
|
-
}
|
|
37
|
+
process.stdout.write("\n");
|
|
38
|
+
console.log(chunk.result.llmCalls, chunk.result.session.data); // 1 { nome: 'Rui' }
|
|
83
39
|
}
|
|
84
40
|
```
|
|
85
41
|
|
|
86
|
-
|
|
42
|
+
The stream prints the reply one piece at a time, then the last chunk hands you the same `TurnResult` that `turn()` would have returned.
|
|
87
43
|
|
|
88
|
-
|
|
44
|
+
## The chunks
|
|
89
45
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
for await (const chunk of agent.respondStream({ history })) {
|
|
96
|
-
// ...render delta...
|
|
97
|
-
if (chunk.done) {
|
|
98
|
-
console.log("flow complete:", chunk.isFlowComplete);
|
|
99
|
-
console.log("instructions rendered:", chunk.appliedInstructions);
|
|
100
|
-
console.log("signals fired:", chunk.triggeredSignals);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
46
|
+
```ts fragment
|
|
47
|
+
type TurnStreamChunk<D> =
|
|
48
|
+
| { delta: string } // a piece of the reply, in order
|
|
49
|
+
| { done: true; result: TurnResult<D> }; // always last, exactly once
|
|
103
50
|
```
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
- **`triggeredSignals`** — the [signals](../reference/signals.md) that fired during this turn (pre- and post-phase), in fire order. Same population rule.
|
|
107
|
-
- **`isFlowComplete`** — `true` when this turn finished the flow. Use it to decide whether to clear the conversation, show a summary card, or transition the UI.
|
|
52
|
+
Every `delta` is plain message text. Joined together they add up to the reply. The `done` chunk carries the whole result: `session`, `changed`, `messages[]`, `schedule[]`, `outcomes[]`, `started`, `ended`, `skipped`, `llmCalls`. Read [the agent reference](../reference/agent.md) for the fields.
|
|
108
53
|
|
|
109
|
-
|
|
54
|
+
## What streams and what does not
|
|
110
55
|
|
|
111
|
-
|
|
56
|
+
Only the speak call streams: the one call that phrases the reply. Everything else in the turn is code or a call that never streams.
|
|
112
57
|
|
|
113
|
-
|
|
58
|
+
| Source | Arrives as |
|
|
59
|
+
|---|---|
|
|
60
|
+
| the talk step's reply, or the idle speaker's | `delta` chunks, then in `result.messages[]` as one `kind: "ai"` message |
|
|
61
|
+
| a `say` step's text | `result.messages[]` only, `kind: "verbatim"` |
|
|
62
|
+
| the understand call (routing, mentions, extraction) | nothing visible; it finishes before the first delta |
|
|
63
|
+
| actions, waits, `if` steps | `result.outcomes[]`, `result.schedule[]` |
|
|
114
64
|
|
|
115
|
-
|
|
116
|
-
const controller = new AbortController();
|
|
65
|
+
The provider streams a JSON envelope, not bare text: `{"message":"Oi, Rui! Em que posso"…` followed by the collected fields. The framework unwraps it as it arrives (`src/utils/streamingMessage.ts`), so a `delta` never contains a brace, a quote or a field name, and a field the model writes before the message is skipped rather than leaked. A provider that streams plain text passes through as it is.
|
|
117
66
|
|
|
118
|
-
|
|
119
|
-
const timer = setTimeout(() => controller.abort(), 5000);
|
|
67
|
+
## Tool calls during a stream
|
|
120
68
|
|
|
121
|
-
|
|
122
|
-
for await (const chunk of agent.respondStream({
|
|
123
|
-
history,
|
|
124
|
-
signal: controller.signal,
|
|
125
|
-
})) {
|
|
126
|
-
process.stdout.write(chunk.delta);
|
|
127
|
-
}
|
|
128
|
-
} finally {
|
|
129
|
-
clearTimeout(timer);
|
|
130
|
-
}
|
|
131
|
-
```
|
|
69
|
+
A speak call may run in rounds: the model calls tools, the results go back as history, and the model is asked again. This happens inside the stream, before the `done` chunk. Each round streams. If the model writes something beside a tool call ("deixa eu ver"), that preamble reaches the stream, while `result.messages[0].text` holds only the final round's message. A UI that shows deltas as they come should replace what it showed with `result.messages[0].text` when `done` arrives, so both paths end on the same text.
|
|
132
70
|
|
|
133
|
-
|
|
71
|
+
Rounds are capped by `maxToolLoops` on the agent, default 5; after the cap the model is asked once more with no tools so a message always comes back. Each round is one model call and counts in `result.llmCalls`.
|
|
134
72
|
|
|
135
|
-
|
|
73
|
+
## A provider failure mid-stream
|
|
136
74
|
|
|
137
|
-
|
|
75
|
+
The stream never throws for a speak failure. You get zero or more deltas and then the `done` chunk, whose result carries a `deferred` outcome and a retry wake, exactly as `turn()` would report it.
|
|
138
76
|
|
|
139
|
-
|
|
77
|
+
A failure mid-stream leaves the person looking at half a reply. Nothing of that half reaches `result.messages[]`, so the deltas you showed are its only trace: clear them when `done` carries a `deferred` outcome, and leave a short line saying the reply is coming. The retry wake fires a minute later, speaks that step again from the start, and its reply arrives as an ordinary message carrying the key the first attempt would have used.
|
|
140
78
|
|
|
141
|
-
|
|
79
|
+
A failure in the understand call, before any delta, throws from the `for await` like `turn()` does. See [error handling](./error-handling.md).
|
|
142
80
|
|
|
143
|
-
|
|
144
|
-
- **First-chunk deadline.** `retryConfig.timeout` doubles as the time-to-first-token budget. If the provider opens a stream but produces no first chunk within it, the attempt counts as failed and the retry and backup machinery takes over. Only the first chunk is bounded — later chunks are unbounded, so a long-but-healthy stream is never cut off.
|
|
145
|
-
- **Transparent backup-model switch.** With `backupModels` configured, a model that fails mid-stream — even after deltas were delivered — falls through to the next model, whose chunks flow through unchanged. The switchover happens between chunks; no error reaches the consumer unless every model fails.
|
|
81
|
+
## The same settle, the same result
|
|
146
82
|
|
|
147
|
-
|
|
83
|
+
`turnStream` runs the same eight phases as `turn()` and applies the reply the same way. With the same provider output, the two return identical results: the same message keys, the same data written, the same schedule. Stream when you show text to a person as it is written. When the messages leave through a channel you send to yourself, `turn()` is simpler, because it gives you the messages after the save and nothing before it.
|
|
148
84
|
|
|
149
|
-
|
|
85
|
+
Save and send are still yours, and still in that order: the `done` chunk's `result.session` is what you save with the version you loaded, and a `SessionConflictError` means you replay the same input; see [persistence](./persistence.md). With a stream the person has already seen the text by then, which is fine in a chat window and is the reason to prefer `turn()` on a channel.
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Testing"
|
|
3
|
+
description: "A clock you hold still, a scheduler you fire by hand, a store in memory and a provider you script: everything a turn needs, with no network."
|
|
4
|
+
type: guide
|
|
5
|
+
order: 12
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Testing
|
|
9
|
+
|
|
10
|
+
The core does no I/O beyond the provider and your actions, so a test drives a real `Agent` with four fakes. Start with the clock.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { fakeClock } from "@falai/agent";
|
|
14
|
+
|
|
15
|
+
const clock = fakeClock("2026-09-20T10:00:00.000Z");
|
|
16
|
+
clock.advance("24h");
|
|
17
|
+
console.log(clock.now().toISOString()); // 2026-09-21T10:00:00.000Z
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Pass `clock` to the agent and every `now`, every wake time and every key that carries a timestamp comes from it. The core never reads `Date.now()`.
|
|
21
|
+
|
|
22
|
+
## The four fakes
|
|
23
|
+
|
|
24
|
+
| Fake | From | What it replaces |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `fakeClock(iso)` | `@falai/agent` | time: `now()`, `advance("2d" \| ms)`, `set(iso)` |
|
|
27
|
+
| `MemoryScheduler` | `@falai/agent` | your queue: `add(entry)`, `remove(key)`, `size`, `due(now)` returns and removes what is due, earliest first; a new entry with the same key replaces the old one, and `replaces` removes that key |
|
|
28
|
+
| `MemoryStore` | `@falai/agent` | your database, with the same version check |
|
|
29
|
+
| a scripted `AiProvider` | you write it, about 25 lines | the model |
|
|
30
|
+
|
|
31
|
+
The snippets below use `node:assert/strict` so they run under `bun run` or `node` with no framework. The repo's own tests use `bun test` the same way.
|
|
32
|
+
|
|
33
|
+
## A scripted provider
|
|
34
|
+
|
|
35
|
+
The framework names each call through `parameters.schemaName`: `"understand"` for the call that judges the customer's message, `"speak"` for the call that phrases the reply. A scripted provider keeps one queue per name, shifts the next reply off it, and throws when a queue runs dry, so a turn that spends a call you did not expect fails loudly.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { AiProvider, GenerateMessageInput, GenerateMessageOutput, GenerateMessageStreamChunk } from "@falai/agent";
|
|
39
|
+
|
|
40
|
+
type Reply = Record<string, unknown>;
|
|
41
|
+
|
|
42
|
+
export interface Scripted extends AiProvider {
|
|
43
|
+
/** Every call's schema name, in order. */
|
|
44
|
+
calls: string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function scripted(script: { understand?: Reply[]; speak?: Reply[] }): Scripted {
|
|
48
|
+
const queues: Record<string, Reply[]> = { understand: [...(script.understand ?? [])], speak: [...(script.speak ?? [])] };
|
|
49
|
+
const calls: string[] = [];
|
|
50
|
+
|
|
51
|
+
function next<T>(input: GenerateMessageInput): GenerateMessageOutput<T> {
|
|
52
|
+
const name = input.parameters?.schemaName ?? "(unnamed)";
|
|
53
|
+
calls.push(name);
|
|
54
|
+
const reply = queues[name]?.shift();
|
|
55
|
+
if (!reply) throw new Error(`no scripted "${name}" reply left for call #${calls.length}`);
|
|
56
|
+
const message = typeof reply.message === "string" ? reply.message : JSON.stringify(reply);
|
|
57
|
+
return { message, structured: reply as T };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
name: "scripted",
|
|
62
|
+
calls,
|
|
63
|
+
capabilities: { supportsTools: true, supportsNativeJsonSchema: true, supportsStreaming: true, supportsStreamingToolCalls: true, supportsPromptCaching: false },
|
|
64
|
+
generateMessage: <_C, T>(input: GenerateMessageInput) => Promise.resolve().then(() => next<T>(input)),
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- one chunk, nothing to await
|
|
66
|
+
async *generateMessageStream<_C, T>(input: GenerateMessageInput): AsyncGenerator<GenerateMessageStreamChunk<T>> {
|
|
67
|
+
const out = next<T>(input);
|
|
68
|
+
yield { delta: out.message, accumulated: out.message, done: true, structured: out.structured };
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The two envelopes you script, as the framework reads them:
|
|
75
|
+
|
|
76
|
+
```ts fragment
|
|
77
|
+
// understand: every section present, empty when there is nothing to say
|
|
78
|
+
{
|
|
79
|
+
flows: { triagem: 90 }, // flowId → 0–100 fit of the message to the flow
|
|
80
|
+
mentions: { concorrente: true }, // flowId → the customer brought it up
|
|
81
|
+
extract: { concorrente: { trecho: "a Acme cobra metade" } }, // flowId → values for the mention's `extract`
|
|
82
|
+
branches: {}, // "runId/stepId/index" → the `when` holds
|
|
83
|
+
fields: { nome: "Ana" }, // field → the raw value the customer gave
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// speak: the message, then one property per pending field, null when the customer did not give it
|
|
87
|
+
{ message: "Oi Ana! De qual empresa você fala?", empresa: null }
|
|
88
|
+
|
|
89
|
+
// speak, calling a tool first: the next scripted speak reply answers after the tool ran
|
|
90
|
+
{ toolCalls: [{ toolName: "orcamento", arguments: { pessoas: 30 } }] }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
A `fields` value goes through the same coercion as production: `"sim"` becomes `true` for a boolean, `"1,5"` becomes `1.5` for a number, `"mil"` is dropped with the outcome `code: 'bad-value'`, and an enum value outside the list is dropped with `code: 'not-in-enum'`.
|
|
94
|
+
|
|
95
|
+
## One test, end to end
|
|
96
|
+
|
|
97
|
+
A triage flow that collects two fields and a silence flow that nudges after 24 hours. The test asserts the call count, the message keys, the wake key, then fires the wake through the scheduler.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import assert from "node:assert/strict";
|
|
101
|
+
import { falai, fakeClock, MemoryScheduler, MemoryStore, type AiProvider, type DataOf, type GenerateMessageInput, type GenerateMessageOutput, type GenerateMessageStreamChunk, type TurnKind } from "@falai/agent";
|
|
102
|
+
|
|
103
|
+
// The scripted provider from above, inlined so this file stands alone.
|
|
104
|
+
type Reply = Record<string, unknown>;
|
|
105
|
+
function scripted(script: { understand?: Reply[]; speak?: Reply[] }): AiProvider & { calls: string[] } {
|
|
106
|
+
const queues: Record<string, Reply[]> = { understand: [...(script.understand ?? [])], speak: [...(script.speak ?? [])] };
|
|
107
|
+
const calls: string[] = [];
|
|
108
|
+
function next<T>(input: GenerateMessageInput): GenerateMessageOutput<T> {
|
|
109
|
+
const name = input.parameters?.schemaName ?? "(unnamed)";
|
|
110
|
+
calls.push(name);
|
|
111
|
+
const reply = queues[name]?.shift();
|
|
112
|
+
if (!reply) throw new Error(`no scripted "${name}" reply left for call #${calls.length}`);
|
|
113
|
+
return { message: typeof reply.message === "string" ? reply.message : JSON.stringify(reply), structured: reply as T };
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
name: "scripted",
|
|
117
|
+
calls,
|
|
118
|
+
capabilities: { supportsTools: true, supportsNativeJsonSchema: true, supportsStreaming: true, supportsStreamingToolCalls: true, supportsPromptCaching: false },
|
|
119
|
+
generateMessage: <_C, T>(input: GenerateMessageInput) => Promise.resolve().then(() => next<T>(input)),
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- one chunk, nothing to await
|
|
121
|
+
async *generateMessageStream<_C, T>(input: GenerateMessageInput): AsyncGenerator<GenerateMessageStreamChunk<T>> {
|
|
122
|
+
const out = next<T>(input);
|
|
123
|
+
yield { delta: out.message, accumulated: out.message, done: true, structured: out.structured };
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const T0 = "2026-09-20T10:00:00.000Z";
|
|
129
|
+
const f = falai().fields({
|
|
130
|
+
nome: { type: "string", ask: "Pergunte o nome de um jeito leve." },
|
|
131
|
+
empresa: { type: "string", ask: "Pergunte de qual empresa a pessoa fala." },
|
|
132
|
+
});
|
|
133
|
+
type Data = DataOf<typeof f>;
|
|
134
|
+
|
|
135
|
+
const triagem = f.flow({
|
|
136
|
+
id: "triagem",
|
|
137
|
+
name: "Triagem",
|
|
138
|
+
on: [{ message: ["quer saber como funciona", "pede um orçamento"] }],
|
|
139
|
+
steps: [
|
|
140
|
+
{ id: "quem", prompt: "Descubra quem é e de onde fala.", collect: ["nome", "empresa"] },
|
|
141
|
+
{ id: "tchau", prompt: "Agradeça e diga que um vendedor continua daqui." },
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const retomar = f.flow({
|
|
146
|
+
id: "retomar",
|
|
147
|
+
name: "Retomar quem sumiu",
|
|
148
|
+
on: [{ silence: "24h" }],
|
|
149
|
+
steps: [
|
|
150
|
+
{ id: "p1", prompt: "Retome a conversa de forma leve e pergunte se ainda faz sentido." },
|
|
151
|
+
{ id: "w1", wait: "2d", else: "end" },
|
|
152
|
+
{ id: "p2", prompt: "Última tentativa, curta e sem pressão." },
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const clock = fakeClock(T0);
|
|
157
|
+
const provider = scripted({
|
|
158
|
+
understand: [{ flows: {}, mentions: {}, extract: {}, branches: {}, fields: { nome: "Ana" } }],
|
|
159
|
+
speak: [{ message: "Oi Ana! De qual empresa você fala?", empresa: null }, { message: "Oi Ana, ainda faz sentido conversarmos?" }],
|
|
160
|
+
});
|
|
161
|
+
const agent = f.agent({ name: "Ana", provider, clock, flows: [triagem, retomar] });
|
|
162
|
+
const store = new MemoryStore<Data>();
|
|
163
|
+
const scheduler = new MemoryScheduler();
|
|
164
|
+
|
|
165
|
+
async function runTurn(input: TurnKind & { sessionId: string }) {
|
|
166
|
+
const session = await store.load(input.sessionId);
|
|
167
|
+
const r = await agent.turn({ ...input, session: session ?? undefined, history: [] });
|
|
168
|
+
if (r.changed) {
|
|
169
|
+
await store.save(r.session, session?.version ?? 0);
|
|
170
|
+
for (const entry of r.schedule) scheduler.add(entry);
|
|
171
|
+
}
|
|
172
|
+
return r;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Turn 1: the customer writes. Understand extracts the name (1 call), speak asks for the company (1 call).
|
|
176
|
+
const t1 = await runTurn({ sessionId: "s1", message: "oi, sou a Ana, quero saber como funciona", id: "m1" });
|
|
177
|
+
assert.equal(t1.llmCalls, 2);
|
|
178
|
+
assert.deepEqual(provider.calls, ["understand", "speak"]);
|
|
179
|
+
assert.equal(t1.session.data.nome, "Ana");
|
|
180
|
+
assert.equal(t1.messages[0]?.key, "triagem#m1:quem:1"); // ${runId}:${stepId}:${visit}
|
|
181
|
+
assert.equal(t1.outcomes.find((o) => o.kind === "collect")?.status, "ok");
|
|
182
|
+
// The assistant spoke last: the silence flow armed a wake for 24h from now.
|
|
183
|
+
const silenceKey = `silence:retomar:s1:${Date.parse(T0)}`;
|
|
184
|
+
assert.deepEqual(t1.schedule.map((s) => s.key), [silenceKey]);
|
|
185
|
+
assert.equal(scheduler.size, 1);
|
|
186
|
+
|
|
187
|
+
// 23h later nothing is due; at 24h the wake fires.
|
|
188
|
+
clock.advance("23h");
|
|
189
|
+
assert.equal(scheduler.due(clock.now()).length, 0);
|
|
190
|
+
clock.advance("1h");
|
|
191
|
+
const due = scheduler.due(clock.now());
|
|
192
|
+
assert.deepEqual(due.map((d) => d.key), [silenceKey]);
|
|
193
|
+
|
|
194
|
+
// Turn 2: the wake starts `retomar`, which speaks first (1 call) and parks on w1.
|
|
195
|
+
const t2 = await runTurn({ sessionId: "s1", wake: due[0].key });
|
|
196
|
+
assert.equal(t2.llmCalls, 1);
|
|
197
|
+
assert.deepEqual(t2.started.map((s) => s.flowId), ["retomar"]);
|
|
198
|
+
assert.equal(t2.messages[0]?.key, `retomar#${Date.parse(T0)}:p1:1`);
|
|
199
|
+
assert.deepEqual(t2.outcomes.find((o) => o.stepId === "w1"), {
|
|
200
|
+
runId: `retomar#${Date.parse(T0)}`,
|
|
201
|
+
flowId: "retomar",
|
|
202
|
+
stepId: "w1",
|
|
203
|
+
key: `retomar#${Date.parse(T0)}:w1:1`,
|
|
204
|
+
kind: "wait",
|
|
205
|
+
status: "waiting",
|
|
206
|
+
until: new Date(clock.now().getTime() + 2 * 86_400_000).toISOString(),
|
|
207
|
+
at: clock.now().toISOString(),
|
|
208
|
+
});
|
|
209
|
+
assert.deepEqual(t2.schedule.map((s) => s.key), [`retomar#${Date.parse(T0)}:w1:${clock.now().getTime() + 2 * 86_400_000}`]);
|
|
210
|
+
// Triagem still holds its question: the nudge did not take the floor for good.
|
|
211
|
+
assert.equal(t2.session.runs.find((r) => r.flowId === "triagem")?.status, "asking");
|
|
212
|
+
assert.equal((await store.load("s1"))?.version, 2);
|
|
213
|
+
|
|
214
|
+
console.log("ok");
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
What each assertion pins down:
|
|
218
|
+
|
|
219
|
+
- `llmCalls` is the budget. A turn that spends more than you scripted throws inside the provider, so an unexpected third call cannot pass silently. `usage` is absent in tests unless your scripted provider reports token counts — real providers do, and the turn adds them up.
|
|
220
|
+
- `messages[].key` is `${runId}:${stepId}:${visit}`, and `runId` is `${flowId}#${triggerKey}`. The trigger key of a message turn is the message `id` you passed; of a silence wake, the `lastAssistantAt` timestamp in milliseconds.
|
|
221
|
+
- `schedule[].key` is what your queue stores as `jobId` and what you pass back as `wake`. The silence key is `silence:${flowId}:${sessionId}:${ms}`; a timer wait's key is `${runId}:${stepId}:${atMs}`.
|
|
222
|
+
- `outcomes[]` is the execution log, one line per step. Assert on `code`, which is stable across versions, not on `message`, the English sentence beside it; see [outcomes](../reference/outcomes.md).
|
|
223
|
+
|
|
224
|
+
## Replaying the same input
|
|
225
|
+
|
|
226
|
+
The keys are deterministic: the same input on the same session version mints the same run id, the same message keys and the same wake keys. That is what makes a `SessionConflictError` safe to replay and a duplicate webhook harmless. Prove it with two agents that share a clock:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import assert from "node:assert/strict";
|
|
230
|
+
import { falai, fakeClock, type AiProvider, type GenerateMessageInput, type GenerateMessageOutput, type GenerateMessageStreamChunk } from "@falai/agent";
|
|
231
|
+
|
|
232
|
+
type Reply = Record<string, unknown>;
|
|
233
|
+
function scripted(speak: Reply[]): AiProvider {
|
|
234
|
+
const queue = [...speak];
|
|
235
|
+
function next<T>(input: GenerateMessageInput): GenerateMessageOutput<T> {
|
|
236
|
+
if (input.parameters?.schemaName !== "speak") throw new Error(`unexpected ${input.parameters?.schemaName ?? "unnamed"} call`);
|
|
237
|
+
const reply = queue.shift();
|
|
238
|
+
if (!reply) throw new Error("no scripted speak reply left");
|
|
239
|
+
return { message: String(reply.message), structured: reply as T };
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
name: "scripted",
|
|
243
|
+
capabilities: { supportsTools: true, supportsNativeJsonSchema: true, supportsStreaming: true, supportsStreamingToolCalls: true, supportsPromptCaching: false },
|
|
244
|
+
generateMessage: <_C, T>(input: GenerateMessageInput) => Promise.resolve().then(() => next<T>(input)),
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- one chunk, nothing to await
|
|
246
|
+
async *generateMessageStream<_C, T>(input: GenerateMessageInput): AsyncGenerator<GenerateMessageStreamChunk<T>> {
|
|
247
|
+
const out = next<T>(input);
|
|
248
|
+
yield { delta: out.message, accumulated: out.message, done: true, structured: out.structured };
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const f = falai().fields({
|
|
254
|
+
nome: { type: "string", ask: "Pergunte o nome." },
|
|
255
|
+
});
|
|
256
|
+
const flows = [
|
|
257
|
+
f.flow({ id: "boas-vindas", name: "Boas-vindas", on: [{ message: [] }], steps: [{ id: "nome", collect: ["nome"] }] }),
|
|
258
|
+
f.flow({ id: "retomar", name: "Retomar", on: [{ silence: "24h" }], steps: [{ id: "p1", prompt: "Retome a conversa." }] }),
|
|
259
|
+
];
|
|
260
|
+
const clock = fakeClock("2026-09-20T10:00:00.000Z");
|
|
261
|
+
const reply = { message: "Oi! Como você se chama?", nome: null };
|
|
262
|
+
|
|
263
|
+
const first = await f.agent({ name: "Ana", provider: scripted([reply]), clock, flows }).turn({ sessionId: "s1", message: "oi", id: "m1" });
|
|
264
|
+
const replay = await f.agent({ name: "Ana", provider: scripted([reply]), clock, flows }).turn({ sessionId: "s1", message: "oi", id: "m1" });
|
|
265
|
+
|
|
266
|
+
assert.deepEqual(replay.messages, first.messages); // same key: boas-vindas#m1:nome:1
|
|
267
|
+
assert.deepEqual(replay.schedule, first.schedule); // same wake: silence:retomar:s1:<ms>
|
|
268
|
+
assert.deepEqual(replay.session.runs, first.session.runs);
|
|
269
|
+
assert.equal(first.llmCalls, 1); // a catch-all alone, and nothing to extract before the ask: no understand call
|
|
270
|
+
console.log("ok");
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The same holds inside one session: feed the same `{ message, id }` to the session version it was computed on and the result is the same. Feed it again to a version that already recorded that id and the turn is ignored with `changed: false` and the outcome `code: 'duplicate-input'`.
|
|
274
|
+
|
|
275
|
+
## Other things worth a test
|
|
276
|
+
|
|
277
|
+
- A `silenced` turn: `agent.turn({ …, silenced: "humano no comando" })` spends zero calls, phrases nothing, and still runs `do` steps. Assert `llmCalls === 0` and `messages.length === 0`.
|
|
278
|
+
- A speak failure: leave the `speak` queue empty so the scripted provider throws inside the turn. `agent.turn()` still returns — no try/catch needed. Assert the outcome `{ status: "deferred", code: "provider-unavailable" }` and a `schedule[]` key ending in `:retry:<ms>`. See [error handling](./error-handling.md).
|
|
279
|
+
- A stale wake: fire a key the session no longer waits for and assert `changed === false` and the outcome `code: 'stale-wake'`.
|
|
280
|
+
- Actions: register `f.action` handlers that push `ctx.key` and `ctx.dedupeKey` to an array, and assert the list. The keys are the same on a replay.
|
|
281
|
+
- The prompt: keep every `GenerateMessageInput` your provider receives and assert on `input.prompt` (which instructions reached it) and `input.tools` (which tools were offered). The repo's own scripted provider, `tests/mock-provider.ts`, records them as `calls[].prompt` and `calls[].input`.
|
|
282
|
+
- Streaming: `turnStream` with the same scripted provider yields one `delta` per provider chunk and a final `{ done, result }` equal to what `turn()` returns.
|
|
283
|
+
|
|
284
|
+
See [the pipeline](../concepts/pipeline.md) for what each phase costs, and [runs and waits](../concepts/runs-and-waits.md) for the full key table.
|