@oomol-lab/open-flow 0.1.0-beta.75 → 0.1.0-beta.77
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-FCpKiwjp.js → ContentIcon-VZQO8VZU.js} +9 -6
- package/dist/browser/{FlowCanvas-dzRBnlUT.js → FlowCanvas-BNGDMaWr.js} +75 -63
- package/dist/browser/{createResourceDialog-BeYDdUl-.js → createResourceDialog-BmtakfVg.js} +63 -57
- package/dist/browser/{dialog-ZtpsFbl4.js → dialog-BcFBfRB1.js} +126 -32
- package/dist/browser/{exportSvg-DqXw1yf-.js → exportSvg-CG8hEUNk.js} +2 -2
- package/dist/browser/{flowChanges-b_5UobFj.js → flowChanges-BGo_4Ypo.js} +6063 -11285
- package/dist/browser/{flowWorkspace-ItojZbO4.js → flowWorkspace-BFHGev7s.js} +1065 -2570
- package/dist/browser/preview.css +626 -653
- package/dist/browser/preview.js +1907 -9663
- package/dist/browser/theme.css +117 -263
- package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-BAWSUexx.js} +2 -2
- package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-CRoezJPN.js} +1 -1
- package/dist/browser/ui.css +464 -463
- package/dist/browser/ui.js +4 -3
- package/dist/browser/workbench.css +9891 -9897
- package/dist/browser/workbench.d.ts +6 -2
- package/dist/browser/workbench.js +838 -499
- package/dist/browser/{workbenchSelect-M441Lz0d.js → workbenchSelect-CjK-xdm3.js} +2 -2
- package/dist/command/index.js +48 -50
- package/dist/common/authoring.d.ts +5 -5
- package/dist/common/authoringExamples.d.ts +3 -2
- package/dist/common/authoringSchema.d.ts +26 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.js +352 -144
- package/dist/common/control-api-errors.d.ts +12 -0
- package/dist/common/control-api.d.ts +38 -4
- package/dist/common/control-api.js +373 -162
- package/dist/common/control-requests.d.ts +22 -3
- package/dist/common/control-requests.js +268 -28
- 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 -20
- package/dist/common/flow-change-schema.d.ts +9 -1
- package/dist/common/flow-change.d.ts +8 -202
- package/dist/common/flow-change.js +96 -24
- package/dist/common/flow-encoding.js +89 -21
- 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 +2 -4
- package/dist/common/flow-semantics.js +161 -80
- package/dist/common/flow-state.d.ts +123 -0
- package/dist/common/flow-state.js +5852 -0
- 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 +13 -5
- package/dist/common/http-request.js +23 -5
- package/dist/common/integration-trigger.d.ts +2 -1
- package/dist/common/mcp.d.ts +96 -3
- package/dist/common/mcp.js +355 -142
- 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 +1 -0
- package/dist/common/runtime-contract.d.ts +37 -1
- package/dist/common/runtime-contract.js +717 -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 +2 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +76 -6
- package/dist/common/state-conformance.d.ts +16 -0
- package/dist/common/tags.d.ts +4 -0
- 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 -1
- package/dist/common/webhook-trigger.d.ts +3 -1
- package/dist/common/workflow.d.ts +3 -12
- package/dist/common/workflow.js +25 -23
- package/dist/index.d.ts +52 -14
- package/package.json +9 -1
- package/src/base/common/json.ts +1 -1
- package/src/connector/common/proxy.ts +1 -1
- package/src/control/common/api.ts +90 -16
- package/src/control/common/authoring.ts +6 -1
- package/src/control/common/authoringExamples.ts +8 -0
- package/src/control/common/authoringSchema.ts +26 -13
- 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/errors.ts +6 -0
- package/src/control/common/eventSources.ts +2 -29
- package/src/control/common/flowDecoders.ts +1 -0
- package/src/control/common/mcp.ts +16 -0
- package/src/control/common/requests.ts +10 -2
- package/src/control/common/tags.ts +20 -0
- 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 +4 -1
- package/src/execution/common/scheduler.ts +3 -1
- package/src/flow/common/change.ts +60 -193
- package/src/flow/common/changeSchema.ts +39 -4
- package/src/flow/common/connectionUsage.ts +1 -1
- package/src/flow/common/errorHandling.ts +1 -1
- 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 +2 -4
- package/src/flow/common/semantics.ts +31 -4
- package/src/flow/common/webhookResponse.ts +1 -1
- package/src/flow/common/workflowReferences.ts +31 -0
- package/src/http/common/authBindings.ts +6 -9
- package/src/http/common/hosts.ts +13 -0
- package/src/http/common/httpRequest.ts +30 -15
- package/src/openapi/common/openapi.ts +9 -5
- package/src/{execution → runtime}/common/engineContract.ts +23 -15
- package/src/runtime/common/nodejsCompat.ts +275 -0
- package/src/runtime/common/nodejsGuest.generated.json +47 -0
- package/src/runtime/common/runtime.ts +1254 -0
- package/src/state/common/conformance.ts +86 -0
- package/src/state/common/state.ts +169 -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 +3 -1
- 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 +55 -15
- package/src/workflow/common/workflow.ts +3 -44
- package/src/execution/common/runtime.ts +0 -563
- /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
|
@@ -35,7 +35,7 @@ export declare const controlRequests: {
|
|
|
35
35
|
edits: ({
|
|
36
36
|
op: "node.add";
|
|
37
37
|
as: string;
|
|
38
|
-
type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
|
|
38
|
+
type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
|
|
39
39
|
name: string;
|
|
40
40
|
onError?: "error" | "stop" | undefined;
|
|
41
41
|
retry?: {
|
|
@@ -178,12 +178,12 @@ export declare const controlRequests: {
|
|
|
178
178
|
authoringSearch: (value: unknown) => {
|
|
179
179
|
revision?: string | undefined;
|
|
180
180
|
query: string;
|
|
181
|
-
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
181
|
+
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
182
182
|
offset: number;
|
|
183
183
|
limit: number;
|
|
184
184
|
};
|
|
185
185
|
authoringSchema: (value: unknown) => {
|
|
186
|
-
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
186
|
+
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
187
187
|
action?: string | undefined;
|
|
188
188
|
};
|
|
189
189
|
loadOpenApiDocument: (value: unknown) => {
|
|
@@ -200,11 +200,30 @@ export declare const controlRequests: {
|
|
|
200
200
|
file: JsonValue;
|
|
201
201
|
name?: string | undefined;
|
|
202
202
|
teamId?: string | undefined;
|
|
203
|
+
tagIds?: string[] | undefined;
|
|
203
204
|
version: 1;
|
|
204
205
|
};
|
|
205
206
|
createFlow: (value: unknown) => {
|
|
206
207
|
name: string;
|
|
207
208
|
teamId?: string | undefined;
|
|
209
|
+
tagIds?: string[] | undefined;
|
|
210
|
+
version: 1;
|
|
211
|
+
};
|
|
212
|
+
saveTag: (value: unknown) => {
|
|
213
|
+
name: string;
|
|
214
|
+
version: 1;
|
|
215
|
+
};
|
|
216
|
+
setFlowTags: (value: unknown) => {
|
|
217
|
+
tagIds: string[];
|
|
218
|
+
version: 1;
|
|
219
|
+
};
|
|
220
|
+
updateFlow: (value: unknown) => {
|
|
221
|
+
name: string;
|
|
222
|
+
tagIds?: string[] | undefined;
|
|
223
|
+
version: 1;
|
|
224
|
+
} | {
|
|
225
|
+
name?: string | undefined;
|
|
226
|
+
tagIds: string[];
|
|
208
227
|
version: 1;
|
|
209
228
|
};
|
|
210
229
|
renameFlow: (value: unknown) => {
|
|
@@ -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;
|
|
@@ -12286,12 +12289,17 @@ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decisi
|
|
|
12286
12289
|
}
|
|
12287
12290
|
//#endregion
|
|
12288
12291
|
//#region src/http/common/authBindings.ts
|
|
12289
|
-
/** Never allow credentials to enter a Revision as literal node
|
|
12290
|
-
function assertHttpAuthBindings(
|
|
12291
|
-
for (const
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
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("."));
|
|
12295
12303
|
}
|
|
12296
12304
|
//#endregion
|
|
12297
12305
|
//#region src/flow/common/portChanges.ts
|
|
@@ -12465,6 +12473,71 @@ function httpRequestInputs(mappings, previous, next) {
|
|
|
12465
12473
|
const rename = candidate != null && ["query.", "header."].some((prefix) => candidate.every((name) => name.startsWith(prefix))) ? candidate : void 0;
|
|
12466
12474
|
return remapInputMappings(mappings, next.inputs, rename);
|
|
12467
12475
|
}
|
|
12476
|
+
strictObject({
|
|
12477
|
+
scope: _enum(["draft", "live"]),
|
|
12478
|
+
values: boolean().optional()
|
|
12479
|
+
});
|
|
12480
|
+
strictObject({
|
|
12481
|
+
scope: _enum(["draft", "live"]),
|
|
12482
|
+
key: string().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
|
|
12483
|
+
});
|
|
12484
|
+
strictObject({
|
|
12485
|
+
scope: _enum(["draft", "live"]),
|
|
12486
|
+
space: string().regex(/^(flow|node:.+)$/)
|
|
12487
|
+
});
|
|
12488
|
+
var dedupeConfigSchema = strictObject({
|
|
12489
|
+
field: string().default(""),
|
|
12490
|
+
mode: _enum(["new", "increasing"]).default("new"),
|
|
12491
|
+
space: _enum(["node", "flow"]).default("node")
|
|
12492
|
+
});
|
|
12493
|
+
var dedupeExecutorSchema = dedupeConfigSchema.extend({ kind: literal("dedupe") });
|
|
12494
|
+
function dedupeTask(config = dedupeConfigSchema.parse({}), name = "Remove Duplicates") {
|
|
12495
|
+
return {
|
|
12496
|
+
name,
|
|
12497
|
+
executor: {
|
|
12498
|
+
...config,
|
|
12499
|
+
kind: "dedupe"
|
|
12500
|
+
},
|
|
12501
|
+
inputs: [{
|
|
12502
|
+
handle: "items",
|
|
12503
|
+
jsonSchema: { type: "array" },
|
|
12504
|
+
nullable: false
|
|
12505
|
+
}],
|
|
12506
|
+
outputs: ["items", "duplicates"].map((handle) => ({
|
|
12507
|
+
handle,
|
|
12508
|
+
jsonSchema: { type: "array" },
|
|
12509
|
+
nullable: false
|
|
12510
|
+
}))
|
|
12511
|
+
};
|
|
12512
|
+
}
|
|
12513
|
+
object$1({
|
|
12514
|
+
version: literal(1),
|
|
12515
|
+
scope: _enum(["draft", "live"]),
|
|
12516
|
+
limits: object$1({
|
|
12517
|
+
maxValueBytes: number().positive(),
|
|
12518
|
+
maxValues: number().int().positive(),
|
|
12519
|
+
maxSpaces: number().int().positive(),
|
|
12520
|
+
maxIdentities: number().positive(),
|
|
12521
|
+
maxRunWrites: number().positive()
|
|
12522
|
+
}),
|
|
12523
|
+
values: array(object$1({
|
|
12524
|
+
key: string(),
|
|
12525
|
+
size: number().nonnegative(),
|
|
12526
|
+
updatedAt: number(),
|
|
12527
|
+
value: json$5().optional()
|
|
12528
|
+
})),
|
|
12529
|
+
spaces: array(object$1({
|
|
12530
|
+
space: string(),
|
|
12531
|
+
mode: _enum(["new", "increasing"]),
|
|
12532
|
+
count: number().nonnegative(),
|
|
12533
|
+
watermark: union([
|
|
12534
|
+
string(),
|
|
12535
|
+
number(),
|
|
12536
|
+
_null()
|
|
12537
|
+
]),
|
|
12538
|
+
updatedAt: number()
|
|
12539
|
+
}))
|
|
12540
|
+
});
|
|
12468
12541
|
function checkJsonDepth(value, depth = 0) {
|
|
12469
12542
|
if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
|
|
12470
12543
|
if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
|
|
@@ -12665,7 +12738,15 @@ var workflowCapabilitySchema = strictObject({
|
|
|
12665
12738
|
inputs: array(port),
|
|
12666
12739
|
outputs: array(port).nullable()
|
|
12667
12740
|
});
|
|
12668
|
-
var
|
|
12741
|
+
var httpCapabilitySchema = strictObject({
|
|
12742
|
+
kind: literal("http"),
|
|
12743
|
+
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.")
|
|
12744
|
+
});
|
|
12745
|
+
var capability = union([
|
|
12746
|
+
connectorCapabilitySchema,
|
|
12747
|
+
workflowCapabilitySchema,
|
|
12748
|
+
httpCapabilitySchema
|
|
12749
|
+
]);
|
|
12669
12750
|
var inline = object$1({
|
|
12670
12751
|
...ports,
|
|
12671
12752
|
name: text$1,
|
|
@@ -12776,7 +12857,8 @@ var managedFields = object$1({
|
|
|
12776
12857
|
flowId: text$1,
|
|
12777
12858
|
revisionId: text$1
|
|
12778
12859
|
}),
|
|
12779
|
-
httpRequestExecutorSchema
|
|
12860
|
+
httpRequestExecutorSchema,
|
|
12861
|
+
dedupeExecutorSchema
|
|
12780
12862
|
])
|
|
12781
12863
|
});
|
|
12782
12864
|
var managed = managedFields.transform(limitDecisionTask);
|
|
@@ -13045,7 +13127,9 @@ var revision = object$1({
|
|
|
13045
13127
|
literal(8),
|
|
13046
13128
|
literal(9),
|
|
13047
13129
|
literal(10),
|
|
13048
|
-
literal(11)
|
|
13130
|
+
literal(11),
|
|
13131
|
+
literal(12),
|
|
13132
|
+
literal(13)
|
|
13049
13133
|
]),
|
|
13050
13134
|
document,
|
|
13051
13135
|
modules: record$3(text$1, module)
|
|
@@ -13076,7 +13160,7 @@ function decodeRevisionContent(value) {
|
|
|
13076
13160
|
checkJsonDepth(value);
|
|
13077
13161
|
const content = revision.parse(value);
|
|
13078
13162
|
checkModelVersion(content);
|
|
13079
|
-
|
|
13163
|
+
assertDocumentHttpAuthBindings(content.document);
|
|
13080
13164
|
return content;
|
|
13081
13165
|
}
|
|
13082
13166
|
var shapes = {
|
|
@@ -13270,6 +13354,8 @@ function changeOperationsSchema(kind) {
|
|
|
13270
13354
|
return toJSONSchema(schema, { io: "input" });
|
|
13271
13355
|
}
|
|
13272
13356
|
function checkModelVersion(content) {
|
|
13357
|
+
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "dedupe")) throw new Error("Deduplication requires Flow model v13.");
|
|
13358
|
+
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.");
|
|
13273
13359
|
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.");
|
|
13274
13360
|
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.");
|
|
13275
13361
|
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.");
|
|
@@ -13285,6 +13371,87 @@ function checkModelVersion(content) {
|
|
|
13285
13371
|
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.");
|
|
13286
13372
|
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.");
|
|
13287
13373
|
}
|
|
13374
|
+
function assertDocumentHttpAuthBindings(content) {
|
|
13375
|
+
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);
|
|
13376
|
+
}
|
|
13377
|
+
//#endregion
|
|
13378
|
+
//#region src/runtime/common/engineContract.ts
|
|
13379
|
+
/** v10 adds persistent Flow State to the published v9 Node compatibility and fetch contract. */
|
|
13380
|
+
var currentEngineContract = "open-flow-engine/v10";
|
|
13381
|
+
/** The published v8 Node compatibility contract, retained for existing Publications and Runs. */
|
|
13382
|
+
var nodejsEngineContract = "open-flow-engine/v8/nodejs-compat-v1";
|
|
13383
|
+
var platformSource = (contract) => `export const engineContract = ${JSON.stringify(contract)}
|
|
13384
|
+
export function identity(value) { return value }
|
|
13385
|
+
`;
|
|
13386
|
+
var v8Contract = {
|
|
13387
|
+
workflowTools: true,
|
|
13388
|
+
httpRequests: true,
|
|
13389
|
+
waitAutoContinue: true,
|
|
13390
|
+
webhookResponses: true,
|
|
13391
|
+
platformExports: /* @__PURE__ */ new Set(["engineContract", "identity"]),
|
|
13392
|
+
platformModule: "open-flow:platform",
|
|
13393
|
+
platformSource: platformSource("open-flow-engine/v8")
|
|
13394
|
+
};
|
|
13395
|
+
var nodejsContract = {
|
|
13396
|
+
...v8Contract,
|
|
13397
|
+
builtinModules: new Set([
|
|
13398
|
+
"assert",
|
|
13399
|
+
"assert/strict",
|
|
13400
|
+
"buffer",
|
|
13401
|
+
"console",
|
|
13402
|
+
"constants",
|
|
13403
|
+
"crypto",
|
|
13404
|
+
"events",
|
|
13405
|
+
"fs",
|
|
13406
|
+
"fs/promises",
|
|
13407
|
+
"os",
|
|
13408
|
+
"path",
|
|
13409
|
+
"path/posix",
|
|
13410
|
+
"process",
|
|
13411
|
+
"punycode",
|
|
13412
|
+
"querystring",
|
|
13413
|
+
"stream",
|
|
13414
|
+
"stream/promises",
|
|
13415
|
+
"stream/web",
|
|
13416
|
+
"string_decoder",
|
|
13417
|
+
"timers",
|
|
13418
|
+
"timers/promises",
|
|
13419
|
+
"url",
|
|
13420
|
+
"util",
|
|
13421
|
+
"zlib"
|
|
13422
|
+
].flatMap((name) => [name, `node:${name}`])),
|
|
13423
|
+
platformSource: platformSource(nodejsEngineContract)
|
|
13424
|
+
};
|
|
13425
|
+
var v9Contract = {
|
|
13426
|
+
...nodejsContract,
|
|
13427
|
+
codeFetch: true,
|
|
13428
|
+
platformSource: platformSource("open-flow-engine/v9")
|
|
13429
|
+
};
|
|
13430
|
+
var currentContract = {
|
|
13431
|
+
...v9Contract,
|
|
13432
|
+
flowState: true,
|
|
13433
|
+
platformSource: platformSource(currentEngineContract)
|
|
13434
|
+
};
|
|
13435
|
+
function findEngineContract(contract) {
|
|
13436
|
+
if (contract == "open-flow-engine/v10") return currentContract;
|
|
13437
|
+
if (contract == "open-flow-engine/v9") return v9Contract;
|
|
13438
|
+
if (contract == "open-flow-engine/v8") return v8Contract;
|
|
13439
|
+
if (contract == "open-flow-engine/v8/nodejs-compat-v1") return nodejsContract;
|
|
13440
|
+
if (contract == "open-flow-engine/v7" || contract == "open-flow-engine/v7/nodejs-compat-v1") return {
|
|
13441
|
+
...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : v8Contract,
|
|
13442
|
+
workflowTools: false,
|
|
13443
|
+
httpRequests: false,
|
|
13444
|
+
platformSource: platformSource(contract)
|
|
13445
|
+
};
|
|
13446
|
+
if (contract == "open-flow-engine/v6" || contract == "open-flow-engine/v6/nodejs-compat-v1") return {
|
|
13447
|
+
...contract == "open-flow-engine/v6" ? v8Contract : nodejsContract,
|
|
13448
|
+
workflowTools: false,
|
|
13449
|
+
httpRequests: false,
|
|
13450
|
+
waitAutoContinue: false,
|
|
13451
|
+
webhookResponses: false,
|
|
13452
|
+
platformSource: platformSource(contract)
|
|
13453
|
+
};
|
|
13454
|
+
}
|
|
13288
13455
|
//#endregion
|
|
13289
13456
|
//#region src/control/common/authoringLlm.ts
|
|
13290
13457
|
var authoringLlmConfiguration = strictObject({
|
|
@@ -13872,6 +14039,7 @@ var authoringTypes = [
|
|
|
13872
14039
|
"decision",
|
|
13873
14040
|
"openapi",
|
|
13874
14041
|
"http-request",
|
|
14042
|
+
"dedupe",
|
|
13875
14043
|
"condition",
|
|
13876
14044
|
"value",
|
|
13877
14045
|
"wait",
|
|
@@ -13934,11 +14102,15 @@ var agentTool = union([workflowAgentToolSchema.omit({
|
|
|
13934
14102
|
id: true,
|
|
13935
14103
|
inputs: true
|
|
13936
14104
|
}).extend({ inputs: toolSources }).strict()]);
|
|
13937
|
-
var authoringCapabilities = array(union([
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
14105
|
+
var authoringCapabilities = array(union([
|
|
14106
|
+
connectorCapabilitySchema,
|
|
14107
|
+
strictObject({
|
|
14108
|
+
kind: literal("workflow"),
|
|
14109
|
+
name: id$1,
|
|
14110
|
+
flowId: id$1
|
|
14111
|
+
}),
|
|
14112
|
+
httpCapabilitySchema
|
|
14113
|
+
]));
|
|
13942
14114
|
var notification = strictObject({
|
|
13943
14115
|
...authoringDefinitionSchemas.connector.shape,
|
|
13944
14116
|
messageHandle: id$1,
|
|
@@ -13999,6 +14171,7 @@ var authoringConfigurations = {
|
|
|
13999
14171
|
"connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
|
|
14000
14172
|
"openapi": authoringOpenApiSchema,
|
|
14001
14173
|
"http-request": httpRequestConfigSchema,
|
|
14174
|
+
"dedupe": dedupeConfigSchema,
|
|
14002
14175
|
"agent": authoringDefinitionSchemas.agent.omit({
|
|
14003
14176
|
prompt: true,
|
|
14004
14177
|
tools: true
|
|
@@ -14200,6 +14373,7 @@ var requestContracts = {
|
|
|
14200
14373
|
examples: [{ revisionId: "REVISION" }]
|
|
14201
14374
|
}
|
|
14202
14375
|
};
|
|
14376
|
+
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.`;
|
|
14203
14377
|
/** Transport-independent discovery of the same requests the service validates. */
|
|
14204
14378
|
function authoringRequestContract(name) {
|
|
14205
14379
|
if (!Object.hasOwn(requestContracts, name)) return void 0;
|
|
@@ -14217,7 +14391,7 @@ function authoringSchema(kind) {
|
|
|
14217
14391
|
guidance: "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."
|
|
14218
14392
|
} : {
|
|
14219
14393
|
type: kind,
|
|
14220
|
-
onError: retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ["stop", "error"] } : false,
|
|
14394
|
+
onError: kind == "dedupe" || retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ["stop", "error"] } : false,
|
|
14221
14395
|
retry: retryNodeTypes.some((nodeType) => nodeType == kind) ? toJSONSchema(retryConfigurationSchema) : false,
|
|
14222
14396
|
inputSources: ["poll", "integration"].includes(kind) ? [
|
|
14223
14397
|
"value",
|
|
@@ -14247,7 +14421,7 @@ function authoringSchema(kind) {
|
|
|
14247
14421
|
"wait",
|
|
14248
14422
|
"approval"
|
|
14249
14423
|
].includes(kind),
|
|
14250
|
-
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" ?
|
|
14424
|
+
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 == "dedupe" ? "Bind an items array. Configure field (dot-separated identity path, empty for scalar items), mode (new or increasing), and space (node or flow). Outputs are items and duplicates. History persists immediately; downstream failures do not roll it back. Increasing mode accepts finite numbers or RFC 3339 timestamps, never mixed types." : 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.",
|
|
14251
14425
|
example: {
|
|
14252
14426
|
op: "node.add",
|
|
14253
14427
|
as: "step",
|
|
@@ -14270,6 +14444,17 @@ function authoringSchema(kind) {
|
|
|
14270
14444
|
}]
|
|
14271
14445
|
} },
|
|
14272
14446
|
"integration": { config: { key: "<Trigger key>" } },
|
|
14447
|
+
"dedupe": {
|
|
14448
|
+
config: {
|
|
14449
|
+
field: "id",
|
|
14450
|
+
mode: "new",
|
|
14451
|
+
space: "node"
|
|
14452
|
+
},
|
|
14453
|
+
inputs: { items: {
|
|
14454
|
+
kind: "value",
|
|
14455
|
+
value: [{ id: "a" }, { id: "b" }]
|
|
14456
|
+
} }
|
|
14457
|
+
},
|
|
14273
14458
|
"http-request": {
|
|
14274
14459
|
config: {},
|
|
14275
14460
|
inputs: { url: {
|
|
@@ -14529,7 +14714,7 @@ var nodeErrorSchema = {
|
|
|
14529
14714
|
}
|
|
14530
14715
|
};
|
|
14531
14716
|
function supportsNodeErrorHandling(node) {
|
|
14532
|
-
return supportsNodeRetry(node);
|
|
14717
|
+
return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "dedupe";
|
|
14533
14718
|
}
|
|
14534
14719
|
function nodeSystemOutputPorts(node) {
|
|
14535
14720
|
return supportsNodeErrorHandling(node) && node.onError == "error" ? { error: {
|
|
@@ -14537,6 +14722,11 @@ function nodeSystemOutputPorts(node) {
|
|
|
14537
14722
|
nullable: true
|
|
14538
14723
|
} } : {};
|
|
14539
14724
|
}
|
|
14725
|
+
//#endregion
|
|
14726
|
+
//#region src/flow/common/model.ts
|
|
14727
|
+
function portsByHandle(ports) {
|
|
14728
|
+
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
14729
|
+
}
|
|
14540
14730
|
function resourceNameIssue(value) {
|
|
14541
14731
|
const name = value.trim();
|
|
14542
14732
|
if (name.length == 0) return "empty";
|
|
@@ -14547,9 +14737,6 @@ function resourceNameIssue(value) {
|
|
|
14547
14737
|
}
|
|
14548
14738
|
if (!/^[\p{L}\p{N}](?:[\p{L}\p{N} _-]*[\p{L}\p{N}])?$/u.test(name)) return "specialCharacter";
|
|
14549
14739
|
}
|
|
14550
|
-
function portsByHandle(ports) {
|
|
14551
|
-
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
14552
|
-
}
|
|
14553
14740
|
var workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
14554
14741
|
function workflowToolNameIssue(name, otherNames = []) {
|
|
14555
14742
|
if (!workflowToolNamePattern.test(name)) return "invalid";
|
|
@@ -14565,6 +14752,8 @@ function decodeTaskCapabilities(value) {
|
|
|
14565
14752
|
if (workflowToolNameIssue(item.name, names)) throw new TypeError("Workflow tool names must be unique provider-compatible names.");
|
|
14566
14753
|
names.add(item.name);
|
|
14567
14754
|
}
|
|
14755
|
+
const http = parsed.filter((item) => item.kind == "http");
|
|
14756
|
+
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.");
|
|
14568
14757
|
let connectorIndex = 0;
|
|
14569
14758
|
return parsed.map((item) => item.kind == "connector" ? connectors[connectorIndex++] : item);
|
|
14570
14759
|
}
|
|
@@ -14700,10 +14889,10 @@ function upgradeRevisionContent(content) {
|
|
|
14700
14889
|
function upgradeDecodedRevisionContent(content) {
|
|
14701
14890
|
const graph = content.document.graph;
|
|
14702
14891
|
const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
|
|
14703
|
-
if (!hasManual && content.modelVersion ==
|
|
14892
|
+
if (!hasManual && content.modelVersion == 13) return content;
|
|
14704
14893
|
return {
|
|
14705
14894
|
...content,
|
|
14706
|
-
modelVersion:
|
|
14895
|
+
modelVersion: 13,
|
|
14707
14896
|
document: {
|
|
14708
14897
|
...content.document,
|
|
14709
14898
|
graph: hasManual ? {
|
|
@@ -14738,7 +14927,7 @@ function invalid(message) {
|
|
|
14738
14927
|
throw new FlowChangeError(message);
|
|
14739
14928
|
}
|
|
14740
14929
|
function applyFlowChanges(content, operations) {
|
|
14741
|
-
const source = content.modelVersion !=
|
|
14930
|
+
const source = content.modelVersion != 13 || Object.values(content.document.graph.nodes).some((node) => node.kind == "manual") ? decodeRevisionContent(content) : content;
|
|
14742
14931
|
const document = { ...source.document };
|
|
14743
14932
|
const modules = { ...source.modules };
|
|
14744
14933
|
for (const operation of operations) switch (operation.kind) {
|
|
@@ -15183,10 +15372,10 @@ function applyFlowChanges(content, operations) {
|
|
|
15183
15372
|
break;
|
|
15184
15373
|
}
|
|
15185
15374
|
}
|
|
15186
|
-
|
|
15375
|
+
assertDocumentHttpAuthBindings(document);
|
|
15187
15376
|
return upgradeDecodedRevisionContent({
|
|
15188
15377
|
document,
|
|
15189
|
-
modelVersion:
|
|
15378
|
+
modelVersion: 13,
|
|
15190
15379
|
modules
|
|
15191
15380
|
});
|
|
15192
15381
|
}
|
|
@@ -16411,7 +16600,7 @@ function authoringNode(content, ref) {
|
|
|
16411
16600
|
inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
|
|
16412
16601
|
};
|
|
16413
16602
|
else if (task.executor.kind == "workflow") config = { flowId: task.executor.flowId };
|
|
16414
|
-
else if (task.executor.kind == "http-request") {
|
|
16603
|
+
else if (task.executor.kind == "http-request" || task.executor.kind == "dedupe") {
|
|
16415
16604
|
const { kind: _kind, ...settings } = task.executor;
|
|
16416
16605
|
config = settings;
|
|
16417
16606
|
} else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
|
|
@@ -16801,6 +16990,14 @@ async function compileAuthoring(base, request, host) {
|
|
|
16801
16990
|
};
|
|
16802
16991
|
} else task = await connectorTask(config, String(update.name));
|
|
16803
16992
|
} else if (type == "decision") task = decisionTask(config.questions, String(update.name));
|
|
16993
|
+
else if (type == "dedupe") task = {
|
|
16994
|
+
...before,
|
|
16995
|
+
name: String(update.name),
|
|
16996
|
+
executor: {
|
|
16997
|
+
kind: "dedupe",
|
|
16998
|
+
...dedupeConfigSchema.parse(config)
|
|
16999
|
+
}
|
|
17000
|
+
};
|
|
16804
17001
|
else if (type == "http-request") {
|
|
16805
17002
|
task = httpRequestTask(httpRequestConfigSchema.parse(config), String(update.name), before);
|
|
16806
17003
|
next = {
|
|
@@ -17148,6 +17345,9 @@ async function compileAuthoring(base, request, host) {
|
|
|
17148
17345
|
case "connector":
|
|
17149
17346
|
changes = createManagedTask(identity, await connectorTask(config, name));
|
|
17150
17347
|
break;
|
|
17348
|
+
case "dedupe":
|
|
17349
|
+
changes = createManagedTask(identity, dedupeTask(dedupeConfigSchema.parse(config), name));
|
|
17350
|
+
break;
|
|
17151
17351
|
case "http-request":
|
|
17152
17352
|
changes = createManagedTask(identity, httpRequestTask(httpRequestConfigSchema.parse(config), name));
|
|
17153
17353
|
break;
|
|
@@ -17369,6 +17569,7 @@ var descriptions = {
|
|
|
17369
17569
|
"poll": "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection.",
|
|
17370
17570
|
"integration": "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.",
|
|
17371
17571
|
"decision": "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.",
|
|
17572
|
+
"dedupe": "Filter items using persistent history. Records immediately, including when downstream work fails. Empty field uses each scalar item as identity.",
|
|
17372
17573
|
"http-request": "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers.",
|
|
17373
17574
|
"openapi": "A fixed JSON API operation. Replace the example document and URL before running.",
|
|
17374
17575
|
"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.",
|
|
@@ -17413,6 +17614,21 @@ function authoringExample(name) {
|
|
|
17413
17614
|
instructions: "Does the customer need support?"
|
|
17414
17615
|
}]);
|
|
17415
17616
|
break;
|
|
17617
|
+
case "dedupe":
|
|
17618
|
+
operations = [...createManagedTask({ nodeId: "dedupe" }, dedupeTask()), {
|
|
17619
|
+
kind: "graph.node.input.set",
|
|
17620
|
+
nodeId: "dedupe",
|
|
17621
|
+
handle: "items",
|
|
17622
|
+
value: {
|
|
17623
|
+
kind: "value",
|
|
17624
|
+
value: [
|
|
17625
|
+
"a",
|
|
17626
|
+
"b",
|
|
17627
|
+
"a"
|
|
17628
|
+
]
|
|
17629
|
+
}
|
|
17630
|
+
}];
|
|
17631
|
+
break;
|
|
17416
17632
|
case "http-request":
|
|
17417
17633
|
operations = [...createManagedTask({ nodeId: "http" }, httpRequestTask()), {
|
|
17418
17634
|
kind: "graph.node.input.set",
|
|
@@ -17656,6 +17872,8 @@ var json = json$5();
|
|
|
17656
17872
|
var id = string().min(1);
|
|
17657
17873
|
var version = literal(1);
|
|
17658
17874
|
var flowName = id.refine((value) => value == value.trim() && resourceNameIssue(value) == null, "Flow name is invalid.");
|
|
17875
|
+
var tagIds = array(id).transform((ids) => [...new Set(ids)].toSorted());
|
|
17876
|
+
var tagName = id.transform((name) => name.trim()).refine((name) => resourceNameIssue(name) == null, "Tag name is invalid.");
|
|
17659
17877
|
var inputs = record$3(string(), record$3(string(), json));
|
|
17660
17878
|
var trigger = strictObject({
|
|
17661
17879
|
nodeId: id,
|
|
@@ -17682,13 +17900,32 @@ var schemas = {
|
|
|
17682
17900
|
file: json,
|
|
17683
17901
|
name: flowName.optional(),
|
|
17684
17902
|
teamId: id.optional(),
|
|
17903
|
+
tagIds: tagIds.optional(),
|
|
17685
17904
|
version
|
|
17686
17905
|
}),
|
|
17687
17906
|
createFlow: strictObject({
|
|
17688
17907
|
name: flowName,
|
|
17689
17908
|
teamId: id.optional(),
|
|
17909
|
+
tagIds: tagIds.optional(),
|
|
17910
|
+
version
|
|
17911
|
+
}),
|
|
17912
|
+
saveTag: strictObject({
|
|
17913
|
+
name: tagName,
|
|
17914
|
+
version
|
|
17915
|
+
}),
|
|
17916
|
+
setFlowTags: strictObject({
|
|
17917
|
+
tagIds,
|
|
17690
17918
|
version
|
|
17691
17919
|
}),
|
|
17920
|
+
updateFlow: union([strictObject({
|
|
17921
|
+
name: flowName,
|
|
17922
|
+
tagIds: tagIds.optional(),
|
|
17923
|
+
version
|
|
17924
|
+
}), strictObject({
|
|
17925
|
+
name: flowName.optional(),
|
|
17926
|
+
tagIds,
|
|
17927
|
+
version
|
|
17928
|
+
})]),
|
|
17692
17929
|
renameFlow: strictObject({
|
|
17693
17930
|
name: flowName,
|
|
17694
17931
|
version
|
|
@@ -17793,6 +18030,9 @@ var controlRequests = {
|
|
|
17793
18030
|
eventSourceRevision: decoder(schemas.eventSourceRevision),
|
|
17794
18031
|
importFlow: decoder(schemas.importFlow),
|
|
17795
18032
|
createFlow: decoder(schemas.createFlow),
|
|
18033
|
+
saveTag: decoder(schemas.saveTag),
|
|
18034
|
+
setFlowTags: decoder(schemas.setFlowTags),
|
|
18035
|
+
updateFlow: decoder(schemas.updateFlow),
|
|
17796
18036
|
renameFlow: decoder(schemas.renameFlow),
|
|
17797
18037
|
changeDraft(value) {
|
|
17798
18038
|
const body = schemas.changeDraft.parse(value);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { JsonValue
|
|
1
|
+
import type { JsonValue } from './flow-model.js';
|
|
2
|
+
import type { TriggerSchedule } from './trigger-model.js';
|
|
2
3
|
export declare function validateTriggerSchedule(rules: readonly TriggerSchedule[]): void;
|
|
3
4
|
export declare function validateCronExpression(expression: string, timezone: string): void;
|
|
4
5
|
export declare function nextTriggerScheduledAt(rules: readonly TriggerSchedule[], afterMs: number): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonValue,
|
|
1
|
+
import type { JsonValue, ManagedTaskDefinitionOf, TaskExecutor } from './flow-model.js';
|
|
2
2
|
export type DecisionQuestion = {
|
|
3
3
|
readonly name: string;
|
|
4
4
|
readonly instructions: string;
|
|
@@ -36,12 +36,12 @@ export declare const decisionLimits: {
|
|
|
36
36
|
export declare function limitDecisionQuestion(question: DecisionQuestion): DecisionQuestion;
|
|
37
37
|
export declare function limitDecisionQuestions(questions: readonly DecisionQuestion[]): readonly DecisionQuestion[];
|
|
38
38
|
/** Loading an oversized task also updates its previously generated output schemas. */
|
|
39
|
-
export declare function limitDecisionTask(task:
|
|
39
|
+
export declare function limitDecisionTask<Task extends ManagedTaskDefinitionOf<TaskExecutor>>(task: Task): Task;
|
|
40
40
|
export declare const decisionStateSchema: JsonValue;
|
|
41
41
|
export declare const defaultDecisionQuestion: (name?: string) => DecisionQuestion;
|
|
42
42
|
export declare function decisionQuestionIssues(questions: readonly DecisionQuestion[]): readonly DecisionIssue[];
|
|
43
43
|
export declare function decisionAnswerSchema(question: DecisionQuestion): JsonValue;
|
|
44
|
-
export declare function decisionTask(questions?: readonly DecisionQuestion[], name?: string):
|
|
45
|
-
export declare function decisionTaskIssues(task:
|
|
44
|
+
export declare function decisionTask(questions?: readonly DecisionQuestion[], name?: string): ManagedTaskDefinitionOf<DecisionExecutor>;
|
|
45
|
+
export declare function decisionTaskIssues(task: ManagedTaskDefinitionOf<TaskExecutor>): readonly DecisionIssue[];
|
|
46
46
|
export declare function decisionRequest(questions: readonly DecisionQuestion[], state: JsonValue): JsonValue;
|
|
47
47
|
export declare function decisionAnswers(questions: readonly DecisionQuestion[], response: unknown): Readonly<Record<string, JsonValue>>;
|
package/dist/common/decision.js
CHANGED
|
@@ -3686,6 +3686,9 @@ function schemaValidationErrors(value, schema) {
|
|
|
3686
3686
|
}
|
|
3687
3687
|
//#endregion
|
|
3688
3688
|
//#region src/decision/common/decision.ts
|
|
3689
|
+
function isDecisionExecutor(executor) {
|
|
3690
|
+
return executor.kind === "decision";
|
|
3691
|
+
}
|
|
3689
3692
|
var decisionModel = "typesafe/jev";
|
|
3690
3693
|
var decisionLimits = {
|
|
3691
3694
|
choice: 255,
|
|
@@ -3709,7 +3712,7 @@ function limitDecisionQuestions(questions) {
|
|
|
3709
3712
|
}
|
|
3710
3713
|
/** Loading an oversized task also updates its previously generated output schemas. */
|
|
3711
3714
|
function limitDecisionTask(task) {
|
|
3712
|
-
if (task.executor
|
|
3715
|
+
if (!isDecisionExecutor(task.executor)) return task;
|
|
3713
3716
|
const original = task.executor.questions;
|
|
3714
3717
|
const questions = limitDecisionQuestions(original);
|
|
3715
3718
|
if (questions === original) return task;
|
|
@@ -3834,7 +3837,7 @@ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decisi
|
|
|
3834
3837
|
}
|
|
3835
3838
|
function decisionTaskIssues(task) {
|
|
3836
3839
|
task = limitDecisionTask(task);
|
|
3837
|
-
if (task.executor
|
|
3840
|
+
if (!isDecisionExecutor(task.executor)) return [];
|
|
3838
3841
|
const expected = decisionTask(task.executor.questions, task.name);
|
|
3839
3842
|
return [...decisionQuestionIssues(task.executor.questions), ...!dequal(task.inputs, expected.inputs) || !dequal(task.outputs, expected.outputs) ? [{
|
|
3840
3843
|
field: "ports",
|