@oomol-lab/open-flow 0.1.0-beta.73 → 0.1.0-beta.74
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 +36 -0
- package/NOTICE +7 -0
- package/README.md +40 -0
- package/dist/browser/{createResourceDialog-BWJkjiOO.js → createResourceDialog-DI9pL-Yr.js} +2 -2
- package/dist/browser/{dialog-CUy_fwx9.js → dialog-BYJGvItc.js} +54 -19
- package/dist/browser/{flowChanges-CgSnSqqP.js → flowChanges-RL-H4CjD.js} +306 -48
- package/dist/browser/{flowWorkspace-Bf7H-r0t.js → flowWorkspace-BkDsETj0.js} +20745 -20186
- package/dist/browser/preview.css +73 -3
- package/dist/browser/preview.js +21410 -20607
- package/dist/browser/{typeScriptSession-B0hC-C8y.js → typeScriptSession-CSRwWmZm.js} +1 -1
- package/dist/browser/ui.css +72 -2
- package/dist/browser/workbench.css +73 -3
- package/dist/browser/workbench.js +14 -76
- package/dist/browser/{workbenchSelect-C3e4J93X.js → workbenchSelect-BcWPWGzw.js} +1 -1
- package/dist/command/index.js +34 -34
- package/dist/common/authoring.d.ts +1 -1
- package/dist/common/authoringFields.d.ts +1 -1
- package/dist/common/authoringSchema.d.ts +28 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.d.ts +1 -1
- package/dist/common/control-api-conformance.js +61 -24
- package/dist/common/control-api.d.ts +4 -3
- package/dist/common/control-api.js +59 -22
- package/dist/common/control-requests.d.ts +2 -1
- package/dist/common/control-requests.js +204 -42
- package/dist/common/cron-trigger.d.ts +1 -1
- package/dist/common/decision.d.ts +1 -1
- package/dist/common/draftOperations.d.ts +1 -1
- package/dist/common/engine-contract.d.ts +3 -2
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/flow-agent.d.ts +1 -1
- package/dist/{browser → common}/flow-authoring-node.d.ts +3 -3
- package/dist/{browser → common}/flow-authoring.js +75 -23
- package/dist/{browser → common}/flow-change-schema.d.ts +177 -6
- package/dist/{browser → common}/flow-change.d.ts +35 -15
- package/dist/{browser → common}/flow-change.js +77 -25
- package/dist/common/flow-connectionUsage.d.ts +1 -1
- package/dist/common/flow-encoding.d.ts +1 -1
- package/dist/common/flow-encoding.js +34 -16
- package/dist/common/flow-errorHandling.d.ts +1 -1
- package/dist/common/flow-graph.d.ts +1 -1
- package/dist/common/flow-modules.d.ts +1 -1
- package/dist/common/flow-promptTemplate.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +1 -1
- package/dist/common/flow-semantics.d.ts +1 -1
- package/dist/common/flow-semantics.js +151 -32
- package/dist/common/flow-workflowFile.d.ts +1 -1
- package/dist/common/flowInspection.d.ts +3 -3
- package/dist/common/integration-trigger.d.ts +1 -1
- package/dist/common/licenses.md +118 -1
- package/dist/common/liveDetails.d.ts +1 -1
- package/dist/common/mcp.d.ts +2 -1
- package/dist/common/mcp.js +59 -22
- package/dist/common/openapi.d.ts +1 -1
- package/dist/common/poll-trigger.d.ts +1 -1
- package/dist/common/run-results.d.ts +8 -1
- package/dist/common/runtime-contract.d.ts +8 -2
- package/dist/common/runtime-contract.js +22 -5
- package/dist/common/scheduler-checkpoint.d.ts +1 -1
- package/dist/common/scheduler-dependencies.d.ts +1 -1
- package/dist/common/scheduler-node-execution.d.ts +1 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +31 -12
- package/dist/common/trigger-catalog.d.ts +1 -1
- package/dist/common/trigger-config-options.d.ts +1 -1
- package/dist/common/trigger-config.d.ts +1 -1
- package/dist/common/trigger-contract.d.ts +2 -2
- package/dist/common/trigger-localization.d.ts +1 -1
- package/dist/common/webhook-response.d.ts +1 -1
- package/dist/common/webhook-trigger.d.ts +1 -1
- package/dist/common/workflow.d.ts +17 -1
- package/dist/common/workflow.js +68 -22
- package/dist/index.d.ts +6 -3
- package/package.json +7 -6
- package/src/base/common/json.ts +90 -0
- package/src/canvas/common/commands.ts +15 -0
- package/src/connector/common/actionSchema.ts +168 -0
- package/src/connector/common/proxy.ts +44 -0
- package/src/control/common/api.ts +1505 -0
- package/src/control/common/authoring.ts +912 -0
- package/src/control/common/authoringCondition.ts +110 -0
- package/src/control/common/authoringDiagnosticFields.ts +136 -0
- package/src/control/common/authoringExamples.ts +192 -0
- package/src/control/common/authoringFields.ts +53 -0
- package/src/control/common/authoringLlm.ts +70 -0
- package/src/control/common/authoringOpenApi.ts +129 -0
- package/src/control/common/authoringSchema.ts +404 -0
- package/src/control/common/authoringTools.ts +123 -0
- package/src/control/common/authoringTriggers.ts +26 -0
- package/src/control/common/checkDecoders.ts +65 -0
- package/src/control/common/conformance.ts +1989 -0
- package/src/control/common/connectorDecoders.ts +370 -0
- package/src/control/common/connectorQueries.ts +61 -0
- package/src/control/common/decoding.ts +60 -0
- package/src/control/common/draftOperations.ts +61 -0
- package/src/control/common/errors.ts +114 -0
- package/src/control/common/eventSourceSchemas.ts +13 -0
- package/src/control/common/eventSources.ts +186 -0
- package/src/control/common/flowDecoders.ts +153 -0
- package/src/control/common/flowInspection.ts +181 -0
- package/src/control/common/flowNotifications.ts +37 -0
- package/src/control/common/liveDetails.ts +124 -0
- package/src/control/common/mcp.ts +241 -0
- package/src/control/common/mcpConformance.ts +142 -0
- package/src/control/common/providerAccess.ts +28 -0
- package/src/control/common/providerIconSprite.ts +42 -0
- package/src/control/common/publicationDecoders.ts +98 -0
- package/src/control/common/random.ts +16 -0
- package/src/control/common/requests.ts +112 -0
- package/src/control/common/resultQuery.ts +8 -0
- package/src/control/common/results.ts +176 -0
- package/src/control/common/revisionDecoders.ts +52 -0
- package/src/control/common/runDecoders.ts +240 -0
- package/src/control/common/triggerCatalog.ts +89 -0
- package/src/control/common/triggerDecoders.ts +175 -0
- package/src/decision/common/decision.ts +168 -0
- package/src/event-source/common/catalog.generated.json +65 -0
- package/src/event-source/common/definition.ts +66 -0
- package/src/event-source/common/index.ts +99 -0
- package/src/execution/common/checkpoint.ts +311 -0
- package/src/execution/common/dependencies.ts +440 -0
- package/src/execution/common/engineContract.ts +80 -0
- package/src/execution/common/events.ts +328 -0
- package/src/execution/common/node-execution.ts +467 -0
- package/src/execution/common/runLifecycle.ts +250 -0
- package/src/execution/common/runtime.ts +563 -0
- package/src/execution/common/scheduler.ts +696 -0
- package/src/execution/common/wait.ts +36 -0
- package/src/flow/common/agent.ts +305 -0
- package/src/flow/common/authoring.ts +30 -0
- package/src/flow/common/change.ts +1036 -0
- package/src/flow/common/changeSchema.ts +783 -0
- package/src/flow/common/codePermissions.ts +2 -0
- package/src/flow/common/condition.ts +265 -0
- package/src/flow/common/connectionUsage.ts +131 -0
- package/src/flow/common/edgeChanges.ts +35 -0
- package/src/flow/common/encoding.ts +437 -0
- package/src/flow/common/errorHandling.ts +34 -0
- package/src/flow/common/graph.ts +892 -0
- package/src/flow/common/inputValue.ts +16 -0
- package/src/flow/common/json.ts +8 -0
- package/src/flow/common/moduleChanges.ts +31 -0
- package/src/flow/common/modules.ts +292 -0
- package/src/flow/common/nodeChanges.ts +762 -0
- package/src/flow/common/portChanges.ts +36 -0
- package/src/flow/common/promptTemplate.ts +15 -0
- package/src/flow/common/retry.ts +20 -0
- package/src/flow/common/schema.ts +162 -0
- package/src/flow/common/schemaCompare.ts +176 -0
- package/src/flow/common/schemaComparer.ts +178 -0
- package/src/flow/common/schemaKeywords.ts +53 -0
- package/src/flow/common/semantics.ts +474 -0
- package/src/flow/common/sourceField.ts +35 -0
- package/src/flow/common/triggerScheduleSchema.ts +8 -0
- package/src/flow/common/wait.ts +30 -0
- package/src/flow/common/webhookMethod.ts +7 -0
- package/src/flow/common/webhookResponse.ts +75 -0
- package/src/flow/common/workflowFile.ts +97 -0
- package/src/json-schema-subset/checker/array.ts +142 -0
- package/src/json-schema-subset/checker/cache.ts +57 -0
- package/src/json-schema-subset/checker/checker.ts +230 -0
- package/src/json-schema-subset/checker/enumAndConst.ts +113 -0
- package/src/json-schema-subset/checker/equals.ts +93 -0
- package/src/json-schema-subset/checker/numeric/checker.ts +50 -0
- package/src/json-schema-subset/checker/numeric/float.ts +121 -0
- package/src/json-schema-subset/checker/numeric/index.ts +1 -0
- package/src/json-schema-subset/checker/numeric/integer.ts +119 -0
- package/src/json-schema-subset/checker/numeric/integerNormalizer.ts +72 -0
- package/src/json-schema-subset/checker/object.ts +354 -0
- package/src/json-schema-subset/checker/range.ts +91 -0
- package/src/json-schema-subset/checker/string.ts +60 -0
- package/src/json-schema-subset/checker/tools/index.ts +3 -0
- package/src/json-schema-subset/checker/tools/mark.ts +82 -0
- package/src/json-schema-subset/checker/tools/quantum.ts +106 -0
- package/src/json-schema-subset/checker/tools/range.ts +210 -0
- package/src/json-schema-subset/checker/validator.ts +23 -0
- package/src/json-schema-subset/compiler/array.ts +163 -0
- package/src/json-schema-subset/compiler/combination.ts +109 -0
- package/src/json-schema-subset/compiler/common.ts +99 -0
- package/src/json-schema-subset/compiler/compiler.ts +188 -0
- package/src/json-schema-subset/compiler/enumAndConst.ts +75 -0
- package/src/json-schema-subset/compiler/index.ts +11 -0
- package/src/json-schema-subset/compiler/object.ts +411 -0
- package/src/json-schema-subset/compiler/primitive.ts +144 -0
- package/src/json-schema-subset/compiler/utils.ts +24 -0
- package/src/json-schema-subset/compiler/wrapper.ts +192 -0
- package/src/json-schema-subset/error.ts +55 -0
- package/src/json-schema-subset/expression/calculator.ts +442 -0
- package/src/json-schema-subset/expression/combination.ts +49 -0
- package/src/json-schema-subset/expression/expression.ts +191 -0
- package/src/json-schema-subset/expression/index.ts +25 -0
- package/src/json-schema-subset/expression/result.ts +88 -0
- package/src/json-schema-subset/expression/types.ts +36 -0
- package/src/json-schema-subset/extends/extendsContext.ts +89 -0
- package/src/json-schema-subset/extends/index.ts +2 -0
- package/src/json-schema-subset/extends/types.ts +12 -0
- package/src/json-schema-subset/global.ts +60 -0
- package/src/json-schema-subset/index.ts +8 -0
- package/src/json-schema-subset/preprocessing.ts +74 -0
- package/src/json-schema-subset/types.ts +8 -0
- package/src/json-schema-subset/utils.ts +95 -0
- package/src/localization/common/languages.ts +118 -0
- package/src/localization/common/timeZone.ts +25 -0
- package/src/openapi/common/authBindings.ts +12 -0
- package/src/openapi/common/openapi.ts +459 -0
- package/src/trigger/common/config.ts +56 -0
- package/src/trigger/common/configOptions.ts +15 -0
- package/src/trigger/common/configSchema.ts +8 -0
- package/src/trigger/common/contract.ts +132 -0
- package/src/trigger/common/cron.ts +151 -0
- package/src/trigger/common/integration.ts +498 -0
- package/src/trigger/common/poll.ts +187 -0
- package/src/trigger/common/webhook.ts +412 -0
- package/src/trigger/providers/airtable/locales/fr.json +18 -0
- package/src/trigger/providers/airtable/locales/ja.json +18 -0
- package/src/trigger/providers/airtable/locales/ko.json +18 -0
- package/src/trigger/providers/airtable/locales/ru.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-CN.json +18 -0
- package/src/trigger/providers/airtable/locales/zh-TW.json +18 -0
- package/src/trigger/providers/asana/locales/fr.json +15 -0
- package/src/trigger/providers/asana/locales/ja.json +15 -0
- package/src/trigger/providers/asana/locales/ko.json +15 -0
- package/src/trigger/providers/asana/locales/ru.json +15 -0
- package/src/trigger/providers/asana/locales/zh-CN.json +15 -0
- package/src/trigger/providers/asana/locales/zh-TW.json +15 -0
- package/src/trigger/providers/calendly/locales/fr.json +16 -0
- package/src/trigger/providers/calendly/locales/ja.json +16 -0
- package/src/trigger/providers/calendly/locales/ko.json +16 -0
- package/src/trigger/providers/calendly/locales/ru.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-CN.json +16 -0
- package/src/trigger/providers/calendly/locales/zh-TW.json +16 -0
- package/src/trigger/providers/catalog.generated.json +4996 -0
- package/src/trigger/providers/clickup/locales/fr.json +16 -0
- package/src/trigger/providers/clickup/locales/ja.json +16 -0
- package/src/trigger/providers/clickup/locales/ko.json +16 -0
- package/src/trigger/providers/clickup/locales/ru.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-CN.json +16 -0
- package/src/trigger/providers/clickup/locales/zh-TW.json +16 -0
- package/src/trigger/providers/definitions.ts +19 -0
- package/src/trigger/providers/feishu/locales/fr.json +20 -0
- package/src/trigger/providers/feishu/locales/ja.json +20 -0
- package/src/trigger/providers/feishu/locales/ko.json +20 -0
- package/src/trigger/providers/feishu/locales/ru.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-CN.json +20 -0
- package/src/trigger/providers/feishu/locales/zh-TW.json +20 -0
- package/src/trigger/providers/fieldDescriptions.ts +392 -0
- package/src/trigger/providers/fieldLabels.ts +256 -0
- package/src/trigger/providers/fireflies/locales/fr.json +17 -0
- package/src/trigger/providers/fireflies/locales/ja.json +17 -0
- package/src/trigger/providers/fireflies/locales/ko.json +17 -0
- package/src/trigger/providers/fireflies/locales/ru.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-CN.json +17 -0
- package/src/trigger/providers/fireflies/locales/zh-TW.json +17 -0
- package/src/trigger/providers/github/locales/fr.json +30 -0
- package/src/trigger/providers/github/locales/ja.json +30 -0
- package/src/trigger/providers/github/locales/ko.json +30 -0
- package/src/trigger/providers/github/locales/ru.json +30 -0
- package/src/trigger/providers/github/locales/zh-CN.json +30 -0
- package/src/trigger/providers/github/locales/zh-TW.json +30 -0
- package/src/trigger/providers/gitlab/locales/fr.json +18 -0
- package/src/trigger/providers/gitlab/locales/ja.json +18 -0
- package/src/trigger/providers/gitlab/locales/ko.json +18 -0
- package/src/trigger/providers/gitlab/locales/ru.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gitlab/locales/zh-TW.json +18 -0
- package/src/trigger/providers/gmail/locales/fr.json +18 -0
- package/src/trigger/providers/gmail/locales/ja.json +18 -0
- package/src/trigger/providers/gmail/locales/ko.json +18 -0
- package/src/trigger/providers/gmail/locales/ru.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-CN.json +18 -0
- package/src/trigger/providers/gmail/locales/zh-TW.json +18 -0
- package/src/trigger/providers/google-calendar/locales/fr.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ja.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ko.json +15 -0
- package/src/trigger/providers/google-calendar/locales/ru.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-CN.json +15 -0
- package/src/trigger/providers/google-calendar/locales/zh-TW.json +15 -0
- package/src/trigger/providers/google-drive/locales/fr.json +48 -0
- package/src/trigger/providers/google-drive/locales/ja.json +48 -0
- package/src/trigger/providers/google-drive/locales/ko.json +48 -0
- package/src/trigger/providers/google-drive/locales/ru.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-CN.json +48 -0
- package/src/trigger/providers/google-drive/locales/zh-TW.json +48 -0
- package/src/trigger/providers/google-sheets/locales/fr.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ja.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ko.json +19 -0
- package/src/trigger/providers/google-sheets/locales/ru.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-CN.json +19 -0
- package/src/trigger/providers/google-sheets/locales/zh-TW.json +19 -0
- package/src/trigger/providers/intercom/locales/fr.json +17 -0
- package/src/trigger/providers/intercom/locales/ja.json +17 -0
- package/src/trigger/providers/intercom/locales/ko.json +17 -0
- package/src/trigger/providers/intercom/locales/ru.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/intercom/locales/zh-TW.json +17 -0
- package/src/trigger/providers/jira/locales/fr.json +17 -0
- package/src/trigger/providers/jira/locales/ja.json +17 -0
- package/src/trigger/providers/jira/locales/ko.json +17 -0
- package/src/trigger/providers/jira/locales/ru.json +17 -0
- package/src/trigger/providers/jira/locales/zh-CN.json +17 -0
- package/src/trigger/providers/jira/locales/zh-TW.json +17 -0
- package/src/trigger/providers/linear/locales/fr.json +13 -0
- package/src/trigger/providers/linear/locales/ja.json +13 -0
- package/src/trigger/providers/linear/locales/ko.json +13 -0
- package/src/trigger/providers/linear/locales/ru.json +13 -0
- package/src/trigger/providers/linear/locales/zh-CN.json +13 -0
- package/src/trigger/providers/linear/locales/zh-TW.json +13 -0
- package/src/trigger/providers/locales/fr.ts +71 -0
- package/src/trigger/providers/locales/ja.ts +71 -0
- package/src/trigger/providers/locales/ko.ts +71 -0
- package/src/trigger/providers/locales/ru.ts +71 -0
- package/src/trigger/providers/locales/zh-CN.ts +71 -0
- package/src/trigger/providers/locales/zh-TW.ts +71 -0
- package/src/trigger/providers/localization.ts +59 -0
- package/src/trigger/providers/notion/locales/fr.json +16 -0
- package/src/trigger/providers/notion/locales/ja.json +16 -0
- package/src/trigger/providers/notion/locales/ko.json +16 -0
- package/src/trigger/providers/notion/locales/ru.json +16 -0
- package/src/trigger/providers/notion/locales/zh-CN.json +16 -0
- package/src/trigger/providers/notion/locales/zh-TW.json +16 -0
- package/src/trigger/providers/one-drive/locales/fr.json +16 -0
- package/src/trigger/providers/one-drive/locales/ja.json +16 -0
- package/src/trigger/providers/one-drive/locales/ko.json +16 -0
- package/src/trigger/providers/one-drive/locales/ru.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-CN.json +16 -0
- package/src/trigger/providers/one-drive/locales/zh-TW.json +16 -0
- package/src/trigger/providers/outlook/locales/fr.json +18 -0
- package/src/trigger/providers/outlook/locales/ja.json +18 -0
- package/src/trigger/providers/outlook/locales/ko.json +18 -0
- package/src/trigger/providers/outlook/locales/ru.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-CN.json +18 -0
- package/src/trigger/providers/outlook/locales/zh-TW.json +18 -0
- package/src/trigger/providers/pandadoc/locales/fr.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ja.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ko.json +12 -0
- package/src/trigger/providers/pandadoc/locales/ru.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-CN.json +12 -0
- package/src/trigger/providers/pandadoc/locales/zh-TW.json +12 -0
- package/src/trigger/providers/pipedrive/locales/fr.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ja.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ko.json +15 -0
- package/src/trigger/providers/pipedrive/locales/ru.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-CN.json +15 -0
- package/src/trigger/providers/pipedrive/locales/zh-TW.json +15 -0
- package/src/trigger/providers/remote.ts +163 -0
- package/src/trigger/providers/resend/locales/fr.json +16 -0
- package/src/trigger/providers/resend/locales/ja.json +16 -0
- package/src/trigger/providers/resend/locales/ko.json +16 -0
- package/src/trigger/providers/resend/locales/ru.json +16 -0
- package/src/trigger/providers/resend/locales/zh-CN.json +16 -0
- package/src/trigger/providers/resend/locales/zh-TW.json +16 -0
- package/src/trigger/providers/sentry/locales/fr.json +19 -0
- package/src/trigger/providers/sentry/locales/ja.json +19 -0
- package/src/trigger/providers/sentry/locales/ko.json +19 -0
- package/src/trigger/providers/sentry/locales/ru.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-CN.json +19 -0
- package/src/trigger/providers/sentry/locales/zh-TW.json +19 -0
- package/src/trigger/providers/shopify/locales/fr.json +18 -0
- package/src/trigger/providers/shopify/locales/ja.json +18 -0
- package/src/trigger/providers/shopify/locales/ko.json +18 -0
- package/src/trigger/providers/shopify/locales/ru.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-CN.json +18 -0
- package/src/trigger/providers/shopify/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slack/locales/fr.json +18 -0
- package/src/trigger/providers/slack/locales/ja.json +18 -0
- package/src/trigger/providers/slack/locales/ko.json +18 -0
- package/src/trigger/providers/slack/locales/ru.json +18 -0
- package/src/trigger/providers/slack/locales/zh-CN.json +18 -0
- package/src/trigger/providers/slack/locales/zh-TW.json +18 -0
- package/src/trigger/providers/slackbot/locales/fr.json +23 -0
- package/src/trigger/providers/slackbot/locales/ja.json +23 -0
- package/src/trigger/providers/slackbot/locales/ko.json +23 -0
- package/src/trigger/providers/slackbot/locales/ru.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-CN.json +23 -0
- package/src/trigger/providers/slackbot/locales/zh-TW.json +23 -0
- package/src/trigger/providers/source-events.ts +25 -0
- package/src/trigger/providers/stripe/locales/fr.json +17 -0
- package/src/trigger/providers/stripe/locales/ja.json +17 -0
- package/src/trigger/providers/stripe/locales/ko.json +17 -0
- package/src/trigger/providers/stripe/locales/ru.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-CN.json +17 -0
- package/src/trigger/providers/stripe/locales/zh-TW.json +17 -0
- package/src/trigger/providers/tally/locales/fr.json +12 -0
- package/src/trigger/providers/tally/locales/ja.json +12 -0
- package/src/trigger/providers/tally/locales/ko.json +12 -0
- package/src/trigger/providers/tally/locales/ru.json +12 -0
- package/src/trigger/providers/tally/locales/zh-CN.json +12 -0
- package/src/trigger/providers/tally/locales/zh-TW.json +12 -0
- package/src/trigger/providers/telegram/locales/fr.json +17 -0
- package/src/trigger/providers/telegram/locales/ja.json +17 -0
- package/src/trigger/providers/telegram/locales/ko.json +17 -0
- package/src/trigger/providers/telegram/locales/ru.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-CN.json +17 -0
- package/src/trigger/providers/telegram/locales/zh-TW.json +17 -0
- package/src/trigger/providers/typeform/locales/fr.json +12 -0
- package/src/trigger/providers/typeform/locales/ja.json +12 -0
- package/src/trigger/providers/typeform/locales/ko.json +12 -0
- package/src/trigger/providers/typeform/locales/ru.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-CN.json +12 -0
- package/src/trigger/providers/typeform/locales/zh-TW.json +12 -0
- package/src/trigger/providers/vercel/locales/fr.json +18 -0
- package/src/trigger/providers/vercel/locales/ja.json +18 -0
- package/src/trigger/providers/vercel/locales/ko.json +18 -0
- package/src/trigger/providers/vercel/locales/ru.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-CN.json +18 -0
- package/src/trigger/providers/vercel/locales/zh-TW.json +18 -0
- package/src/trigger/providers/woocommerce/locales/fr.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ja.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ko.json +19 -0
- package/src/trigger/providers/woocommerce/locales/ru.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-CN.json +19 -0
- package/src/trigger/providers/woocommerce/locales/zh-TW.json +19 -0
- package/src/trigger/providers/zendesk/locales/fr.json +15 -0
- package/src/trigger/providers/zendesk/locales/ja.json +15 -0
- package/src/trigger/providers/zendesk/locales/ko.json +15 -0
- package/src/trigger/providers/zendesk/locales/ru.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-CN.json +15 -0
- package/src/trigger/providers/zendesk/locales/zh-TW.json +15 -0
- package/src/trigger/providers/zoom/locales/fr.json +17 -0
- package/src/trigger/providers/zoom/locales/ja.json +17 -0
- package/src/trigger/providers/zoom/locales/ko.json +17 -0
- package/src/trigger/providers/zoom/locales/ru.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-CN.json +17 -0
- package/src/trigger/providers/zoom/locales/zh-TW.json +17 -0
- package/src/types/index.ts +112 -0
- package/src/workflow/common/workflow.ts +273 -0
- package/dist/browser/lib-DrKav3HG.js +0 -11403
- /package/dist/{browser → common}/flow-authoring-edge.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring-module.d.ts +0 -0
- /package/dist/{browser → common}/flow-authoring.d.ts +0 -0
- /package/dist/{browser → common}/flow-input-value.d.ts +0 -0
- /package/dist/{browser → common}/webhook-method.d.ts +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { JsonValue, ManagedTaskDefinition } from '../../flow/common/change.ts'
|
|
2
|
+
import type { OpenApiAuth, OpenApiExecutor } from '../../openapi/common/openapi.ts'
|
|
3
|
+
|
|
4
|
+
import { dequal } from 'dequal/lite'
|
|
5
|
+
import { z } from 'zod'
|
|
6
|
+
import { httpUrl, openApiTask, securityOptions, selectOperation, serverAddress, servers, snapshot } from '../../openapi/common/openapi.ts'
|
|
7
|
+
|
|
8
|
+
const authenticationSchema = z.union([
|
|
9
|
+
z.strictObject({
|
|
10
|
+
schemes: z.array(z.string().min(1)).describe('One complete security alternative advertised by this operation; [] selects no authentication.'),
|
|
11
|
+
}),
|
|
12
|
+
z.strictObject({ type: z.enum(['bearer', 'basic']) }),
|
|
13
|
+
z.strictObject({ type: z.literal('apiKey'), name: z.string().min(1), in: z.enum(['header', 'query']) }),
|
|
14
|
+
])
|
|
15
|
+
|
|
16
|
+
export const authoringOpenApiSchema = z.strictObject({
|
|
17
|
+
sourceUrl: z.string().min(1),
|
|
18
|
+
path: z.string().min(1),
|
|
19
|
+
method: z.string().min(1),
|
|
20
|
+
serverUrl: z.string().optional(),
|
|
21
|
+
authentication: authenticationSchema.optional().describe('Omit to use the operation default. Bind credentials through the advertised node inputs.'),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
export type AuthoringOpenApiConfig = z.infer<typeof authoringOpenApiSchema>
|
|
25
|
+
|
|
26
|
+
export function openApiAuthenticationChoices(config: OpenApiExecutor) {
|
|
27
|
+
try {
|
|
28
|
+
return securityOptions(config.document, config.path, config.method).map(({ label, auth, error }) =>
|
|
29
|
+
Object.assign({ label }, auth == null ? { error } : { authentication: { schemes: auth.map((item) => item.id) } }),
|
|
30
|
+
)
|
|
31
|
+
} catch (error) {
|
|
32
|
+
// Reading an incomplete saved draft must not require a valid operation snapshot.
|
|
33
|
+
return [{ label: 'Saved operation', error: (error as Error).message }]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function authenticationView(config: OpenApiExecutor): NonNullable<AuthoringOpenApiConfig['authentication']> {
|
|
38
|
+
const schemes = config.auth.map((item) => item.id)
|
|
39
|
+
const declared = openApiAuthenticationChoices(config).some((option) => 'authentication' in option && dequal(option.authentication?.schemes, schemes))
|
|
40
|
+
if (!declared && config.auth.length == 1) {
|
|
41
|
+
const { id: _id, ...manual } = config.auth[0]!
|
|
42
|
+
return manual as NonNullable<AuthoringOpenApiConfig['authentication']>
|
|
43
|
+
}
|
|
44
|
+
return { schemes }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function openApiConfigView(config: OpenApiExecutor): AuthoringOpenApiConfig {
|
|
48
|
+
return {
|
|
49
|
+
sourceUrl: config.sourceUrl,
|
|
50
|
+
path: config.path,
|
|
51
|
+
method: config.method,
|
|
52
|
+
serverUrl: config.serverUrl,
|
|
53
|
+
authentication: authenticationView(config),
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class AuthoringOpenApiAuthenticationError extends Error {
|
|
58
|
+
readonly code = 'openapi.authentication-invalid'
|
|
59
|
+
readonly details: { field: string; choices: ReturnType<typeof openApiAuthenticationChoices> }
|
|
60
|
+
constructor(config: OpenApiExecutor) {
|
|
61
|
+
super('Choose one complete authentication alternative advertised by this operation, or configure manual authentication.')
|
|
62
|
+
this.name = 'AuthoringOpenApiAuthenticationError'
|
|
63
|
+
this.details = { field: 'config.authentication', choices: openApiAuthenticationChoices(config) }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function prepareAuthentication(config: OpenApiExecutor, choice: NonNullable<AuthoringOpenApiConfig['authentication']>): readonly OpenApiAuth[] {
|
|
68
|
+
if (!('schemes' in choice)) return [{ id: 'manual', ...choice }]
|
|
69
|
+
const names = new Set(choice.schemes)
|
|
70
|
+
const matched = securityOptions(config.document, config.path, config.method).find(
|
|
71
|
+
(option) =>
|
|
72
|
+
option.auth != null && names.size == choice.schemes.length && option.auth.length == names.size && option.auth.every((auth) => names.has(auth.id)),
|
|
73
|
+
)
|
|
74
|
+
if (matched?.auth == null) throw new AuthoringOpenApiAuthenticationError(config)
|
|
75
|
+
return matched.auth
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Operation snapshots and credential handles remain stable until their business selection changes. */
|
|
79
|
+
export async function prepareOpenApiTask(
|
|
80
|
+
config: AuthoringOpenApiConfig,
|
|
81
|
+
previous: ManagedTaskDefinition | undefined,
|
|
82
|
+
fetch: (url: string) => Promise<JsonValue>,
|
|
83
|
+
name: string,
|
|
84
|
+
explicit: { authentication?: boolean; serverUrl?: boolean } = {},
|
|
85
|
+
): Promise<ManagedTaskDefinition> {
|
|
86
|
+
const current = previous?.executor.kind == 'openapi' ? previous.executor : undefined
|
|
87
|
+
const changed = current == null || config.sourceUrl != current.sourceUrl || config.path != current.path || config.method != current.method
|
|
88
|
+
const authentication = changed && current != null && !explicit.authentication ? undefined : config.authentication
|
|
89
|
+
let selected: OpenApiExecutor
|
|
90
|
+
if (!changed) selected = current
|
|
91
|
+
else {
|
|
92
|
+
const document = await fetch(config.sourceUrl)
|
|
93
|
+
if (authentication != null && !('schemes' in authentication)) {
|
|
94
|
+
// Manual access tokens also support operations whose declared OAuth scheme is unsupported.
|
|
95
|
+
const saved = snapshot(document, config.path, config.method)
|
|
96
|
+
selected = {
|
|
97
|
+
kind: 'openapi',
|
|
98
|
+
sourceUrl: httpUrl(config.sourceUrl),
|
|
99
|
+
path: config.path,
|
|
100
|
+
method: config.method,
|
|
101
|
+
serverUrl: serverAddress(servers(saved, config.path, config.method)[0]!, config.sourceUrl),
|
|
102
|
+
document: saved,
|
|
103
|
+
auth: [],
|
|
104
|
+
}
|
|
105
|
+
} else selected = selectOperation(document, config.sourceUrl, config.path, config.method)
|
|
106
|
+
}
|
|
107
|
+
const defaultAuth = () => {
|
|
108
|
+
const defaultSelection = securityOptions(current!.document, current!.path, current!.method).find((option) => option.auth != null)?.auth
|
|
109
|
+
if (defaultSelection == null) throw new AuthoringOpenApiAuthenticationError(current!)
|
|
110
|
+
return defaultSelection
|
|
111
|
+
}
|
|
112
|
+
const auth =
|
|
113
|
+
authentication == null
|
|
114
|
+
? !changed && explicit.authentication
|
|
115
|
+
? defaultAuth()
|
|
116
|
+
: selected.auth
|
|
117
|
+
: !changed && dequal(authentication, authenticationView(current))
|
|
118
|
+
? current.auth
|
|
119
|
+
: prepareAuthentication(selected, authentication)
|
|
120
|
+
const serverUrl =
|
|
121
|
+
!changed && explicit.serverUrl && config.serverUrl == null
|
|
122
|
+
? serverAddress(servers(current.document, current.path, current.method)[0]!, current.sourceUrl)
|
|
123
|
+
: changed && current != null && !explicit.serverUrl
|
|
124
|
+
? selected.serverUrl
|
|
125
|
+
: (config.serverUrl ?? selected.serverUrl)
|
|
126
|
+
const executor = { ...selected, auth, serverUrl }
|
|
127
|
+
if (previous != null && !changed && dequal(auth, current.auth)) return { ...previous, name, executor }
|
|
128
|
+
return openApiTask(executor, name)
|
|
129
|
+
}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import type { JsonValue } from '../../types/index.ts'
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import {
|
|
5
|
+
agentToolFields,
|
|
6
|
+
connectorAgentToolSchema,
|
|
7
|
+
workflowAgentToolSchema,
|
|
8
|
+
connectorCapabilitySchema,
|
|
9
|
+
authoringDefinitionSchemas as definitions,
|
|
10
|
+
} from '../../flow/common/changeSchema.ts'
|
|
11
|
+
import { retryConfigurationSchema, retryNodeTypes } from '../../flow/common/retry.ts'
|
|
12
|
+
import { authoringLlmConfiguration } from './authoringLlm.ts'
|
|
13
|
+
import { authoringOpenApiSchema } from './authoringOpenApi.ts'
|
|
14
|
+
|
|
15
|
+
const id = z.string().min(1)
|
|
16
|
+
const json = z.json()
|
|
17
|
+
const patch = z.record(id, json)
|
|
18
|
+
export const authoringTypes = [
|
|
19
|
+
'start',
|
|
20
|
+
'outputs',
|
|
21
|
+
'webhook-response',
|
|
22
|
+
'workflow',
|
|
23
|
+
'webhook',
|
|
24
|
+
'cron',
|
|
25
|
+
'error',
|
|
26
|
+
'poll',
|
|
27
|
+
'integration',
|
|
28
|
+
'code',
|
|
29
|
+
'connector',
|
|
30
|
+
'agent',
|
|
31
|
+
'llm',
|
|
32
|
+
'decision',
|
|
33
|
+
'openapi',
|
|
34
|
+
'condition',
|
|
35
|
+
'value',
|
|
36
|
+
'wait',
|
|
37
|
+
'approval',
|
|
38
|
+
] as const
|
|
39
|
+
const type = z.enum(authoringTypes)
|
|
40
|
+
export type AuthoringType = z.infer<typeof type>
|
|
41
|
+
const referenceSchema = id.describe(
|
|
42
|
+
'An existing node reference returned by read/search, or $alias for a preceding node.add in this edit batch. For node.add.as "step", reference "$step", never bare "step". Aliases are local to one batch.',
|
|
43
|
+
)
|
|
44
|
+
const output = z.strictObject({
|
|
45
|
+
kind: z.literal('output'),
|
|
46
|
+
node: referenceSchema,
|
|
47
|
+
port: id.optional().describe('Omit for a node with one output. For multiple outputs, choose a name from node details.'),
|
|
48
|
+
field: z.string().optional(),
|
|
49
|
+
})
|
|
50
|
+
const system = z.strictObject({ kind: z.literal('system'), node: referenceSchema, port: z.literal('error'), field: z.string().optional() })
|
|
51
|
+
const variable = z.strictObject({ kind: z.literal('variable'), name: id })
|
|
52
|
+
export const authoringSourceSchema = z.union([
|
|
53
|
+
output,
|
|
54
|
+
system,
|
|
55
|
+
variable,
|
|
56
|
+
z.strictObject({ kind: z.literal('value'), value: json }),
|
|
57
|
+
z.strictObject({ kind: z.literal('unset') }),
|
|
58
|
+
z.strictObject({ kind: z.literal('default') }),
|
|
59
|
+
z.strictObject({ kind: z.literal('sources'), sources: z.array(z.union([output, system, variable])).min(1) }),
|
|
60
|
+
])
|
|
61
|
+
const operand = z.union([z.strictObject({ kind: z.literal('value'), value: json.optional(), schema: json.optional() }), output, system, variable])
|
|
62
|
+
const toolSources = z
|
|
63
|
+
.record(id, agentToolFields.inputs.element.shape.source)
|
|
64
|
+
.optional()
|
|
65
|
+
.describe(
|
|
66
|
+
'Tool input sources by name. The platform resolves types from the selected Action or workflow. New inputs default to model-provided; omitted existing sources are preserved.',
|
|
67
|
+
)
|
|
68
|
+
const agentTool = z.union([
|
|
69
|
+
workflowAgentToolSchema.omit({ id: true, inputs: true, outputs: true, revisionId: true }).extend({ inputs: toolSources }).strict(),
|
|
70
|
+
connectorAgentToolSchema.omit({ id: true, inputs: true }).extend({ inputs: toolSources }).strict(),
|
|
71
|
+
])
|
|
72
|
+
const authoringCapabilities = z.array(z.union([connectorCapabilitySchema, z.strictObject({ kind: z.literal('workflow'), name: id, flowId: id })]))
|
|
73
|
+
const notification = z.strictObject({
|
|
74
|
+
...definitions.connector.shape,
|
|
75
|
+
messageHandle: id,
|
|
76
|
+
inputs: z.record(id, z.union([z.strictObject({ kind: z.literal('value'), value: json }), z.strictObject({ kind: z.literal('input'), input: id })])),
|
|
77
|
+
})
|
|
78
|
+
const field = z.strictObject({ schema: json.optional(), nullable: z.boolean().optional(), description: z.string().optional() })
|
|
79
|
+
const inputFields = z
|
|
80
|
+
.record(id, field.extend({ default: json.optional() }))
|
|
81
|
+
.describe(
|
|
82
|
+
'Optional business input constraints by name. A binding to a new Code, Agent, LLM, Wait or Approval input automatically declares an input accepting any JSON. Existing constraints are preserved. Omitted schema accepts any JSON; omitted nullable is true. Use default for inherited values; input.set supplies data.',
|
|
83
|
+
)
|
|
84
|
+
export const flowInputFields = z
|
|
85
|
+
.record(id, field)
|
|
86
|
+
.describe(
|
|
87
|
+
'Workflow input definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Supply call values as trigger.outputs.',
|
|
88
|
+
)
|
|
89
|
+
export const flowOutputFields = flowInputFields.describe(
|
|
90
|
+
'Workflow output definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Set values on the Outputs node with input.set or node.add.inputs.',
|
|
91
|
+
)
|
|
92
|
+
export const flowInputFieldsView = z.record(id, field.extend({ schema: json as z.ZodType<JsonValue>, nullable: z.boolean() }))
|
|
93
|
+
const outputFields = z.record(id, field).describe('Code return fields by name. Omitted schema accepts any JSON; omitted nullable is true.')
|
|
94
|
+
const expression = z.strictObject({
|
|
95
|
+
left: operand,
|
|
96
|
+
operator: definitions.condition.shape.cases.element.shape.groups.element.shape.expressions.element.shape.operator,
|
|
97
|
+
right: operand.optional(),
|
|
98
|
+
})
|
|
99
|
+
const all = z.strictObject({ all: z.array(expression) })
|
|
100
|
+
const when = z.union([expression, all, z.strictObject({ any: z.array(z.union([expression, all])) })])
|
|
101
|
+
export const authoringConfigurations = {
|
|
102
|
+
'webhook-response': z.strictObject({}),
|
|
103
|
+
'workflow': z.strictObject({ flowId: id }),
|
|
104
|
+
'start': z.strictObject({ inputDefs: flowInputFields.default({}) }),
|
|
105
|
+
'outputs': z.strictObject({ outputDefs: flowOutputFields.default({}) }),
|
|
106
|
+
'error': z.strictObject({ sourceFlowIds: z.array(id).optional() }),
|
|
107
|
+
'webhook': definitions.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
|
|
108
|
+
'cron': z.strictObject({ schedule: definitions.schedule }),
|
|
109
|
+
'poll': z.strictObject({ key: id, connectionId: id.optional(), schedule: definitions.schedule }),
|
|
110
|
+
'integration': z.strictObject({ key: id, connectionId: id.optional() }),
|
|
111
|
+
'code': z.strictObject({ inputs: inputFields, outputs: outputFields, capabilities: authoringCapabilities.optional() }),
|
|
112
|
+
'connector': definitions.connector.omit({ outputMode: true }).strict(),
|
|
113
|
+
'openapi': authoringOpenApiSchema,
|
|
114
|
+
'agent': definitions.agent
|
|
115
|
+
.omit({ prompt: true, tools: true })
|
|
116
|
+
.extend({
|
|
117
|
+
inputs: inputFields,
|
|
118
|
+
resultSchema: json.describe('JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port.'),
|
|
119
|
+
tools: z.array(agentTool),
|
|
120
|
+
notification: notification.optional(),
|
|
121
|
+
})
|
|
122
|
+
.strict(),
|
|
123
|
+
'llm': authoringLlmConfiguration.extend({ inputs: inputFields }),
|
|
124
|
+
'decision': definitions.decision,
|
|
125
|
+
'condition': z.strictObject({ match: z.enum(['first', 'all']), branches: z.array(z.strictObject({ name: id, description: z.string().optional(), when })) }),
|
|
126
|
+
'value': z.strictObject({ values: patch, outputs: outputFields }),
|
|
127
|
+
'wait': z.strictObject({
|
|
128
|
+
inputs: inputFields,
|
|
129
|
+
autoContinue: definitions.waitAutoContinue
|
|
130
|
+
.optional()
|
|
131
|
+
.describe(
|
|
132
|
+
'Wait only. Omit to disable; clear config.autoContinue to remove. after counts from each wait registration; at requires an explicit offset and continues immediately if already past. Optional timezone preserves the editor zone; at remains the absolute instant. Server requires the deadline to precede the 7-day expiry.',
|
|
133
|
+
),
|
|
134
|
+
}),
|
|
135
|
+
'approval': z.strictObject({ inputs: inputFields }),
|
|
136
|
+
}
|
|
137
|
+
const metadata = {
|
|
138
|
+
onError: z.enum(['stop', 'error']).optional(),
|
|
139
|
+
name: id.optional(),
|
|
140
|
+
description: z.string().optional(),
|
|
141
|
+
icon: z.string().optional(),
|
|
142
|
+
maxExecutions: z.int().positive().optional(),
|
|
143
|
+
timeoutMs: z.number().nonnegative().optional(),
|
|
144
|
+
retry: retryConfigurationSchema
|
|
145
|
+
.partial()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe(
|
|
148
|
+
'Node retry policy for Code, Connector, OpenAPI, LLM and AI Decision. Omitted update fields preserve the policy; use clear: [["retry"]] to disable it. maxRetries counts additional attempts; intervalMs is 1000–60000 in whole seconds.',
|
|
149
|
+
),
|
|
150
|
+
}
|
|
151
|
+
const updates = z.strictObject({
|
|
152
|
+
...metadata,
|
|
153
|
+
config: patch
|
|
154
|
+
.optional()
|
|
155
|
+
.describe(
|
|
156
|
+
'Recursively merge configuration; omitted fields remain unchanged and arrays replace as a whole. This includes schema objects: {} does not clear an existing schema. Use clear paths to remove fields, e.g. ["config","inputs","amount","schema","type"].',
|
|
157
|
+
),
|
|
158
|
+
})
|
|
159
|
+
export const authoringEditSchema = z.discriminatedUnion('op', [
|
|
160
|
+
z.strictObject({
|
|
161
|
+
op: z.literal('node.add'),
|
|
162
|
+
as: id
|
|
163
|
+
.regex(/^[A-Za-z][\w-]*$/)
|
|
164
|
+
.describe('Unique batch-local alias without the $ prefix. Later edits must reference this new node as $alias; the bare alias is not its node ID.'),
|
|
165
|
+
type,
|
|
166
|
+
name: id,
|
|
167
|
+
onError: z.enum(['stop', 'error']).optional(),
|
|
168
|
+
retry: retryConfigurationSchema.optional(),
|
|
169
|
+
config: patch.optional(),
|
|
170
|
+
inputs: z
|
|
171
|
+
.record(id, authoringSourceSchema)
|
|
172
|
+
.optional()
|
|
173
|
+
.describe('Input data sources, applied after creation, as input.set operations. Execution edges are separate.'),
|
|
174
|
+
code: z.string().optional(),
|
|
175
|
+
prompt: z.string().optional(),
|
|
176
|
+
}),
|
|
177
|
+
z.strictObject({ op: z.literal('node.update'), node: referenceSchema, set: updates.optional(), clear: z.array(z.array(id).min(1)).optional() }),
|
|
178
|
+
z.strictObject({
|
|
179
|
+
op: z.literal('node.refresh'),
|
|
180
|
+
node: referenceSchema,
|
|
181
|
+
tool: id.optional().describe('Name of a workflow tool on an Agent or Code node. Omit for a Call Workflow node.'),
|
|
182
|
+
}),
|
|
183
|
+
z.strictObject({ op: z.literal('node.remove'), node: referenceSchema }),
|
|
184
|
+
z.strictObject({ op: z.literal('input.set'), node: referenceSchema, input: id, source: authoringSourceSchema }),
|
|
185
|
+
z.strictObject({ op: z.enum(['edge.connect', 'edge.disconnect']), source: referenceSchema, target: referenceSchema, branch: id.optional() }),
|
|
186
|
+
z.strictObject({ op: z.literal('text.edit'), node: referenceSchema, field: z.enum(['code', 'prompt']), oldText: id, newText: z.string() }),
|
|
187
|
+
z.strictObject({ op: z.literal('text.set'), node: referenceSchema, field: z.enum(['code', 'prompt']), text: z.string() }),
|
|
188
|
+
])
|
|
189
|
+
export const authoringRequestSchema = z.strictObject({ baseRevision: id, requestId: id.max(256), edits: z.array(authoringEditSchema).min(1).max(1000) })
|
|
190
|
+
export const authoringReadSchema = z
|
|
191
|
+
.strictObject({
|
|
192
|
+
revision: id.optional().describe('Fixed revision from a previous read; omit to read the current draft.'),
|
|
193
|
+
nodes: z.array(id).min(1).max(100).optional().describe('Node references to read in one batch. Mutually exclusive with text. Long texts return metadata.'),
|
|
194
|
+
text: z
|
|
195
|
+
.strictObject({ node: id, field: z.enum(['code', 'prompt']), start: z.int().positive().default(1), lines: z.int().min(1).max(200).default(80) })
|
|
196
|
+
.optional()
|
|
197
|
+
.describe('Read code or prompt by line (1-based). Mutually exclusive with nodes. Follow nextStart at the same revision until truncated is false.'),
|
|
198
|
+
})
|
|
199
|
+
.refine((v) => v.nodes == null || v.text == null, 'Choose nodes or text.')
|
|
200
|
+
.meta({ not: { required: ['nodes', 'text'] }, description: 'Omit nodes and text for an outline; provide nodes for details, or text for an excerpt.' })
|
|
201
|
+
export const authoringCheckSchema = z.strictObject({ revisionId: id })
|
|
202
|
+
export const authoringSearchSchema = z.strictObject({
|
|
203
|
+
revision: id.optional(),
|
|
204
|
+
query: id.max(1000),
|
|
205
|
+
type: type.optional(),
|
|
206
|
+
offset: z.int().nonnegative().default(0),
|
|
207
|
+
limit: z.int().min(1).max(100).default(20),
|
|
208
|
+
})
|
|
209
|
+
export type AuthoringRequest = z.infer<typeof authoringRequestSchema>
|
|
210
|
+
export type AuthoringEdit = z.infer<typeof authoringEditSchema>
|
|
211
|
+
export type AuthoringRead = z.input<typeof authoringReadSchema>
|
|
212
|
+
export type AuthoringSearch = z.input<typeof authoringSearchSchema>
|
|
213
|
+
export type AuthoringSource = z.infer<typeof authoringSourceSchema>
|
|
214
|
+
export const authoringSchemaQuery = z
|
|
215
|
+
.strictObject({ type: type.optional(), action: id.optional() })
|
|
216
|
+
.refine((v) => v.type == null || v.action == null, 'Choose type or action.')
|
|
217
|
+
|
|
218
|
+
const requestContracts = {
|
|
219
|
+
read: {
|
|
220
|
+
schema: authoringReadSchema,
|
|
221
|
+
guidance:
|
|
222
|
+
'Read Start and Outputs node details for their interface definitions and data sources. Choose one mode: outline (omit nodes and text), node details (nodes), or text excerpt (text). nodes and text are mutually exclusive. Text defaults to 80 lines, at most 200 lines and 24000 characters. For the complete text, repeat at nextStart with the same revision until truncated is false.',
|
|
223
|
+
examples: [{}, { revision: 'REVISION', nodes: ['NODE'] }, { revision: 'REVISION', text: { node: 'NODE', field: 'prompt', start: 1, lines: 80 } }],
|
|
224
|
+
},
|
|
225
|
+
search: {
|
|
226
|
+
schema: authoringSearchSchema,
|
|
227
|
+
guidance: 'Search names, configurations and text. Keep the returned revision when following nextOffset or reading a match.',
|
|
228
|
+
examples: [{ query: 'Customer summary', type: 'agent' }],
|
|
229
|
+
},
|
|
230
|
+
edit: {
|
|
231
|
+
schema: authoringRequestSchema,
|
|
232
|
+
guidance:
|
|
233
|
+
'Edit Start config.inputDefs and Outputs config.outputDefs through node.add or node.update; clear paths are relative to the node, e.g. ["config","inputDefs","amount"]. Set Outputs values with input.set. Use the observed revision as baseRevision and a stable requestId. Edits are ordered and atomic. node.add.as declares a batch-local alias without $. Every later reference to that new node must use $alias, including node, edge source/target and output source node fields; a bare alias is not the node ID. Use returned node references in later batches. Updates recursively merge objects (including schemas); {} preserves existing fields. Arrays replace as a whole. Remove fields with clear paths. Text replacement requires exactly one match. Read the target text first. A saved draft can have validation diagnostics.',
|
|
234
|
+
examples: [
|
|
235
|
+
{
|
|
236
|
+
baseRevision: 'REVISION',
|
|
237
|
+
requestId: 'CREATE_REQUEST',
|
|
238
|
+
edits: [
|
|
239
|
+
{ op: 'node.add', as: 'start', type: 'start', name: 'Start' },
|
|
240
|
+
{ op: 'node.add', as: 'step', type: 'code', name: 'Process', code: 'export default ({value}) => ({result:value})' },
|
|
241
|
+
{ op: 'edge.connect', source: '$start', target: '$step' },
|
|
242
|
+
{ op: 'node.update', node: '$step', set: { description: 'Created and connected in one atomic edit.' } },
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
baseRevision: 'REVISION',
|
|
247
|
+
requestId: 'REQUEST',
|
|
248
|
+
edits: [{ op: 'text.edit', node: 'NODE', field: 'prompt', oldText: 'Original rule.', newText: 'Updated rule.' }],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
check: {
|
|
253
|
+
schema: authoringCheckSchema,
|
|
254
|
+
guidance: 'Check a fixed revision. In the CLI, pass this identity with --revision REVISION.',
|
|
255
|
+
examples: [{ revisionId: 'REVISION' }],
|
|
256
|
+
},
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Transport-independent discovery of the same requests the service validates. */
|
|
260
|
+
export function authoringRequestContract(name: string) {
|
|
261
|
+
if (!Object.hasOwn(requestContracts, name)) return undefined
|
|
262
|
+
const contract = requestContracts[name as keyof typeof requestContracts]
|
|
263
|
+
return { request: z.toJSONSchema(contract.schema, { io: 'input' }), guidance: contract.guidance, examples: contract.examples }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function authoringSchema(kind?: AuthoringType) {
|
|
267
|
+
return kind == null
|
|
268
|
+
? {
|
|
269
|
+
types: authoringTypes,
|
|
270
|
+
request: z.toJSONSchema(authoringRequestSchema),
|
|
271
|
+
guidance:
|
|
272
|
+
'Read a node type schema before creating or configuring it. Use $alias to reference a preceding node.add in the same batch. Read returns stable node references. Long code and prompt fields use text reads and edits. Changes use the observed baseRevision and a stable requestId.',
|
|
273
|
+
}
|
|
274
|
+
: {
|
|
275
|
+
type: kind,
|
|
276
|
+
onError: retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ['stop', 'error'] } : false,
|
|
277
|
+
retry: retryNodeTypes.some((nodeType) => nodeType == kind) ? z.toJSONSchema(retryConfigurationSchema) : false,
|
|
278
|
+
inputSources: ['poll', 'integration'].includes(kind)
|
|
279
|
+
? ['value', 'unset', 'default']
|
|
280
|
+
: ['start', 'outputs', 'error', 'cron', 'webhook', 'value', 'condition'].includes(kind)
|
|
281
|
+
? []
|
|
282
|
+
: ['value', 'unset', 'default', 'output', 'system', 'variable', 'sources'],
|
|
283
|
+
extensibleInputs: ['code', 'agent', 'llm', 'wait', 'approval'].includes(kind),
|
|
284
|
+
guidance:
|
|
285
|
+
kind == 'webhook-response'
|
|
286
|
+
? 'Prepare an HTTP response using fixed inputs body (any JSON, default empty text), statusCode (number, default 200) and headers (scalar-valued object, default {}). Select this node in Webhook options.responseBody as {kind: "webhook-response", nodeId: "node reference", timeoutMs: 30000}. Its first completion responds immediately while the Run continues. It has no business outputs. Multiple response nodes are allowed; each Webhook selects one reachable node.'
|
|
287
|
+
: kind == 'outputs'
|
|
288
|
+
? 'Declare output fields through config.outputDefs. Set their values through node.add.inputs or input.set. Outputs is a singleton execution sink; it waits for its predecessors and produces workflow business outputs independently of node logs. No downstream edges or data references to Outputs are allowed.'
|
|
289
|
+
: kind == 'webhook'
|
|
290
|
+
? 'Use options.responseBody: {kind: "webhook-response", nodeId: "node ID or $alias", timeoutMs: 30000} to respond on the selected node’s first completion while the Run continues. Body, statusCode and headers come exclusively from that node; clear workflow-output-only status/header references when switching. Alternatively configure options.responseBody as {kind: "workflow-outputs", output?: "top-level output name", timeoutMs?: 30000} to respond after the Run succeeds. Omit output for the complete object. Connect Webhook to Outputs. Timeout is 1000–60000 ms; HTTP timeout does not cancel the Run. Strings return text; other values return JSON. Only in this mode, options.responseStatusCodeOutput can select a numeric top-level workflow output as the HTTP status, overriding the preserved fixed responseStatusCode (default 200). Its runtime value must be an integer from 200 to 599, excluding 204, 205, 304; missing or invalid values return 500. Use responseHeaders for fixed text headers. In workflow-output mode, responseHeaderOutputs maps header names to top-level output names; values can be string, number or boolean and are converted to text. Alternatively responseHeadersSource: {kind: "workflow-outputs", output?: "object field"} replaces the entire header object (omit output for all outputs), preserving but ignoring per-header settings. Missing, null, complex or invalid header values return 500 without fallback. Header restrictions and Content-Type policy still apply. Omit responseBody for immediate responseData. Clear options.responseBody, options.responseStatusCodeOutput, options.responseHeadersSource and options.responseHeaderOutputs explicitly to switch back.'
|
|
291
|
+
: kind == 'start'
|
|
292
|
+
? 'Declare workflow inputs through config.inputDefs; read them in Start node details. REST calls and manual runs supply them as trigger.outputs. Downstream nodes bind these parameters as Start outputs. Start has no input sources or defaults; non-nullable parameters are required, and omitted nullable parameters become null.'
|
|
293
|
+
: kind == 'condition'
|
|
294
|
+
? 'Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise.'
|
|
295
|
+
: ['poll', 'integration'].includes(kind)
|
|
296
|
+
? 'Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable.'
|
|
297
|
+
: kind == 'llm'
|
|
298
|
+
? 'Configure model settings, message templates and history as defaults. Input bindings with the same names override these defaults; named business inputs can be bound directly. Template strings interpolate {{name}}.'
|
|
299
|
+
: kind == 'openapi'
|
|
300
|
+
? 'Select an operation; the tool resolves its ports and authentication. Read authenticationChoices from node details. authentication is replaced as a complete choice. Bind advertised credentials through inputs.'
|
|
301
|
+
: kind == 'workflow'
|
|
302
|
+
? 'Select another workflow with config.flowId. A workflow cannot call itself, including in a disconnected node. Owned unpublished or unavailable targets may be saved as incomplete drafts. Use node.refresh to load the current published interface.'
|
|
303
|
+
: kind == 'agent'
|
|
304
|
+
? 'Tools accept Connector Actions or {kind: "workflow", flowId, name, description, approval, inputs}. Workflow parameter sources use model, input or value. The platform derives the interface. Refresh a workflow tool with node.refresh and tool: its name.'
|
|
305
|
+
: kind == 'code'
|
|
306
|
+
? 'Select workflows through config.capabilities: [{kind: "workflow", flowId, name}]. Call context.workflows.call(name, input) and await its business output. The platform derives input/output types. Refresh a selected workflow tool with node.refresh and tool: its name. Calls obey node and Run time limits.'
|
|
307
|
+
: 'Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.',
|
|
308
|
+
example: {
|
|
309
|
+
op: 'node.add',
|
|
310
|
+
as: 'step',
|
|
311
|
+
type: kind,
|
|
312
|
+
name: 'Step',
|
|
313
|
+
...((
|
|
314
|
+
{
|
|
315
|
+
start: { config: { inputDefs: {} } },
|
|
316
|
+
outputs: { config: { outputDefs: {} } },
|
|
317
|
+
workflow: { config: { flowId: '<Flow ID>' } },
|
|
318
|
+
connector: { config: { action: '<Action ID>', connectionId: '<Connection ID>' } },
|
|
319
|
+
poll: { config: { key: '<Trigger key>', schedule: [{ type: 'every', unit: 'minute', value: 5 }] } },
|
|
320
|
+
integration: { config: { key: '<Trigger key>' } },
|
|
321
|
+
openapi: { config: { sourceUrl: 'https://example.com/openapi.json', path: '/items', method: 'get' } },
|
|
322
|
+
code: { code: 'export default ({value}) => ({result:value})', inputs: { value: { kind: 'value', value: 'Hello' } } },
|
|
323
|
+
condition: {
|
|
324
|
+
config: {
|
|
325
|
+
match: 'first',
|
|
326
|
+
branches: [
|
|
327
|
+
{
|
|
328
|
+
name: 'yes',
|
|
329
|
+
when: {
|
|
330
|
+
left: { kind: 'value', value: 120 },
|
|
331
|
+
operator: '>',
|
|
332
|
+
right: { kind: 'value', value: 100 },
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
value: { config: { values: { threshold: 100, region: 'EU' } } },
|
|
339
|
+
webhook: { config: { method: 'POST', body: { orderId: { schema: { type: 'string' }, nullable: false } } } },
|
|
340
|
+
wait: { prompt: 'Continue processing this order?', inputs: { order: { kind: 'value', value: { orderId: 'A-1' } } } },
|
|
341
|
+
approval: { prompt: 'Approve this order?', inputs: { order: { kind: 'value', value: { orderId: 'A-1' } } } },
|
|
342
|
+
llm: {
|
|
343
|
+
config: { model: { model: 'deepseek-v4-flash' }, template: [{ role: 'user', content: 'Summarize {{order}}.' }] },
|
|
344
|
+
inputs: { order: { kind: 'value', value: { orderId: 'A-1', total: 42 } } },
|
|
345
|
+
},
|
|
346
|
+
agent: {
|
|
347
|
+
config: {
|
|
348
|
+
model: 'deepseek-v4-flash',
|
|
349
|
+
},
|
|
350
|
+
inputs: { orders: { kind: 'value', value: [{ orderId: 'A-1', total: 42 }] } },
|
|
351
|
+
prompt: 'Summarize {{orders}}.',
|
|
352
|
+
},
|
|
353
|
+
} as Partial<Record<AuthoringType, unknown>>
|
|
354
|
+
)[kind] as object),
|
|
355
|
+
},
|
|
356
|
+
configuration: z.toJSONSchema(authoringConfigurations[kind].partial()),
|
|
357
|
+
texts: kind == 'code' ? ['code'] : ['agent', 'wait', 'approval'].includes(kind) ? ['prompt'] : [],
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export const authoringDiagnosticSchema = z.object({
|
|
362
|
+
code: id,
|
|
363
|
+
message: z.string(),
|
|
364
|
+
nodes: z.array(id),
|
|
365
|
+
field: z.string().optional(),
|
|
366
|
+
line: z.number().optional(),
|
|
367
|
+
column: z.number().optional(),
|
|
368
|
+
})
|
|
369
|
+
export const authoringCheckResponse = z.object({
|
|
370
|
+
flowId: id,
|
|
371
|
+
revisionId: id,
|
|
372
|
+
valid: z.boolean(),
|
|
373
|
+
diagnostics: z.array(authoringDiagnosticSchema),
|
|
374
|
+
version: z.literal(1),
|
|
375
|
+
})
|
|
376
|
+
export const authoringEditResponse = z.object({
|
|
377
|
+
flowId: id,
|
|
378
|
+
saved: z.literal(true),
|
|
379
|
+
revision: id,
|
|
380
|
+
nodes: z.record(id, id),
|
|
381
|
+
changes: z.array(z.object({ index: z.int(), op: id, node: id.optional() })),
|
|
382
|
+
validation: z.object({ status: z.enum(['valid', 'invalid', 'unavailable']), diagnostics: z.array(authoringDiagnosticSchema).optional() }),
|
|
383
|
+
version: z.literal(1),
|
|
384
|
+
})
|
|
385
|
+
export const authoringReadResponse = z.object({
|
|
386
|
+
flowId: id,
|
|
387
|
+
revision: id,
|
|
388
|
+
data: z.object({
|
|
389
|
+
nodes: z.array(z.record(z.string(), json)).optional(),
|
|
390
|
+
edges: z.array(json).optional(),
|
|
391
|
+
text: z.record(z.string(), json).optional(),
|
|
392
|
+
}),
|
|
393
|
+
version: z.literal(1),
|
|
394
|
+
})
|
|
395
|
+
export const authoringSearchResponse = z.object({
|
|
396
|
+
flowId: id,
|
|
397
|
+
revision: id,
|
|
398
|
+
data: z.object({
|
|
399
|
+
matches: z.array(z.object({ node: id.optional(), field: id, line: z.int().optional(), excerpt: z.string() })),
|
|
400
|
+
total: z.int(),
|
|
401
|
+
nextOffset: z.int().optional(),
|
|
402
|
+
}),
|
|
403
|
+
version: z.literal(1),
|
|
404
|
+
})
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { AgentInput, AgentTool, TaskCapability, WorkflowCapability } from '../../flow/common/change.ts'
|
|
2
|
+
import type { WorkflowContract, WorkflowCandidate } from '../../workflow/common/workflow.ts'
|
|
3
|
+
import type { ConnectorAction } from './api.ts'
|
|
4
|
+
|
|
5
|
+
import { workflowAgentTool, workflowCapability } from '../../workflow/common/workflow.ts'
|
|
6
|
+
|
|
7
|
+
interface AuthoringAgentToolBase {
|
|
8
|
+
readonly name: string
|
|
9
|
+
readonly description: string
|
|
10
|
+
readonly approval: boolean
|
|
11
|
+
readonly inputs?: Readonly<Record<string, AgentInput>>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type AuthoringAgentTool = AuthoringAgentToolBase &
|
|
15
|
+
({ readonly kind?: 'connector'; readonly action: string; readonly connectionId?: string } | { readonly kind: 'workflow'; readonly flowId: string })
|
|
16
|
+
export type AuthoringCapability = Exclude<TaskCapability, WorkflowCapability> | Pick<WorkflowCapability, 'kind' | 'name' | 'flowId'>
|
|
17
|
+
export type WorkflowLookup = (flowId: string) => Promise<WorkflowContract | WorkflowCandidate>
|
|
18
|
+
|
|
19
|
+
interface ToolIdentity {
|
|
20
|
+
readonly kind?: 'connector' | 'workflow'
|
|
21
|
+
readonly name?: string
|
|
22
|
+
readonly flowId?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A rename retains a snapshot only when one removed name matches one added name for the same target. */
|
|
26
|
+
function previousWorkflowTool<T extends ToolIdentity>(
|
|
27
|
+
tool: Pick<WorkflowCapability, 'name' | 'flowId'>,
|
|
28
|
+
next: readonly ToolIdentity[],
|
|
29
|
+
previous: readonly T[],
|
|
30
|
+
): T | undefined {
|
|
31
|
+
const named = previous.find((item) => item.name == tool.name)
|
|
32
|
+
if (named != null) return named
|
|
33
|
+
const added = next.filter((item) => item.kind == 'workflow' && item.flowId == tool.flowId && !previous.some((old) => old.name == item.name))
|
|
34
|
+
if (added.length != 1) return
|
|
35
|
+
const removed = previous.filter((item) => item.kind == 'workflow' && item.flowId == tool.flowId && !next.some((itemNext) => itemNext.name == item.name))
|
|
36
|
+
return removed.length == 1 ? removed[0] : undefined
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function outwardCapabilities(capabilities: readonly TaskCapability[]): readonly AuthoringCapability[] {
|
|
40
|
+
return capabilities.map((item) => (item.kind == 'workflow' ? { kind: item.kind, name: item.name, flowId: item.flowId } : item))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function prepareCapabilities(
|
|
44
|
+
capabilities: readonly AuthoringCapability[],
|
|
45
|
+
previous: readonly TaskCapability[],
|
|
46
|
+
workflow: WorkflowLookup,
|
|
47
|
+
): Promise<readonly TaskCapability[]> {
|
|
48
|
+
return Promise.all(
|
|
49
|
+
capabilities.map(async (item) => {
|
|
50
|
+
if (item.kind != 'workflow') return item
|
|
51
|
+
const old = previousWorkflowTool(item, capabilities, previous)
|
|
52
|
+
return old?.kind == 'workflow' && old.flowId == item.flowId ? { ...old, name: item.name } : workflowCapability(item.name, await workflow(item.flowId))
|
|
53
|
+
}),
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class AuthoringToolInputError extends Error {
|
|
58
|
+
readonly code = 'tool.input-not-found'
|
|
59
|
+
readonly details: { tool: string; action: string; input: string; choices: readonly string[] }
|
|
60
|
+
constructor(details: AuthoringToolInputError['details']) {
|
|
61
|
+
super(`Unknown input ${JSON.stringify(details.input)} for tool ${JSON.stringify(details.tool)}. Choose from: ${details.choices.join(', ') || '(none)'}.`)
|
|
62
|
+
this.name = 'AuthoringToolInputError'
|
|
63
|
+
this.details = details
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function outwardAgentTools(tools: readonly AgentTool[]): readonly AuthoringAgentTool[] {
|
|
68
|
+
return tools.map((tool) => {
|
|
69
|
+
const { id: _id, inputs, ...settings } = tool
|
|
70
|
+
return {
|
|
71
|
+
...(tool.kind == 'workflow'
|
|
72
|
+
? { kind: tool.kind, name: tool.name, description: tool.description, approval: tool.approval, flowId: tool.flowId }
|
|
73
|
+
: settings),
|
|
74
|
+
inputs: Object.fromEntries(inputs.map((input) => [input.handle, input.source])),
|
|
75
|
+
} as AuthoringAgentTool
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Keep persisted tool contracts until the caller selects a different target or explicitly refreshes. */
|
|
80
|
+
export async function prepareAgentTools(
|
|
81
|
+
tools: readonly AuthoringAgentTool[],
|
|
82
|
+
previous: readonly AgentTool[],
|
|
83
|
+
action: (id: string) => Promise<ConnectorAction>,
|
|
84
|
+
id: () => string,
|
|
85
|
+
workflow?: WorkflowLookup,
|
|
86
|
+
): Promise<readonly AgentTool[]> {
|
|
87
|
+
const prepared: AgentTool[] = []
|
|
88
|
+
for (const tool of tools) {
|
|
89
|
+
const old = tool.kind == 'workflow' ? previousWorkflowTool(tool, tools, previous) : previous.find((item) => item.name == tool.name)
|
|
90
|
+
if (tool.kind == 'workflow') {
|
|
91
|
+
if (workflow == null) throw new Error('Workflow tools are unavailable.')
|
|
92
|
+
const retained = old?.kind == 'workflow' && old.flowId == tool.flowId ? old : undefined
|
|
93
|
+
const preparedTool = retained ?? workflowAgentTool(old?.id ?? id(), tool.name, await workflow(tool.flowId))
|
|
94
|
+
const choices = preparedTool.inputs.map((port) => port.handle)
|
|
95
|
+
for (const input of Object.keys(tool.inputs ?? {}))
|
|
96
|
+
if (!choices.includes(input)) throw new AuthoringToolInputError({ tool: tool.name, action: tool.flowId, input, choices })
|
|
97
|
+
prepared.push({
|
|
98
|
+
...preparedTool,
|
|
99
|
+
name: tool.name,
|
|
100
|
+
description: tool.description,
|
|
101
|
+
approval: tool.approval,
|
|
102
|
+
inputs: preparedTool.inputs.map((port) => Object.assign({}, port, { source: tool.inputs?.[port.handle] ?? port.source })),
|
|
103
|
+
})
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
const retained = old?.kind != 'workflow' && old?.action == tool.action ? old : undefined
|
|
107
|
+
const definition = retained == null ? await action(tool.action) : undefined
|
|
108
|
+
const ports =
|
|
109
|
+
retained?.inputs ?? Object.entries(definition!.inputs).map(([handle, port]) => Object.assign({}, port, { handle, source: { kind: 'model' } as const }))
|
|
110
|
+
const choices = ports.map((port) => port.handle)
|
|
111
|
+
for (const input of Object.keys(tool.inputs ?? {})) {
|
|
112
|
+
if (!choices.includes(input)) throw new AuthoringToolInputError({ tool: tool.name, action: tool.action, input, choices })
|
|
113
|
+
}
|
|
114
|
+
const { inputs: sources, ...settings } = tool
|
|
115
|
+
prepared.push({
|
|
116
|
+
...settings,
|
|
117
|
+
id: old?.id ?? id(),
|
|
118
|
+
action: definition?.actionId ?? tool.action,
|
|
119
|
+
inputs: ports.map((port) => (sources != null && Object.hasOwn(sources, port.handle) ? Object.assign({}, port, { source: sources[port.handle]! }) : port)),
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
return prepared
|
|
123
|
+
}
|