@ai.ntellect/core 1.0.0 → 1.1.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/.mocharc.json +6 -0
- package/AGENTS.md +50 -0
- package/ARCHITECTURE.md +58 -0
- package/BENCHMARK.md +38 -0
- package/CHANGELOG.md +224 -0
- package/README.md +411 -142
- package/agent/agent-workflow.ts +569 -0
- package/agent/agent.ts +183 -0
- package/agent/base/executor.ts +103 -0
- package/agent/base/index.ts +87 -0
- package/agent/entity-resolver/confidence.ts +54 -0
- package/agent/entity-resolver/entity-index.ts +241 -0
- package/agent/entity-resolver/explore-strategy.ts +82 -0
- package/agent/entity-resolver/index.ts +22 -0
- package/agent/entity-resolver/resolver.ts +193 -0
- package/agent/entity-resolver/scorer.ts +211 -0
- package/agent/entity-resolver/types.ts +98 -0
- package/agent/generic-executor.ts +713 -0
- package/agent/handlers/cognitive-handler.ts +197 -0
- package/agent/handlers/index.ts +1 -0
- package/agent/handoff.ts +58 -0
- package/agent/llm-factory.ts +343 -0
- package/agent/orchestrator.ts +45 -0
- package/agent/prompt-builder.ts +78 -0
- package/agent/registry.ts +64 -0
- package/agent/tools/file-system.ts +471 -0
- package/agent/tools/index.ts +23 -0
- package/agent/tools/logger.ts +105 -0
- package/agent/tools/tool-resolver.ts +104 -0
- package/benchmark/cortexflow-workflow.ts +182 -0
- package/benchmark/langgraph-workflow.ts +201 -0
- package/benchmark/llm-client.ts +76 -0
- package/benchmark/run-benchmark.ts +222 -0
- package/cli-dev.ts +419 -0
- package/dist/agent/agent-workflow.d.ts +41 -0
- package/dist/agent/agent-workflow.d.ts.map +1 -0
- package/dist/agent/agent-workflow.js +560 -0
- package/dist/agent/agent-workflow.js.map +1 -0
- package/dist/agent/agent.d.ts +38 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +149 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/base/executor.d.ts +51 -0
- package/dist/agent/base/executor.d.ts.map +1 -0
- package/dist/agent/base/executor.js +69 -0
- package/dist/agent/base/executor.js.map +1 -0
- package/dist/agent/base/index.d.ts +30 -0
- package/dist/agent/base/index.d.ts.map +1 -0
- package/dist/agent/base/index.js +88 -0
- package/dist/agent/base/index.js.map +1 -0
- package/dist/agent/entity-resolver/confidence.d.ts +4 -0
- package/dist/agent/entity-resolver/confidence.d.ts.map +1 -0
- package/dist/agent/entity-resolver/confidence.js +47 -0
- package/dist/agent/entity-resolver/confidence.js.map +1 -0
- package/dist/agent/entity-resolver/entity-index.d.ts +40 -0
- package/dist/agent/entity-resolver/entity-index.d.ts.map +1 -0
- package/dist/agent/entity-resolver/entity-index.js +244 -0
- package/dist/agent/entity-resolver/entity-index.js.map +1 -0
- package/dist/agent/entity-resolver/explore-strategy.d.ts +13 -0
- package/dist/agent/entity-resolver/explore-strategy.d.ts.map +1 -0
- package/dist/agent/entity-resolver/explore-strategy.js +109 -0
- package/dist/agent/entity-resolver/explore-strategy.js.map +1 -0
- package/dist/agent/entity-resolver/index.d.ts +8 -0
- package/dist/agent/entity-resolver/index.d.ts.map +1 -0
- package/dist/agent/entity-resolver/index.js +16 -0
- package/dist/agent/entity-resolver/index.js.map +1 -0
- package/dist/agent/entity-resolver/resolver.d.ts +18 -0
- package/dist/agent/entity-resolver/resolver.d.ts.map +1 -0
- package/dist/agent/entity-resolver/resolver.js +158 -0
- package/dist/agent/entity-resolver/resolver.js.map +1 -0
- package/dist/agent/entity-resolver/scorer.d.ts +3 -0
- package/dist/agent/entity-resolver/scorer.d.ts.map +1 -0
- package/dist/agent/entity-resolver/scorer.js +182 -0
- package/dist/agent/entity-resolver/scorer.js.map +1 -0
- package/dist/agent/entity-resolver/types.d.ts +89 -0
- package/dist/agent/entity-resolver/types.d.ts.map +1 -0
- package/dist/agent/entity-resolver/types.js +3 -0
- package/dist/agent/entity-resolver/types.js.map +1 -0
- package/dist/agent/generic-executor.d.ts +68 -0
- package/dist/agent/generic-executor.d.ts.map +1 -0
- package/dist/agent/generic-executor.js +620 -0
- package/dist/agent/generic-executor.js.map +1 -0
- package/dist/agent/handlers/cognitive-handler.d.ts +44 -0
- package/dist/agent/handlers/cognitive-handler.d.ts.map +1 -0
- package/dist/agent/handlers/cognitive-handler.js +172 -0
- package/dist/agent/handlers/cognitive-handler.js.map +1 -0
- package/dist/agent/handlers/index.d.ts +2 -0
- package/dist/agent/handlers/index.d.ts.map +1 -0
- package/dist/agent/handlers/index.js +7 -0
- package/dist/agent/handlers/index.js.map +1 -0
- package/dist/agent/handoff.d.ts +12 -0
- package/dist/agent/handoff.d.ts.map +1 -0
- package/dist/agent/handoff.js +62 -0
- package/dist/agent/handoff.js.map +1 -0
- package/dist/agent/llm-factory.d.ts +19 -0
- package/dist/agent/llm-factory.d.ts.map +1 -0
- package/dist/agent/llm-factory.js +297 -0
- package/dist/agent/llm-factory.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +18 -0
- package/dist/agent/orchestrator.d.ts.map +1 -0
- package/dist/agent/orchestrator.js +44 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/prompt-builder.d.ts +35 -0
- package/dist/agent/prompt-builder.d.ts.map +1 -0
- package/dist/agent/prompt-builder.js +76 -0
- package/dist/agent/prompt-builder.js.map +1 -0
- package/dist/agent/registry.d.ts +19 -0
- package/dist/agent/registry.d.ts.map +1 -0
- package/dist/agent/registry.js +48 -0
- package/dist/agent/registry.js.map +1 -0
- package/dist/agent/tools/file-system.d.ts +11 -0
- package/dist/agent/tools/file-system.d.ts.map +1 -0
- package/dist/agent/tools/file-system.js +528 -0
- package/dist/agent/tools/file-system.js.map +1 -0
- package/dist/agent/tools/index.d.ts +4 -0
- package/dist/agent/tools/index.d.ts.map +1 -0
- package/dist/agent/tools/index.js +20 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/tools/logger.d.ts +33 -0
- package/dist/agent/tools/logger.d.ts.map +1 -0
- package/dist/agent/tools/logger.js +86 -0
- package/dist/agent/tools/logger.js.map +1 -0
- package/dist/agent/tools/tool-resolver.d.ts +7 -0
- package/dist/agent/tools/tool-resolver.d.ts.map +1 -0
- package/dist/agent/tools/tool-resolver.js +122 -0
- package/dist/agent/tools/tool-resolver.js.map +1 -0
- package/dist/execution/adapters/in-memory-checkpoint.d.ts +11 -0
- package/dist/execution/adapters/in-memory-checkpoint.d.ts.map +1 -0
- package/dist/execution/adapters/in-memory-checkpoint.js +54 -0
- package/dist/execution/adapters/in-memory-checkpoint.js.map +1 -0
- package/dist/execution/compiler.d.ts +8 -0
- package/dist/execution/compiler.d.ts.map +1 -0
- package/dist/execution/compiler.js +50 -0
- package/dist/execution/compiler.js.map +1 -0
- package/dist/execution/controller.d.ts +30 -0
- package/dist/execution/controller.d.ts.map +1 -0
- package/dist/execution/controller.js +80 -0
- package/dist/execution/controller.js.map +1 -0
- package/dist/execution/event-manager.d.ts +29 -0
- package/dist/execution/event-manager.d.ts.map +1 -0
- package/dist/execution/event-manager.js +264 -0
- package/dist/execution/event-manager.js.map +1 -0
- package/dist/execution/index.d.ts +221 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +638 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/logger.d.ts +46 -0
- package/dist/execution/logger.d.ts.map +1 -0
- package/dist/execution/logger.js +69 -0
- package/dist/execution/logger.js.map +1 -0
- package/dist/execution/node.d.ts +65 -0
- package/dist/execution/node.d.ts.map +1 -0
- package/dist/execution/node.js +250 -0
- package/dist/execution/node.js.map +1 -0
- package/dist/execution/observer.d.ts +38 -0
- package/dist/execution/observer.d.ts.map +1 -0
- package/dist/execution/observer.js +111 -0
- package/dist/execution/observer.js.map +1 -0
- package/dist/execution/planner.d.ts +14 -0
- package/dist/execution/planner.d.ts.map +1 -0
- package/dist/execution/planner.js +43 -0
- package/dist/execution/planner.js.map +1 -0
- package/dist/execution/reducer.d.ts +19 -0
- package/dist/execution/reducer.d.ts.map +1 -0
- package/dist/execution/reducer.js +61 -0
- package/dist/execution/reducer.js.map +1 -0
- package/dist/execution/registry.d.ts +38 -0
- package/dist/execution/registry.d.ts.map +1 -0
- package/dist/execution/registry.js +63 -0
- package/dist/execution/registry.js.map +1 -0
- package/dist/execution/send-api.d.ts +24 -0
- package/dist/execution/send-api.d.ts.map +1 -0
- package/dist/execution/send-api.js +52 -0
- package/dist/execution/send-api.js.map +1 -0
- package/dist/execution/types.parallel.d.ts +61 -0
- package/dist/execution/types.parallel.d.ts.map +1 -0
- package/dist/execution/types.parallel.js +3 -0
- package/dist/execution/types.parallel.js.map +1 -0
- package/dist/execution/visualizer.d.ts +35 -0
- package/dist/execution/visualizer.d.ts.map +1 -0
- package/dist/execution/visualizer.js +131 -0
- package/dist/execution/visualizer.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/index.d.ts +487 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +75 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/modules/agenda/adapters/node-cron/index.d.ts +17 -0
- package/dist/modules/agenda/adapters/node-cron/index.d.ts.map +1 -0
- package/dist/modules/agenda/adapters/node-cron/index.js +30 -0
- package/dist/modules/agenda/adapters/node-cron/index.js.map +1 -0
- package/dist/modules/agenda/index.d.ts +63 -0
- package/dist/modules/agenda/index.d.ts.map +1 -0
- package/dist/modules/agenda/index.js +141 -0
- package/dist/modules/agenda/index.js.map +1 -0
- package/dist/modules/cli/index.d.ts +13 -0
- package/dist/modules/cli/index.d.ts.map +1 -0
- package/dist/modules/cli/index.js +672 -0
- package/dist/modules/cli/index.js.map +1 -0
- package/dist/modules/embedding/adapters/ai/index.d.ts +29 -0
- package/dist/modules/embedding/adapters/ai/index.d.ts.map +1 -0
- package/dist/modules/embedding/adapters/ai/index.js +58 -0
- package/dist/modules/embedding/adapters/ai/index.js.map +1 -0
- package/dist/modules/embedding/index.d.ts +36 -0
- package/dist/modules/embedding/index.d.ts.map +1 -0
- package/dist/modules/embedding/index.js +60 -0
- package/dist/modules/embedding/index.js.map +1 -0
- package/dist/modules/nlp/engine.d.ts +126 -0
- package/dist/modules/nlp/engine.d.ts.map +1 -0
- package/dist/modules/nlp/engine.js +299 -0
- package/dist/modules/nlp/engine.js.map +1 -0
- package/dist/modules/nlp/index.d.ts +27 -0
- package/dist/modules/nlp/index.d.ts.map +1 -0
- package/dist/modules/nlp/index.js +56 -0
- package/dist/modules/nlp/index.js.map +1 -0
- package/dist/persistence/index.d.ts +12 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +24 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/neo4j/driver.d.ts +26 -0
- package/dist/persistence/neo4j/driver.d.ts.map +1 -0
- package/dist/persistence/neo4j/driver.js +64 -0
- package/dist/persistence/neo4j/driver.js.map +1 -0
- package/dist/persistence/neo4j/entity-store.d.ts +15 -0
- package/dist/persistence/neo4j/entity-store.d.ts.map +1 -0
- package/dist/persistence/neo4j/entity-store.js +136 -0
- package/dist/persistence/neo4j/entity-store.js.map +1 -0
- package/dist/persistence/neo4j/execution-tracer.d.ts +19 -0
- package/dist/persistence/neo4j/execution-tracer.d.ts.map +1 -0
- package/dist/persistence/neo4j/execution-tracer.js +166 -0
- package/dist/persistence/neo4j/execution-tracer.js.map +1 -0
- package/dist/persistence/neo4j/memory-adapter.d.ts +35 -0
- package/dist/persistence/neo4j/memory-adapter.d.ts.map +1 -0
- package/dist/persistence/neo4j/memory-adapter.js +252 -0
- package/dist/persistence/neo4j/memory-adapter.js.map +1 -0
- package/dist/persistence/neo4j/petri-checkpoint-adapter.d.ts +22 -0
- package/dist/persistence/neo4j/petri-checkpoint-adapter.d.ts.map +1 -0
- package/dist/persistence/neo4j/petri-checkpoint-adapter.js +141 -0
- package/dist/persistence/neo4j/petri-checkpoint-adapter.js.map +1 -0
- package/dist/pipeline/agent-pipeline.d.ts +99 -0
- package/dist/pipeline/agent-pipeline.d.ts.map +1 -0
- package/dist/pipeline/agent-pipeline.js +356 -0
- package/dist/pipeline/agent-pipeline.js.map +1 -0
- package/dist/routing/checkpoint-adapter.d.ts +30 -0
- package/dist/routing/checkpoint-adapter.d.ts.map +1 -0
- package/dist/routing/checkpoint-adapter.js +83 -0
- package/dist/routing/checkpoint-adapter.js.map +1 -0
- package/dist/routing/documentation-generator.d.ts +47 -0
- package/dist/routing/documentation-generator.d.ts.map +1 -0
- package/dist/routing/documentation-generator.js +320 -0
- package/dist/routing/documentation-generator.js.map +1 -0
- package/dist/routing/index.d.ts +38 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +375 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/intent-classifier.d.ts +206 -0
- package/dist/routing/intent-classifier.d.ts.map +1 -0
- package/dist/routing/intent-classifier.js +267 -0
- package/dist/routing/intent-classifier.js.map +1 -0
- package/dist/routing/matrix.d.ts +6 -0
- package/dist/routing/matrix.d.ts.map +1 -0
- package/dist/routing/matrix.js +131 -0
- package/dist/routing/matrix.js.map +1 -0
- package/dist/routing/orchestrator.d.ts +87 -0
- package/dist/routing/orchestrator.d.ts.map +1 -0
- package/dist/routing/orchestrator.js +425 -0
- package/dist/routing/orchestrator.js.map +1 -0
- package/dist/routing/postgres-checkpoint-adapter.d.ts +32 -0
- package/dist/routing/postgres-checkpoint-adapter.d.ts.map +1 -0
- package/dist/routing/postgres-checkpoint-adapter.js +167 -0
- package/dist/routing/postgres-checkpoint-adapter.js.map +1 -0
- package/dist/routing/redis-checkpoint-adapter.d.ts +34 -0
- package/dist/routing/redis-checkpoint-adapter.d.ts.map +1 -0
- package/dist/routing/redis-checkpoint-adapter.js +170 -0
- package/dist/routing/redis-checkpoint-adapter.js.map +1 -0
- package/dist/routing/types.d.ts +49 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +3 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/types/agent.d.ts +289 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +78 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/index.d.ts +343 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/generate-action-schema.d.ts +4 -0
- package/dist/utils/generate-action-schema.d.ts.map +1 -0
- package/dist/utils/generate-action-schema.js +46 -0
- package/dist/utils/generate-action-schema.js.map +1 -0
- package/dist/utils/header-builder.d.ts +12 -0
- package/dist/utils/header-builder.d.ts.map +1 -0
- package/dist/utils/header-builder.js +35 -0
- package/dist/utils/header-builder.js.map +1 -0
- package/dist/utils/logger.d.ts +27 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +45 -0
- package/dist/utils/logger.js.map +1 -0
- package/docs/.gitbook/assets/image (1).png +0 -0
- package/docs/.gitbook/assets/image (2).png +0 -0
- package/docs/.gitbook/assets/image (3).png +0 -0
- package/docs/.gitbook/assets/image (4).png +0 -0
- package/docs/.gitbook/assets/image (5).png +0 -0
- package/docs/.gitbook/assets/image (6).png +0 -0
- package/docs/.gitbook/assets/image.png +0 -0
- package/docs/README.md +57 -0
- package/docs/SUMMARY.md +34 -0
- package/docs/cas-dusages.md +69 -0
- package/docs/cli/README.md +65 -0
- package/docs/concepts-cles.md +50 -0
- package/docs/core/architecture.md +87 -0
- package/docs/core/benchmark.md +59 -0
- package/docs/core/checkpoint.md +72 -0
- package/docs/core/documentation.md +55 -0
- package/docs/core/graphcontroller.md +63 -0
- package/docs/core/graphflow.md +137 -0
- package/docs/core/introduction.md +41 -0
- package/docs/core/les-evenements.md +95 -0
- package/docs/modules/agenda/README.md +63 -0
- package/docs/modules/agenda/interface-iagenda.md +170 -0
- package/docs/modules/agenda/les-adaptateurs/README.md +237 -0
- package/docs/modules/agenda/les-adaptateurs/nodecronadapter.md +91 -0
- package/docs/modules/introduction.md +55 -0
- package/docs/modules/les-adaptateurs.md +52 -0
- package/docs/modules/memoire/README.md +68 -0
- package/docs/modules/memoire/interface-imemory.md +183 -0
- package/docs/modules/memoire/les-adaptateurs/README.md +209 -0
- package/docs/modules/memoire/les-adaptateurs/inmemoryadapter.md +110 -0
- package/docs/modules/memoire/les-adaptateurs/meilisearchadapter.md +147 -0
- package/docs/modules/memoire/les-adaptateurs/redisadapter.md +212 -0
- package/docs/modules/nlp/README.md +44 -0
- package/docs/philosophie.md +51 -0
- package/docs/tutoriels/ajouter-des-conditions.md +150 -0
- package/docs/tutoriels/branching.md +194 -0
- package/docs/tutoriels/checkpoint-usage.md +99 -0
- package/docs/tutoriels/creer-agent-onchain.md +1041 -0
- package/docs/tutoriels/creer-un-agent.md +108 -0
- package/docs/tutoriels/creer-un-graphe-simple.md +92 -0
- package/docs/tutoriels/gerer-les-erreurs.md +124 -0
- package/docs/tutoriels/pour-commencer.md +73 -0
- package/docs/tutoriels/retry.md +166 -0
- package/execution/adapters/in-memory-checkpoint.ts +35 -0
- package/execution/compiler.ts +47 -0
- package/execution/controller.ts +84 -0
- package/execution/event-manager.ts +331 -0
- package/execution/index.ts +800 -0
- package/execution/logger.ts +70 -0
- package/execution/node.ts +315 -0
- package/execution/observer.ts +192 -0
- package/execution/planner.ts +40 -0
- package/execution/reducer.ts +73 -0
- package/execution/registry.ts +86 -0
- package/execution/send-api.ts +58 -0
- package/execution/types.parallel.ts +81 -0
- package/execution/visualizer.ts +158 -0
- package/index.ts +55 -465
- package/interfaces/index.ts +597 -0
- package/modules/agenda/adapters/node-cron/index.ts +25 -0
- package/modules/agenda/index.ts +146 -0
- package/modules/cli/index.ts +580 -0
- package/modules/embedding/adapters/ai/index.ts +42 -0
- package/modules/embedding/index.ts +45 -0
- package/modules/nlp/engine.ts +324 -0
- package/modules/nlp/index.ts +45 -0
- package/package.json +81 -9
- package/persistence/index.ts +27 -0
- package/persistence/neo4j/driver.ts +34 -0
- package/persistence/neo4j/entity-store.ts +141 -0
- package/persistence/neo4j/execution-tracer.ts +194 -0
- package/persistence/neo4j/memory-adapter.ts +281 -0
- package/persistence/neo4j/petri-checkpoint-adapter.ts +153 -0
- package/pipeline/agent-pipeline.ts +426 -0
- package/routing/checkpoint-adapter.ts +79 -0
- package/routing/documentation-generator.ts +358 -0
- package/routing/index.ts +459 -0
- package/routing/intent-classifier.ts +360 -0
- package/routing/matrix.ts +138 -0
- package/routing/orchestrator.ts +498 -0
- package/routing/patterns/data-extraction.json +79 -0
- package/routing/patterns/human-approval.json +64 -0
- package/routing/patterns/rag-search.json +68 -0
- package/routing/postgres-checkpoint-adapter.ts +172 -0
- package/routing/redis-checkpoint-adapter.ts +187 -0
- package/routing/types.ts +59 -0
- package/routing/web-server.ts +260 -0
- package/scripts/generate-petri-docs.ts +70 -0
- package/scripts/get-gmail-token.js +65 -0
- package/scripts/get-gmail-token.ts +65 -0
- package/test/agent/agent.test.ts +92 -0
- package/test/agent/clone.test.ts +143 -0
- package/test/agent/cognitive-handler.test.ts +78 -0
- package/test/agent/entity-store.test.ts +80 -0
- package/test/agent/generic-executor.test.ts +230 -0
- package/test/agent/handoff.test.ts +163 -0
- package/test/agent/llm-factory.test.ts +40 -0
- package/test/agent/orchestrator.test.ts +156 -0
- package/test/agent/registry.test.ts +97 -0
- package/test/agent/tools.test.ts +267 -0
- package/test/execution/checkpoint.test.ts +811 -0
- package/test/execution/controller.test.ts +236 -0
- package/test/execution/event-manager.test.ts +118 -0
- package/test/execution/index.test.ts +690 -0
- package/test/execution/node.test.ts +464 -0
- package/test/execution/observer.test.ts +393 -0
- package/test/execution/parallel.test.ts +135 -0
- package/test/execution/plan-llm-integration.test.ts +290 -0
- package/test/execution/plan-real-onchain.test.ts +226 -0
- package/test/execution/send-api.test.ts +121 -0
- package/test/modules/agenda/node-cron.test.ts +307 -0
- package/test/modules/cli/index.test.ts +125 -0
- package/test/persistence/neo4j-execution-tracer.test.ts +96 -0
- package/test/persistence/neo4j-memory-adapter.test.ts +107 -0
- package/test/persistence/neo4j-petri-checkpoint.test.ts +89 -0
- package/test/pipeline/agent-pipeline.test.ts +118 -0
- package/test/routing/checkpoint-persistence.test.ts +58 -0
- package/test/routing/documentation-generator.test.ts +76 -0
- package/test/routing/integration.test.ts +261 -0
- package/test/routing/intent-classifier.test.ts +102 -0
- package/test/routing/petri.test.ts +156 -0
- package/test/routing/real-llm.test.ts +260 -0
- package/test-petri-features.ts +218 -0
- package/test-pipeline-api.ts +163 -0
- package/tsconfig.json +30 -108
- package/types/agent.ts +296 -0
- package/types/index.ts +387 -0
- package/utils/generate-action-schema.ts +47 -0
- package/utils/header-builder.ts +40 -0
- package/utils/logger.ts +40 -0
- package/package copy.json +0 -21
- package/types.ts +0 -62
- package/utils/executor.ts +0 -42
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles logging operations for a graph instance
|
|
3
|
+
* Provides methods for adding, retrieving, and managing logs with optional verbose output
|
|
4
|
+
*/
|
|
5
|
+
export class GraphLogger {
|
|
6
|
+
private logs: string[] = [];
|
|
7
|
+
private verbose: boolean = false;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new GraphLogger instance
|
|
11
|
+
* @param graphName - The name of the graph this logger is associated with
|
|
12
|
+
* @param verbose - Whether to output logs to console in real-time
|
|
13
|
+
*/
|
|
14
|
+
constructor(private graphName: string, verbose: boolean = false) {
|
|
15
|
+
this.verbose = verbose;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Adds a new log entry with timestamp
|
|
20
|
+
* @param message - The message to log
|
|
21
|
+
*/
|
|
22
|
+
public addLog(message: string): void {
|
|
23
|
+
const timestamp = new Date().toISOString();
|
|
24
|
+
const logMessage = `[${timestamp}] ${message}`;
|
|
25
|
+
this.logs.push(logMessage);
|
|
26
|
+
if (this.verbose) {
|
|
27
|
+
console.log(`${this.graphName} - ${message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns a copy of all stored logs
|
|
33
|
+
* @returns Array of log messages
|
|
34
|
+
*/
|
|
35
|
+
public getLogs(): string[] {
|
|
36
|
+
return [...this.logs];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Clears all stored logs
|
|
41
|
+
*/
|
|
42
|
+
public clearLogs(): void {
|
|
43
|
+
this.logs = [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Sets the verbose mode
|
|
48
|
+
* @param enabled - Whether to enable verbose mode
|
|
49
|
+
*/
|
|
50
|
+
public setVerbose(enabled: boolean): void {
|
|
51
|
+
this.verbose = enabled;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets the current verbose mode status
|
|
56
|
+
* @returns Current verbose mode state
|
|
57
|
+
*/
|
|
58
|
+
public isVerbose(): boolean {
|
|
59
|
+
return this.verbose;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Logs a message to console with graph name prefix
|
|
64
|
+
* @param message - The message to log
|
|
65
|
+
* @param data - Optional data to log
|
|
66
|
+
*/
|
|
67
|
+
log(message: string, data?: any): void {
|
|
68
|
+
console.log(`[Graph ${this.graphName}] ${message}`, data);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { IEventEmitter, ICheckpointAdapter } from "interfaces";
|
|
2
|
+
import { BehaviorSubject, Subject } from "rxjs";
|
|
3
|
+
import { ZodSchema } from "zod";
|
|
4
|
+
import { Checkpoint, GraphContext, GraphEvent, GraphNodeConfig } from "../types";
|
|
5
|
+
import { GraphEventManager } from "./event-manager";
|
|
6
|
+
import { SendAPI } from "./send-api";
|
|
7
|
+
import { applyReducers } from "./reducer";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents a node in the graph that can execute operations and manage state
|
|
11
|
+
* @template T - The Zod schema type for validation
|
|
12
|
+
*/
|
|
13
|
+
export interface NodeParams<T = any> {
|
|
14
|
+
[key: string]: T;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface GraphLogger {
|
|
18
|
+
addLog: (message: string, data?: any) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface NodeExecutionHooks<T extends ZodSchema> {
|
|
22
|
+
onBeforeExecute?: (nodeName: string, context: GraphContext<T>) => Promise<void>;
|
|
23
|
+
onBeforeExecuteNext?: (
|
|
24
|
+
nodeName: string,
|
|
25
|
+
context: GraphContext<T>,
|
|
26
|
+
nextNodes: string[]
|
|
27
|
+
) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class GraphNode<T extends ZodSchema> {
|
|
31
|
+
private lastStateEvent: GraphEvent<T> | null = null;
|
|
32
|
+
private eventEmitter: IEventEmitter;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new GraphNode instance
|
|
36
|
+
* @param nodes - Map of all nodes in the graph
|
|
37
|
+
* @param logger - Logger instance for tracking node operations
|
|
38
|
+
* @param eventManager - Manager for handling graph events
|
|
39
|
+
* @param eventSubject - Subject for emitting events
|
|
40
|
+
* @param stateSubject - Subject for managing graph state
|
|
41
|
+
*/
|
|
42
|
+
constructor(
|
|
43
|
+
private nodes: Map<string, GraphNodeConfig<T, any>>,
|
|
44
|
+
private logger: GraphLogger,
|
|
45
|
+
private eventManager: GraphEventManager<T>,
|
|
46
|
+
private eventSubject: Subject<GraphEvent<T>>,
|
|
47
|
+
private stateSubject: BehaviorSubject<GraphContext<T>>
|
|
48
|
+
) {
|
|
49
|
+
this.eventEmitter = eventManager["eventEmitter"];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Emits an event with the specified type and payload
|
|
54
|
+
* @param type - The type of event to emit
|
|
55
|
+
* @param payload - The data associated with the event
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
private emitEvent(type: string, payload: any) {
|
|
59
|
+
if (type === "nodeStateChanged") {
|
|
60
|
+
if (
|
|
61
|
+
this.lastStateEvent?.type === type &&
|
|
62
|
+
this.lastStateEvent.payload.property === payload.property &&
|
|
63
|
+
this.lastStateEvent.payload.newValue === payload.newValue &&
|
|
64
|
+
this.lastStateEvent.payload.nodeName === payload.nodeName
|
|
65
|
+
) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const event = {
|
|
71
|
+
type,
|
|
72
|
+
payload: {
|
|
73
|
+
...payload,
|
|
74
|
+
name: type === "nodeStateChanged" ? payload.nodeName : payload.name,
|
|
75
|
+
context: { ...payload.context },
|
|
76
|
+
},
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
this.eventSubject.next(event);
|
|
81
|
+
this.eventManager.emitEvent(type, event);
|
|
82
|
+
|
|
83
|
+
if (type === "nodeStateChanged") {
|
|
84
|
+
this.lastStateEvent = event;
|
|
85
|
+
this.stateSubject.next({ ...payload.context });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Executes a node with the given name and context
|
|
91
|
+
* @param nodeName - The name of the node to execute
|
|
92
|
+
* @param context - The current graph context
|
|
93
|
+
* @param params - Input data for the node
|
|
94
|
+
* @param triggeredByEvent - Whether the execution was triggered by an event
|
|
95
|
+
* @param hooks - Optional execution hooks
|
|
96
|
+
* @throws Error if the node is not found or execution fails
|
|
97
|
+
*/
|
|
98
|
+
public async executeNode(
|
|
99
|
+
nodeName: string,
|
|
100
|
+
context: GraphContext<T>,
|
|
101
|
+
triggeredByEvent: boolean = false,
|
|
102
|
+
hooks?: NodeExecutionHooks<T>
|
|
103
|
+
): Promise<void> {
|
|
104
|
+
const node = this.nodes.get(nodeName);
|
|
105
|
+
if (!node) throw new Error(`Node "${nodeName}" not found.`);
|
|
106
|
+
|
|
107
|
+
if (hooks?.onBeforeExecute) {
|
|
108
|
+
await hooks.onBeforeExecute(nodeName, context);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const nodeContext = { ...context };
|
|
112
|
+
this.emitEvent("nodeStarted", { name: nodeName, context: nodeContext });
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
if (node.when) {
|
|
116
|
+
await this.eventManager.handleNodeEvents(nodeName, node.when);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const contextProxy = new Proxy(nodeContext, {
|
|
120
|
+
set: (target: any, prop: string | symbol, value: any) => {
|
|
121
|
+
const oldValue = target[prop.toString()];
|
|
122
|
+
if (oldValue === value) return true;
|
|
123
|
+
|
|
124
|
+
target[prop.toString()] = value;
|
|
125
|
+
context[prop.toString() as keyof typeof context] = value;
|
|
126
|
+
|
|
127
|
+
this.emitEvent("nodeStateChanged", {
|
|
128
|
+
nodeName,
|
|
129
|
+
property: prop.toString(),
|
|
130
|
+
oldValue,
|
|
131
|
+
newValue: value,
|
|
132
|
+
context: { ...target },
|
|
133
|
+
});
|
|
134
|
+
return true;
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
if (node.condition && !node.condition(contextProxy)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await this.executeWithRetry(node, contextProxy, nodeName);
|
|
143
|
+
this.emitEvent("nodeCompleted", { name: nodeName, context: nodeContext });
|
|
144
|
+
|
|
145
|
+
// ====== HANDOFF / COMMAND DETECTION ======
|
|
146
|
+
const command = (context as any)._handoff || (context as any)._command;
|
|
147
|
+
if (command?.goto) {
|
|
148
|
+
if (command.graph === "PARENT") {
|
|
149
|
+
return; // Stop here; parent orchestrator checks context._handoff
|
|
150
|
+
}
|
|
151
|
+
if (this.nodes.has(command.goto)) {
|
|
152
|
+
if (command.update) Object.assign(context, command.update);
|
|
153
|
+
await this.executeNode(command.goto, context, false, hooks);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!triggeredByEvent && (node.next || (node as any).send)) {
|
|
159
|
+
const nextNodes =
|
|
160
|
+
typeof node.next === "function" ? node.next(contextProxy) : node.next;
|
|
161
|
+
|
|
162
|
+
// ====== SEND API (Fan-out dynamique) ======
|
|
163
|
+
if ((node as any).send) {
|
|
164
|
+
const sends = (node as any).send(contextProxy);
|
|
165
|
+
const branchResults = await SendAPI.processSends(
|
|
166
|
+
sends,
|
|
167
|
+
context,
|
|
168
|
+
(nodeName: string, ctx: any) => this.executeNode(nodeName, ctx, false, hooks)
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// Merge avec reducers
|
|
172
|
+
const merged = applyReducers(
|
|
173
|
+
context,
|
|
174
|
+
branchResults,
|
|
175
|
+
(node as any).reducers || []
|
|
176
|
+
);
|
|
177
|
+
Object.assign(context, merged);
|
|
178
|
+
|
|
179
|
+
// Si un joinNode est spécifié (dans parallel), l'exécuter
|
|
180
|
+
const joinNode = (node as any).parallel?.joinNode;
|
|
181
|
+
if (joinNode) {
|
|
182
|
+
await this.executeNode(joinNode, context, false, hooks);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return; // Pas de next séquentiel après Send
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Filtrer les valeurs nulles/undefined
|
|
189
|
+
const nextNodeConfigs = (Array.isArray(nextNodes) ? nextNodes : [nextNodes]).filter(
|
|
190
|
+
(n) => n != null
|
|
191
|
+
);
|
|
192
|
+
const validNextNodes = nextNodeConfigs
|
|
193
|
+
.map((nextNode) => {
|
|
194
|
+
const nextNodeName =
|
|
195
|
+
typeof nextNode === "string" ? nextNode : nextNode.node;
|
|
196
|
+
const condition =
|
|
197
|
+
typeof nextNode === "string" ? undefined : nextNode.condition;
|
|
198
|
+
return {
|
|
199
|
+
name: nextNodeName,
|
|
200
|
+
condition,
|
|
201
|
+
isValid: !condition || (condition && condition(contextProxy)),
|
|
202
|
+
};
|
|
203
|
+
})
|
|
204
|
+
.filter((n) => n.isValid);
|
|
205
|
+
|
|
206
|
+
const nextNodeNames = validNextNodes.map((n) => n.name);
|
|
207
|
+
|
|
208
|
+
if (hooks?.onBeforeExecuteNext) {
|
|
209
|
+
await hooks.onBeforeExecuteNext(nodeName, context, nextNodeNames);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ====== PARALLÉLISME FORK-JOIN ======
|
|
213
|
+
if ((node as any).parallel?.enabled) {
|
|
214
|
+
const { joinNode, reducers, mergeStrategy } = (node as any).parallel;
|
|
215
|
+
|
|
216
|
+
// Fork : cloner le contexte pour chaque branche
|
|
217
|
+
const branchContexts = validNextNodes.map((n, i: number) => ({
|
|
218
|
+
nodeName: n.name,
|
|
219
|
+
context: structuredClone(context),
|
|
220
|
+
branchId: `${n.name}_${i}`,
|
|
221
|
+
}));
|
|
222
|
+
|
|
223
|
+
// Exécution parallèle (Promise.all)
|
|
224
|
+
const branchResults = await Promise.all(
|
|
225
|
+
branchContexts.map(async ({ nodeName, context: ctx, branchId }: any) => {
|
|
226
|
+
await this.executeNode(nodeName, ctx, false, hooks);
|
|
227
|
+
return { branchId, context: ctx };
|
|
228
|
+
})
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
// Join : merger les résultats
|
|
232
|
+
if (reducers && reducers.length > 0) {
|
|
233
|
+
const merged = applyReducers(context, branchResults, reducers);
|
|
234
|
+
Object.assign(context, merged);
|
|
235
|
+
} else if (mergeStrategy === "isolated") {
|
|
236
|
+
branchResults.forEach(({ branchId, context: ctx }: any) => {
|
|
237
|
+
(context as any)[`branch_${branchId}`] = ctx;
|
|
238
|
+
});
|
|
239
|
+
} else {
|
|
240
|
+
// deep-merge par défaut
|
|
241
|
+
const { deepMerge } = require("./reducer");
|
|
242
|
+
const merged = deepMerge(context, ...branchResults.map((r: any) => r.context));
|
|
243
|
+
Object.assign(context, merged);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Si un joinNode est spécifié, l'exécuter
|
|
247
|
+
if (joinNode) {
|
|
248
|
+
await this.executeNode(joinNode, context, false, hooks);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ====== SÉQUENTIEL (logique existante) ======
|
|
255
|
+
for (const nextNode of validNextNodes) {
|
|
256
|
+
await this.executeNode(nextNode.name, context, false, hooks);
|
|
257
|
+
if ((context as any)._handoff || (context as any)._command) break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} catch (error) {
|
|
261
|
+
this.emitEvent("nodeError", {
|
|
262
|
+
name: nodeName,
|
|
263
|
+
error,
|
|
264
|
+
context: nodeContext,
|
|
265
|
+
});
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Executes a node with retry logic
|
|
272
|
+
* @param node - The node to execute
|
|
273
|
+
* @param contextProxy - The proxied graph context
|
|
274
|
+
* @param params - Input data for the node
|
|
275
|
+
* @param nodeName - The name of the node
|
|
276
|
+
* @param params - Parameters for the node
|
|
277
|
+
* @throws Error if all retry attempts fail
|
|
278
|
+
* @private
|
|
279
|
+
*/
|
|
280
|
+
private async executeWithRetry(
|
|
281
|
+
node: GraphNodeConfig<T, any>,
|
|
282
|
+
contextProxy: GraphContext<T>,
|
|
283
|
+
nodeName: string
|
|
284
|
+
): Promise<void> {
|
|
285
|
+
let attempts = 0;
|
|
286
|
+
let lastError: Error = new Error("Unknown error");
|
|
287
|
+
|
|
288
|
+
while (attempts < (node.retry?.maxAttempts || 1)) {
|
|
289
|
+
try {
|
|
290
|
+
await node.execute(contextProxy, {
|
|
291
|
+
eventEmitter: this.eventEmitter,
|
|
292
|
+
});
|
|
293
|
+
return;
|
|
294
|
+
} catch (error: any) {
|
|
295
|
+
lastError =
|
|
296
|
+
error instanceof Error
|
|
297
|
+
? error
|
|
298
|
+
: new Error(error?.message || "Unknown error");
|
|
299
|
+
attempts++;
|
|
300
|
+
|
|
301
|
+
if (attempts === (node.retry?.maxAttempts || 1)) {
|
|
302
|
+
if (node.retry?.onRetryFailed) {
|
|
303
|
+
await node.retry.onRetryFailed(lastError, contextProxy);
|
|
304
|
+
if (node.retry.continueOnFailed) return;
|
|
305
|
+
}
|
|
306
|
+
throw lastError;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
await new Promise((resolve) =>
|
|
310
|
+
setTimeout(resolve, node.retry?.delay || 0)
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BehaviorSubject,
|
|
3
|
+
Observable,
|
|
4
|
+
Subject,
|
|
5
|
+
combineLatest,
|
|
6
|
+
firstValueFrom,
|
|
7
|
+
} from "rxjs";
|
|
8
|
+
import {
|
|
9
|
+
debounceTime,
|
|
10
|
+
distinctUntilChanged,
|
|
11
|
+
filter,
|
|
12
|
+
map,
|
|
13
|
+
share,
|
|
14
|
+
take,
|
|
15
|
+
takeUntil,
|
|
16
|
+
} from "rxjs/operators";
|
|
17
|
+
import { ZodSchema } from "zod";
|
|
18
|
+
import { GraphObservable } from "../interfaces";
|
|
19
|
+
import { GraphContext, GraphEvent, ObserverOptions } from "../types";
|
|
20
|
+
import { GraphEventManager } from "./event-manager";
|
|
21
|
+
import { GraphFlow } from "./index";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* GraphObserver class provides reactive observation capabilities for a GraphFlow instance
|
|
25
|
+
* It allows monitoring state changes, node updates, and specific events in the graph
|
|
26
|
+
* @template T - The Zod schema type that defines the structure of the graph data
|
|
27
|
+
*/
|
|
28
|
+
export class GraphObserver<T extends ZodSchema> {
|
|
29
|
+
constructor(
|
|
30
|
+
private graph: GraphFlow<T>,
|
|
31
|
+
private eventSubject: Subject<GraphEvent<T>>,
|
|
32
|
+
private stateSubject: BehaviorSubject<GraphContext<T>>,
|
|
33
|
+
private destroySubject: Subject<void>,
|
|
34
|
+
private eventManager: GraphEventManager<T>
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Observes the entire graph state changes
|
|
39
|
+
* @param options Configuration options for the observation
|
|
40
|
+
* @returns An Observable that emits the complete graph context whenever it changes
|
|
41
|
+
*/
|
|
42
|
+
state(options: ObserverOptions = {}): GraphObservable<T> {
|
|
43
|
+
const baseObservable = new Observable<any>((subscriber) => {
|
|
44
|
+
const subscription = combineLatest([
|
|
45
|
+
this.eventSubject.pipe(
|
|
46
|
+
filter((event) => event.type === "nodeStateChanged"),
|
|
47
|
+
map((event) => event.payload.context),
|
|
48
|
+
distinctUntilChanged(
|
|
49
|
+
(prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)
|
|
50
|
+
),
|
|
51
|
+
debounceTime(options.debounce || 100)
|
|
52
|
+
),
|
|
53
|
+
this.stateSubject,
|
|
54
|
+
])
|
|
55
|
+
.pipe(
|
|
56
|
+
map(([eventContext, stateContext]) => ({
|
|
57
|
+
...stateContext,
|
|
58
|
+
...eventContext,
|
|
59
|
+
})),
|
|
60
|
+
distinctUntilChanged(
|
|
61
|
+
(prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
.subscribe(subscriber);
|
|
65
|
+
|
|
66
|
+
if (options.stream && options.properties) {
|
|
67
|
+
const context = this.stateSubject.getValue();
|
|
68
|
+
options.properties.forEach((property) => {
|
|
69
|
+
const message = context[property];
|
|
70
|
+
if (message) {
|
|
71
|
+
this.streamMessage(
|
|
72
|
+
message.toString(),
|
|
73
|
+
500,
|
|
74
|
+
property as string
|
|
75
|
+
).subscribe({
|
|
76
|
+
next: (data) => options.onStreamLetter?.(data),
|
|
77
|
+
complete: () => options.onStreamComplete?.(),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return () => subscription.unsubscribe();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return Object.assign(baseObservable, {
|
|
87
|
+
state: () => this.stateSubject.asObservable(),
|
|
88
|
+
node: (nodeName: string) =>
|
|
89
|
+
this.stateSubject.pipe(map((state) => ({ ...state, nodeName }))),
|
|
90
|
+
nodes: (nodeNames: string[]) =>
|
|
91
|
+
this.eventSubject.pipe(
|
|
92
|
+
filter(
|
|
93
|
+
(event) =>
|
|
94
|
+
event.type === "nodeStateChanged" &&
|
|
95
|
+
nodeNames.includes(event.payload?.name ?? "")
|
|
96
|
+
),
|
|
97
|
+
map((event) => event.payload.context),
|
|
98
|
+
distinctUntilChanged(
|
|
99
|
+
(prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)
|
|
100
|
+
),
|
|
101
|
+
takeUntil(this.destroySubject),
|
|
102
|
+
share()
|
|
103
|
+
),
|
|
104
|
+
property: (props: string | string[]) =>
|
|
105
|
+
this.stateSubject.pipe(
|
|
106
|
+
map((state) => {
|
|
107
|
+
const properties = Array.isArray(props) ? props : [props];
|
|
108
|
+
return properties.reduce(
|
|
109
|
+
(acc, prop) => ({
|
|
110
|
+
...acc,
|
|
111
|
+
[prop]: state[prop],
|
|
112
|
+
}),
|
|
113
|
+
{}
|
|
114
|
+
);
|
|
115
|
+
})
|
|
116
|
+
),
|
|
117
|
+
event: (eventName: string) =>
|
|
118
|
+
this.eventSubject.pipe(filter((event) => event.type === eventName)),
|
|
119
|
+
until: (
|
|
120
|
+
observable: Observable<any>,
|
|
121
|
+
predicate: (state: any) => boolean
|
|
122
|
+
) => firstValueFrom(observable.pipe(filter(predicate), take(1))),
|
|
123
|
+
}) as GraphObservable<T>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Waits for correlated events to occur and validates them using a correlation function
|
|
128
|
+
* @param eventTypes - Array of event types to wait for
|
|
129
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
130
|
+
* @param correlationFn - Function to validate event correlation
|
|
131
|
+
* @returns Promise that resolves with the correlated events
|
|
132
|
+
*/
|
|
133
|
+
waitForCorrelatedEvents(
|
|
134
|
+
eventTypes: string[],
|
|
135
|
+
timeoutMs: number,
|
|
136
|
+
correlationFn: (events: GraphEvent<T>[]) => boolean
|
|
137
|
+
): Promise<GraphEvent<T>[]> {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
const events: GraphEvent<T>[] = [];
|
|
140
|
+
const timeout = setTimeout(() => {
|
|
141
|
+
reject(
|
|
142
|
+
new Error(
|
|
143
|
+
`Timeout waiting for correlated events: ${eventTypes.join(", ")}`
|
|
144
|
+
)
|
|
145
|
+
);
|
|
146
|
+
}, timeoutMs);
|
|
147
|
+
|
|
148
|
+
const subscription = this.eventSubject
|
|
149
|
+
.pipe(
|
|
150
|
+
filter((event) => eventTypes.includes(event.type)),
|
|
151
|
+
takeUntil(this.destroySubject)
|
|
152
|
+
)
|
|
153
|
+
.subscribe({
|
|
154
|
+
next: (event) => {
|
|
155
|
+
events.push(event);
|
|
156
|
+
if (events.length === eventTypes.length && correlationFn(events)) {
|
|
157
|
+
clearTimeout(timeout);
|
|
158
|
+
subscription.unsubscribe();
|
|
159
|
+
resolve(events);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
error: (error) => {
|
|
163
|
+
clearTimeout(timeout);
|
|
164
|
+
subscription.unsubscribe();
|
|
165
|
+
reject(error);
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Streams a message letter by letter with a specified delay
|
|
173
|
+
*/
|
|
174
|
+
private streamMessage(
|
|
175
|
+
message: string,
|
|
176
|
+
delayMs: number,
|
|
177
|
+
property: string
|
|
178
|
+
): Observable<{ letter: string; property: string }> {
|
|
179
|
+
return new Observable<{ letter: string; property: string }>(
|
|
180
|
+
(subscriber) => {
|
|
181
|
+
for (let i = 0; i < message.length; i++) {
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
subscriber.next({ letter: message[i], property });
|
|
184
|
+
if (i === message.length - 1) {
|
|
185
|
+
subscriber.complete();
|
|
186
|
+
}
|
|
187
|
+
}, i * delayMs);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ToolRegistry, PlanStep } from './registry';
|
|
3
|
+
|
|
4
|
+
export const PlanSchema = z.object({
|
|
5
|
+
goal: z.string(),
|
|
6
|
+
steps: z.array(
|
|
7
|
+
z.object({
|
|
8
|
+
node: z.string(),
|
|
9
|
+
params: z.record(z.string(), z.any()).optional(),
|
|
10
|
+
description: z.string().optional(),
|
|
11
|
+
})
|
|
12
|
+
),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type Plan = z.infer<typeof PlanSchema>;
|
|
16
|
+
|
|
17
|
+
export async function generatePlan(
|
|
18
|
+
userIntent: string,
|
|
19
|
+
registry: ToolRegistry,
|
|
20
|
+
llmCall: (prompt: string) => Promise<string>
|
|
21
|
+
): Promise<Plan> {
|
|
22
|
+
const availableTools = registry.list();
|
|
23
|
+
|
|
24
|
+
const prompt = `You are a workflow planner. Generate a structured plan as JSON with "goal" (string) and "steps" (array of { node: string, params?: Record<string, any>, description?: string }).
|
|
25
|
+
Only use tools from the available list.
|
|
26
|
+
|
|
27
|
+
Available tools:
|
|
28
|
+
${availableTools.map(t => `- ${t.name}: ${t.description}`).join('\n')}
|
|
29
|
+
|
|
30
|
+
User intent: ${userIntent}
|
|
31
|
+
|
|
32
|
+
Respond with valid JSON only.`;
|
|
33
|
+
|
|
34
|
+
const response = await llmCall(prompt);
|
|
35
|
+
return PlanSchema.parse(JSON.parse(response));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function renderPlan(plan: Plan): string {
|
|
39
|
+
return `Goal: ${plan.goal}\nSteps:\n${plan.steps.map((s, i) => `${i + 1}. ${s.node}${s.description ? ` (${s.description})` : ''}`).join('\n')}`;
|
|
40
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { StateReducer } from "./types.parallel";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Implémentation des State Reducers (pattern LangGraph)
|
|
5
|
+
* Gère le merge des contextes après exécution parallèle
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Fonction de deep merge simple (sans dépendance externe)
|
|
9
|
+
export function deepMerge<T extends Record<string, any>>(...objects: T[]): T {
|
|
10
|
+
const result: any = {};
|
|
11
|
+
|
|
12
|
+
for (const obj of objects) {
|
|
13
|
+
if (obj === null || obj === undefined) continue;
|
|
14
|
+
|
|
15
|
+
for (const key of Object.keys(obj)) {
|
|
16
|
+
const val = obj[key];
|
|
17
|
+
|
|
18
|
+
if (val !== null && typeof val === "object" && !Array.isArray(val)) {
|
|
19
|
+
// Objet : merge récursif
|
|
20
|
+
result[key] = deepMerge(result[key] || {}, val);
|
|
21
|
+
} else if (Array.isArray(val) && Array.isArray(result[key])) {
|
|
22
|
+
// Array : concaténation
|
|
23
|
+
result[key] = [...result[key], ...val];
|
|
24
|
+
} else {
|
|
25
|
+
// Primitive ou nouvel objet : remplacement
|
|
26
|
+
result[key] = val;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return result as T;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ReducerFunction<T = any> = (acc: T, value: T) => T;
|
|
35
|
+
|
|
36
|
+
export const Reducers = {
|
|
37
|
+
// Concatène les arrays
|
|
38
|
+
append: <T>(acc: T[], value: T[]): T[] => [...acc, ...value],
|
|
39
|
+
|
|
40
|
+
// Merge profond
|
|
41
|
+
deepMerge: <T>(acc: T, value: T): T => deepMerge(acc as any, value as any) as T,
|
|
42
|
+
|
|
43
|
+
// Dernière valeur gagne
|
|
44
|
+
lastWins: <T>(_acc: T, value: T): T => value,
|
|
45
|
+
|
|
46
|
+
// Somme (pour nombres)
|
|
47
|
+
sum: (acc: number, value: number): number => acc + value,
|
|
48
|
+
|
|
49
|
+
// Pour les branches isolées (ctx.branch_0, ctx.branch_1, ...)
|
|
50
|
+
isolated: (acc: Record<string, any>, value: any, branchId: string): Record<string, any> => {
|
|
51
|
+
acc[`branch_${branchId}`] = value;
|
|
52
|
+
return acc;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export function applyReducers(
|
|
57
|
+
context: any,
|
|
58
|
+
branchResults: Array<{ context: any; branchId: string }>,
|
|
59
|
+
reducers: StateReducer[] = []
|
|
60
|
+
): any {
|
|
61
|
+
if (reducers.length === 0) {
|
|
62
|
+
// Deep merge par défaut
|
|
63
|
+
return deepMerge(context, ...branchResults.map(br => br.context));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const result = { ...context };
|
|
67
|
+
for (const reducer of reducers) {
|
|
68
|
+
const values = branchResults.map(br => br.context[reducer.key]);
|
|
69
|
+
result[reducer.key] = values.reduce(reducer.reducer, reducer.initial);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return result;
|
|
73
|
+
}
|