@oomol-lab/open-flow 0.1.0-beta.77 → 0.1.0-beta.79
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 +2 -0
- package/dist/browser/{ContentIcon-VZQO8VZU.js → ContentIcon-CMn0c-kl.js} +93 -3
- package/dist/browser/{FlowCanvas-BNGDMaWr.js → FlowCanvas-BQGBcfoL.js} +1675 -591
- package/dist/browser/{createResourceDialog-BmtakfVg.js → createResourceDialog-DkovGogv.js} +3 -3
- package/dist/browser/{dialog-BcFBfRB1.js → dialog-CFFuRM8s.js} +37 -86
- package/dist/browser/{exportSvg-CG8hEUNk.js → exportSvg-CYwyYiuH.js} +2 -2
- package/dist/browser/{flowChanges-BGo_4Ypo.js → flowChanges-CN2R-m1M.js} +1258 -422
- package/dist/browser/{flowWorkspace-BFHGev7s.js → flowWorkspace-CXVL1FNv.js} +634 -628
- package/dist/browser/licenses.md +1 -1
- package/dist/browser/preview.css +512 -462
- package/dist/browser/preview.js +8183 -6384
- package/dist/browser/{tooltip-BAWSUexx.js → tooltip-BDcVTNpu.js} +65 -2
- package/dist/browser/{typeScriptSession-CRoezJPN.js → typeScriptSession-CoEIptNC.js} +1 -1
- package/dist/browser/ui.css +5 -24
- package/dist/browser/workbench.css +512 -462
- package/dist/browser/workbench.d.ts +2 -3
- package/dist/browser/workbench.js +65 -690
- package/dist/browser/{workbenchSelect-CjK-xdm3.js → workbenchSelect-CkOS95gX.js} +2 -2
- package/dist/command/index.js +31 -31
- package/dist/common/authoring.d.ts +3 -3
- package/dist/common/authoringExamples.d.ts +3 -3
- package/dist/common/authoringSchema.d.ts +14 -22
- package/dist/common/control-api-conformance.js +91 -25
- package/dist/common/control-api.d.ts +8 -3
- package/dist/common/control-api.js +51 -25
- package/dist/common/control-requests.d.ts +9 -3
- package/dist/common/control-requests.js +54 -42
- package/dist/common/flow-authoring.js +32 -19
- package/dist/common/flow-change.d.ts +1 -1
- package/dist/common/flow-change.js +32 -19
- package/dist/common/flow-encoding.js +31 -18
- package/dist/common/flow-semantics.js +41 -26
- package/dist/common/flow-state.d.ts +49 -43
- package/dist/common/flow-state.js +95 -110
- package/dist/common/mcp.d.ts +35 -4
- package/dist/common/mcp.js +51 -26
- package/dist/common/run-events.js +19 -9
- package/dist/common/runtime-contract.d.ts +4 -1
- package/dist/common/runtime-contract.js +66 -17
- package/dist/common/runtime-nodejs-compat.js +11 -12
- package/dist/common/scheduler.d.ts +2 -1
- package/dist/common/scheduler.js +82 -55
- package/dist/common/state-conformance.d.ts +3 -3
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/control/common/api.ts +36 -7
- package/src/control/common/authoring.ts +6 -5
- package/src/control/common/authoringExamples.ts +6 -5
- package/src/control/common/authoringSchema.ts +7 -7
- package/src/control/common/conformance.ts +31 -0
- package/src/control/common/mcp.ts +7 -2
- package/src/control/common/requests.ts +10 -1
- package/src/execution/common/events.ts +22 -10
- package/src/execution/common/node-execution.ts +1 -1
- package/src/execution/common/scheduler.ts +28 -14
- package/src/flow/common/change.ts +1 -1
- package/src/flow/common/changeSchema.ts +4 -4
- package/src/flow/common/errorHandling.ts +1 -1
- package/src/flow/common/semantics.ts +12 -6
- package/src/runtime/common/nodejsGuest.generated.json +11 -12
- package/src/runtime/common/runtime.ts +45 -12
- package/src/state/common/conformance.ts +32 -21
- package/src/state/common/state.ts +85 -80
- package/src/types/index.ts +1 -0
|
@@ -5773,24 +5773,31 @@ function dequal(foo, bar) {
|
|
|
5773
5773
|
}
|
|
5774
5774
|
return foo !== foo && bar !== bar;
|
|
5775
5775
|
}
|
|
5776
|
+
//#endregion
|
|
5777
|
+
//#region src/state/common/state.ts
|
|
5778
|
+
var stateReadLimits = {
|
|
5779
|
+
maxKeys: 16,
|
|
5780
|
+
maxBytes: 1048576
|
|
5781
|
+
};
|
|
5782
|
+
var keySchema = string$1().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
|
|
5776
5783
|
strictObject({
|
|
5777
5784
|
scope: _enum(["draft", "live"]),
|
|
5778
|
-
values:
|
|
5785
|
+
values: literal(false).optional()
|
|
5779
5786
|
});
|
|
5780
5787
|
strictObject({
|
|
5781
5788
|
scope: _enum(["draft", "live"]),
|
|
5782
|
-
|
|
5789
|
+
keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
|
|
5783
5790
|
});
|
|
5784
5791
|
strictObject({
|
|
5785
5792
|
scope: _enum(["draft", "live"]),
|
|
5786
|
-
|
|
5793
|
+
key: keySchema.optional()
|
|
5787
5794
|
});
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
space: _enum(["node", "flow"]).default("node")
|
|
5795
|
+
strictObject({
|
|
5796
|
+
scope: _enum(["draft", "live"]),
|
|
5797
|
+
space: string$1().regex(/^(flow|node:.+)$/)
|
|
5792
5798
|
});
|
|
5793
|
-
var
|
|
5799
|
+
var skipDuplicatesConfigSchema = strictObject({ fields: array(string$1().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) });
|
|
5800
|
+
var skipDuplicatesExecutorSchema = skipDuplicatesConfigSchema.extend({ kind: literal("skip-duplicates") });
|
|
5794
5801
|
var flowStateViewSchema = object({
|
|
5795
5802
|
version: literal(1),
|
|
5796
5803
|
scope: _enum(["draft", "live"]),
|
|
@@ -5801,24 +5808,30 @@ var flowStateViewSchema = object({
|
|
|
5801
5808
|
maxIdentities: number().positive(),
|
|
5802
5809
|
maxRunWrites: number().positive()
|
|
5803
5810
|
}),
|
|
5804
|
-
values: array(
|
|
5811
|
+
values: array(strictObject({
|
|
5805
5812
|
key: string$1(),
|
|
5806
5813
|
size: number().nonnegative(),
|
|
5807
|
-
updatedAt: number()
|
|
5808
|
-
value: json$3().optional()
|
|
5814
|
+
updatedAt: number()
|
|
5809
5815
|
})),
|
|
5810
5816
|
spaces: array(object({
|
|
5811
5817
|
space: string$1(),
|
|
5812
|
-
mode: _enum(["new", "increasing"]),
|
|
5813
5818
|
count: number().nonnegative(),
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
number(),
|
|
5817
|
-
_null()
|
|
5818
|
-
]),
|
|
5819
|
+
pendingCount: number().nonnegative(),
|
|
5820
|
+
reservedCount: number().nonnegative(),
|
|
5819
5821
|
updatedAt: number()
|
|
5820
5822
|
}))
|
|
5821
5823
|
});
|
|
5824
|
+
var flowStateValuesSchema = object({
|
|
5825
|
+
version: literal(1),
|
|
5826
|
+
scope: _enum(["draft", "live"]),
|
|
5827
|
+
values: array(strictObject({
|
|
5828
|
+
key: keySchema,
|
|
5829
|
+
value: json$3()
|
|
5830
|
+
})).min(1).max(stateReadLimits.maxKeys)
|
|
5831
|
+
}).refine((response) => {
|
|
5832
|
+
const encoder = new TextEncoder();
|
|
5833
|
+
return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
|
|
5834
|
+
}, "State values exceed the 1 MiB read limit.");
|
|
5822
5835
|
//#endregion
|
|
5823
5836
|
//#region src/json-schema-subset/utils.ts
|
|
5824
5837
|
var nextId = 0;
|
|
@@ -9098,7 +9111,7 @@ var managedFields = object({
|
|
|
9098
9111
|
revisionId: text
|
|
9099
9112
|
}),
|
|
9100
9113
|
httpRequestExecutorSchema,
|
|
9101
|
-
|
|
9114
|
+
skipDuplicatesExecutorSchema
|
|
9102
9115
|
])
|
|
9103
9116
|
});
|
|
9104
9117
|
var managed = managedFields.transform(limitDecisionTask);
|
|
@@ -9570,7 +9583,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
|
|
|
9570
9583
|
...shape
|
|
9571
9584
|
})])).values()])).min(1);
|
|
9572
9585
|
function checkModelVersion(content) {
|
|
9573
|
-
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "
|
|
9586
|
+
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
|
|
9574
9587
|
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.");
|
|
9575
9588
|
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.");
|
|
9576
9589
|
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.");
|
|
@@ -9639,7 +9652,7 @@ var type = _enum([
|
|
|
9639
9652
|
"decision",
|
|
9640
9653
|
"openapi",
|
|
9641
9654
|
"http-request",
|
|
9642
|
-
"
|
|
9655
|
+
"skip-duplicates",
|
|
9643
9656
|
"condition",
|
|
9644
9657
|
"value",
|
|
9645
9658
|
"wait",
|
|
@@ -9770,7 +9783,7 @@ var authoringConfigurations = {
|
|
|
9770
9783
|
"connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
|
|
9771
9784
|
"openapi": authoringOpenApiSchema,
|
|
9772
9785
|
"http-request": httpRequestConfigSchema,
|
|
9773
|
-
"
|
|
9786
|
+
"skip-duplicates": skipDuplicatesConfigSchema,
|
|
9774
9787
|
"agent": authoringDefinitionSchemas.agent.omit({
|
|
9775
9788
|
prompt: true,
|
|
9776
9789
|
tools: true
|
|
@@ -12557,7 +12570,7 @@ function decodeRunEvent(value) {
|
|
|
12557
12570
|
switch (kind) {
|
|
12558
12571
|
case "node.started": {
|
|
12559
12572
|
const nodeKind = payload.nodeKind;
|
|
12560
|
-
if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "http-request" && nodeKind !== "
|
|
12573
|
+
if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "http-request" && nodeKind !== "skip-duplicates" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "webhook-response" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
|
|
12561
12574
|
return {
|
|
12562
12575
|
...base,
|
|
12563
12576
|
kind,
|
|
@@ -12782,12 +12795,13 @@ var ControlClient = class {
|
|
|
12782
12795
|
})
|
|
12783
12796
|
}));
|
|
12784
12797
|
}
|
|
12785
|
-
async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds) {
|
|
12798
|
+
async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds, initialPresentation) {
|
|
12786
12799
|
return flow(await this.request("/v1/flows", {
|
|
12787
12800
|
body: JSON.stringify({
|
|
12788
12801
|
name,
|
|
12789
12802
|
...teamId == null ? {} : { teamId },
|
|
12790
12803
|
...tagIds == null ? {} : { tagIds },
|
|
12804
|
+
...initialPresentation == null ? {} : { presentation: initialPresentation },
|
|
12791
12805
|
version: 1
|
|
12792
12806
|
}),
|
|
12793
12807
|
headers: { "idempotency-key": idempotencyKey },
|
|
@@ -12869,10 +12883,22 @@ var ControlClient = class {
|
|
|
12869
12883
|
})
|
|
12870
12884
|
}));
|
|
12871
12885
|
}
|
|
12872
|
-
async getFlowState(flowId, scope
|
|
12873
|
-
const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}
|
|
12886
|
+
async getFlowState(flowId, scope) {
|
|
12887
|
+
const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}`));
|
|
12874
12888
|
return result.success && result.data.scope === scope ? result.data : invalidResponse();
|
|
12875
12889
|
}
|
|
12890
|
+
async getFlowStateValues(flowId, scope, keys, signal) {
|
|
12891
|
+
const result = flowStateValuesSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state/read`, {
|
|
12892
|
+
method: "POST",
|
|
12893
|
+
body: JSON.stringify({
|
|
12894
|
+
version: 1,
|
|
12895
|
+
scope,
|
|
12896
|
+
keys
|
|
12897
|
+
}),
|
|
12898
|
+
signal
|
|
12899
|
+
}));
|
|
12900
|
+
return result.success && result.data.scope === scope && result.data.values.length === keys.length && result.data.values.every((item, index) => item.key === keys[index]) ? result.data : invalidResponse();
|
|
12901
|
+
}
|
|
12876
12902
|
async clearFlowState(flowId, scope, key) {
|
|
12877
12903
|
const source = record(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}${key == null ? "" : `&key=${encodeURIComponent(key)}`}`, { method: "DELETE" }));
|
|
12878
12904
|
if (source.version !== 1 || source.cleared !== true) invalidResponse();
|
|
@@ -10,6 +10,11 @@ export declare const waitActionBodySchema: {
|
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
12
|
export declare const controlRequests: {
|
|
13
|
+
readFlowState: (value: unknown) => {
|
|
14
|
+
scope: "draft" | "live";
|
|
15
|
+
keys: string[];
|
|
16
|
+
version: 1;
|
|
17
|
+
};
|
|
13
18
|
canvas: (value: unknown) => {
|
|
14
19
|
command: {
|
|
15
20
|
type: "focus";
|
|
@@ -35,7 +40,7 @@ export declare const controlRequests: {
|
|
|
35
40
|
edits: ({
|
|
36
41
|
op: "node.add";
|
|
37
42
|
as: string;
|
|
38
|
-
type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "
|
|
43
|
+
type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
|
|
39
44
|
name: string;
|
|
40
45
|
onError?: "error" | "stop" | undefined;
|
|
41
46
|
retry?: {
|
|
@@ -178,12 +183,12 @@ export declare const controlRequests: {
|
|
|
178
183
|
authoringSearch: (value: unknown) => {
|
|
179
184
|
revision?: string | undefined;
|
|
180
185
|
query: string;
|
|
181
|
-
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "
|
|
186
|
+
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
182
187
|
offset: number;
|
|
183
188
|
limit: number;
|
|
184
189
|
};
|
|
185
190
|
authoringSchema: (value: unknown) => {
|
|
186
|
-
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "
|
|
191
|
+
type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
|
|
187
192
|
action?: string | undefined;
|
|
188
193
|
};
|
|
189
194
|
loadOpenApiDocument: (value: unknown) => {
|
|
@@ -207,6 +212,7 @@ export declare const controlRequests: {
|
|
|
207
212
|
name: string;
|
|
208
213
|
teamId?: string | undefined;
|
|
209
214
|
tagIds?: string[] | undefined;
|
|
215
|
+
presentation?: Record<string, JsonValue> | undefined;
|
|
210
216
|
version: 1;
|
|
211
217
|
};
|
|
212
218
|
saveTag: (value: unknown) => {
|
|
@@ -12473,30 +12473,37 @@ function httpRequestInputs(mappings, previous, next) {
|
|
|
12473
12473
|
const rename = candidate != null && ["query.", "header."].some((prefix) => candidate.every((name) => name.startsWith(prefix))) ? candidate : void 0;
|
|
12474
12474
|
return remapInputMappings(mappings, next.inputs, rename);
|
|
12475
12475
|
}
|
|
12476
|
+
//#endregion
|
|
12477
|
+
//#region src/state/common/state.ts
|
|
12478
|
+
var stateReadLimits = {
|
|
12479
|
+
maxKeys: 16,
|
|
12480
|
+
maxBytes: 1048576
|
|
12481
|
+
};
|
|
12482
|
+
var keySchema = string().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
|
|
12476
12483
|
strictObject({
|
|
12477
12484
|
scope: _enum(["draft", "live"]),
|
|
12478
|
-
values:
|
|
12485
|
+
values: literal(false).optional()
|
|
12486
|
+
});
|
|
12487
|
+
var stateReadSchema = strictObject({
|
|
12488
|
+
scope: _enum(["draft", "live"]),
|
|
12489
|
+
keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
|
|
12479
12490
|
});
|
|
12480
12491
|
strictObject({
|
|
12481
12492
|
scope: _enum(["draft", "live"]),
|
|
12482
|
-
key:
|
|
12493
|
+
key: keySchema.optional()
|
|
12483
12494
|
});
|
|
12484
12495
|
strictObject({
|
|
12485
12496
|
scope: _enum(["draft", "live"]),
|
|
12486
12497
|
space: string().regex(/^(flow|node:.+)$/)
|
|
12487
12498
|
});
|
|
12488
|
-
var
|
|
12489
|
-
|
|
12490
|
-
|
|
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") {
|
|
12499
|
+
var skipDuplicatesConfigSchema = strictObject({ fields: array(string().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) });
|
|
12500
|
+
var skipDuplicatesExecutorSchema = skipDuplicatesConfigSchema.extend({ kind: literal("skip-duplicates") });
|
|
12501
|
+
function skipDuplicatesTask(config = skipDuplicatesConfigSchema.parse({}), name = "Skip Duplicates") {
|
|
12495
12502
|
return {
|
|
12496
12503
|
name,
|
|
12497
12504
|
executor: {
|
|
12498
12505
|
...config,
|
|
12499
|
-
kind: "
|
|
12506
|
+
kind: "skip-duplicates"
|
|
12500
12507
|
},
|
|
12501
12508
|
inputs: [{
|
|
12502
12509
|
handle: "items",
|
|
@@ -12520,24 +12527,30 @@ object$1({
|
|
|
12520
12527
|
maxIdentities: number().positive(),
|
|
12521
12528
|
maxRunWrites: number().positive()
|
|
12522
12529
|
}),
|
|
12523
|
-
values: array(
|
|
12530
|
+
values: array(strictObject({
|
|
12524
12531
|
key: string(),
|
|
12525
12532
|
size: number().nonnegative(),
|
|
12526
|
-
updatedAt: number()
|
|
12527
|
-
value: json$5().optional()
|
|
12533
|
+
updatedAt: number()
|
|
12528
12534
|
})),
|
|
12529
12535
|
spaces: array(object$1({
|
|
12530
12536
|
space: string(),
|
|
12531
|
-
mode: _enum(["new", "increasing"]),
|
|
12532
12537
|
count: number().nonnegative(),
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
number(),
|
|
12536
|
-
_null()
|
|
12537
|
-
]),
|
|
12538
|
+
pendingCount: number().nonnegative(),
|
|
12539
|
+
reservedCount: number().nonnegative(),
|
|
12538
12540
|
updatedAt: number()
|
|
12539
12541
|
}))
|
|
12540
12542
|
});
|
|
12543
|
+
object$1({
|
|
12544
|
+
version: literal(1),
|
|
12545
|
+
scope: _enum(["draft", "live"]),
|
|
12546
|
+
values: array(strictObject({
|
|
12547
|
+
key: keySchema,
|
|
12548
|
+
value: json$5()
|
|
12549
|
+
})).min(1).max(stateReadLimits.maxKeys)
|
|
12550
|
+
}).refine((response) => {
|
|
12551
|
+
const encoder = new TextEncoder();
|
|
12552
|
+
return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
|
|
12553
|
+
}, "State values exceed the 1 MiB read limit.");
|
|
12541
12554
|
function checkJsonDepth(value, depth = 0) {
|
|
12542
12555
|
if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
|
|
12543
12556
|
if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
|
|
@@ -12858,7 +12871,7 @@ var managedFields = object$1({
|
|
|
12858
12871
|
revisionId: text$1
|
|
12859
12872
|
}),
|
|
12860
12873
|
httpRequestExecutorSchema,
|
|
12861
|
-
|
|
12874
|
+
skipDuplicatesExecutorSchema
|
|
12862
12875
|
])
|
|
12863
12876
|
});
|
|
12864
12877
|
var managed = managedFields.transform(limitDecisionTask);
|
|
@@ -13354,7 +13367,7 @@ function changeOperationsSchema(kind) {
|
|
|
13354
13367
|
return toJSONSchema(schema, { io: "input" });
|
|
13355
13368
|
}
|
|
13356
13369
|
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 === "
|
|
13370
|
+
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
|
|
13358
13371
|
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.");
|
|
13359
13372
|
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.");
|
|
13360
13373
|
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.");
|
|
@@ -14039,7 +14052,7 @@ var authoringTypes = [
|
|
|
14039
14052
|
"decision",
|
|
14040
14053
|
"openapi",
|
|
14041
14054
|
"http-request",
|
|
14042
|
-
"
|
|
14055
|
+
"skip-duplicates",
|
|
14043
14056
|
"condition",
|
|
14044
14057
|
"value",
|
|
14045
14058
|
"wait",
|
|
@@ -14171,7 +14184,7 @@ var authoringConfigurations = {
|
|
|
14171
14184
|
"connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
|
|
14172
14185
|
"openapi": authoringOpenApiSchema,
|
|
14173
14186
|
"http-request": httpRequestConfigSchema,
|
|
14174
|
-
"
|
|
14187
|
+
"skip-duplicates": skipDuplicatesConfigSchema,
|
|
14175
14188
|
"agent": authoringDefinitionSchemas.agent.omit({
|
|
14176
14189
|
prompt: true,
|
|
14177
14190
|
tools: true
|
|
@@ -14391,7 +14404,7 @@ function authoringSchema(kind) {
|
|
|
14391
14404
|
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."
|
|
14392
14405
|
} : {
|
|
14393
14406
|
type: kind,
|
|
14394
|
-
onError: kind == "
|
|
14407
|
+
onError: kind == "skip-duplicates" || retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ["stop", "error"] } : false,
|
|
14395
14408
|
retry: retryNodeTypes.some((nodeType) => nodeType == kind) ? toJSONSchema(retryConfigurationSchema) : false,
|
|
14396
14409
|
inputSources: ["poll", "integration"].includes(kind) ? [
|
|
14397
14410
|
"value",
|
|
@@ -14421,7 +14434,7 @@ function authoringSchema(kind) {
|
|
|
14421
14434
|
"wait",
|
|
14422
14435
|
"approval"
|
|
14423
14436
|
].includes(kind),
|
|
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 == "
|
|
14437
|
+
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 == "skip-duplicates" ? "Bind an items array. Configure fields as dot-separated identity paths; an empty list uses each scalar item. Outputs are items and duplicates. History belongs to this node and commits only when the Run completes successfully. Fields accept strings or finite numbers; missing or complex values reject the batch." : 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.",
|
|
14425
14438
|
example: {
|
|
14426
14439
|
op: "node.add",
|
|
14427
14440
|
as: "step",
|
|
@@ -14444,12 +14457,8 @@ function authoringSchema(kind) {
|
|
|
14444
14457
|
}]
|
|
14445
14458
|
} },
|
|
14446
14459
|
"integration": { config: { key: "<Trigger key>" } },
|
|
14447
|
-
"
|
|
14448
|
-
config: {
|
|
14449
|
-
field: "id",
|
|
14450
|
-
mode: "new",
|
|
14451
|
-
space: "node"
|
|
14452
|
-
},
|
|
14460
|
+
"skip-duplicates": {
|
|
14461
|
+
config: { fields: ["id"] },
|
|
14453
14462
|
inputs: { items: {
|
|
14454
14463
|
kind: "value",
|
|
14455
14464
|
value: [{ id: "a" }, { id: "b" }]
|
|
@@ -14714,7 +14723,7 @@ var nodeErrorSchema = {
|
|
|
14714
14723
|
}
|
|
14715
14724
|
};
|
|
14716
14725
|
function supportsNodeErrorHandling(node) {
|
|
14717
|
-
return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "
|
|
14726
|
+
return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "skip-duplicates";
|
|
14718
14727
|
}
|
|
14719
14728
|
function nodeSystemOutputPorts(node) {
|
|
14720
14729
|
return supportsNodeErrorHandling(node) && node.onError == "error" ? { error: {
|
|
@@ -16600,7 +16609,7 @@ function authoringNode(content, ref) {
|
|
|
16600
16609
|
inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
|
|
16601
16610
|
};
|
|
16602
16611
|
else if (task.executor.kind == "workflow") config = { flowId: task.executor.flowId };
|
|
16603
|
-
else if (task.executor.kind == "http-request" || task.executor.kind == "
|
|
16612
|
+
else if (task.executor.kind == "http-request" || task.executor.kind == "skip-duplicates") {
|
|
16604
16613
|
const { kind: _kind, ...settings } = task.executor;
|
|
16605
16614
|
config = settings;
|
|
16606
16615
|
} else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
|
|
@@ -16990,12 +16999,12 @@ async function compileAuthoring(base, request, host) {
|
|
|
16990
16999
|
};
|
|
16991
17000
|
} else task = await connectorTask(config, String(update.name));
|
|
16992
17001
|
} else if (type == "decision") task = decisionTask(config.questions, String(update.name));
|
|
16993
|
-
else if (type == "
|
|
17002
|
+
else if (type == "skip-duplicates") task = {
|
|
16994
17003
|
...before,
|
|
16995
17004
|
name: String(update.name),
|
|
16996
17005
|
executor: {
|
|
16997
|
-
kind: "
|
|
16998
|
-
...
|
|
17006
|
+
kind: "skip-duplicates",
|
|
17007
|
+
...skipDuplicatesConfigSchema.parse(config)
|
|
16999
17008
|
}
|
|
17000
17009
|
};
|
|
17001
17010
|
else if (type == "http-request") {
|
|
@@ -17345,8 +17354,8 @@ async function compileAuthoring(base, request, host) {
|
|
|
17345
17354
|
case "connector":
|
|
17346
17355
|
changes = createManagedTask(identity, await connectorTask(config, name));
|
|
17347
17356
|
break;
|
|
17348
|
-
case "
|
|
17349
|
-
changes = createManagedTask(identity,
|
|
17357
|
+
case "skip-duplicates":
|
|
17358
|
+
changes = createManagedTask(identity, skipDuplicatesTask(skipDuplicatesConfigSchema.parse(config), name));
|
|
17350
17359
|
break;
|
|
17351
17360
|
case "http-request":
|
|
17352
17361
|
changes = createManagedTask(identity, httpRequestTask(httpRequestConfigSchema.parse(config), name));
|
|
@@ -17569,7 +17578,7 @@ var descriptions = {
|
|
|
17569
17578
|
"poll": "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection.",
|
|
17570
17579
|
"integration": "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.",
|
|
17571
17580
|
"decision": "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.",
|
|
17572
|
-
"
|
|
17581
|
+
"skip-duplicates": "Skip items already recorded by successful Runs. Configure identity fields; an empty list uses each string or numeric item. History is private to the node and only commits after Run success.",
|
|
17573
17582
|
"http-request": "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers.",
|
|
17574
17583
|
"openapi": "A fixed JSON API operation. Replace the example document and URL before running.",
|
|
17575
17584
|
"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.",
|
|
@@ -17614,10 +17623,10 @@ function authoringExample(name) {
|
|
|
17614
17623
|
instructions: "Does the customer need support?"
|
|
17615
17624
|
}]);
|
|
17616
17625
|
break;
|
|
17617
|
-
case "
|
|
17618
|
-
operations = [...createManagedTask({ nodeId: "
|
|
17626
|
+
case "skip-duplicates":
|
|
17627
|
+
operations = [...createManagedTask({ nodeId: "skip-duplicates" }, skipDuplicatesTask()), {
|
|
17619
17628
|
kind: "graph.node.input.set",
|
|
17620
|
-
nodeId: "
|
|
17629
|
+
nodeId: "skip-duplicates",
|
|
17621
17630
|
handle: "items",
|
|
17622
17631
|
value: {
|
|
17623
17632
|
kind: "value",
|
|
@@ -17880,6 +17889,7 @@ var trigger = strictObject({
|
|
|
17880
17889
|
outputs: record$3(string(), json)
|
|
17881
17890
|
});
|
|
17882
17891
|
var schemas = {
|
|
17892
|
+
readFlowState: stateReadSchema.extend({ version }),
|
|
17883
17893
|
canvas: strictObject({
|
|
17884
17894
|
command: canvasCommandSchema,
|
|
17885
17895
|
version
|
|
@@ -17907,6 +17917,7 @@ var schemas = {
|
|
|
17907
17917
|
name: flowName,
|
|
17908
17918
|
teamId: id.optional(),
|
|
17909
17919
|
tagIds: tagIds.optional(),
|
|
17920
|
+
presentation: record$3(string(), json).optional(),
|
|
17910
17921
|
version
|
|
17911
17922
|
}),
|
|
17912
17923
|
saveTag: strictObject({
|
|
@@ -18018,6 +18029,7 @@ function decoder(schema) {
|
|
|
18018
18029
|
return (value) => schema.parse(value);
|
|
18019
18030
|
}
|
|
18020
18031
|
var controlRequests = {
|
|
18032
|
+
readFlowState: decoder(schemas.readFlowState),
|
|
18021
18033
|
canvas: decoder(schemas.canvas),
|
|
18022
18034
|
authoringCheck: decoder(schemas.authoringCheck),
|
|
18023
18035
|
authoringEdit: decoder(schemas.authoringEdit),
|
|
@@ -8760,23 +8760,30 @@ var httpRequestExecutorSchema = strictObject({
|
|
|
8760
8760
|
]).default("auto"),
|
|
8761
8761
|
statusPolicy: _enum(["success", "all"]).default("success")
|
|
8762
8762
|
}).extend({ kind: literal("http-request") });
|
|
8763
|
+
//#endregion
|
|
8764
|
+
//#region src/state/common/state.ts
|
|
8765
|
+
var stateReadLimits = {
|
|
8766
|
+
maxKeys: 16,
|
|
8767
|
+
maxBytes: 1048576
|
|
8768
|
+
};
|
|
8769
|
+
var keySchema = string().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
|
|
8770
|
+
strictObject({
|
|
8771
|
+
scope: _enum(["draft", "live"]),
|
|
8772
|
+
values: literal(false).optional()
|
|
8773
|
+
});
|
|
8763
8774
|
strictObject({
|
|
8764
8775
|
scope: _enum(["draft", "live"]),
|
|
8765
|
-
|
|
8776
|
+
keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
|
|
8766
8777
|
});
|
|
8767
8778
|
strictObject({
|
|
8768
8779
|
scope: _enum(["draft", "live"]),
|
|
8769
|
-
key:
|
|
8780
|
+
key: keySchema.optional()
|
|
8770
8781
|
});
|
|
8771
8782
|
strictObject({
|
|
8772
8783
|
scope: _enum(["draft", "live"]),
|
|
8773
8784
|
space: string().regex(/^(flow|node:.+)$/)
|
|
8774
8785
|
});
|
|
8775
|
-
var
|
|
8776
|
-
field: string().default(""),
|
|
8777
|
-
mode: _enum(["new", "increasing"]).default("new"),
|
|
8778
|
-
space: _enum(["node", "flow"]).default("node")
|
|
8779
|
-
}).extend({ kind: literal("dedupe") });
|
|
8786
|
+
var skipDuplicatesExecutorSchema = strictObject({ fields: array(string().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) }).extend({ kind: literal("skip-duplicates") });
|
|
8780
8787
|
object({
|
|
8781
8788
|
version: literal(1),
|
|
8782
8789
|
scope: _enum(["draft", "live"]),
|
|
@@ -8787,24 +8794,30 @@ object({
|
|
|
8787
8794
|
maxIdentities: number().positive(),
|
|
8788
8795
|
maxRunWrites: number().positive()
|
|
8789
8796
|
}),
|
|
8790
|
-
values: array(
|
|
8797
|
+
values: array(strictObject({
|
|
8791
8798
|
key: string(),
|
|
8792
8799
|
size: number().nonnegative(),
|
|
8793
|
-
updatedAt: number()
|
|
8794
|
-
value: json$1().optional()
|
|
8800
|
+
updatedAt: number()
|
|
8795
8801
|
})),
|
|
8796
8802
|
spaces: array(object({
|
|
8797
8803
|
space: string(),
|
|
8798
|
-
mode: _enum(["new", "increasing"]),
|
|
8799
8804
|
count: number().nonnegative(),
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
number(),
|
|
8803
|
-
_null()
|
|
8804
|
-
]),
|
|
8805
|
+
pendingCount: number().nonnegative(),
|
|
8806
|
+
reservedCount: number().nonnegative(),
|
|
8805
8807
|
updatedAt: number()
|
|
8806
8808
|
}))
|
|
8807
8809
|
});
|
|
8810
|
+
object({
|
|
8811
|
+
version: literal(1),
|
|
8812
|
+
scope: _enum(["draft", "live"]),
|
|
8813
|
+
values: array(strictObject({
|
|
8814
|
+
key: keySchema,
|
|
8815
|
+
value: json$1()
|
|
8816
|
+
})).min(1).max(stateReadLimits.maxKeys)
|
|
8817
|
+
}).refine((response) => {
|
|
8818
|
+
const encoder = new TextEncoder();
|
|
8819
|
+
return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
|
|
8820
|
+
}, "State values exceed the 1 MiB read limit.");
|
|
8808
8821
|
function checkJsonDepth(value, depth = 0) {
|
|
8809
8822
|
if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
|
|
8810
8823
|
if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
|
|
@@ -9101,7 +9114,7 @@ var managedFields = object({
|
|
|
9101
9114
|
revisionId: text
|
|
9102
9115
|
}),
|
|
9103
9116
|
httpRequestExecutorSchema,
|
|
9104
|
-
|
|
9117
|
+
skipDuplicatesExecutorSchema
|
|
9105
9118
|
])
|
|
9106
9119
|
});
|
|
9107
9120
|
var managed = managedFields.transform(limitDecisionTask);
|
|
@@ -9573,7 +9586,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
|
|
|
9573
9586
|
...shape
|
|
9574
9587
|
})])).values()])).min(1);
|
|
9575
9588
|
function checkModelVersion(content) {
|
|
9576
|
-
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "
|
|
9589
|
+
if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
|
|
9577
9590
|
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.");
|
|
9578
9591
|
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.");
|
|
9579
9592
|
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.");
|
|
@@ -9652,7 +9665,7 @@ function setConditionInput(node, handle, mapping) {
|
|
|
9652
9665
|
//#endregion
|
|
9653
9666
|
//#region src/flow/common/errorHandling.ts
|
|
9654
9667
|
function supportsNodeErrorHandling(node) {
|
|
9655
|
-
return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "
|
|
9668
|
+
return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "skip-duplicates";
|
|
9656
9669
|
}
|
|
9657
9670
|
//#endregion
|
|
9658
9671
|
//#region src/flow/common/change.ts
|
|
@@ -71,7 +71,7 @@ export interface ConditionNode extends GraphNodeBase {
|
|
|
71
71
|
readonly matchMode: 'first' | 'all';
|
|
72
72
|
readonly kind: 'condition';
|
|
73
73
|
}
|
|
74
|
-
export type ManagedTaskExecutor = import('./http-request.js').HttpRequestExecutor | import('./flow-state.js').
|
|
74
|
+
export type ManagedTaskExecutor = import('./http-request.js').HttpRequestExecutor | import('./flow-state.js').SkipDuplicatesExecutor | WorkflowExecutor | import('./decision.js').DecisionExecutor | import('./openapi.js').OpenApiExecutor | {
|
|
75
75
|
readonly kind: 'connector';
|
|
76
76
|
readonly action: string;
|
|
77
77
|
readonly connectionId?: string;
|