@synergenius/flow-weaver 0.2.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/LICENSE +122 -0
- package/README.md +315 -0
- package/dist/annotation-generator.d.ts +45 -0
- package/dist/annotation-generator.js +557 -0
- package/dist/api/builder.d.ts +223 -0
- package/dist/api/builder.js +345 -0
- package/dist/api/compile.d.ts +92 -0
- package/dist/api/compile.js +149 -0
- package/dist/api/extract-types.d.ts +29 -0
- package/dist/api/extract-types.js +57 -0
- package/dist/api/generate-in-place.d.ts +73 -0
- package/dist/api/generate-in-place.js +1353 -0
- package/dist/api/generate.d.ts +83 -0
- package/dist/api/generate.js +510 -0
- package/dist/api/helpers.d.ts +248 -0
- package/dist/api/helpers.js +285 -0
- package/dist/api/index.d.ts +46 -0
- package/dist/api/index.js +45 -0
- package/dist/api/inline-runtime.d.ts +27 -0
- package/dist/api/inline-runtime.js +551 -0
- package/dist/api/manipulation/connections.d.ts +79 -0
- package/dist/api/manipulation/connections.js +151 -0
- package/dist/api/manipulation/index.d.ts +34 -0
- package/dist/api/manipulation/index.js +41 -0
- package/dist/api/manipulation/node-types.d.ts +123 -0
- package/dist/api/manipulation/node-types.js +200 -0
- package/dist/api/manipulation/nodes.d.ts +144 -0
- package/dist/api/manipulation/nodes.js +333 -0
- package/dist/api/manipulation/ports.d.ts +59 -0
- package/dist/api/manipulation/ports.js +228 -0
- package/dist/api/manipulation/scopes.d.ts +52 -0
- package/dist/api/manipulation/scopes.js +156 -0
- package/dist/api/manipulation/validation.d.ts +6 -0
- package/dist/api/manipulation/validation.js +6 -0
- package/dist/api/manipulation/workflow.d.ts +81 -0
- package/dist/api/manipulation/workflow.js +116 -0
- package/dist/api/manipulation.d.ts +8 -0
- package/dist/api/manipulation.js +8 -0
- package/dist/api/parse.d.ts +48 -0
- package/dist/api/parse.js +110 -0
- package/dist/api/patterns.d.ts +112 -0
- package/dist/api/patterns.js +306 -0
- package/dist/api/query.d.ts +429 -0
- package/dist/api/query.js +816 -0
- package/dist/api/templates.d.ts +98 -0
- package/dist/api/templates.js +117 -0
- package/dist/api/transform.d.ts +31 -0
- package/dist/api/transform.js +40 -0
- package/dist/api/validate.d.ts +25 -0
- package/dist/api/validate.js +39 -0
- package/dist/api/workflow-file-operations.d.ts +29 -0
- package/dist/api/workflow-file-operations.js +180 -0
- package/dist/ast/builder.d.ts +210 -0
- package/dist/ast/builder.js +395 -0
- package/dist/ast/index.d.ts +5 -0
- package/dist/ast/index.js +5 -0
- package/dist/ast/serialization-node.d.ts +6 -0
- package/dist/ast/serialization-node.js +30 -0
- package/dist/ast/serialization.d.ts +43 -0
- package/dist/ast/serialization.js +134 -0
- package/dist/ast/types.d.ts +852 -0
- package/dist/ast/types.js +2 -0
- package/dist/ast/workflow-utils.d.ts +54 -0
- package/dist/ast/workflow-utils.js +114 -0
- package/dist/body-generator.d.ts +31 -0
- package/dist/body-generator.js +35 -0
- package/dist/built-in-nodes/delay.d.ts +11 -0
- package/dist/built-in-nodes/delay.js +29 -0
- package/dist/built-in-nodes/index.d.ts +5 -0
- package/dist/built-in-nodes/index.js +4 -0
- package/dist/built-in-nodes/invoke-workflow.d.ts +13 -0
- package/dist/built-in-nodes/invoke-workflow.js +25 -0
- package/dist/built-in-nodes/mock-types.d.ts +18 -0
- package/dist/built-in-nodes/mock-types.js +12 -0
- package/dist/built-in-nodes/wait-for-event.d.ts +13 -0
- package/dist/built-in-nodes/wait-for-event.js +25 -0
- package/dist/chevrotain-parser/connect-parser.d.ts +24 -0
- package/dist/chevrotain-parser/connect-parser.js +98 -0
- package/dist/chevrotain-parser/grammar-diagrams.d.ts +29 -0
- package/dist/chevrotain-parser/grammar-diagrams.js +264 -0
- package/dist/chevrotain-parser/index.d.ts +25 -0
- package/dist/chevrotain-parser/index.js +27 -0
- package/dist/chevrotain-parser/map-parser.d.ts +33 -0
- package/dist/chevrotain-parser/map-parser.js +130 -0
- package/dist/chevrotain-parser/node-parser.d.ts +36 -0
- package/dist/chevrotain-parser/node-parser.js +466 -0
- package/dist/chevrotain-parser/path-parser.d.ts +28 -0
- package/dist/chevrotain-parser/path-parser.js +118 -0
- package/dist/chevrotain-parser/port-parser.d.ts +36 -0
- package/dist/chevrotain-parser/port-parser.js +442 -0
- package/dist/chevrotain-parser/position-parser.d.ts +20 -0
- package/dist/chevrotain-parser/position-parser.js +83 -0
- package/dist/chevrotain-parser/scope-parser.d.ts +19 -0
- package/dist/chevrotain-parser/scope-parser.js +104 -0
- package/dist/chevrotain-parser/tokens.d.ts +78 -0
- package/dist/chevrotain-parser/tokens.js +384 -0
- package/dist/chevrotain-parser/trigger-cancel-parser.d.ts +50 -0
- package/dist/chevrotain-parser/trigger-cancel-parser.js +282 -0
- package/dist/cli/commands/changelog.d.ts +13 -0
- package/dist/cli/commands/changelog.js +135 -0
- package/dist/cli/commands/compile.d.ts +64 -0
- package/dist/cli/commands/compile.js +278 -0
- package/dist/cli/commands/create.d.ts +33 -0
- package/dist/cli/commands/create.js +147 -0
- package/dist/cli/commands/describe.d.ts +68 -0
- package/dist/cli/commands/describe.js +377 -0
- package/dist/cli/commands/dev.d.ts +32 -0
- package/dist/cli/commands/dev.js +384 -0
- package/dist/cli/commands/diagram.d.ts +13 -0
- package/dist/cli/commands/diagram.js +33 -0
- package/dist/cli/commands/diff.d.ts +11 -0
- package/dist/cli/commands/diff.js +59 -0
- package/dist/cli/commands/doctor.d.ts +57 -0
- package/dist/cli/commands/doctor.js +719 -0
- package/dist/cli/commands/export.d.ts +57 -0
- package/dist/cli/commands/export.js +163 -0
- package/dist/cli/commands/grammar.d.ts +9 -0
- package/dist/cli/commands/grammar.js +39 -0
- package/dist/cli/commands/init.d.ts +59 -0
- package/dist/cli/commands/init.js +435 -0
- package/dist/cli/commands/listen.d.ts +16 -0
- package/dist/cli/commands/listen.js +39 -0
- package/dist/cli/commands/market.d.ts +52 -0
- package/dist/cli/commands/market.js +436 -0
- package/dist/cli/commands/migrate.d.ts +13 -0
- package/dist/cli/commands/migrate.js +89 -0
- package/dist/cli/commands/openapi.d.ts +37 -0
- package/dist/cli/commands/openapi.js +67 -0
- package/dist/cli/commands/pattern.d.ts +34 -0
- package/dist/cli/commands/pattern.js +185 -0
- package/dist/cli/commands/plugin.d.ts +16 -0
- package/dist/cli/commands/plugin.js +176 -0
- package/dist/cli/commands/run.d.ts +49 -0
- package/dist/cli/commands/run.js +191 -0
- package/dist/cli/commands/serve.d.ts +45 -0
- package/dist/cli/commands/serve.js +81 -0
- package/dist/cli/commands/templates.d.ts +8 -0
- package/dist/cli/commands/templates.js +54 -0
- package/dist/cli/commands/ui.d.ts +16 -0
- package/dist/cli/commands/ui.js +130 -0
- package/dist/cli/commands/validate.d.ts +12 -0
- package/dist/cli/commands/validate.js +247 -0
- package/dist/cli/commands/watch.d.ts +9 -0
- package/dist/cli/commands/watch.js +70 -0
- package/dist/cli/flow-weaver.mjs +92924 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +742 -0
- package/dist/cli/templates/ai/mock-provider.d.ts +7 -0
- package/dist/cli/templates/ai/mock-provider.js +64 -0
- package/dist/cli/templates/ai/types.d.ts +47 -0
- package/dist/cli/templates/ai/types.js +5 -0
- package/dist/cli/templates/approvals/index.d.ts +15 -0
- package/dist/cli/templates/approvals/index.js +241 -0
- package/dist/cli/templates/index.d.ts +102 -0
- package/dist/cli/templates/index.js +101 -0
- package/dist/cli/templates/nodes/agent-router.d.ts +3 -0
- package/dist/cli/templates/nodes/agent-router.js +114 -0
- package/dist/cli/templates/nodes/aggregator.d.ts +7 -0
- package/dist/cli/templates/nodes/aggregator.js +63 -0
- package/dist/cli/templates/nodes/conversation-memory.d.ts +3 -0
- package/dist/cli/templates/nodes/conversation-memory.js +85 -0
- package/dist/cli/templates/nodes/http.d.ts +7 -0
- package/dist/cli/templates/nodes/http.js +80 -0
- package/dist/cli/templates/nodes/human-approval.d.ts +3 -0
- package/dist/cli/templates/nodes/human-approval.js +110 -0
- package/dist/cli/templates/nodes/json-extractor.d.ts +3 -0
- package/dist/cli/templates/nodes/json-extractor.js +119 -0
- package/dist/cli/templates/nodes/llm-call.d.ts +3 -0
- package/dist/cli/templates/nodes/llm-call.js +106 -0
- package/dist/cli/templates/nodes/prompt-template.d.ts +3 -0
- package/dist/cli/templates/nodes/prompt-template.js +52 -0
- package/dist/cli/templates/nodes/rag-retriever.d.ts +3 -0
- package/dist/cli/templates/nodes/rag-retriever.js +128 -0
- package/dist/cli/templates/nodes/tool-executor.d.ts +3 -0
- package/dist/cli/templates/nodes/tool-executor.js +108 -0
- package/dist/cli/templates/nodes/transformer.d.ts +7 -0
- package/dist/cli/templates/nodes/transformer.js +68 -0
- package/dist/cli/templates/nodes/validator.d.ts +7 -0
- package/dist/cli/templates/nodes/validator.js +62 -0
- package/dist/cli/templates/providers/index.d.ts +14 -0
- package/dist/cli/templates/providers/index.js +239 -0
- package/dist/cli/templates/shared/approval-types.d.ts +9 -0
- package/dist/cli/templates/shared/approval-types.js +31 -0
- package/dist/cli/templates/shared/llm-types.d.ts +15 -0
- package/dist/cli/templates/shared/llm-types.js +104 -0
- package/dist/cli/templates/workflows/aggregator.d.ts +7 -0
- package/dist/cli/templates/workflows/aggregator.js +104 -0
- package/dist/cli/templates/workflows/ai-agent-durable.d.ts +8 -0
- package/dist/cli/templates/workflows/ai-agent-durable.js +338 -0
- package/dist/cli/templates/workflows/ai-agent.d.ts +31 -0
- package/dist/cli/templates/workflows/ai-agent.js +326 -0
- package/dist/cli/templates/workflows/ai-chat.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-chat.js +169 -0
- package/dist/cli/templates/workflows/ai-pipeline-durable.d.ts +8 -0
- package/dist/cli/templates/workflows/ai-pipeline-durable.js +330 -0
- package/dist/cli/templates/workflows/ai-rag.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-rag.js +186 -0
- package/dist/cli/templates/workflows/ai-react.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-react.js +294 -0
- package/dist/cli/templates/workflows/conditional.d.ts +12 -0
- package/dist/cli/templates/workflows/conditional.js +142 -0
- package/dist/cli/templates/workflows/error-handler.d.ts +7 -0
- package/dist/cli/templates/workflows/error-handler.js +147 -0
- package/dist/cli/templates/workflows/foreach.d.ts +7 -0
- package/dist/cli/templates/workflows/foreach.js +143 -0
- package/dist/cli/templates/workflows/sequential.d.ts +7 -0
- package/dist/cli/templates/workflows/sequential.js +198 -0
- package/dist/cli/templates/workflows/webhook.d.ts +7 -0
- package/dist/cli/templates/workflows/webhook.js +161 -0
- package/dist/cli/utils/logger.d.ts +15 -0
- package/dist/cli/utils/logger.js +46 -0
- package/dist/constants.d.ts +100 -0
- package/dist/constants.js +125 -0
- package/dist/defaults.d.ts +3 -0
- package/dist/defaults.js +3 -0
- package/dist/deployment/config/defaults.d.ts +29 -0
- package/dist/deployment/config/defaults.js +98 -0
- package/dist/deployment/config/loader.d.ts +24 -0
- package/dist/deployment/config/loader.js +236 -0
- package/dist/deployment/config/types.d.ts +117 -0
- package/dist/deployment/config/types.js +5 -0
- package/dist/deployment/core/adapters.d.ts +90 -0
- package/dist/deployment/core/adapters.js +251 -0
- package/dist/deployment/core/executor.d.ts +62 -0
- package/dist/deployment/core/executor.js +197 -0
- package/dist/deployment/core/formatters.d.ts +57 -0
- package/dist/deployment/core/formatters.js +170 -0
- package/dist/deployment/index.d.ts +31 -0
- package/dist/deployment/index.js +48 -0
- package/dist/deployment/openapi/generator.d.ts +146 -0
- package/dist/deployment/openapi/generator.js +347 -0
- package/dist/deployment/openapi/schema-converter.d.ts +49 -0
- package/dist/deployment/openapi/schema-converter.js +192 -0
- package/dist/deployment/targets/base.d.ts +316 -0
- package/dist/deployment/targets/base.js +823 -0
- package/dist/deployment/targets/cloudflare.d.ts +23 -0
- package/dist/deployment/targets/cloudflare.js +1125 -0
- package/dist/deployment/targets/inngest.d.ts +38 -0
- package/dist/deployment/targets/inngest.js +926 -0
- package/dist/deployment/targets/lambda.d.ts +23 -0
- package/dist/deployment/targets/lambda.js +1289 -0
- package/dist/deployment/targets/vercel.d.ts +23 -0
- package/dist/deployment/targets/vercel.js +886 -0
- package/dist/deployment/types.d.ts +183 -0
- package/dist/deployment/types.js +8 -0
- package/dist/diagram/geometry.d.ts +26 -0
- package/dist/diagram/geometry.js +850 -0
- package/dist/diagram/index.d.ts +16 -0
- package/dist/diagram/index.js +42 -0
- package/dist/diagram/layout.d.ts +11 -0
- package/dist/diagram/layout.js +143 -0
- package/dist/diagram/orthogonal-router.d.ts +79 -0
- package/dist/diagram/orthogonal-router.js +568 -0
- package/dist/diagram/renderer.d.ts +3 -0
- package/dist/diagram/renderer.js +207 -0
- package/dist/diagram/theme.d.ts +20 -0
- package/dist/diagram/theme.js +189 -0
- package/dist/diagram/types.d.ts +70 -0
- package/dist/diagram/types.js +2 -0
- package/dist/diff/WorkflowDiffer.d.ts +13 -0
- package/dist/diff/WorkflowDiffer.js +429 -0
- package/dist/diff/formatDiff.d.ts +10 -0
- package/dist/diff/formatDiff.js +220 -0
- package/dist/diff/impact.d.ts +29 -0
- package/dist/diff/impact.js +119 -0
- package/dist/diff/index.d.ts +10 -0
- package/dist/diff/index.js +9 -0
- package/dist/diff/types.d.ts +138 -0
- package/dist/diff/types.js +35 -0
- package/dist/doc-metadata/extractors/annotations.d.ts +56 -0
- package/dist/doc-metadata/extractors/annotations.js +337 -0
- package/dist/doc-metadata/extractors/cli-commands.d.ts +17 -0
- package/dist/doc-metadata/extractors/cli-commands.js +355 -0
- package/dist/doc-metadata/extractors/mcp-tools.d.ts +16 -0
- package/dist/doc-metadata/extractors/mcp-tools.js +689 -0
- package/dist/doc-metadata/extractors/plugin-api.d.ts +19 -0
- package/dist/doc-metadata/extractors/plugin-api.js +279 -0
- package/dist/doc-metadata/index.d.ts +5 -0
- package/dist/doc-metadata/index.js +4 -0
- package/dist/doc-metadata/types.d.ts +120 -0
- package/dist/doc-metadata/types.js +5 -0
- package/dist/editor-completions/annotationValues.d.ts +12 -0
- package/dist/editor-completions/annotationValues.js +138 -0
- package/dist/editor-completions/contextParser.d.ts +40 -0
- package/dist/editor-completions/contextParser.js +410 -0
- package/dist/editor-completions/dataTypes.d.ts +16 -0
- package/dist/editor-completions/dataTypes.js +95 -0
- package/dist/editor-completions/goToDefinition.d.ts +27 -0
- package/dist/editor-completions/goToDefinition.js +112 -0
- package/dist/editor-completions/index.d.ts +39 -0
- package/dist/editor-completions/index.js +181 -0
- package/dist/editor-completions/jsDocAnnotations.d.ts +29 -0
- package/dist/editor-completions/jsDocAnnotations.js +357 -0
- package/dist/editor-completions/modifierCompletions.d.ts +17 -0
- package/dist/editor-completions/modifierCompletions.js +197 -0
- package/dist/editor-completions/types.d.ts +119 -0
- package/dist/editor-completions/types.js +8 -0
- package/dist/export/index.d.ts +68 -0
- package/dist/export/index.js +1074 -0
- package/dist/export/templates.d.ts +24 -0
- package/dist/export/templates.js +186 -0
- package/dist/friendly-errors.d.ts +35 -0
- package/dist/friendly-errors.js +375 -0
- package/dist/function-like.d.ts +38 -0
- package/dist/function-like.js +83 -0
- package/dist/generated-branding.d.ts +16 -0
- package/dist/generated-branding.js +22 -0
- package/dist/generator/async-detection.d.ts +27 -0
- package/dist/generator/async-detection.js +56 -0
- package/dist/generator/code-utils.d.ts +76 -0
- package/dist/generator/code-utils.js +410 -0
- package/dist/generator/control-flow.d.ts +54 -0
- package/dist/generator/control-flow.js +284 -0
- package/dist/generator/inngest.d.ts +53 -0
- package/dist/generator/inngest.js +1126 -0
- package/dist/generator/scope-function-generator.d.ts +78 -0
- package/dist/generator/scope-function-generator.js +360 -0
- package/dist/generator/unified.d.ts +42 -0
- package/dist/generator/unified.js +1504 -0
- package/dist/generator.d.ts +54 -0
- package/dist/generator.js +100 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +89 -0
- package/dist/jsdoc-parser.d.ts +308 -0
- package/dist/jsdoc-parser.js +923 -0
- package/dist/jsdoc-port-sync/constants.d.ts +41 -0
- package/dist/jsdoc-port-sync/constants.js +103 -0
- package/dist/jsdoc-port-sync/diff.d.ts +76 -0
- package/dist/jsdoc-port-sync/diff.js +319 -0
- package/dist/jsdoc-port-sync/index.d.ts +42 -0
- package/dist/jsdoc-port-sync/index.js +45 -0
- package/dist/jsdoc-port-sync/port-parser.d.ts +68 -0
- package/dist/jsdoc-port-sync/port-parser.js +579 -0
- package/dist/jsdoc-port-sync/rename.d.ts +21 -0
- package/dist/jsdoc-port-sync/rename.js +256 -0
- package/dist/jsdoc-port-sync/signature-parser.d.ts +104 -0
- package/dist/jsdoc-port-sync/signature-parser.js +559 -0
- package/dist/jsdoc-port-sync/sync.d.ts +36 -0
- package/dist/jsdoc-port-sync/sync.js +644 -0
- package/dist/jsdoc-port-sync.d.ts +10 -0
- package/dist/jsdoc-port-sync.js +10 -0
- package/dist/marketplace/index.d.ts +11 -0
- package/dist/marketplace/index.js +10 -0
- package/dist/marketplace/manifest.d.ts +32 -0
- package/dist/marketplace/manifest.js +176 -0
- package/dist/marketplace/registry.d.ts +30 -0
- package/dist/marketplace/registry.js +100 -0
- package/dist/marketplace/types.d.ts +154 -0
- package/dist/marketplace/types.js +9 -0
- package/dist/marketplace/validator.d.ts +13 -0
- package/dist/marketplace/validator.js +131 -0
- package/dist/mcp/auto-registration.d.ts +3 -0
- package/dist/mcp/auto-registration.js +62 -0
- package/dist/mcp/editor-connection.d.ts +50 -0
- package/dist/mcp/editor-connection.js +125 -0
- package/dist/mcp/event-buffer.d.ts +62 -0
- package/dist/mcp/event-buffer.js +150 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/resources.d.ts +14 -0
- package/dist/mcp/resources.js +55 -0
- package/dist/mcp/response-utils.d.ts +63 -0
- package/dist/mcp/response-utils.js +89 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +99 -0
- package/dist/mcp/tools-diagram.d.ts +8 -0
- package/dist/mcp/tools-diagram.js +53 -0
- package/dist/mcp/tools-editor.d.ts +5 -0
- package/dist/mcp/tools-editor.js +190 -0
- package/dist/mcp/tools-export.d.ts +9 -0
- package/dist/mcp/tools-export.js +180 -0
- package/dist/mcp/tools-marketplace.d.ts +9 -0
- package/dist/mcp/tools-marketplace.js +132 -0
- package/dist/mcp/tools-pattern.d.ts +3 -0
- package/dist/mcp/tools-pattern.js +783 -0
- package/dist/mcp/tools-query.d.ts +3 -0
- package/dist/mcp/tools-query.js +364 -0
- package/dist/mcp/tools-template.d.ts +10 -0
- package/dist/mcp/tools-template.js +119 -0
- package/dist/mcp/types.d.ts +70 -0
- package/dist/mcp/types.js +8 -0
- package/dist/mcp/workflow-executor.d.ts +47 -0
- package/dist/mcp/workflow-executor.js +133 -0
- package/dist/migration/registry.d.ts +30 -0
- package/dist/migration/registry.js +29 -0
- package/dist/node-types-generator.d.ts +49 -0
- package/dist/node-types-generator.js +139 -0
- package/dist/npm-packages.d.ts +56 -0
- package/dist/npm-packages.js +255 -0
- package/dist/parser.d.ts +204 -0
- package/dist/parser.js +2100 -0
- package/dist/plugin/PluginPanel.d.ts +12 -0
- package/dist/plugin/PluginPanel.js +5 -0
- package/dist/plugin/index.d.ts +13 -0
- package/dist/plugin/index.js +14 -0
- package/dist/plugin/types.d.ts +75 -0
- package/dist/plugin/types.js +8 -0
- package/dist/resolve-package-types.d.ts +17 -0
- package/dist/resolve-package-types.js +123 -0
- package/dist/runtime/CancellationError.d.ts +11 -0
- package/dist/runtime/CancellationError.js +20 -0
- package/dist/runtime/ExecutionContext.d.ts +146 -0
- package/dist/runtime/ExecutionContext.js +235 -0
- package/dist/runtime/builtin-functions.d.ts +8 -0
- package/dist/runtime/builtin-functions.js +549 -0
- package/dist/runtime/events.d.ts +50 -0
- package/dist/runtime/events.js +2 -0
- package/dist/runtime/function-registry.d.ts +59 -0
- package/dist/runtime/function-registry.js +66 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/parameter-resolver.d.ts +62 -0
- package/dist/runtime/parameter-resolver.js +113 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +6 -0
- package/dist/server/types.d.ts +93 -0
- package/dist/server/types.js +5 -0
- package/dist/server/webhook-server.d.ts +50 -0
- package/dist/server/webhook-server.js +269 -0
- package/dist/server/workflow-registry.d.ts +61 -0
- package/dist/server/workflow-registry.js +202 -0
- package/dist/shared-project.d.ts +9 -0
- package/dist/shared-project.js +28 -0
- package/dist/sugar-optimizer.d.ts +40 -0
- package/dist/sugar-optimizer.js +387 -0
- package/dist/testing/assertions.d.ts +51 -0
- package/dist/testing/assertions.js +127 -0
- package/dist/testing/index.d.ts +30 -0
- package/dist/testing/index.js +24 -0
- package/dist/testing/mock-approval.d.ts +81 -0
- package/dist/testing/mock-approval.js +98 -0
- package/dist/testing/mock-llm.d.ts +124 -0
- package/dist/testing/mock-llm.js +119 -0
- package/dist/testing/recorder.d.ts +72 -0
- package/dist/testing/recorder.js +70 -0
- package/dist/testing/replayer.d.ts +56 -0
- package/dist/testing/replayer.js +143 -0
- package/dist/testing/token-tracker.d.ts +71 -0
- package/dist/testing/token-tracker.js +94 -0
- package/dist/type-checker.d.ts +42 -0
- package/dist/type-checker.js +190 -0
- package/dist/type-mappings.d.ts +29 -0
- package/dist/type-mappings.js +125 -0
- package/dist/types/branded-ports.d.ts +151 -0
- package/dist/types/branded-ports.js +121 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types.d.ts +139 -0
- package/dist/types.js +15 -0
- package/dist/utils/error-utils.d.ts +15 -0
- package/dist/utils/error-utils.js +27 -0
- package/dist/utils/lru-cache.d.ts +15 -0
- package/dist/utils/lru-cache.js +40 -0
- package/dist/utils/port-ordering.d.ts +26 -0
- package/dist/utils/port-ordering.js +88 -0
- package/dist/utils/port-tag-utils.d.ts +23 -0
- package/dist/utils/port-tag-utils.js +41 -0
- package/dist/utils/string-distance.d.ts +14 -0
- package/dist/utils/string-distance.js +56 -0
- package/dist/validation/agent-detection.d.ts +33 -0
- package/dist/validation/agent-detection.js +115 -0
- package/dist/validation/agent-rules.d.ts +48 -0
- package/dist/validation/agent-rules.js +262 -0
- package/dist/validator.d.ts +92 -0
- package/dist/validator.js +970 -0
- package/package.json +109 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port tag validation utilities
|
|
3
|
+
* Shared logic for determining port tag types (@input, @output, @step)
|
|
4
|
+
*/
|
|
5
|
+
import { isExecutePort, isSuccessPort, isFailurePort, isScopedMandatoryPort } from "../constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Check if a port name is a reserved STEP port.
|
|
8
|
+
* Includes both external (execute, onSuccess, onFailure) and scoped (start, success, failure).
|
|
9
|
+
*/
|
|
10
|
+
export function isReservedStepPort(name) {
|
|
11
|
+
return isExecutePort(name) || isSuccessPort(name) || isFailurePort(name) || isScopedMandatoryPort(name);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Determine if a port should use the @step tag.
|
|
15
|
+
* Returns true only for custom STEP ports (not reserved ones).
|
|
16
|
+
*/
|
|
17
|
+
export function shouldUseStepTag(portName, port) {
|
|
18
|
+
if (port.dataType !== "STEP")
|
|
19
|
+
return false;
|
|
20
|
+
// Reserved STEP ports use @input/@output, not @step
|
|
21
|
+
const isExternalReserved = isExecutePort(portName) || isSuccessPort(portName) || isFailurePort(portName);
|
|
22
|
+
if (isExternalReserved)
|
|
23
|
+
return false;
|
|
24
|
+
// Scoped mandatory ports also use @input/@output
|
|
25
|
+
if (port.scope && isScopedMandatoryPort(portName))
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the JSDoc tag type for a port.
|
|
31
|
+
* - Custom STEP ports → "step"
|
|
32
|
+
* - Reserved STEP ports → direction ("input" or "output")
|
|
33
|
+
* - Data ports → direction ("input" or "output")
|
|
34
|
+
*/
|
|
35
|
+
export function getPortTagType(portName, port, direction) {
|
|
36
|
+
if (shouldUseStepTag(portName, port)) {
|
|
37
|
+
return "step";
|
|
38
|
+
}
|
|
39
|
+
return direction;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=port-tag-utils.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Levenshtein distance and fuzzy matching utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Compute the Levenshtein edit distance between two strings.
|
|
6
|
+
*/
|
|
7
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
8
|
+
/**
|
|
9
|
+
* Find the closest matches from a list of candidates.
|
|
10
|
+
* Returns candidates within maxDistance, sorted by distance (ascending).
|
|
11
|
+
* When maxDistance is not provided, uses a length-proportional default.
|
|
12
|
+
*/
|
|
13
|
+
export declare function findClosestMatches(target: string, candidates: string[], maxDistance?: number): string[];
|
|
14
|
+
//# sourceMappingURL=string-distance.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Levenshtein distance and fuzzy matching utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Compute the Levenshtein edit distance between two strings.
|
|
6
|
+
*/
|
|
7
|
+
export function levenshteinDistance(a, b) {
|
|
8
|
+
const la = a.length;
|
|
9
|
+
const lb = b.length;
|
|
10
|
+
if (la === 0)
|
|
11
|
+
return lb;
|
|
12
|
+
if (lb === 0)
|
|
13
|
+
return la;
|
|
14
|
+
// Use single-row optimization
|
|
15
|
+
let prev = Array.from({ length: lb + 1 }, (_, i) => i);
|
|
16
|
+
let curr = new Array(lb + 1);
|
|
17
|
+
for (let i = 1; i <= la; i++) {
|
|
18
|
+
curr[0] = i;
|
|
19
|
+
for (let j = 1; j <= lb; j++) {
|
|
20
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
21
|
+
curr[j] = Math.min(curr[j - 1] + 1, // insertion
|
|
22
|
+
prev[j] + 1, // deletion
|
|
23
|
+
prev[j - 1] + cost // substitution
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
[prev, curr] = [curr, prev];
|
|
27
|
+
}
|
|
28
|
+
return prev[lb];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compute an adaptive max edit distance based on target string length.
|
|
32
|
+
* Short strings get a tighter threshold to avoid nonsensical suggestions.
|
|
33
|
+
*/
|
|
34
|
+
function adaptiveMaxDistance(target) {
|
|
35
|
+
const len = target.length;
|
|
36
|
+
if (len <= 3)
|
|
37
|
+
return 1;
|
|
38
|
+
if (len <= 6)
|
|
39
|
+
return 2;
|
|
40
|
+
return 3;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Find the closest matches from a list of candidates.
|
|
44
|
+
* Returns candidates within maxDistance, sorted by distance (ascending).
|
|
45
|
+
* When maxDistance is not provided, uses a length-proportional default.
|
|
46
|
+
*/
|
|
47
|
+
export function findClosestMatches(target, candidates, maxDistance) {
|
|
48
|
+
const effectiveMax = maxDistance ?? adaptiveMaxDistance(target);
|
|
49
|
+
const scored = candidates
|
|
50
|
+
.filter((c) => c !== target)
|
|
51
|
+
.map((c) => ({ name: c, distance: levenshteinDistance(target, c) }))
|
|
52
|
+
.filter((s) => s.distance <= effectiveMax)
|
|
53
|
+
.sort((a, b) => a.distance - b.distance);
|
|
54
|
+
return scored.map((s) => s.name);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=string-distance.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Node Detection
|
|
3
|
+
*
|
|
4
|
+
* Multi-signal detection to classify workflow nodes by their agent role.
|
|
5
|
+
* Uses a priority hierarchy: port signatures > visual annotations > name heuristics.
|
|
6
|
+
*/
|
|
7
|
+
import type { TNodeTypeAST } from '../ast/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Recognized agent node roles.
|
|
10
|
+
* - llm: Calls a language model (has messages/toolCalls/content ports)
|
|
11
|
+
* - tool-executor: Executes tool calls from an LLM (has toolCall input, result output)
|
|
12
|
+
* - human-approval: Gates execution on human review (has approved/rejected outputs)
|
|
13
|
+
* - memory: Stores/retrieves conversation history (has conversationId input, messages output)
|
|
14
|
+
*/
|
|
15
|
+
export type AgentNodeRole = 'llm' | 'tool-executor' | 'human-approval' | 'memory';
|
|
16
|
+
/**
|
|
17
|
+
* Detect the agent role of a node type using multi-signal analysis.
|
|
18
|
+
*
|
|
19
|
+
* Priority:
|
|
20
|
+
* 1. Port signature patterns (strongest — defines the contract)
|
|
21
|
+
* 2. @icon annotation (strong — explicit visual intent)
|
|
22
|
+
* 3. @color annotation (weak — only used to break ties)
|
|
23
|
+
* 4. Function name heuristics (weakest — fallback only)
|
|
24
|
+
*
|
|
25
|
+
* @returns The detected role, or null if the node is not an agent node
|
|
26
|
+
*/
|
|
27
|
+
export declare function detectNodeRole(nodeType: TNodeTypeAST): AgentNodeRole | null;
|
|
28
|
+
/**
|
|
29
|
+
* Convenience: find all node types in a workflow that match a specific role.
|
|
30
|
+
* Returns array of [instanceId, nodeType] pairs for all instances with that role.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findNodesByRole(nodeTypes: TNodeTypeAST[], role: AgentNodeRole): TNodeTypeAST[];
|
|
33
|
+
//# sourceMappingURL=agent-detection.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Node Detection
|
|
3
|
+
*
|
|
4
|
+
* Multi-signal detection to classify workflow nodes by their agent role.
|
|
5
|
+
* Uses a priority hierarchy: port signatures > visual annotations > name heuristics.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Signal matchers (ordered by priority)
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** Port-based detection — most reliable since port names define the contract */
|
|
11
|
+
const PORT_SIGNATURES = [
|
|
12
|
+
{
|
|
13
|
+
// LLM node: has 'messages' input AND ('content' or 'toolCalls' output)
|
|
14
|
+
role: 'llm',
|
|
15
|
+
match: (nt) => {
|
|
16
|
+
const hasMessagesInput = 'messages' in nt.inputs;
|
|
17
|
+
const hasContentOutput = 'content' in nt.outputs;
|
|
18
|
+
const hasToolCallsOutput = 'toolCalls' in nt.outputs;
|
|
19
|
+
return hasMessagesInput && (hasContentOutput || hasToolCallsOutput);
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
// Tool executor: has 'toolCall' input AND 'result' output
|
|
24
|
+
role: 'tool-executor',
|
|
25
|
+
match: (nt) => {
|
|
26
|
+
const hasToolCallInput = 'toolCall' in nt.inputs || 'toolCalls' in nt.inputs;
|
|
27
|
+
const hasResultOutput = 'result' in nt.outputs || 'resultMessage' in nt.outputs;
|
|
28
|
+
return hasToolCallInput && hasResultOutput;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
// Human approval: has ('approved' AND 'rejected') outputs
|
|
33
|
+
role: 'human-approval',
|
|
34
|
+
match: (nt) => {
|
|
35
|
+
return 'approved' in nt.outputs && 'rejected' in nt.outputs;
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
// Memory: has 'conversationId' input AND 'messages' output
|
|
40
|
+
role: 'memory',
|
|
41
|
+
match: (nt) => {
|
|
42
|
+
const hasConversationIdInput = 'conversationId' in nt.inputs;
|
|
43
|
+
const hasMessagesOutput = 'messages' in nt.outputs;
|
|
44
|
+
return hasConversationIdInput && hasMessagesOutput;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
/** Icon-based detection — reliable when present, from @icon annotation */
|
|
49
|
+
const ICON_MAP = {
|
|
50
|
+
psychology: 'llm',
|
|
51
|
+
build: 'tool-executor',
|
|
52
|
+
verified: 'human-approval',
|
|
53
|
+
database: 'memory',
|
|
54
|
+
};
|
|
55
|
+
/** Color-based detection — weaker signal, only used to confirm */
|
|
56
|
+
const COLOR_MAP = {
|
|
57
|
+
purple: 'llm',
|
|
58
|
+
cyan: 'tool-executor',
|
|
59
|
+
orange: 'human-approval',
|
|
60
|
+
};
|
|
61
|
+
/** Name pattern heuristics — fallback only */
|
|
62
|
+
const NAME_PATTERNS = [
|
|
63
|
+
{ role: 'llm', pattern: /^(llm|chat|completion|model|ai)/i },
|
|
64
|
+
{ role: 'tool-executor', pattern: /^(tool|action|execute|exec)/i },
|
|
65
|
+
{ role: 'human-approval', pattern: /^(human|approv|review|gate)/i },
|
|
66
|
+
{ role: 'memory', pattern: /^(memory|conversation|history|context)/i },
|
|
67
|
+
];
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Public API
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
/**
|
|
72
|
+
* Detect the agent role of a node type using multi-signal analysis.
|
|
73
|
+
*
|
|
74
|
+
* Priority:
|
|
75
|
+
* 1. Port signature patterns (strongest — defines the contract)
|
|
76
|
+
* 2. @icon annotation (strong — explicit visual intent)
|
|
77
|
+
* 3. @color annotation (weak — only used to break ties)
|
|
78
|
+
* 4. Function name heuristics (weakest — fallback only)
|
|
79
|
+
*
|
|
80
|
+
* @returns The detected role, or null if the node is not an agent node
|
|
81
|
+
*/
|
|
82
|
+
export function detectNodeRole(nodeType) {
|
|
83
|
+
// 1. Port signatures (highest confidence)
|
|
84
|
+
for (const sig of PORT_SIGNATURES) {
|
|
85
|
+
if (sig.match(nodeType)) {
|
|
86
|
+
return sig.role;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 2. Icon annotation
|
|
90
|
+
const icon = nodeType.visuals?.icon;
|
|
91
|
+
if (icon && icon in ICON_MAP) {
|
|
92
|
+
return ICON_MAP[icon];
|
|
93
|
+
}
|
|
94
|
+
// 3. Color annotation (only if it maps unambiguously)
|
|
95
|
+
const color = nodeType.visuals?.color;
|
|
96
|
+
if (color && color in COLOR_MAP) {
|
|
97
|
+
return COLOR_MAP[color];
|
|
98
|
+
}
|
|
99
|
+
// 4. Function name heuristics
|
|
100
|
+
const name = nodeType.functionName || nodeType.name;
|
|
101
|
+
for (const { role, pattern } of NAME_PATTERNS) {
|
|
102
|
+
if (pattern.test(name)) {
|
|
103
|
+
return role;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Convenience: find all node types in a workflow that match a specific role.
|
|
110
|
+
* Returns array of [instanceId, nodeType] pairs for all instances with that role.
|
|
111
|
+
*/
|
|
112
|
+
export function findNodesByRole(nodeTypes, role) {
|
|
113
|
+
return nodeTypes.filter((nt) => detectNodeRole(nt) === role);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=agent-detection.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-Specific Validation Rules
|
|
3
|
+
*
|
|
4
|
+
* Custom TValidationRule implementations for agent/AI workflow patterns.
|
|
5
|
+
* These run AFTER the built-in validator via the api/validate.ts custom rules injection.
|
|
6
|
+
*
|
|
7
|
+
* Rules:
|
|
8
|
+
* 1. AGENT_LLM_MISSING_ERROR_HANDLER - LLM node's onFailure is unconnected
|
|
9
|
+
* 2. AGENT_UNGUARDED_TOOL_EXECUTOR - Tool executor has no human-approval upstream
|
|
10
|
+
* 3. AGENT_MISSING_MEMORY_IN_LOOP - Agent loop has LLM but no memory node
|
|
11
|
+
* 4. AGENT_LLM_NO_FALLBACK - LLM onFailure goes directly to Exit
|
|
12
|
+
* 5. AGENT_TOOL_NO_OUTPUT_HANDLING - Tool executor outputs are all unconnected
|
|
13
|
+
*/
|
|
14
|
+
import type { TValidationRule } from '../ast/types.js';
|
|
15
|
+
/**
|
|
16
|
+
* LLM nodes should have their onFailure port connected.
|
|
17
|
+
* LLM calls are inherently unreliable (rate limits, timeouts, model errors).
|
|
18
|
+
* An unconnected onFailure means failures are silently swallowed.
|
|
19
|
+
*/
|
|
20
|
+
export declare const missingErrorHandlerRule: TValidationRule;
|
|
21
|
+
/**
|
|
22
|
+
* Tool executors that perform actions should have a human-approval node upstream.
|
|
23
|
+
* This is a warning, not an error — read-only tools may not need approval.
|
|
24
|
+
*/
|
|
25
|
+
export declare const unguardedToolExecutorRule: TValidationRule;
|
|
26
|
+
/**
|
|
27
|
+
* An agent loop (scope) containing an LLM node but no memory node means
|
|
28
|
+
* the LLM loses context between iterations. This is almost always a bug.
|
|
29
|
+
*/
|
|
30
|
+
export declare const missingMemoryInLoopRule: TValidationRule;
|
|
31
|
+
/**
|
|
32
|
+
* An LLM node whose onFailure goes directly to Exit.onFailure means
|
|
33
|
+
* any LLM error immediately aborts the workflow. Consider a retry or fallback.
|
|
34
|
+
*/
|
|
35
|
+
export declare const llmWithoutFallbackRule: TValidationRule;
|
|
36
|
+
/**
|
|
37
|
+
* A tool executor whose non-STEP output ports are all unconnected means
|
|
38
|
+
* tool results are computed but never used — likely a wiring mistake.
|
|
39
|
+
*/
|
|
40
|
+
export declare const toolNoOutputHandlingRule: TValidationRule;
|
|
41
|
+
/** All agent validation rules */
|
|
42
|
+
export declare const agentValidationRules: TValidationRule[];
|
|
43
|
+
/**
|
|
44
|
+
* Get all agent validation rules.
|
|
45
|
+
* Convenience function for passing to validateWorkflow().
|
|
46
|
+
*/
|
|
47
|
+
export declare function getAgentValidationRules(): TValidationRule[];
|
|
48
|
+
//# sourceMappingURL=agent-rules.d.ts.map
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-Specific Validation Rules
|
|
3
|
+
*
|
|
4
|
+
* Custom TValidationRule implementations for agent/AI workflow patterns.
|
|
5
|
+
* These run AFTER the built-in validator via the api/validate.ts custom rules injection.
|
|
6
|
+
*
|
|
7
|
+
* Rules:
|
|
8
|
+
* 1. AGENT_LLM_MISSING_ERROR_HANDLER - LLM node's onFailure is unconnected
|
|
9
|
+
* 2. AGENT_UNGUARDED_TOOL_EXECUTOR - Tool executor has no human-approval upstream
|
|
10
|
+
* 3. AGENT_MISSING_MEMORY_IN_LOOP - Agent loop has LLM but no memory node
|
|
11
|
+
* 4. AGENT_LLM_NO_FALLBACK - LLM onFailure goes directly to Exit
|
|
12
|
+
* 5. AGENT_TOOL_NO_OUTPUT_HANDLING - Tool executor outputs are all unconnected
|
|
13
|
+
*/
|
|
14
|
+
import { detectNodeRole } from './agent-detection.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Helpers
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/** Resolve a node instance to its node type definition */
|
|
19
|
+
function resolveNodeType(ast, instance) {
|
|
20
|
+
return ast.nodeTypes.find((nt) => nt.name === instance.nodeType || nt.functionName === instance.nodeType);
|
|
21
|
+
}
|
|
22
|
+
/** Get all outgoing connections from a specific port of a node */
|
|
23
|
+
function getOutgoing(ast, nodeId, portName) {
|
|
24
|
+
return ast.connections.filter((c) => {
|
|
25
|
+
if (c.from.node !== nodeId)
|
|
26
|
+
return false;
|
|
27
|
+
if (portName && c.from.port !== portName)
|
|
28
|
+
return false;
|
|
29
|
+
return true;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Get all instances whose node type has a given agent role */
|
|
33
|
+
function getInstancesByRole(ast, role) {
|
|
34
|
+
const results = [];
|
|
35
|
+
for (const instance of ast.instances) {
|
|
36
|
+
const nt = resolveNodeType(ast, instance);
|
|
37
|
+
if (nt && detectNodeRole(nt) === role) {
|
|
38
|
+
results.push({ instance, nodeType: nt });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get all transitive upstream node IDs for a given node.
|
|
45
|
+
* Walks backwards through connections (BFS).
|
|
46
|
+
*/
|
|
47
|
+
function getUpstreamNodes(ast, nodeId) {
|
|
48
|
+
const visited = new Set();
|
|
49
|
+
const queue = [nodeId];
|
|
50
|
+
while (queue.length > 0) {
|
|
51
|
+
const current = queue.shift();
|
|
52
|
+
if (visited.has(current))
|
|
53
|
+
continue;
|
|
54
|
+
visited.add(current);
|
|
55
|
+
for (const conn of ast.connections) {
|
|
56
|
+
if (conn.to.node === current && !visited.has(conn.from.node)) {
|
|
57
|
+
queue.push(conn.from.node);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
visited.delete(nodeId); // exclude self
|
|
62
|
+
return visited;
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Rule 1: Missing Error Handler
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* LLM nodes should have their onFailure port connected.
|
|
69
|
+
* LLM calls are inherently unreliable (rate limits, timeouts, model errors).
|
|
70
|
+
* An unconnected onFailure means failures are silently swallowed.
|
|
71
|
+
*/
|
|
72
|
+
export const missingErrorHandlerRule = {
|
|
73
|
+
name: 'AGENT_LLM_MISSING_ERROR_HANDLER',
|
|
74
|
+
validate(ast) {
|
|
75
|
+
const errors = [];
|
|
76
|
+
const llmInstances = getInstancesByRole(ast, 'llm');
|
|
77
|
+
for (const { instance, nodeType } of llmInstances) {
|
|
78
|
+
// Only check if the node type has an onFailure port
|
|
79
|
+
if (!nodeType.hasFailurePort && !('onFailure' in nodeType.outputs)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const failureConnections = getOutgoing(ast, instance.id, 'onFailure');
|
|
83
|
+
if (failureConnections.length === 0) {
|
|
84
|
+
errors.push({
|
|
85
|
+
type: 'error',
|
|
86
|
+
code: 'AGENT_LLM_MISSING_ERROR_HANDLER',
|
|
87
|
+
message: `LLM node '${instance.id}' has no error handler — its onFailure port is unconnected. LLM calls can fail due to rate limits, timeouts, or model errors.`,
|
|
88
|
+
node: instance.id,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return errors;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Rule 2: Unguarded Tool Executor
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
/**
|
|
99
|
+
* Tool executors that perform actions should have a human-approval node upstream.
|
|
100
|
+
* This is a warning, not an error — read-only tools may not need approval.
|
|
101
|
+
*/
|
|
102
|
+
export const unguardedToolExecutorRule = {
|
|
103
|
+
name: 'AGENT_UNGUARDED_TOOL_EXECUTOR',
|
|
104
|
+
validate(ast) {
|
|
105
|
+
const errors = [];
|
|
106
|
+
const toolInstances = getInstancesByRole(ast, 'tool-executor');
|
|
107
|
+
const approvalInstances = getInstancesByRole(ast, 'human-approval');
|
|
108
|
+
// If no tool executors, nothing to check
|
|
109
|
+
if (toolInstances.length === 0)
|
|
110
|
+
return errors;
|
|
111
|
+
// If no approval nodes at all, warn for every tool executor
|
|
112
|
+
if (approvalInstances.length === 0) {
|
|
113
|
+
for (const { instance } of toolInstances) {
|
|
114
|
+
errors.push({
|
|
115
|
+
type: 'warning',
|
|
116
|
+
code: 'AGENT_UNGUARDED_TOOL_EXECUTOR',
|
|
117
|
+
message: `Tool executor '${instance.id}' has no human approval gate upstream. If this node performs destructive actions, consider adding a human-approval node before it.`,
|
|
118
|
+
node: instance.id,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return errors;
|
|
122
|
+
}
|
|
123
|
+
// Check each tool executor for upstream approval
|
|
124
|
+
for (const { instance: toolInstance } of toolInstances) {
|
|
125
|
+
const upstream = getUpstreamNodes(ast, toolInstance.id);
|
|
126
|
+
const hasUpstreamApproval = approvalInstances.some(({ instance: approvalInstance }) => upstream.has(approvalInstance.id));
|
|
127
|
+
if (!hasUpstreamApproval) {
|
|
128
|
+
errors.push({
|
|
129
|
+
type: 'warning',
|
|
130
|
+
code: 'AGENT_UNGUARDED_TOOL_EXECUTOR',
|
|
131
|
+
message: `Tool executor '${toolInstance.id}' has no human approval gate upstream. If this node performs destructive actions, consider adding a human-approval node before it.`,
|
|
132
|
+
node: toolInstance.id,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return errors;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Rule 3: Missing Memory in Loop
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
/**
|
|
143
|
+
* An agent loop (scope) containing an LLM node but no memory node means
|
|
144
|
+
* the LLM loses context between iterations. This is almost always a bug.
|
|
145
|
+
*/
|
|
146
|
+
export const missingMemoryInLoopRule = {
|
|
147
|
+
name: 'AGENT_MISSING_MEMORY_IN_LOOP',
|
|
148
|
+
validate(ast) {
|
|
149
|
+
const errors = [];
|
|
150
|
+
if (!ast.scopes)
|
|
151
|
+
return errors;
|
|
152
|
+
for (const [scopeName, instanceIds] of Object.entries(ast.scopes)) {
|
|
153
|
+
let hasLlm = false;
|
|
154
|
+
let hasMemory = false;
|
|
155
|
+
for (const instId of instanceIds) {
|
|
156
|
+
const instance = ast.instances.find((i) => i.id === instId);
|
|
157
|
+
if (!instance)
|
|
158
|
+
continue;
|
|
159
|
+
const nt = resolveNodeType(ast, instance);
|
|
160
|
+
if (!nt)
|
|
161
|
+
continue;
|
|
162
|
+
const role = detectNodeRole(nt);
|
|
163
|
+
if (role === 'llm')
|
|
164
|
+
hasLlm = true;
|
|
165
|
+
if (role === 'memory')
|
|
166
|
+
hasMemory = true;
|
|
167
|
+
}
|
|
168
|
+
if (hasLlm && !hasMemory) {
|
|
169
|
+
errors.push({
|
|
170
|
+
type: 'warning',
|
|
171
|
+
code: 'AGENT_MISSING_MEMORY_IN_LOOP',
|
|
172
|
+
message: `Scope '${scopeName}' contains an LLM node but no conversation memory node. The LLM will lose context between loop iterations.`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return errors;
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Rule 4: LLM Without Fallback
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
/**
|
|
183
|
+
* An LLM node whose onFailure goes directly to Exit.onFailure means
|
|
184
|
+
* any LLM error immediately aborts the workflow. Consider a retry or fallback.
|
|
185
|
+
*/
|
|
186
|
+
export const llmWithoutFallbackRule = {
|
|
187
|
+
name: 'AGENT_LLM_NO_FALLBACK',
|
|
188
|
+
validate(ast) {
|
|
189
|
+
const errors = [];
|
|
190
|
+
const llmInstances = getInstancesByRole(ast, 'llm');
|
|
191
|
+
for (const { instance, nodeType } of llmInstances) {
|
|
192
|
+
if (!nodeType.hasFailurePort && !('onFailure' in nodeType.outputs)) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const failureConnections = getOutgoing(ast, instance.id, 'onFailure');
|
|
196
|
+
// If unconnected, Rule 1 handles it — skip here
|
|
197
|
+
if (failureConnections.length === 0)
|
|
198
|
+
continue;
|
|
199
|
+
// Check if ALL failure connections go directly to Exit
|
|
200
|
+
const allToExit = failureConnections.every((c) => c.to.node === 'Exit');
|
|
201
|
+
if (allToExit) {
|
|
202
|
+
errors.push({
|
|
203
|
+
type: 'warning',
|
|
204
|
+
code: 'AGENT_LLM_NO_FALLBACK',
|
|
205
|
+
message: `LLM node '${instance.id}' routes failures directly to Exit. Consider adding a retry node or fallback LLM provider for resilience.`,
|
|
206
|
+
node: instance.id,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return errors;
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// Rule 5: Tool Executor No Output Handling
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
/**
|
|
217
|
+
* A tool executor whose non-STEP output ports are all unconnected means
|
|
218
|
+
* tool results are computed but never used — likely a wiring mistake.
|
|
219
|
+
*/
|
|
220
|
+
export const toolNoOutputHandlingRule = {
|
|
221
|
+
name: 'AGENT_TOOL_NO_OUTPUT_HANDLING',
|
|
222
|
+
validate(ast) {
|
|
223
|
+
const errors = [];
|
|
224
|
+
const toolInstances = getInstancesByRole(ast, 'tool-executor');
|
|
225
|
+
const stepPorts = new Set(['onSuccess', 'onFailure', 'execute']);
|
|
226
|
+
for (const { instance, nodeType } of toolInstances) {
|
|
227
|
+
const dataPorts = Object.keys(nodeType.outputs).filter((p) => !stepPorts.has(p));
|
|
228
|
+
// If no data ports, nothing to check
|
|
229
|
+
if (dataPorts.length === 0)
|
|
230
|
+
continue;
|
|
231
|
+
const hasAnyConnected = dataPorts.some((port) => getOutgoing(ast, instance.id, port).length > 0);
|
|
232
|
+
if (!hasAnyConnected) {
|
|
233
|
+
errors.push({
|
|
234
|
+
type: 'warning',
|
|
235
|
+
code: 'AGENT_TOOL_NO_OUTPUT_HANDLING',
|
|
236
|
+
message: `Tool executor '${instance.id}' has no data output ports connected. Tool results (${dataPorts.join(', ')}) are being discarded.`,
|
|
237
|
+
node: instance.id,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return errors;
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// Public API
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
/** All agent validation rules */
|
|
248
|
+
export const agentValidationRules = [
|
|
249
|
+
missingErrorHandlerRule,
|
|
250
|
+
unguardedToolExecutorRule,
|
|
251
|
+
missingMemoryInLoopRule,
|
|
252
|
+
llmWithoutFallbackRule,
|
|
253
|
+
toolNoOutputHandlingRule,
|
|
254
|
+
];
|
|
255
|
+
/**
|
|
256
|
+
* Get all agent validation rules.
|
|
257
|
+
* Convenience function for passing to validateWorkflow().
|
|
258
|
+
*/
|
|
259
|
+
export function getAgentValidationRules() {
|
|
260
|
+
return agentValidationRules;
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=agent-rules.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { TNodeTypeAST, TWorkflowAST, TValidationError } from './ast/types.js';
|
|
2
|
+
export type { TValidationError } from './ast/types.js';
|
|
3
|
+
export declare class WorkflowValidator {
|
|
4
|
+
private errors;
|
|
5
|
+
private warnings;
|
|
6
|
+
private strictMode;
|
|
7
|
+
/** Look up instance sourceLocation by instance ID */
|
|
8
|
+
private getInstanceLocation;
|
|
9
|
+
/** Look up connection sourceLocation */
|
|
10
|
+
private getConnectionLocation;
|
|
11
|
+
/**
|
|
12
|
+
* Validate a single node type for scoped port requirements
|
|
13
|
+
*
|
|
14
|
+
* Scoped Port Architecture Rules:
|
|
15
|
+
* - Scope names must be valid JavaScript identifiers
|
|
16
|
+
*
|
|
17
|
+
* Per-Port Scope Architecture:
|
|
18
|
+
* - Scoped OUTPUT ports become callback PARAMETERS (data flows to children)
|
|
19
|
+
* - Scoped INPUT ports become callback RETURN VALUES (data flows from children)
|
|
20
|
+
* - Scoped ports can be ANY data type - they're not functions themselves
|
|
21
|
+
* - The callback function is passed as a function parameter (e.g., forEach's itemProcessor)
|
|
22
|
+
*
|
|
23
|
+
* NOTE: execute/onSuccess/onFailure ports are mandatory base interface ports
|
|
24
|
+
* that are auto-added to ALL nodes - no validation needed for those.
|
|
25
|
+
*/
|
|
26
|
+
validateNodeType(nodeType: TNodeTypeAST): string[];
|
|
27
|
+
validate(workflow: TWorkflowAST, options?: {
|
|
28
|
+
strictMode?: boolean;
|
|
29
|
+
}): {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
errors: TValidationError[];
|
|
32
|
+
warnings: TValidationError[];
|
|
33
|
+
};
|
|
34
|
+
private validateStructure;
|
|
35
|
+
private validateDuplicateNodeNames;
|
|
36
|
+
private validateMutableBindings;
|
|
37
|
+
private validateReservedNames;
|
|
38
|
+
private validateConnections;
|
|
39
|
+
/**
|
|
40
|
+
* Validate type compatibility for connections with coercion support
|
|
41
|
+
*
|
|
42
|
+
* Type coercion rules:
|
|
43
|
+
* - ANY type connections always allowed (no warning)
|
|
44
|
+
* - Safe coercions: NUMBER → STRING, BOOLEAN → STRING (no warning)
|
|
45
|
+
* - Lossy coercions: STRING → NUMBER, STRING → BOOLEAN, OBJECT → STRING (warning or error in strict mode)
|
|
46
|
+
* - Unusual coercions: NUMBER → BOOLEAN, BOOLEAN → NUMBER (warning or error in strict mode)
|
|
47
|
+
* - Same type connections always allowed (no warning)
|
|
48
|
+
*
|
|
49
|
+
* Strict types mode (@strictTypes):
|
|
50
|
+
* - When enabled, type incompatibilities are errors instead of warnings
|
|
51
|
+
*/
|
|
52
|
+
private validateTypeCompatibility;
|
|
53
|
+
private validateNodeReferences;
|
|
54
|
+
private validateRequiredInputs;
|
|
55
|
+
private detectUnusedNodes;
|
|
56
|
+
private validateStartAndExit;
|
|
57
|
+
/**
|
|
58
|
+
* Validate data flow in the workflow
|
|
59
|
+
*
|
|
60
|
+
* Checks for:
|
|
61
|
+
* - Unused output ports (data produced but never consumed)
|
|
62
|
+
* - Unreachable Exit ports (Exit expects data but no connection provides it)
|
|
63
|
+
* - Dead-end data paths (data that never reaches Exit)
|
|
64
|
+
*/
|
|
65
|
+
private validateDataFlow;
|
|
66
|
+
/**
|
|
67
|
+
* Validate for cycles (loops) in the workflow graph.
|
|
68
|
+
* Cycles are connections that form a loop back to an earlier node.
|
|
69
|
+
* Scoped nodes handle loops internally, so cycles within same scope are checked.
|
|
70
|
+
*/
|
|
71
|
+
private validateCycles;
|
|
72
|
+
private detectCyclesInLayer;
|
|
73
|
+
/**
|
|
74
|
+
* Validate that no input port has multiple connections.
|
|
75
|
+
* Only one value can be received per input port.
|
|
76
|
+
* (STEP ports can have multiple connections as they're control flow)
|
|
77
|
+
*/
|
|
78
|
+
private validateMultipleInputConnections;
|
|
79
|
+
/**
|
|
80
|
+
* Cross-check @input annotations against TypeScript function signatures.
|
|
81
|
+
* Warns on optionality and type mismatches between annotations and actual code.
|
|
82
|
+
*/
|
|
83
|
+
private validateAnnotationSignatureConsistency;
|
|
84
|
+
/**
|
|
85
|
+
* Check if a set of source nodes are mutually exclusive — i.e., they descend
|
|
86
|
+
* from opposite branches (onSuccess vs onFailure) of the same branching node.
|
|
87
|
+
*/
|
|
88
|
+
private areMutuallyExclusive;
|
|
89
|
+
private normalizeTypeString;
|
|
90
|
+
}
|
|
91
|
+
export declare const validator: WorkflowValidator;
|
|
92
|
+
//# sourceMappingURL=validator.d.ts.map
|