@oomol-lab/open-flow 0.1.0-beta.74 → 0.1.0-beta.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-Cm1hbVzW.js} +4 -3
- package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-NzKtla_c.js} +62 -62
- package/dist/browser/{createResourceDialog-DI9pL-Yr.js → createResourceDialog-BgdedQqu.js} +3 -3
- package/dist/browser/{dialog-BYJGvItc.js → dialog-aSElFFw2.js} +322 -26
- package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-Dcz4HTo_.js} +2 -2
- package/dist/browser/{flowChanges-RL-H4CjD.js → flowChanges-NZyS7HSp.js} +490 -438
- package/dist/browser/{flowWorkspace-BkDsETj0.js → flowWorkspace-Bl0SDehy.js} +499 -61
- package/dist/browser/preview.css +696 -825
- package/dist/browser/preview.js +1399 -717
- package/dist/browser/theme.css +114 -262
- package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-3XMK9jkr.js} +1 -1
- package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-C9sBGOKZ.js} +1 -1
- package/dist/browser/ui.css +354 -460
- package/dist/browser/ui.js +1 -1
- package/dist/browser/workbench.css +696 -825
- package/dist/browser/workbench.js +13 -7
- package/dist/browser/{workbenchSelect-BcWPWGzw.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
- package/dist/command/index.js +41 -43
- package/dist/common/authoring.d.ts +5 -5
- package/dist/common/authoringExamples.d.ts +3 -2
- package/dist/common/authoringSchema.d.ts +70 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.js +250 -138
- package/dist/common/control-api.d.ts +3 -2
- package/dist/common/control-api.js +246 -134
- package/dist/common/control-requests.d.ts +3 -3
- package/dist/common/control-requests.js +353 -79
- package/dist/common/cron-trigger.d.ts +2 -1
- package/dist/common/decision.d.ts +4 -4
- package/dist/common/decision.js +5 -2
- package/dist/common/engine-contract.d.ts +6 -1
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/event-source-view.d.ts +22 -0
- package/dist/common/event-source.d.ts +1 -1
- package/dist/common/event-source.js +24 -65
- package/dist/common/event-sources.d.ts +0 -21
- package/dist/common/flow-authoring.js +90 -19
- package/dist/common/flow-change-schema.d.ts +9 -1
- package/dist/common/flow-change.d.ts +7 -201
- package/dist/common/flow-change.js +96 -23
- package/dist/common/flow-encoding.js +89 -21
- package/dist/common/flow-graph.d.ts +2 -1
- package/dist/common/flow-input-value.d.ts +1 -1
- package/dist/common/flow-model.d.ts +121 -0
- package/dist/common/flow-notifications.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +3 -5
- package/dist/common/flow-semantics.js +816 -586
- package/dist/common/flow-workflowReferences.d.ts +8 -0
- package/dist/common/flowInspection.d.ts +1 -1
- package/dist/common/http-hosts.d.ts +6 -0
- package/dist/common/http-request.d.ts +164 -0
- package/dist/common/http-request.js +5272 -0
- package/dist/common/integration-trigger.d.ts +2 -1
- package/dist/common/mcp.d.ts +3 -3
- package/dist/common/mcp.js +248 -136
- package/dist/common/openapi.d.ts +4 -4
- package/dist/common/openapi.js +4 -1
- package/dist/common/poll-trigger.d.ts +2 -1
- package/dist/common/run-events.js +11 -9
- package/dist/common/runtime-contract.d.ts +23 -1
- package/dist/common/runtime-contract.js +607 -72
- package/dist/common/runtime-nodejs-compat.d.ts +44 -0
- package/dist/common/runtime-nodejs-compat.js +5870 -0
- package/dist/common/scheduler-checkpoint.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 +95 -25
- package/dist/common/trigger-catalog.d.ts +1 -7
- 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 -1
- package/dist/common/trigger-localization.d.ts +8 -2
- package/dist/common/trigger-model.d.ts +101 -0
- package/dist/common/webhook-response.d.ts +1 -3
- package/dist/common/webhook-trigger.d.ts +3 -1
- package/dist/common/webhook-trigger.js +12 -11
- package/dist/common/workflow.d.ts +3 -12
- package/dist/common/workflow.js +25 -23
- package/dist/index.d.ts +41 -14
- package/package.json +9 -1
- package/skills/open-flow/references/flow-authoring.md +1 -0
- package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
- package/src/base/common/json.ts +1 -1
- package/src/connector/common/proxy.ts +1 -1
- package/src/control/common/api.ts +7 -5
- package/src/control/common/authoring.ts +14 -3
- package/src/control/common/authoringExamples.ts +8 -0
- package/src/control/common/authoringSchema.ts +38 -25
- package/src/control/common/authoringTools.ts +1 -1
- package/src/control/common/conformance.ts +1 -1
- package/src/control/common/connectorDecoders.ts +1 -1
- package/src/control/common/eventSources.ts +2 -29
- package/src/control/common/triggerCatalog.ts +1 -8
- package/src/decision/common/decision.ts +15 -7
- package/src/event-source/common/definition.ts +1 -1
- package/src/event-source/common/index.ts +1 -1
- package/src/event-source/common/view.ts +20 -0
- package/src/execution/common/checkpoint.ts +1 -1
- package/src/execution/common/events.ts +3 -0
- package/src/execution/common/node-execution.ts +5 -3
- package/src/execution/common/scheduler.ts +2 -1
- package/src/flow/common/change.ts +59 -192
- package/src/flow/common/changeSchema.ts +39 -5
- package/src/flow/common/connectionUsage.ts +1 -1
- package/src/flow/common/graph.ts +10 -4
- package/src/flow/common/inputValue.ts +1 -1
- package/src/flow/common/model.ts +130 -0
- package/src/flow/common/modules.ts +1 -1
- package/src/flow/common/portChanges.ts +1 -1
- package/src/flow/common/retry.ts +3 -5
- package/src/flow/common/semantics.ts +71 -7
- package/src/flow/common/webhookResponse.ts +4 -8
- package/src/flow/common/workflowReferences.ts +31 -0
- package/src/http/common/authBindings.ts +9 -0
- package/src/http/common/headers.ts +5 -0
- package/src/http/common/hosts.ts +13 -0
- package/src/http/common/httpRequest.ts +266 -0
- package/src/openapi/common/openapi.ts +9 -5
- package/src/{execution → runtime}/common/engineContract.ts +24 -15
- package/src/runtime/common/nodejsCompat.ts +275 -0
- package/src/runtime/common/nodejsGuest.generated.json +47 -0
- package/src/runtime/common/runtime.ts +1138 -0
- package/src/trigger/common/config.ts +1 -1
- package/src/trigger/common/configOptions.ts +1 -1
- package/src/trigger/common/contract.ts +2 -1
- package/src/trigger/common/cron.ts +2 -1
- package/src/trigger/common/integration.ts +2 -1
- package/src/trigger/common/model.ts +87 -0
- package/src/trigger/common/poll.ts +2 -1
- package/src/trigger/common/webhook.ts +7 -4
- package/src/trigger/providers/fieldDescriptions.ts +1 -1
- package/src/trigger/providers/localization.ts +9 -2
- package/src/trigger/providers/remote.ts +1 -1
- package/src/types/index.ts +44 -15
- package/src/workflow/common/workflow.ts +3 -44
- package/src/execution/common/runtime.ts +0 -563
- package/src/openapi/common/authBindings.ts +0 -12
- /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
|
@@ -12163,6 +12163,9 @@ function schemaValidationErrors(value, schema) {
|
|
|
12163
12163
|
}
|
|
12164
12164
|
//#endregion
|
|
12165
12165
|
//#region src/decision/common/decision.ts
|
|
12166
|
+
function isDecisionExecutor(executor) {
|
|
12167
|
+
return executor.kind === "decision";
|
|
12168
|
+
}
|
|
12166
12169
|
var decisionLimits = {
|
|
12167
12170
|
choice: 255,
|
|
12168
12171
|
score: 10
|
|
@@ -12185,7 +12188,7 @@ function limitDecisionQuestions(questions) {
|
|
|
12185
12188
|
}
|
|
12186
12189
|
/** Loading an oversized task also updates its previously generated output schemas. */
|
|
12187
12190
|
function limitDecisionTask(task) {
|
|
12188
|
-
if (task.executor
|
|
12191
|
+
if (!isDecisionExecutor(task.executor)) return task;
|
|
12189
12192
|
const original = task.executor.questions;
|
|
12190
12193
|
const questions = limitDecisionQuestions(original);
|
|
12191
12194
|
if (questions === original) return task;
|
|
@@ -12285,13 +12288,190 @@ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decisi
|
|
|
12285
12288
|
};
|
|
12286
12289
|
}
|
|
12287
12290
|
//#endregion
|
|
12288
|
-
//#region src/
|
|
12289
|
-
/** Never allow credentials to enter a Revision as literal node
|
|
12290
|
-
function
|
|
12291
|
-
for (const
|
|
12292
|
-
|
|
12293
|
-
|
|
12291
|
+
//#region src/http/common/authBindings.ts
|
|
12292
|
+
/** Never allow credentials to enter a Revision as literal inputs of an OpenAPI or HTTP request node. */
|
|
12293
|
+
function assertHttpAuthBindings(inputs) {
|
|
12294
|
+
for (const [handle, mapping] of Object.entries(inputs)) if (handle.startsWith("auth.") && mapping.kind == "value") throw new TypeError("HTTP authentication accepts deployment variables and upstream outputs only.");
|
|
12295
|
+
}
|
|
12296
|
+
//#endregion
|
|
12297
|
+
//#region src/http/common/hosts.ts
|
|
12298
|
+
/** Hosts of a Code `http` Capability: lowercase DNS names or IPv4 addresses; `*.example.com` matches subdomains only. */
|
|
12299
|
+
var httpHostPattern = /^(?:\*\.)?(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
12300
|
+
/** Wildcards must name a registrable suffix, so `*.com` is rejected. */
|
|
12301
|
+
function isHttpHost(value) {
|
|
12302
|
+
return httpHostPattern.test(value) && (!value.startsWith("*.") || value.slice(2).includes("."));
|
|
12303
|
+
}
|
|
12304
|
+
//#endregion
|
|
12305
|
+
//#region src/flow/common/portChanges.ts
|
|
12306
|
+
function renamedPort(previous, next) {
|
|
12307
|
+
const previousNames = new Set(previous.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12308
|
+
const nextNames = new Set(next.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12309
|
+
const removed = [...previousNames].filter((name) => !nextNames.has(name));
|
|
12310
|
+
const added = [...nextNames].filter((name) => !previousNames.has(name));
|
|
12311
|
+
return removed.length == 1 && added.length == 1 ? [removed[0], added[0]] : void 0;
|
|
12312
|
+
}
|
|
12313
|
+
function renameOutputMapping(mapping, nodeIds, rename) {
|
|
12314
|
+
if (rename == null || mapping.kind != "sources") return mapping;
|
|
12315
|
+
const sources = mapping.sources.map((source) => source.kind == "node" && !source.system && nodeIds.has(source.nodeId) && source.output == rename[0] ? {
|
|
12316
|
+
...source,
|
|
12317
|
+
output: rename[1]
|
|
12318
|
+
} : source);
|
|
12319
|
+
return sources.every((source, index) => source === mapping.sources[index]) ? mapping : {
|
|
12320
|
+
kind: "sources",
|
|
12321
|
+
sources
|
|
12322
|
+
};
|
|
12323
|
+
}
|
|
12324
|
+
/** Carry saved mappings through a field rename and remove only fields absent from the new contract. */
|
|
12325
|
+
function remapInputMappings(mappings, ports, rename) {
|
|
12326
|
+
const inputs = { ...mappings };
|
|
12327
|
+
if (rename != null && Object.hasOwn(inputs, rename[0])) {
|
|
12328
|
+
Object.defineProperty(inputs, rename[1], {
|
|
12329
|
+
value: inputs[rename[0]],
|
|
12330
|
+
enumerable: true,
|
|
12331
|
+
configurable: true,
|
|
12332
|
+
writable: true
|
|
12333
|
+
});
|
|
12334
|
+
delete inputs[rename[0]];
|
|
12294
12335
|
}
|
|
12336
|
+
const names = new Set(ports.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12337
|
+
for (const name of Object.keys(inputs)) if (!names.has(name)) delete inputs[name];
|
|
12338
|
+
return inputs;
|
|
12339
|
+
}
|
|
12340
|
+
//#endregion
|
|
12341
|
+
//#region src/http/common/httpRequest.ts
|
|
12342
|
+
var parameterSchema = strictObject({
|
|
12343
|
+
mode: _enum(["fields", "object"]).default("fields"),
|
|
12344
|
+
names: array(string()).default([])
|
|
12345
|
+
});
|
|
12346
|
+
var httpRequestConfigSchema = strictObject({
|
|
12347
|
+
method: _enum([
|
|
12348
|
+
"GET",
|
|
12349
|
+
"POST",
|
|
12350
|
+
"PUT",
|
|
12351
|
+
"PATCH",
|
|
12352
|
+
"DELETE",
|
|
12353
|
+
"HEAD",
|
|
12354
|
+
"OPTIONS"
|
|
12355
|
+
]).default("GET"),
|
|
12356
|
+
query: parameterSchema.default({
|
|
12357
|
+
mode: "fields",
|
|
12358
|
+
names: []
|
|
12359
|
+
}),
|
|
12360
|
+
headers: parameterSchema.default({
|
|
12361
|
+
mode: "fields",
|
|
12362
|
+
names: []
|
|
12363
|
+
}),
|
|
12364
|
+
bodyFormat: _enum([
|
|
12365
|
+
"none",
|
|
12366
|
+
"json",
|
|
12367
|
+
"text",
|
|
12368
|
+
"form"
|
|
12369
|
+
]).default("none"),
|
|
12370
|
+
authentication: union([
|
|
12371
|
+
strictObject({ type: literal("none") }),
|
|
12372
|
+
strictObject({ type: _enum(["bearer", "basic"]) }),
|
|
12373
|
+
strictObject({
|
|
12374
|
+
type: literal("apiKey"),
|
|
12375
|
+
name: string(),
|
|
12376
|
+
in: _enum(["header", "query"])
|
|
12377
|
+
})
|
|
12378
|
+
]).default({ type: "none" }),
|
|
12379
|
+
responseFormat: _enum([
|
|
12380
|
+
"auto",
|
|
12381
|
+
"json",
|
|
12382
|
+
"text"
|
|
12383
|
+
]).default("auto"),
|
|
12384
|
+
statusPolicy: _enum(["success", "all"]).default("success")
|
|
12385
|
+
});
|
|
12386
|
+
var httpRequestExecutorSchema = httpRequestConfigSchema.extend({ kind: literal("http-request") });
|
|
12387
|
+
var scalarSchema = { type: [
|
|
12388
|
+
"string",
|
|
12389
|
+
"number",
|
|
12390
|
+
"boolean"
|
|
12391
|
+
] };
|
|
12392
|
+
var queryValueSchema = { anyOf: [scalarSchema, {
|
|
12393
|
+
type: "array",
|
|
12394
|
+
items: scalarSchema
|
|
12395
|
+
}] };
|
|
12396
|
+
var httpHeaderSchema = {
|
|
12397
|
+
type: "object",
|
|
12398
|
+
additionalProperties: { type: "string" }
|
|
12399
|
+
};
|
|
12400
|
+
var httpQuerySchema = {
|
|
12401
|
+
type: "object",
|
|
12402
|
+
additionalProperties: queryValueSchema
|
|
12403
|
+
};
|
|
12404
|
+
function httpAuthHandles(config) {
|
|
12405
|
+
return config.authentication.type == "none" ? [] : config.authentication.type == "basic" ? ["auth.username", "auth.password"] : ["auth.token"];
|
|
12406
|
+
}
|
|
12407
|
+
function retain(ports, old) {
|
|
12408
|
+
const remaining = new Map(ports.map((port) => [port.handle, port]));
|
|
12409
|
+
return [...old.flatMap((item) => {
|
|
12410
|
+
if ("group" in item) return [item];
|
|
12411
|
+
const next = remaining.get(item.handle);
|
|
12412
|
+
if (next == null) return [];
|
|
12413
|
+
remaining.delete(item.handle);
|
|
12414
|
+
return [dequal(item.jsonSchema, next.jsonSchema) && item.nullable == next.nullable ? item : next];
|
|
12415
|
+
}), ...remaining.values()];
|
|
12416
|
+
}
|
|
12417
|
+
function httpRequestTask(config = httpRequestConfigSchema.parse({}), name = "HTTP Request", previous) {
|
|
12418
|
+
const inputs = [{
|
|
12419
|
+
handle: "url",
|
|
12420
|
+
jsonSchema: { type: "string" },
|
|
12421
|
+
nullable: false
|
|
12422
|
+
}];
|
|
12423
|
+
for (const group of ["query", "headers"]) if (config[group].mode == "object") inputs.push({
|
|
12424
|
+
handle: group,
|
|
12425
|
+
jsonSchema: group == "query" ? httpQuerySchema : httpHeaderSchema,
|
|
12426
|
+
nullable: true
|
|
12427
|
+
});
|
|
12428
|
+
else for (const parameterName of config[group].names.filter((value) => value.trim())) inputs.push({
|
|
12429
|
+
handle: `${group == "query" ? "query" : "header"}.${parameterName}`,
|
|
12430
|
+
jsonSchema: group == "query" ? queryValueSchema : { type: "string" },
|
|
12431
|
+
nullable: true
|
|
12432
|
+
});
|
|
12433
|
+
if (config.bodyFormat != "none") inputs.push({
|
|
12434
|
+
handle: "body",
|
|
12435
|
+
jsonSchema: config.bodyFormat == "json" ? {} : config.bodyFormat == "text" ? { type: "string" } : httpQuerySchema,
|
|
12436
|
+
nullable: config.bodyFormat == "json"
|
|
12437
|
+
});
|
|
12438
|
+
inputs.push(...httpAuthHandles(config).map((handle) => ({
|
|
12439
|
+
handle,
|
|
12440
|
+
jsonSchema: { type: "string" },
|
|
12441
|
+
nullable: false
|
|
12442
|
+
})));
|
|
12443
|
+
const outputs = [
|
|
12444
|
+
{
|
|
12445
|
+
handle: "body",
|
|
12446
|
+
jsonSchema: config.responseFormat == "text" ? { type: "string" } : {},
|
|
12447
|
+
nullable: true
|
|
12448
|
+
},
|
|
12449
|
+
{
|
|
12450
|
+
handle: "statusCode",
|
|
12451
|
+
jsonSchema: { type: "integer" },
|
|
12452
|
+
nullable: false
|
|
12453
|
+
},
|
|
12454
|
+
{
|
|
12455
|
+
handle: "headers",
|
|
12456
|
+
jsonSchema: httpHeaderSchema,
|
|
12457
|
+
nullable: false
|
|
12458
|
+
}
|
|
12459
|
+
];
|
|
12460
|
+
return {
|
|
12461
|
+
name,
|
|
12462
|
+
executor: {
|
|
12463
|
+
...config,
|
|
12464
|
+
kind: "http-request"
|
|
12465
|
+
},
|
|
12466
|
+
inputs: retain(inputs, previous?.inputs ?? []),
|
|
12467
|
+
outputs: retain(outputs, previous?.outputs ?? [])
|
|
12468
|
+
};
|
|
12469
|
+
}
|
|
12470
|
+
/** Only a named parameter rename carries a value; changing source modes is not a rename. */
|
|
12471
|
+
function httpRequestInputs(mappings, previous, next) {
|
|
12472
|
+
const candidate = renamedPort(previous.inputs, next.inputs);
|
|
12473
|
+
const rename = candidate != null && ["query.", "header."].some((prefix) => candidate.every((name) => name.startsWith(prefix))) ? candidate : void 0;
|
|
12474
|
+
return remapInputMappings(mappings, next.inputs, rename);
|
|
12295
12475
|
}
|
|
12296
12476
|
function checkJsonDepth(value, depth = 0) {
|
|
12297
12477
|
if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
|
|
@@ -12303,6 +12483,7 @@ var retryNodeTypes = [
|
|
|
12303
12483
|
"code",
|
|
12304
12484
|
"connector",
|
|
12305
12485
|
"openapi",
|
|
12486
|
+
"http-request",
|
|
12306
12487
|
"llm",
|
|
12307
12488
|
"decision"
|
|
12308
12489
|
];
|
|
@@ -12492,7 +12673,15 @@ var workflowCapabilitySchema = strictObject({
|
|
|
12492
12673
|
inputs: array(port),
|
|
12493
12674
|
outputs: array(port).nullable()
|
|
12494
12675
|
});
|
|
12495
|
-
var
|
|
12676
|
+
var httpCapabilitySchema = strictObject({
|
|
12677
|
+
kind: literal("http"),
|
|
12678
|
+
hosts: array(text$1.refine(isHttpHost, "Use a lowercase host name or IPv4 address, optionally prefixed by \"*.\" for subdomains.")).min(1).max(20).describe("Hosts Code may call with context.fetch. \"*.example.com\" matches subdomains only.")
|
|
12679
|
+
});
|
|
12680
|
+
var capability = union([
|
|
12681
|
+
connectorCapabilitySchema,
|
|
12682
|
+
workflowCapabilitySchema,
|
|
12683
|
+
httpCapabilitySchema
|
|
12684
|
+
]);
|
|
12496
12685
|
var inline = object$1({
|
|
12497
12686
|
...ports,
|
|
12498
12687
|
name: text$1,
|
|
@@ -12602,7 +12791,8 @@ var managedFields = object$1({
|
|
|
12602
12791
|
kind: literal("workflow"),
|
|
12603
12792
|
flowId: text$1,
|
|
12604
12793
|
revisionId: text$1
|
|
12605
|
-
})
|
|
12794
|
+
}),
|
|
12795
|
+
httpRequestExecutorSchema
|
|
12606
12796
|
])
|
|
12607
12797
|
});
|
|
12608
12798
|
var managed = managedFields.transform(limitDecisionTask);
|
|
@@ -12871,7 +13061,8 @@ var revision = object$1({
|
|
|
12871
13061
|
literal(8),
|
|
12872
13062
|
literal(9),
|
|
12873
13063
|
literal(10),
|
|
12874
|
-
literal(11)
|
|
13064
|
+
literal(11),
|
|
13065
|
+
literal(12)
|
|
12875
13066
|
]),
|
|
12876
13067
|
document,
|
|
12877
13068
|
modules: record$3(text$1, module)
|
|
@@ -12902,7 +13093,7 @@ function decodeRevisionContent(value) {
|
|
|
12902
13093
|
checkJsonDepth(value);
|
|
12903
13094
|
const content = revision.parse(value);
|
|
12904
13095
|
checkModelVersion(content);
|
|
12905
|
-
|
|
13096
|
+
assertDocumentHttpAuthBindings(content.document);
|
|
12906
13097
|
return content;
|
|
12907
13098
|
}
|
|
12908
13099
|
var shapes = {
|
|
@@ -13096,6 +13287,8 @@ function changeOperationsSchema(kind) {
|
|
|
13096
13287
|
return toJSONSchema(schema, { io: "input" });
|
|
13097
13288
|
}
|
|
13098
13289
|
function checkModelVersion(content) {
|
|
13290
|
+
if (content.modelVersion < 12 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "moduleId" in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == "http"))) throw new TypeError("Code HTTP access requires Flow model version 12.");
|
|
13291
|
+
if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind == "http-request")) throw new TypeError("HTTP Request requires Flow model version 11.");
|
|
13099
13292
|
if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && ("moduleId" in candidateNode.task ? candidateNode.task.capabilities?.some((item) => item.kind == "workflow") : candidateNode.task.executor.kind == "agent" && candidateNode.task.executor.tools.some((item) => item.kind == "workflow")))) throw new TypeError("Workflow tools require Flow model version 11.");
|
|
13100
13293
|
if (content.modelVersion < 10 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "webhook" && (candidateNode.options?.responseBody != null || candidateNode.options?.responseStatusCodeOutput != null || candidateNode.options?.responseHeadersSource != null || candidateNode.options?.responseHeaderOutputs != null))) throw new TypeError("Dynamic Webhook responses require Flow model version 10.");
|
|
13101
13294
|
if (content.modelVersion < 9 && Object.values(content.document.graph.nodes).some((candidateNode) => "retry" in candidateNode && candidateNode.retry != null)) throw new TypeError("Node retries require Flow model version 9.");
|
|
@@ -13110,6 +13303,81 @@ function checkModelVersion(content) {
|
|
|
13110
13303
|
if (content.modelVersion < 6 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task)) throw new TypeError("Node-owned managed Tasks require Flow model version 6.");
|
|
13111
13304
|
if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == "error")) throw new TypeError("Error workflows require Flow model version 5.");
|
|
13112
13305
|
}
|
|
13306
|
+
function assertDocumentHttpAuthBindings(content) {
|
|
13307
|
+
for (const graphNode of Object.values(content.graph.nodes)) if (graphNode.kind == "task" && "executor" in graphNode.task && ["openapi", "http-request"].includes(graphNode.task.executor.kind)) assertHttpAuthBindings(graphNode.inputs);
|
|
13308
|
+
}
|
|
13309
|
+
//#endregion
|
|
13310
|
+
//#region src/runtime/common/engineContract.ts
|
|
13311
|
+
/** v9 is a single contract: the Node compatibility builtins, `context.fetch`, and no `context.egress`. */
|
|
13312
|
+
var currentEngineContract = "open-flow-engine/v9";
|
|
13313
|
+
/** The published v8 Node compatibility contract, retained for existing Publications and Runs. */
|
|
13314
|
+
var nodejsEngineContract = "open-flow-engine/v8/nodejs-compat-v1";
|
|
13315
|
+
var platformSource = (contract) => `export const engineContract = ${JSON.stringify(contract)}
|
|
13316
|
+
export function identity(value) { return value }
|
|
13317
|
+
`;
|
|
13318
|
+
var v8Contract = {
|
|
13319
|
+
workflowTools: true,
|
|
13320
|
+
httpRequests: true,
|
|
13321
|
+
waitAutoContinue: true,
|
|
13322
|
+
webhookResponses: true,
|
|
13323
|
+
platformExports: /* @__PURE__ */ new Set(["engineContract", "identity"]),
|
|
13324
|
+
platformModule: "open-flow:platform",
|
|
13325
|
+
platformSource: platformSource("open-flow-engine/v8")
|
|
13326
|
+
};
|
|
13327
|
+
var nodejsContract = {
|
|
13328
|
+
...v8Contract,
|
|
13329
|
+
builtinModules: new Set([
|
|
13330
|
+
"assert",
|
|
13331
|
+
"assert/strict",
|
|
13332
|
+
"buffer",
|
|
13333
|
+
"console",
|
|
13334
|
+
"constants",
|
|
13335
|
+
"crypto",
|
|
13336
|
+
"events",
|
|
13337
|
+
"fs",
|
|
13338
|
+
"fs/promises",
|
|
13339
|
+
"os",
|
|
13340
|
+
"path",
|
|
13341
|
+
"path/posix",
|
|
13342
|
+
"process",
|
|
13343
|
+
"punycode",
|
|
13344
|
+
"querystring",
|
|
13345
|
+
"stream",
|
|
13346
|
+
"stream/promises",
|
|
13347
|
+
"stream/web",
|
|
13348
|
+
"string_decoder",
|
|
13349
|
+
"timers",
|
|
13350
|
+
"timers/promises",
|
|
13351
|
+
"url",
|
|
13352
|
+
"util",
|
|
13353
|
+
"zlib"
|
|
13354
|
+
].flatMap((name) => [name, `node:${name}`])),
|
|
13355
|
+
platformSource: platformSource(nodejsEngineContract)
|
|
13356
|
+
};
|
|
13357
|
+
var currentContract = {
|
|
13358
|
+
...nodejsContract,
|
|
13359
|
+
codeFetch: true,
|
|
13360
|
+
platformSource: platformSource(currentEngineContract)
|
|
13361
|
+
};
|
|
13362
|
+
function findEngineContract(contract) {
|
|
13363
|
+
if (contract == "open-flow-engine/v9") return currentContract;
|
|
13364
|
+
if (contract == "open-flow-engine/v8") return v8Contract;
|
|
13365
|
+
if (contract == "open-flow-engine/v8/nodejs-compat-v1") return nodejsContract;
|
|
13366
|
+
if (contract == "open-flow-engine/v7" || contract == "open-flow-engine/v7/nodejs-compat-v1") return {
|
|
13367
|
+
...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : v8Contract,
|
|
13368
|
+
workflowTools: false,
|
|
13369
|
+
httpRequests: false,
|
|
13370
|
+
platformSource: platformSource(contract)
|
|
13371
|
+
};
|
|
13372
|
+
if (contract == "open-flow-engine/v6" || contract == "open-flow-engine/v6/nodejs-compat-v1") return {
|
|
13373
|
+
...contract == "open-flow-engine/v6" ? v8Contract : nodejsContract,
|
|
13374
|
+
workflowTools: false,
|
|
13375
|
+
httpRequests: false,
|
|
13376
|
+
waitAutoContinue: false,
|
|
13377
|
+
webhookResponses: false,
|
|
13378
|
+
platformSource: platformSource(contract)
|
|
13379
|
+
};
|
|
13380
|
+
}
|
|
13113
13381
|
//#endregion
|
|
13114
13382
|
//#region src/control/common/authoringLlm.ts
|
|
13115
13383
|
var authoringLlmConfiguration = strictObject({
|
|
@@ -13696,6 +13964,7 @@ var authoringTypes = [
|
|
|
13696
13964
|
"llm",
|
|
13697
13965
|
"decision",
|
|
13698
13966
|
"openapi",
|
|
13967
|
+
"http-request",
|
|
13699
13968
|
"condition",
|
|
13700
13969
|
"value",
|
|
13701
13970
|
"wait",
|
|
@@ -13758,11 +14027,15 @@ var agentTool = union([workflowAgentToolSchema.omit({
|
|
|
13758
14027
|
id: true,
|
|
13759
14028
|
inputs: true
|
|
13760
14029
|
}).extend({ inputs: toolSources }).strict()]);
|
|
13761
|
-
var authoringCapabilities = array(union([
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
14030
|
+
var authoringCapabilities = array(union([
|
|
14031
|
+
connectorCapabilitySchema,
|
|
14032
|
+
strictObject({
|
|
14033
|
+
kind: literal("workflow"),
|
|
14034
|
+
name: id$1,
|
|
14035
|
+
flowId: id$1
|
|
14036
|
+
}),
|
|
14037
|
+
httpCapabilitySchema
|
|
14038
|
+
]));
|
|
13766
14039
|
var notification = strictObject({
|
|
13767
14040
|
...authoringDefinitionSchemas.connector.shape,
|
|
13768
14041
|
messageHandle: id$1,
|
|
@@ -13822,6 +14095,7 @@ var authoringConfigurations = {
|
|
|
13822
14095
|
}),
|
|
13823
14096
|
"connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
|
|
13824
14097
|
"openapi": authoringOpenApiSchema,
|
|
14098
|
+
"http-request": httpRequestConfigSchema,
|
|
13825
14099
|
"agent": authoringDefinitionSchemas.agent.omit({
|
|
13826
14100
|
prompt: true,
|
|
13827
14101
|
tools: true
|
|
@@ -14023,6 +14297,7 @@ var requestContracts = {
|
|
|
14023
14297
|
examples: [{ revisionId: "REVISION" }]
|
|
14024
14298
|
}
|
|
14025
14299
|
};
|
|
14300
|
+
var codeGuidance = `Code is an ES module whose default export receives (inputs, context) and returns the business outputs. It may import the Node builtins ${[...findEngineContract(currentEngineContract).builtinModules].filter((name) => !name.startsWith("node:")).join(", ")}, with or without the node: prefix; fs is a fresh in-memory filesystem containing /tmp per execution. require, dynamic import, packages and the http/net builtins are unavailable. To call HTTP APIs, declare their hosts in config.capabilities as {kind: "http", hosts: ["api.example.com", "*.example.org"]} and use context.fetch(url, {method, headers, body}); it returns status, ok, headers.get(), text(), json() and bytes(), does not follow redirects, adds no credentials, and limits bodies to 1 MiB. Prefer an HTTP Request node for a single call without transformation and Connector Actions for services with accounts. context provides inputs, signal, getPrevious(), fetch, actions, workflows, artifact, flowId, runId and blockId. 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.`;
|
|
14026
14301
|
/** Transport-independent discovery of the same requests the service validates. */
|
|
14027
14302
|
function authoringRequestContract(name) {
|
|
14028
14303
|
if (!Object.hasOwn(requestContracts, name)) return void 0;
|
|
@@ -14070,21 +14345,21 @@ function authoringSchema(kind) {
|
|
|
14070
14345
|
"wait",
|
|
14071
14346
|
"approval"
|
|
14072
14347
|
].includes(kind),
|
|
14073
|
-
guidance: kind == "webhook-response" ? "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." : kind == "outputs" ? "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." : kind == "webhook" ? "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." : kind == "start" ? "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." : kind == "condition" ? "Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise." : ["poll", "integration"].includes(kind) ? "Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable." : kind == "llm" ? "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}}." : kind == "openapi" ? "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." : kind == "workflow" ? "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." : kind == "agent" ? "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." : kind == "code" ?
|
|
14348
|
+
guidance: kind == "webhook-response" ? "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." : kind == "outputs" ? "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." : kind == "webhook" ? "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." : kind == "start" ? "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." : kind == "condition" ? "Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise." : ["poll", "integration"].includes(kind) ? "Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable." : kind == "llm" ? "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}}." : kind == "http-request" ? "Configure method, query/headers modes and names, bodyFormat, authentication, responseFormat and statusPolicy. Bind url, query.<name>/header.<name> or whole query/headers objects, body and auth.token (Basic: auth.username/auth.password). Credentials accept variables or upstream outputs only. Outputs: body, statusCode, headers. Authentication is replaced as a complete choice." : kind == "openapi" ? "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." : kind == "workflow" ? "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." : kind == "agent" ? "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." : kind == "code" ? codeGuidance : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
|
|
14074
14349
|
example: {
|
|
14075
14350
|
op: "node.add",
|
|
14076
14351
|
as: "step",
|
|
14077
14352
|
type: kind,
|
|
14078
14353
|
name: "Step",
|
|
14079
14354
|
...{
|
|
14080
|
-
start: { config: { inputDefs: {} } },
|
|
14081
|
-
outputs: { config: { outputDefs: {} } },
|
|
14082
|
-
workflow: { config: { flowId: "<Flow ID>" } },
|
|
14083
|
-
connector: { config: {
|
|
14355
|
+
"start": { config: { inputDefs: {} } },
|
|
14356
|
+
"outputs": { config: { outputDefs: {} } },
|
|
14357
|
+
"workflow": { config: { flowId: "<Flow ID>" } },
|
|
14358
|
+
"connector": { config: {
|
|
14084
14359
|
action: "<Action ID>",
|
|
14085
14360
|
connectionId: "<Connection ID>"
|
|
14086
14361
|
} },
|
|
14087
|
-
poll: { config: {
|
|
14362
|
+
"poll": { config: {
|
|
14088
14363
|
key: "<Trigger key>",
|
|
14089
14364
|
schedule: [{
|
|
14090
14365
|
type: "every",
|
|
@@ -14092,20 +14367,27 @@ function authoringSchema(kind) {
|
|
|
14092
14367
|
value: 5
|
|
14093
14368
|
}]
|
|
14094
14369
|
} },
|
|
14095
|
-
integration: { config: { key: "<Trigger key>" } },
|
|
14096
|
-
|
|
14370
|
+
"integration": { config: { key: "<Trigger key>" } },
|
|
14371
|
+
"http-request": {
|
|
14372
|
+
config: {},
|
|
14373
|
+
inputs: { url: {
|
|
14374
|
+
kind: "value",
|
|
14375
|
+
value: "https://example.com"
|
|
14376
|
+
} }
|
|
14377
|
+
},
|
|
14378
|
+
"openapi": { config: {
|
|
14097
14379
|
sourceUrl: "https://example.com/openapi.json",
|
|
14098
14380
|
path: "/items",
|
|
14099
14381
|
method: "get"
|
|
14100
14382
|
} },
|
|
14101
|
-
code: {
|
|
14383
|
+
"code": {
|
|
14102
14384
|
code: "export default ({value}) => ({result:value})",
|
|
14103
14385
|
inputs: { value: {
|
|
14104
14386
|
kind: "value",
|
|
14105
14387
|
value: "Hello"
|
|
14106
14388
|
} }
|
|
14107
14389
|
},
|
|
14108
|
-
condition: { config: {
|
|
14390
|
+
"condition": { config: {
|
|
14109
14391
|
match: "first",
|
|
14110
14392
|
branches: [{
|
|
14111
14393
|
name: "yes",
|
|
@@ -14122,32 +14404,32 @@ function authoringSchema(kind) {
|
|
|
14122
14404
|
}
|
|
14123
14405
|
}]
|
|
14124
14406
|
} },
|
|
14125
|
-
value: { config: { values: {
|
|
14407
|
+
"value": { config: { values: {
|
|
14126
14408
|
threshold: 100,
|
|
14127
14409
|
region: "EU"
|
|
14128
14410
|
} } },
|
|
14129
|
-
webhook: { config: {
|
|
14411
|
+
"webhook": { config: {
|
|
14130
14412
|
method: "POST",
|
|
14131
14413
|
body: { orderId: {
|
|
14132
14414
|
schema: { type: "string" },
|
|
14133
14415
|
nullable: false
|
|
14134
14416
|
} }
|
|
14135
14417
|
} },
|
|
14136
|
-
wait: {
|
|
14418
|
+
"wait": {
|
|
14137
14419
|
prompt: "Continue processing this order?",
|
|
14138
14420
|
inputs: { order: {
|
|
14139
14421
|
kind: "value",
|
|
14140
14422
|
value: { orderId: "A-1" }
|
|
14141
14423
|
} }
|
|
14142
14424
|
},
|
|
14143
|
-
approval: {
|
|
14425
|
+
"approval": {
|
|
14144
14426
|
prompt: "Approve this order?",
|
|
14145
14427
|
inputs: { order: {
|
|
14146
14428
|
kind: "value",
|
|
14147
14429
|
value: { orderId: "A-1" }
|
|
14148
14430
|
} }
|
|
14149
14431
|
},
|
|
14150
|
-
llm: {
|
|
14432
|
+
"llm": {
|
|
14151
14433
|
config: {
|
|
14152
14434
|
model: { model: "deepseek-v4-flash" },
|
|
14153
14435
|
template: [{
|
|
@@ -14163,7 +14445,7 @@ function authoringSchema(kind) {
|
|
|
14163
14445
|
}
|
|
14164
14446
|
} }
|
|
14165
14447
|
},
|
|
14166
|
-
agent: {
|
|
14448
|
+
"agent": {
|
|
14167
14449
|
config: { model: "deepseek-v4-flash" },
|
|
14168
14450
|
inputs: { orders: {
|
|
14169
14451
|
kind: "value",
|
|
@@ -14353,6 +14635,11 @@ function nodeSystemOutputPorts(node) {
|
|
|
14353
14635
|
nullable: true
|
|
14354
14636
|
} } : {};
|
|
14355
14637
|
}
|
|
14638
|
+
//#endregion
|
|
14639
|
+
//#region src/flow/common/model.ts
|
|
14640
|
+
function portsByHandle(ports) {
|
|
14641
|
+
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
14642
|
+
}
|
|
14356
14643
|
function resourceNameIssue(value) {
|
|
14357
14644
|
const name = value.trim();
|
|
14358
14645
|
if (name.length == 0) return "empty";
|
|
@@ -14363,9 +14650,6 @@ function resourceNameIssue(value) {
|
|
|
14363
14650
|
}
|
|
14364
14651
|
if (!/^[\p{L}\p{N}](?:[\p{L}\p{N} _-]*[\p{L}\p{N}])?$/u.test(name)) return "specialCharacter";
|
|
14365
14652
|
}
|
|
14366
|
-
function portsByHandle(ports) {
|
|
14367
|
-
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
14368
|
-
}
|
|
14369
14653
|
var workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
14370
14654
|
function workflowToolNameIssue(name, otherNames = []) {
|
|
14371
14655
|
if (!workflowToolNamePattern.test(name)) return "invalid";
|
|
@@ -14381,6 +14665,8 @@ function decodeTaskCapabilities(value) {
|
|
|
14381
14665
|
if (workflowToolNameIssue(item.name, names)) throw new TypeError("Workflow tool names must be unique provider-compatible names.");
|
|
14382
14666
|
names.add(item.name);
|
|
14383
14667
|
}
|
|
14668
|
+
const http = parsed.filter((item) => item.kind == "http");
|
|
14669
|
+
if (http.length > 1 || http.some((item) => new Set(item.hosts).size != item.hosts.length)) throw new TypeError("Code declares HTTP hosts once, without duplicates.");
|
|
14384
14670
|
let connectorIndex = 0;
|
|
14385
14671
|
return parsed.map((item) => item.kind == "connector" ? connectors[connectorIndex++] : item);
|
|
14386
14672
|
}
|
|
@@ -14516,10 +14802,10 @@ function upgradeRevisionContent(content) {
|
|
|
14516
14802
|
function upgradeDecodedRevisionContent(content) {
|
|
14517
14803
|
const graph = content.document.graph;
|
|
14518
14804
|
const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
|
|
14519
|
-
if (!hasManual && content.modelVersion ==
|
|
14805
|
+
if (!hasManual && content.modelVersion == 12) return content;
|
|
14520
14806
|
return {
|
|
14521
14807
|
...content,
|
|
14522
|
-
modelVersion:
|
|
14808
|
+
modelVersion: 12,
|
|
14523
14809
|
document: {
|
|
14524
14810
|
...content.document,
|
|
14525
14811
|
graph: hasManual ? {
|
|
@@ -14554,7 +14840,7 @@ function invalid(message) {
|
|
|
14554
14840
|
throw new FlowChangeError(message);
|
|
14555
14841
|
}
|
|
14556
14842
|
function applyFlowChanges(content, operations) {
|
|
14557
|
-
const source = content.modelVersion !=
|
|
14843
|
+
const source = content.modelVersion != 12 || Object.values(content.document.graph.nodes).some((node) => node.kind == "manual") ? decodeRevisionContent(content) : content;
|
|
14558
14844
|
const document = { ...source.document };
|
|
14559
14845
|
const modules = { ...source.modules };
|
|
14560
14846
|
for (const operation of operations) switch (operation.kind) {
|
|
@@ -14999,10 +15285,10 @@ function applyFlowChanges(content, operations) {
|
|
|
14999
15285
|
break;
|
|
15000
15286
|
}
|
|
15001
15287
|
}
|
|
15002
|
-
|
|
15288
|
+
assertDocumentHttpAuthBindings(document);
|
|
15003
15289
|
return upgradeDecodedRevisionContent({
|
|
15004
15290
|
document,
|
|
15005
|
-
modelVersion:
|
|
15291
|
+
modelVersion: 12,
|
|
15006
15292
|
modules
|
|
15007
15293
|
});
|
|
15008
15294
|
}
|
|
@@ -15266,42 +15552,6 @@ async function imports(source) {
|
|
|
15266
15552
|
}
|
|
15267
15553
|
}
|
|
15268
15554
|
//#endregion
|
|
15269
|
-
//#region src/flow/common/portChanges.ts
|
|
15270
|
-
function renamedPort(previous, next) {
|
|
15271
|
-
const previousNames = new Set(previous.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
15272
|
-
const nextNames = new Set(next.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
15273
|
-
const removed = [...previousNames].filter((name) => !nextNames.has(name));
|
|
15274
|
-
const added = [...nextNames].filter((name) => !previousNames.has(name));
|
|
15275
|
-
return removed.length == 1 && added.length == 1 ? [removed[0], added[0]] : void 0;
|
|
15276
|
-
}
|
|
15277
|
-
function renameOutputMapping(mapping, nodeIds, rename) {
|
|
15278
|
-
if (rename == null || mapping.kind != "sources") return mapping;
|
|
15279
|
-
const sources = mapping.sources.map((source) => source.kind == "node" && !source.system && nodeIds.has(source.nodeId) && source.output == rename[0] ? {
|
|
15280
|
-
...source,
|
|
15281
|
-
output: rename[1]
|
|
15282
|
-
} : source);
|
|
15283
|
-
return sources.every((source, index) => source === mapping.sources[index]) ? mapping : {
|
|
15284
|
-
kind: "sources",
|
|
15285
|
-
sources
|
|
15286
|
-
};
|
|
15287
|
-
}
|
|
15288
|
-
/** Carry saved mappings through a field rename and remove only fields absent from the new contract. */
|
|
15289
|
-
function remapInputMappings(mappings, ports, rename) {
|
|
15290
|
-
const inputs = { ...mappings };
|
|
15291
|
-
if (rename != null && Object.hasOwn(inputs, rename[0])) {
|
|
15292
|
-
Object.defineProperty(inputs, rename[1], {
|
|
15293
|
-
value: inputs[rename[0]],
|
|
15294
|
-
enumerable: true,
|
|
15295
|
-
configurable: true,
|
|
15296
|
-
writable: true
|
|
15297
|
-
});
|
|
15298
|
-
delete inputs[rename[0]];
|
|
15299
|
-
}
|
|
15300
|
-
const names = new Set(ports.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
15301
|
-
for (const name of Object.keys(inputs)) if (!names.has(name)) delete inputs[name];
|
|
15302
|
-
return inputs;
|
|
15303
|
-
}
|
|
15304
|
-
//#endregion
|
|
15305
15555
|
//#region src/flow/common/nodeChanges.ts
|
|
15306
15556
|
var codeTaskTemplate = `export default async function (inputs, context) {
|
|
15307
15557
|
return { result: inputs.value }
|
|
@@ -16263,7 +16513,10 @@ function authoringNode(content, ref) {
|
|
|
16263
16513
|
inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
|
|
16264
16514
|
};
|
|
16265
16515
|
else if (task.executor.kind == "workflow") config = { flowId: task.executor.flowId };
|
|
16266
|
-
else if (task.executor.kind == "
|
|
16516
|
+
else if (task.executor.kind == "http-request") {
|
|
16517
|
+
const { kind: _kind, ...settings } = task.executor;
|
|
16518
|
+
config = settings;
|
|
16519
|
+
} else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
|
|
16267
16520
|
} else if (node.kind == "task" && "moduleId" in node.task) {
|
|
16268
16521
|
config = {
|
|
16269
16522
|
inputs: fieldsView([...node.task.inputs, ...node.additionalInputs ?? []]),
|
|
@@ -16564,7 +16817,7 @@ async function compileAuthoring(base, request, host) {
|
|
|
16564
16817
|
const timing = record(record(patch.config).autoContinue);
|
|
16565
16818
|
if (Object.hasOwn(timing, "kind") && timing.kind != record(record(view.config).autoContinue).kind) record(update.config).autoContinue = timing;
|
|
16566
16819
|
}
|
|
16567
|
-
if (type == "openapi" && Object.hasOwn(record(patch.config), "authentication")) record(update.config).authentication = record(patch.config).authentication;
|
|
16820
|
+
if ((type == "openapi" || type == "http-request") && Object.hasOwn(record(patch.config), "authentication")) record(update.config).authentication = record(patch.config).authentication;
|
|
16568
16821
|
for (const path of clear) clearPath(update, path);
|
|
16569
16822
|
if (typeof update.name != "string") fail("node.name-required", "Node name cannot be cleared.");
|
|
16570
16823
|
const config = authoringConfigurations[type].parse(update.config);
|
|
@@ -16650,7 +16903,13 @@ async function compileAuthoring(base, request, host) {
|
|
|
16650
16903
|
};
|
|
16651
16904
|
} else task = await connectorTask(config, String(update.name));
|
|
16652
16905
|
} else if (type == "decision") task = decisionTask(config.questions, String(update.name));
|
|
16653
|
-
else if (type == "
|
|
16906
|
+
else if (type == "http-request") {
|
|
16907
|
+
task = httpRequestTask(httpRequestConfigSchema.parse(config), String(update.name), before);
|
|
16908
|
+
next = {
|
|
16909
|
+
...next,
|
|
16910
|
+
inputs: httpRequestInputs(node.inputs, before, task)
|
|
16911
|
+
};
|
|
16912
|
+
} else if (type == "openapi") task = await prepareOpenApiTask(config, before, (url) => host.openapi(url), String(update.name), {
|
|
16654
16913
|
authentication: explicit("authentication"),
|
|
16655
16914
|
serverUrl: explicit("serverUrl")
|
|
16656
16915
|
});
|
|
@@ -16991,6 +17250,9 @@ async function compileAuthoring(base, request, host) {
|
|
|
16991
17250
|
case "connector":
|
|
16992
17251
|
changes = createManagedTask(identity, await connectorTask(config, name));
|
|
16993
17252
|
break;
|
|
17253
|
+
case "http-request":
|
|
17254
|
+
changes = createManagedTask(identity, httpRequestTask(httpRequestConfigSchema.parse(config), name));
|
|
17255
|
+
break;
|
|
16994
17256
|
case "openapi":
|
|
16995
17257
|
changes = createManagedTask(identity, await prepareOpenApiTask(authoringConfigurations.openapi.parse(config), void 0, (url) => host.openapi(url), name));
|
|
16996
17258
|
break;
|
|
@@ -17209,6 +17471,7 @@ var descriptions = {
|
|
|
17209
17471
|
"poll": "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection.",
|
|
17210
17472
|
"integration": "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.",
|
|
17211
17473
|
"decision": "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.",
|
|
17474
|
+
"http-request": "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers.",
|
|
17212
17475
|
"openapi": "A fixed JSON API operation. Replace the example document and URL before running.",
|
|
17213
17476
|
"connector": "A Connector Task and its node. Replace ACTION_ID, CONNECTION_ID and port definitions using connector_get / connector show. Set connectionId to an empty string to defer account configuration; execution will require an account.",
|
|
17214
17477
|
"code": "A JavaScript module and its node. Use Code for custom computation; use Connector Tasks for existing actions.",
|
|
@@ -17252,6 +17515,17 @@ function authoringExample(name) {
|
|
|
17252
17515
|
instructions: "Does the customer need support?"
|
|
17253
17516
|
}]);
|
|
17254
17517
|
break;
|
|
17518
|
+
case "http-request":
|
|
17519
|
+
operations = [...createManagedTask({ nodeId: "http" }, httpRequestTask()), {
|
|
17520
|
+
kind: "graph.node.input.set",
|
|
17521
|
+
nodeId: "http",
|
|
17522
|
+
handle: "url",
|
|
17523
|
+
value: {
|
|
17524
|
+
kind: "value",
|
|
17525
|
+
value: "https://example.com"
|
|
17526
|
+
}
|
|
17527
|
+
}];
|
|
17528
|
+
break;
|
|
17255
17529
|
case "openapi":
|
|
17256
17530
|
operations = createManagedTask({ nodeId: "api" }, openApiTask(selectOperation({
|
|
17257
17531
|
openapi: "3.1.0",
|