@oomol-lab/open-flow 0.1.0-beta.65 → 0.1.0-beta.67
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/dist/browser/{createResourceDialog-BAJXbzNH.js → createResourceDialog-BQVD8Rqb.js} +2 -2
- package/dist/browser/{icons-Db2Jb2iX.js → dialog-CS2Vt2if.js} +5736 -5621
- package/dist/browser/event-sources.d.ts +4 -1
- package/dist/browser/flow-authoring-node.d.ts +14 -3
- package/dist/browser/flow-authoring.js +120 -24
- package/dist/browser/flow-change-schema.d.ts +3 -1
- package/dist/browser/flow-change.d.ts +15 -3
- package/dist/browser/flow-change.js +117 -21
- package/dist/browser/{flowChanges-DkvG5uDq.js → flowChanges-VB9Y4iy7.js} +3423 -2380
- package/dist/browser/{flowRunInputEditorStore-B2Rw4VsT.js → flowRunInputEditorStore-DJqmR6Qh.js} +3 -2
- package/dist/browser/{flowWorkspace-BEp-lxqF.js → flowWorkspace-C1hlTnZq.js} +1410 -799
- package/dist/browser/preview.css +273 -119
- package/dist/browser/preview.js +17118 -15810
- package/dist/browser/theme.css +1 -0
- package/dist/browser/ui.css +119 -7
- package/dist/browser/ui.js +8 -5
- package/dist/browser/workbench-contract.d.ts +1 -1
- package/dist/browser/workbench.css +282 -162
- package/dist/browser/workbench.d.ts +0 -1
- package/dist/browser/workbench.js +503 -173
- package/dist/browser/{workbenchSelect-C-jf6NIM.js → workbenchSelect-CpXhjUou.js} +1 -1
- package/dist/command/index.js +49 -49
- package/dist/common/authoring.d.ts +7 -5
- package/dist/common/authoringExamples.d.ts +4 -4
- package/dist/common/authoringFields.d.ts +20 -0
- package/dist/common/authoringSchema.d.ts +404 -15
- package/dist/common/control-api-conformance.js +415 -146
- package/dist/common/control-api.d.ts +67 -8
- package/dist/common/control-api.js +3587 -3443
- package/dist/common/control-requests.d.ts +10 -3
- package/dist/common/control-requests.js +425 -49
- package/dist/common/decision.js +33 -7
- package/dist/common/flow-encoding.d.ts +4 -2
- package/dist/common/flow-encoding.js +151 -14
- package/dist/common/flow-graph.d.ts +1 -1
- package/dist/common/flow-semantics.d.ts +12 -2
- package/dist/common/flow-semantics.js +157 -41
- package/dist/common/integration-trigger.js +33 -7
- package/dist/common/liveDetails.d.ts +26 -11
- package/dist/common/mcp.d.ts +6 -3
- package/dist/common/mcp.js +219 -90
- package/dist/common/openapi.js +33 -7
- package/dist/common/poll-trigger.js +33 -7
- package/dist/common/run-events.d.ts +2 -0
- package/dist/common/run-events.js +9 -3
- package/dist/common/scheduler.d.ts +10 -1
- package/dist/common/scheduler.js +172 -49
- package/dist/common/trigger-contract.d.ts +2 -0
- package/dist/common/webhook-trigger.js +33 -7
- package/dist/common/workflow.d.ts +93 -0
- package/dist/common/workflow.js +10492 -0
- package/package.json +5 -1
- package/skills/open-flow/SKILL.md +9 -0
- package/skills/open-flow/references/flow-authoring.md +28 -16
|
@@ -6810,6 +6810,7 @@ function conditionOperands(node) {
|
|
|
6810
6810
|
}] : []])));
|
|
6811
6811
|
}
|
|
6812
6812
|
function nodeInputMappings(node) {
|
|
6813
|
+
if (node.kind == "outputs") return node.outputMappings;
|
|
6813
6814
|
if (node.kind != "condition") return "inputs" in node ? node.inputs : {};
|
|
6814
6815
|
return Object.fromEntries(conditionOperands(node).flatMap(({ handle, operand }) => operand.kind == "source" ? [[handle, {
|
|
6815
6816
|
kind: "sources",
|
|
@@ -6886,7 +6887,7 @@ function decodeConnectorCapabilities(value) {
|
|
|
6886
6887
|
const actions = source.actions.map((entry) => {
|
|
6887
6888
|
if (entry == null || typeof entry != "object" || Array.isArray(entry)) throw new TypeError("Invalid Connector Action.");
|
|
6888
6889
|
const action = entry;
|
|
6889
|
-
if (Object.keys(action).some((key) => !["action", "connectionId"].includes(key)) || typeof action.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) || Object.hasOwn(action, "connectionId") &&
|
|
6890
|
+
if (Object.keys(action).some((key) => !["action", "connectionId"].includes(key)) || typeof action.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) || Object.hasOwn(action, "connectionId") && typeof action.connectionId != "string") throw new TypeError("Invalid Connector Action permission.");
|
|
6890
6891
|
return action.connectionId == null ? { action: action.action } : {
|
|
6891
6892
|
action: action.action,
|
|
6892
6893
|
connectionId: action.connectionId
|
|
@@ -6978,6 +6979,45 @@ function decodeConnectorCapabilities(value) {
|
|
|
6978
6979
|
};
|
|
6979
6980
|
});
|
|
6980
6981
|
}
|
|
6982
|
+
function isTriggerNode(node) {
|
|
6983
|
+
return [
|
|
6984
|
+
"manual",
|
|
6985
|
+
"start",
|
|
6986
|
+
"error",
|
|
6987
|
+
"webhook",
|
|
6988
|
+
"cron",
|
|
6989
|
+
"poll",
|
|
6990
|
+
"integration"
|
|
6991
|
+
].includes(node.kind);
|
|
6992
|
+
}
|
|
6993
|
+
/** Lossless upgrade of readable content. Historical content and its encoding stay unchanged. */
|
|
6994
|
+
function upgradeRevisionContent(content) {
|
|
6995
|
+
const upgraded = upgradeDecodedRevisionContent(decodeRevisionContent(content));
|
|
6996
|
+
return dequal(content, upgraded) ? content : upgraded;
|
|
6997
|
+
}
|
|
6998
|
+
function upgradeDecodedRevisionContent(content) {
|
|
6999
|
+
const graph = content.document.graph;
|
|
7000
|
+
const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
|
|
7001
|
+
if (!hasManual && content.modelVersion == 8) return content;
|
|
7002
|
+
return {
|
|
7003
|
+
...content,
|
|
7004
|
+
modelVersion: 8,
|
|
7005
|
+
document: {
|
|
7006
|
+
...content.document,
|
|
7007
|
+
graph: hasManual ? {
|
|
7008
|
+
...graph,
|
|
7009
|
+
nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => [id, upgradeManualTrigger(node)]))
|
|
7010
|
+
} : graph
|
|
7011
|
+
}
|
|
7012
|
+
};
|
|
7013
|
+
}
|
|
7014
|
+
function upgradeManualTrigger(node) {
|
|
7015
|
+
return node.kind == "manual" ? {
|
|
7016
|
+
...node,
|
|
7017
|
+
kind: "start",
|
|
7018
|
+
inputDefs: []
|
|
7019
|
+
} : node;
|
|
7020
|
+
}
|
|
6981
7021
|
function normalizeNodeName(value) {
|
|
6982
7022
|
return value.trim().normalize("NFC");
|
|
6983
7023
|
}
|
|
@@ -6996,8 +7036,9 @@ function invalid(message) {
|
|
|
6996
7036
|
throw new FlowChangeError(message);
|
|
6997
7037
|
}
|
|
6998
7038
|
function applyFlowChanges(content, operations) {
|
|
6999
|
-
const
|
|
7000
|
-
const
|
|
7039
|
+
const source = content.modelVersion != 8 || Object.values(content.document.graph.nodes).some((node) => node.kind == "manual") ? decodeRevisionContent(content) : content;
|
|
7040
|
+
const document = { ...source.document };
|
|
7041
|
+
const modules = { ...source.modules };
|
|
7001
7042
|
for (const operation of operations) switch (operation.kind) {
|
|
7002
7043
|
case "graph.trigger.sources.set": {
|
|
7003
7044
|
const graph = document.graph;
|
|
@@ -7048,8 +7089,9 @@ function applyFlowChanges(content, operations) {
|
|
|
7048
7089
|
case "graph.edge.connect": {
|
|
7049
7090
|
const graph = document.graph;
|
|
7050
7091
|
if (graph.nodes[operation.edge.source] == null) invalid("The source Node does not exist.");
|
|
7092
|
+
if (graph.nodes[operation.edge.source]?.kind == "outputs") invalid("Outputs cannot have downstream execution edges.");
|
|
7051
7093
|
const node = graph.nodes[operation.edge.target];
|
|
7052
|
-
if (node == null ||
|
|
7094
|
+
if (node == null || isTriggerNode(node)) invalid("The target Node does not accept execution dependencies.");
|
|
7053
7095
|
if (graph.edges.some((edge) => dequal(edge, operation.edge))) invalid("The Nodes are already connected.");
|
|
7054
7096
|
Object.assign(document, { graph: {
|
|
7055
7097
|
...graph,
|
|
@@ -7129,9 +7171,10 @@ function applyFlowChanges(content, operations) {
|
|
|
7129
7171
|
const graph = document.graph;
|
|
7130
7172
|
if (graph.nodes[operation.nodeId] != null) invalid("A Node with this ID already exists in the target graph.");
|
|
7131
7173
|
if (operation.node.kind == "error" && Object.values(graph.nodes).some((node) => node.kind == "error")) invalid("A graph can contain only one Flow Error node.");
|
|
7132
|
-
if (operation.node.kind == "manual" && Object.values(graph.nodes).some((node) => node.kind == "manual")) invalid("A graph can contain only one
|
|
7174
|
+
if ((operation.node.kind == "manual" || operation.node.kind == "start") && Object.values(graph.nodes).some((node) => node.kind == "manual" || node.kind == "start")) invalid("A graph can contain only one Start Trigger.");
|
|
7133
7175
|
if (operation.node.kind == "task" && "moduleId" in operation.node.task && operation.node.task.capabilities !== void 0) decodeConnectorCapabilities(operation.node.task.capabilities);
|
|
7134
7176
|
if (operation.node.name == null) invalid("A Node name cannot be empty.");
|
|
7177
|
+
if (operation.node.kind == "outputs" && Object.values(graph.nodes).some((node) => node.kind == "outputs")) invalid("A graph can contain only one Outputs node.");
|
|
7135
7178
|
const name = normalizeNodeName(operation.node.name);
|
|
7136
7179
|
const issue = nodeNameIssue(graph, operation.nodeId, name);
|
|
7137
7180
|
if (issue == "empty") invalid("A Node name cannot be empty.");
|
|
@@ -7189,11 +7232,24 @@ function applyFlowChanges(content, operations) {
|
|
|
7189
7232
|
case "graph.node.input.set": {
|
|
7190
7233
|
const graph = document.graph;
|
|
7191
7234
|
const node = graph.nodes[operation.nodeId];
|
|
7192
|
-
if (node == null ||
|
|
7235
|
+
if (node == null || isTriggerNode(node)) invalid("The Node does not accept inputs.");
|
|
7193
7236
|
if (!dequal(nodeInputMappings(node)[operation.handle], operation.before)) invalid("The Node input changed before this operation was applied.");
|
|
7194
|
-
const inputs = { ...node
|
|
7237
|
+
const inputs = { ...nodeInputMappings(node) };
|
|
7195
7238
|
if (operation.value == null) delete inputs[operation.handle];
|
|
7196
7239
|
else inputs[operation.handle] = operation.value;
|
|
7240
|
+
if (node.kind == "outputs") {
|
|
7241
|
+
document.graph = {
|
|
7242
|
+
...graph,
|
|
7243
|
+
nodes: {
|
|
7244
|
+
...graph.nodes,
|
|
7245
|
+
[operation.nodeId]: {
|
|
7246
|
+
...node,
|
|
7247
|
+
outputMappings: inputs
|
|
7248
|
+
}
|
|
7249
|
+
}
|
|
7250
|
+
};
|
|
7251
|
+
break;
|
|
7252
|
+
}
|
|
7197
7253
|
Object.assign(document, { graph: {
|
|
7198
7254
|
...graph,
|
|
7199
7255
|
nodes: {
|
|
@@ -7421,11 +7477,11 @@ function applyFlowChanges(content, operations) {
|
|
|
7421
7477
|
}
|
|
7422
7478
|
}
|
|
7423
7479
|
assertOpenApiAuthBindings(document);
|
|
7424
|
-
return {
|
|
7480
|
+
return upgradeDecodedRevisionContent({
|
|
7425
7481
|
document,
|
|
7426
|
-
modelVersion:
|
|
7482
|
+
modelVersion: 8,
|
|
7427
7483
|
modules
|
|
7428
|
-
};
|
|
7484
|
+
});
|
|
7429
7485
|
}
|
|
7430
7486
|
//#endregion
|
|
7431
7487
|
//#region src/json-schema-subset/utils.ts
|
|
@@ -10367,6 +10423,7 @@ function webhookSupportsBody(method) {
|
|
|
10367
10423
|
return method !== "GET";
|
|
10368
10424
|
}
|
|
10369
10425
|
var text$1 = string();
|
|
10426
|
+
var actionConnection = text$1.describe("Account selection: omit while unconfigured; use an account ID to select it; use \"\" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.");
|
|
10370
10427
|
var json$4 = json$5();
|
|
10371
10428
|
var strings = array(text$1);
|
|
10372
10429
|
var port = object$1({
|
|
@@ -10375,6 +10432,7 @@ var port = object$1({
|
|
|
10375
10432
|
nullable: boolean(),
|
|
10376
10433
|
handle: text$1
|
|
10377
10434
|
});
|
|
10435
|
+
var workflowInputDefs = array(port.strict());
|
|
10378
10436
|
var input = port.extend({ value: json$4.optional() });
|
|
10379
10437
|
var group = object$1({
|
|
10380
10438
|
collapsed: boolean().optional(),
|
|
@@ -10421,7 +10479,7 @@ var capability = union([
|
|
|
10421
10479
|
mode: literal("independent"),
|
|
10422
10480
|
actions: array(strictObject({
|
|
10423
10481
|
action: text$1,
|
|
10424
|
-
connectionId:
|
|
10482
|
+
connectionId: actionConnection.optional()
|
|
10425
10483
|
}))
|
|
10426
10484
|
}),
|
|
10427
10485
|
strictObject({
|
|
@@ -10481,7 +10539,7 @@ var managedFields = object$1({
|
|
|
10481
10539
|
object$1({
|
|
10482
10540
|
kind: literal("connector"),
|
|
10483
10541
|
action: text$1,
|
|
10484
|
-
connectionId:
|
|
10542
|
+
connectionId: actionConnection.optional(),
|
|
10485
10543
|
outputMode: literal("value").optional()
|
|
10486
10544
|
}),
|
|
10487
10545
|
object$1({
|
|
@@ -10521,17 +10579,22 @@ var managedFields = object$1({
|
|
|
10521
10579
|
name: text$1,
|
|
10522
10580
|
description: text$1,
|
|
10523
10581
|
action: text$1,
|
|
10524
|
-
connectionId:
|
|
10582
|
+
connectionId: actionConnection.optional(),
|
|
10525
10583
|
approval: boolean(),
|
|
10526
10584
|
inputs: array(input.extend({ source: agentInput }))
|
|
10527
10585
|
})),
|
|
10528
10586
|
notification: object$1({
|
|
10529
10587
|
action: text$1,
|
|
10530
|
-
connectionId:
|
|
10588
|
+
connectionId: actionConnection.optional(),
|
|
10531
10589
|
inputDefinitions: array(input),
|
|
10532
10590
|
messageHandle: text$1,
|
|
10533
10591
|
inputs: record$3(text$1, agentValue)
|
|
10534
10592
|
}).optional()
|
|
10593
|
+
}),
|
|
10594
|
+
strictObject({
|
|
10595
|
+
kind: literal("workflow"),
|
|
10596
|
+
flowId: text$1,
|
|
10597
|
+
revisionId: text$1
|
|
10535
10598
|
})
|
|
10536
10599
|
])
|
|
10537
10600
|
});
|
|
@@ -10640,6 +10703,12 @@ var base = {
|
|
|
10640
10703
|
timeoutMs: number().optional()
|
|
10641
10704
|
};
|
|
10642
10705
|
var node = union([
|
|
10706
|
+
strictObject({
|
|
10707
|
+
...base,
|
|
10708
|
+
kind: literal("outputs"),
|
|
10709
|
+
outputDefs: array(port.strict()),
|
|
10710
|
+
outputMappings: inputs$1
|
|
10711
|
+
}).omit({ inputs: true }),
|
|
10643
10712
|
object$1({
|
|
10644
10713
|
...base,
|
|
10645
10714
|
inputs: record$3(text$1, never()),
|
|
@@ -10672,6 +10741,11 @@ var node = union([
|
|
|
10672
10741
|
...trigger$1,
|
|
10673
10742
|
kind: literal("manual")
|
|
10674
10743
|
}),
|
|
10744
|
+
strictObject({
|
|
10745
|
+
...trigger$1,
|
|
10746
|
+
kind: literal("start"),
|
|
10747
|
+
inputDefs: workflowInputDefs
|
|
10748
|
+
}),
|
|
10675
10749
|
strictObject({
|
|
10676
10750
|
...trigger$1,
|
|
10677
10751
|
kind: literal("error"),
|
|
@@ -10751,35 +10825,51 @@ var module = object$1({
|
|
|
10751
10825
|
imports: strings,
|
|
10752
10826
|
source: text$1
|
|
10753
10827
|
});
|
|
10754
|
-
var document = preprocess(
|
|
10828
|
+
var document = preprocess(normalizeDocument, object$1({
|
|
10755
10829
|
bindings: record$3(text$1, binding),
|
|
10756
10830
|
graph
|
|
10757
10831
|
}));
|
|
10758
|
-
object$1({
|
|
10832
|
+
var revision = object$1({
|
|
10759
10833
|
modelVersion: union([
|
|
10760
10834
|
literal(2),
|
|
10761
10835
|
literal(4),
|
|
10762
10836
|
literal(5),
|
|
10763
|
-
literal(6)
|
|
10837
|
+
literal(6),
|
|
10838
|
+
literal(7),
|
|
10839
|
+
literal(8)
|
|
10764
10840
|
]),
|
|
10765
10841
|
document,
|
|
10766
10842
|
modules: record$3(text$1, module)
|
|
10767
|
-
})
|
|
10843
|
+
});
|
|
10844
|
+
revision.extend({
|
|
10768
10845
|
kind: literal("open-flow-flow-revision"),
|
|
10769
10846
|
version: literal(1)
|
|
10770
10847
|
});
|
|
10771
|
-
function
|
|
10848
|
+
function normalizeDocument(value) {
|
|
10772
10849
|
const candidate = record$2(value);
|
|
10773
10850
|
if (candidate.tasks !== void 0 && (candidate.tasks === null || typeof candidate.tasks !== "object" || Array.isArray(candidate.tasks) || Object.keys(candidate.tasks).length > 0)) throw new TypeError("Independent Task definitions are no longer supported.");
|
|
10774
10851
|
if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record$2(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
|
|
10775
10852
|
const subflows = candidate.subflows;
|
|
10776
10853
|
if (subflows !== void 0 && (subflows === null || typeof subflows !== "object" || Array.isArray(subflows) || Object.keys(subflows).length > 0)) throw new TypeError("Subflows are no longer supported.");
|
|
10777
10854
|
if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => record$2(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
|
|
10855
|
+
if ([
|
|
10856
|
+
"inputDefs",
|
|
10857
|
+
"outputDefs",
|
|
10858
|
+
"outputMappings"
|
|
10859
|
+
].some((field) => Object.hasOwn(candidate, field))) throw new TypeError("Workflow interface configuration must belong to Start and Outputs nodes.");
|
|
10860
|
+
if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => record$2(candidateNode).kind == "start" && Object.hasOwn(record$2(candidateNode), "parameters"))) throw new TypeError("Legacy Start.parameters is unsupported; configure node.inputDefs.");
|
|
10778
10861
|
return value;
|
|
10779
10862
|
}
|
|
10780
10863
|
function record$2(value) {
|
|
10781
10864
|
return value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
|
|
10782
10865
|
}
|
|
10866
|
+
function decodeRevisionContent(value) {
|
|
10867
|
+
checkJsonDepth(value);
|
|
10868
|
+
const content = revision.parse(value);
|
|
10869
|
+
checkModelVersion(content);
|
|
10870
|
+
assertOpenApiAuthBindings(content.document);
|
|
10871
|
+
return content;
|
|
10872
|
+
}
|
|
10783
10873
|
var shapes = {
|
|
10784
10874
|
"graph.trigger.sources.set": {
|
|
10785
10875
|
nodeId: text$1,
|
|
@@ -10956,6 +11046,12 @@ function changeOperationsSchema(kind) {
|
|
|
10956
11046
|
if (schema == null) throw new TypeError(`Unknown operation ${JSON.stringify(kind)}.`);
|
|
10957
11047
|
return toJSONSchema(schema, { io: "input" });
|
|
10958
11048
|
}
|
|
11049
|
+
function checkModelVersion(content) {
|
|
11050
|
+
if (content.modelVersion < 8 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "outputs")) throw new TypeError("Workflow outputs require Flow model version 8.");
|
|
11051
|
+
if (content.modelVersion < 7 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "start")) throw new TypeError("Start Triggers require Flow model version 7.");
|
|
11052
|
+
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.");
|
|
11053
|
+
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.");
|
|
11054
|
+
}
|
|
10959
11055
|
//#endregion
|
|
10960
11056
|
//#region src/control/common/authoringLlm.ts
|
|
10961
11057
|
var authoringLlmConfiguration = strictObject({
|
|
@@ -11527,7 +11623,9 @@ var id$2 = string().min(1);
|
|
|
11527
11623
|
var json$3 = json$5();
|
|
11528
11624
|
var patch = record$3(id$2, json$3);
|
|
11529
11625
|
var authoringTypes = [
|
|
11530
|
-
"
|
|
11626
|
+
"start",
|
|
11627
|
+
"outputs",
|
|
11628
|
+
"workflow",
|
|
11531
11629
|
"webhook",
|
|
11532
11630
|
"cron",
|
|
11533
11631
|
"error",
|
|
@@ -11600,6 +11698,12 @@ var field = strictObject({
|
|
|
11600
11698
|
description: string().optional()
|
|
11601
11699
|
});
|
|
11602
11700
|
var inputFields = record$3(id$2, field.extend({ default: json$3.optional() })).describe("Optional business input constraints by name. A binding to a new Code, Agent, LLM, Wait or Approval input automatically declares an input accepting any JSON. Existing constraints are preserved. Omitted schema accepts any JSON; omitted nullable is true. Use default for inherited values; input.set supplies data.");
|
|
11701
|
+
var flowInputFields = record$3(id$2, field).describe("Workflow input definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Supply call values as trigger.outputs.");
|
|
11702
|
+
var flowOutputFields = flowInputFields.describe("Workflow output definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Set values on the Outputs node with input.set or node.add.inputs.");
|
|
11703
|
+
var flowInputFieldsView = record$3(id$2, field.extend({
|
|
11704
|
+
schema: json$3,
|
|
11705
|
+
nullable: boolean()
|
|
11706
|
+
}));
|
|
11603
11707
|
var outputFields = record$3(id$2, field).describe("Code return fields by name. Omitted schema accepts any JSON; omitted nullable is true.");
|
|
11604
11708
|
var expression = strictObject({
|
|
11605
11709
|
left: operand,
|
|
@@ -11613,7 +11717,9 @@ var when = union([
|
|
|
11613
11717
|
strictObject({ any: array(union([expression, all])) })
|
|
11614
11718
|
]);
|
|
11615
11719
|
var authoringConfigurations = {
|
|
11616
|
-
|
|
11720
|
+
workflow: strictObject({ flowId: id$2 }),
|
|
11721
|
+
start: strictObject({ inputDefs: flowInputFields.default({}) }),
|
|
11722
|
+
outputs: strictObject({ outputDefs: flowOutputFields.default({}) }),
|
|
11617
11723
|
error: strictObject({ sourceFlowIds: array(id$2).optional() }),
|
|
11618
11724
|
webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
|
|
11619
11725
|
cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
|
|
@@ -11684,6 +11790,10 @@ var authoringEditSchema = discriminatedUnion("op", [
|
|
|
11684
11790
|
set: updates.optional(),
|
|
11685
11791
|
clear: array(array(id$2).min(1)).optional()
|
|
11686
11792
|
}),
|
|
11793
|
+
strictObject({
|
|
11794
|
+
op: literal("node.refresh"),
|
|
11795
|
+
node: referenceSchema
|
|
11796
|
+
}),
|
|
11687
11797
|
strictObject({
|
|
11688
11798
|
op: literal("node.remove"),
|
|
11689
11799
|
node: referenceSchema
|
|
@@ -11747,7 +11857,7 @@ var authoringSchemaQuery = strictObject({
|
|
|
11747
11857
|
var requestContracts = {
|
|
11748
11858
|
read: {
|
|
11749
11859
|
schema: authoringReadSchema,
|
|
11750
|
-
guidance: "Choose one mode: outline (omit nodes and text), node details (nodes), or text excerpt (text). nodes and text are mutually exclusive. Text defaults to 80 lines, at most 200 lines and 24000 characters. For the complete text, repeat at nextStart with the same revision until truncated is false.",
|
|
11860
|
+
guidance: "Read Start and Outputs node details for their interface definitions and data sources. Choose one mode: outline (omit nodes and text), node details (nodes), or text excerpt (text). nodes and text are mutually exclusive. Text defaults to 80 lines, at most 200 lines and 24000 characters. For the complete text, repeat at nextStart with the same revision until truncated is false.",
|
|
11751
11861
|
examples: [
|
|
11752
11862
|
{},
|
|
11753
11863
|
{
|
|
@@ -11775,7 +11885,7 @@ var requestContracts = {
|
|
|
11775
11885
|
},
|
|
11776
11886
|
edit: {
|
|
11777
11887
|
schema: authoringRequestSchema,
|
|
11778
|
-
guidance: "Use the observed revision as baseRevision and a stable requestId. Edits are ordered and atomic. node.add.as declares a batch-local alias without $. Every later reference to that new node must use $alias, including node, edge source/target and output source node fields; a bare alias is not the node ID. Use returned node references in later batches. Updates recursively merge objects (including schemas); {} preserves existing fields. Arrays replace as a whole. Remove fields with clear paths. Text replacement requires exactly one match. Read the target text first. A saved draft can have validation diagnostics.",
|
|
11888
|
+
guidance: "Edit Start config.inputDefs and Outputs config.outputDefs through node.add or node.update; clear paths are relative to the node, e.g. [\"config\",\"inputDefs\",\"amount\"]. Set Outputs values with input.set. Use the observed revision as baseRevision and a stable requestId. Edits are ordered and atomic. node.add.as declares a batch-local alias without $. Every later reference to that new node must use $alias, including node, edge source/target and output source node fields; a bare alias is not the node ID. Use returned node references in later batches. Updates recursively merge objects (including schemas); {} preserves existing fields. Arrays replace as a whole. Remove fields with clear paths. Text replacement requires exactly one match. Read the target text first. A saved draft can have validation diagnostics.",
|
|
11779
11889
|
examples: [{
|
|
11780
11890
|
baseRevision: "REVISION",
|
|
11781
11891
|
requestId: "CREATE_REQUEST",
|
|
@@ -11783,7 +11893,7 @@ var requestContracts = {
|
|
|
11783
11893
|
{
|
|
11784
11894
|
op: "node.add",
|
|
11785
11895
|
as: "start",
|
|
11786
|
-
type: "
|
|
11896
|
+
type: "start",
|
|
11787
11897
|
name: "Start"
|
|
11788
11898
|
},
|
|
11789
11899
|
{
|
|
@@ -11844,7 +11954,8 @@ function authoringSchema(kind) {
|
|
|
11844
11954
|
"unset",
|
|
11845
11955
|
"default"
|
|
11846
11956
|
] : [
|
|
11847
|
-
"
|
|
11957
|
+
"start",
|
|
11958
|
+
"outputs",
|
|
11848
11959
|
"error",
|
|
11849
11960
|
"cron",
|
|
11850
11961
|
"webhook",
|
|
@@ -11865,13 +11976,16 @@ function authoringSchema(kind) {
|
|
|
11865
11976
|
"wait",
|
|
11866
11977
|
"approval"
|
|
11867
11978
|
].includes(kind),
|
|
11868
|
-
guidance: kind == "condition" ? "Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise." : ["poll", "integration"].includes(kind) ? "Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable." : kind == "llm" ? "Configure model settings, message templates and history as defaults. Input bindings with the same names override these defaults; named business inputs can be bound directly. Template strings interpolate {{name}}." : kind == "openapi" ? "Select an operation; the tool resolves its ports and authentication. Read authenticationChoices from node details. authentication is replaced as a complete choice. Bind advertised credentials through inputs." : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
|
|
11979
|
+
guidance: 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 == "start" ? "Declare workflow inputs through config.inputDefs; read them in Start node details. REST calls and manual runs supply them as trigger.outputs. Downstream nodes bind these parameters as Start outputs. Start has no input sources or defaults; non-nullable parameters are required, and omitted nullable parameters become null." : kind == "condition" ? "Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise." : ["poll", "integration"].includes(kind) ? "Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable." : kind == "llm" ? "Configure model settings, message templates and history as defaults. Input bindings with the same names override these defaults; named business inputs can be bound directly. Template strings interpolate {{name}}." : kind == "openapi" ? "Select an operation; the tool resolves its ports and authentication. Read authenticationChoices from node details. authentication is replaced as a complete choice. Bind advertised credentials through inputs." : kind == "workflow" ? "Select another workflow with config.flowId. A workflow cannot call itself, including in a disconnected node. Owned unpublished or unavailable targets may be saved as incomplete drafts. Use node.refresh to load the current published interface." : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
|
|
11869
11980
|
example: {
|
|
11870
11981
|
op: "node.add",
|
|
11871
11982
|
as: "step",
|
|
11872
11983
|
type: kind,
|
|
11873
11984
|
name: "Step",
|
|
11874
11985
|
...{
|
|
11986
|
+
start: { config: { inputDefs: {} } },
|
|
11987
|
+
outputs: { config: { outputDefs: {} } },
|
|
11988
|
+
workflow: { config: { flowId: "<Flow ID>" } },
|
|
11875
11989
|
connector: { config: {
|
|
11876
11990
|
action: "<Action ID>",
|
|
11877
11991
|
connectionId: "<Connection ID>"
|
|
@@ -12026,7 +12140,7 @@ var authoringSearchResponse = object$1({
|
|
|
12026
12140
|
revision: id$2,
|
|
12027
12141
|
data: object$1({
|
|
12028
12142
|
matches: array(object$1({
|
|
12029
|
-
node: id$2,
|
|
12143
|
+
node: id$2.optional(),
|
|
12030
12144
|
field: id$2,
|
|
12031
12145
|
line: int().optional(),
|
|
12032
12146
|
excerpt: string()
|
|
@@ -12187,6 +12301,7 @@ function triggerOutputDefinitions(trigger) {
|
|
|
12187
12301
|
switch (trigger.kind) {
|
|
12188
12302
|
case "error": return errorOutputs;
|
|
12189
12303
|
case "manual": return [];
|
|
12304
|
+
case "start": return trigger.inputDefs;
|
|
12190
12305
|
case "cron": return cronOutputs;
|
|
12191
12306
|
case "poll":
|
|
12192
12307
|
case "integration": return trigger.definition.outputs;
|
|
@@ -12205,6 +12320,7 @@ function triggerOutputPorts(trigger) {
|
|
|
12205
12320
|
//#region src/flow/common/graph.ts
|
|
12206
12321
|
function nodeInputPorts(node) {
|
|
12207
12322
|
switch (node.kind) {
|
|
12323
|
+
case "outputs": return portsByHandle(node.outputDefs);
|
|
12208
12324
|
case "condition": return conditionInputPorts(node);
|
|
12209
12325
|
case "value": return {};
|
|
12210
12326
|
case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
|
|
@@ -12215,6 +12331,7 @@ function nodeInputPorts(node) {
|
|
|
12215
12331
|
case "poll":
|
|
12216
12332
|
case "error":
|
|
12217
12333
|
case "manual":
|
|
12334
|
+
case "start":
|
|
12218
12335
|
case "webhook": return {};
|
|
12219
12336
|
}
|
|
12220
12337
|
}
|
|
@@ -12261,6 +12378,7 @@ function resolutionOutputPorts(node) {
|
|
|
12261
12378
|
}
|
|
12262
12379
|
function nodeOutputPorts(node) {
|
|
12263
12380
|
switch (node.kind) {
|
|
12381
|
+
case "outputs":
|
|
12264
12382
|
case "condition": return {};
|
|
12265
12383
|
case "value": return portsByHandle(node.values);
|
|
12266
12384
|
case "task": return portsByHandle(node.task.outputs);
|
|
@@ -12271,6 +12389,7 @@ function nodeOutputPorts(node) {
|
|
|
12271
12389
|
case "poll":
|
|
12272
12390
|
case "error":
|
|
12273
12391
|
case "manual":
|
|
12392
|
+
case "start":
|
|
12274
12393
|
case "webhook": return triggerOutputPorts(node);
|
|
12275
12394
|
}
|
|
12276
12395
|
}
|
|
@@ -12295,6 +12414,42 @@ async function imports(source) {
|
|
|
12295
12414
|
}
|
|
12296
12415
|
}
|
|
12297
12416
|
//#endregion
|
|
12417
|
+
//#region src/flow/common/portChanges.ts
|
|
12418
|
+
function renamedPort(previous, next) {
|
|
12419
|
+
const previousNames = new Set(previous.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12420
|
+
const nextNames = new Set(next.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12421
|
+
const removed = [...previousNames].filter((name) => !nextNames.has(name));
|
|
12422
|
+
const added = [...nextNames].filter((name) => !previousNames.has(name));
|
|
12423
|
+
return removed.length == 1 && added.length == 1 ? [removed[0], added[0]] : void 0;
|
|
12424
|
+
}
|
|
12425
|
+
function renameOutputMapping(mapping, nodeIds, rename) {
|
|
12426
|
+
if (rename == null || mapping.kind != "sources") return mapping;
|
|
12427
|
+
const sources = mapping.sources.map((source) => source.kind == "node" && nodeIds.has(source.nodeId) && source.output == rename[0] ? {
|
|
12428
|
+
...source,
|
|
12429
|
+
output: rename[1]
|
|
12430
|
+
} : source);
|
|
12431
|
+
return sources.every((source, index) => source === mapping.sources[index]) ? mapping : {
|
|
12432
|
+
kind: "sources",
|
|
12433
|
+
sources
|
|
12434
|
+
};
|
|
12435
|
+
}
|
|
12436
|
+
/** Carry saved mappings through a field rename and remove only fields absent from the new contract. */
|
|
12437
|
+
function remapInputMappings(mappings, ports, rename) {
|
|
12438
|
+
const inputs = { ...mappings };
|
|
12439
|
+
if (rename != null && Object.hasOwn(inputs, rename[0])) {
|
|
12440
|
+
Object.defineProperty(inputs, rename[1], {
|
|
12441
|
+
value: inputs[rename[0]],
|
|
12442
|
+
enumerable: true,
|
|
12443
|
+
configurable: true,
|
|
12444
|
+
writable: true
|
|
12445
|
+
});
|
|
12446
|
+
delete inputs[rename[0]];
|
|
12447
|
+
}
|
|
12448
|
+
const names = new Set(ports.flatMap((port) => "handle" in port ? [port.handle] : []));
|
|
12449
|
+
for (const name of Object.keys(inputs)) if (!names.has(name)) delete inputs[name];
|
|
12450
|
+
return inputs;
|
|
12451
|
+
}
|
|
12452
|
+
//#endregion
|
|
12298
12453
|
//#region src/flow/common/nodeChanges.ts
|
|
12299
12454
|
var codeTaskTemplate = `export default async function (inputs, context) {
|
|
12300
12455
|
return { result: inputs.value }
|
|
@@ -12544,7 +12699,7 @@ function bindingReferences(document) {
|
|
|
12544
12699
|
references.set(bindingId, (references.get(bindingId) ?? 0) + 1);
|
|
12545
12700
|
};
|
|
12546
12701
|
for (const node of Object.values(document.graph.nodes)) {
|
|
12547
|
-
if (
|
|
12702
|
+
if (isTriggerNode(node)) continue;
|
|
12548
12703
|
const inputs = Object.values(nodeInputMappings(node));
|
|
12549
12704
|
for (const mapping of inputs) {
|
|
12550
12705
|
if (mapping.kind != "sources") continue;
|
|
@@ -12553,6 +12708,40 @@ function bindingReferences(document) {
|
|
|
12553
12708
|
}
|
|
12554
12709
|
return references;
|
|
12555
12710
|
}
|
|
12711
|
+
/** Edit the workflow input contract and preserve references on a single-field rename. */
|
|
12712
|
+
function updateStartInputDefs(content, nodeId, value) {
|
|
12713
|
+
const node = content.document.graph.nodes[nodeId];
|
|
12714
|
+
if (node?.kind != "start") throw new TypeError("Expected a Start node.");
|
|
12715
|
+
const previous = node.inputDefs;
|
|
12716
|
+
if (dequal(previous, value)) return [];
|
|
12717
|
+
const operations = [{
|
|
12718
|
+
kind: "graph.node.replace",
|
|
12719
|
+
nodeId,
|
|
12720
|
+
before: node,
|
|
12721
|
+
node: {
|
|
12722
|
+
...node,
|
|
12723
|
+
inputDefs: value
|
|
12724
|
+
}
|
|
12725
|
+
}];
|
|
12726
|
+
const rename = renamedPort(previous, value);
|
|
12727
|
+
if (rename != null) {
|
|
12728
|
+
const instances = /* @__PURE__ */ new Set([nodeId]);
|
|
12729
|
+
for (const [id, downstream] of Object.entries(content.document.graph.nodes)) {
|
|
12730
|
+
if (isTriggerNode(downstream)) continue;
|
|
12731
|
+
for (const [handle, before] of Object.entries(nodeInputMappings(downstream))) {
|
|
12732
|
+
const mapping = renameOutputMapping(before, instances, rename);
|
|
12733
|
+
if (before !== mapping) operations.push({
|
|
12734
|
+
before,
|
|
12735
|
+
kind: "graph.node.input.set",
|
|
12736
|
+
nodeId: id,
|
|
12737
|
+
handle,
|
|
12738
|
+
value: mapping
|
|
12739
|
+
});
|
|
12740
|
+
}
|
|
12741
|
+
}
|
|
12742
|
+
}
|
|
12743
|
+
return operations;
|
|
12744
|
+
}
|
|
12556
12745
|
function defaultInputs(ports) {
|
|
12557
12746
|
return Object.fromEntries(ports.flatMap((port) => "handle" in port && Object.hasOwn(port, "value") ? [[port.handle, {
|
|
12558
12747
|
kind: "value",
|
|
@@ -12565,6 +12754,112 @@ function llmInputValue(values, handle, fallback) {
|
|
|
12565
12754
|
function createDecisionTask(identity, name = "AI Decision", questions) {
|
|
12566
12755
|
return createManagedTask(identity, decisionTask(questions, name));
|
|
12567
12756
|
}
|
|
12757
|
+
/** Edit an Outputs node's definitions and mappings as one undoable change. */
|
|
12758
|
+
function updateOutputsDefs(content, nodeId, value, outputMappings) {
|
|
12759
|
+
const node = content.document.graph.nodes[nodeId];
|
|
12760
|
+
if (node?.kind != "outputs") throw new TypeError("Expected an Outputs node.");
|
|
12761
|
+
const mappings = outputMappings ?? remapInputMappings(node.outputMappings, value, renamedPort(node.outputDefs, value));
|
|
12762
|
+
const next = {
|
|
12763
|
+
...node,
|
|
12764
|
+
outputDefs: value,
|
|
12765
|
+
outputMappings: mappings
|
|
12766
|
+
};
|
|
12767
|
+
return dequal(node, next) ? [] : cleanVariableBindings(content, [{
|
|
12768
|
+
kind: "graph.node.replace",
|
|
12769
|
+
nodeId,
|
|
12770
|
+
before: node,
|
|
12771
|
+
node: next
|
|
12772
|
+
}]);
|
|
12773
|
+
}
|
|
12774
|
+
function renameFlowOutputSources(content, nodeIds, previous, next) {
|
|
12775
|
+
const rename = renamedPort(previous, next);
|
|
12776
|
+
if (rename == null) return [];
|
|
12777
|
+
return Object.entries(content.document.graph.nodes).flatMap(([nodeId, node]) => {
|
|
12778
|
+
if (node.kind != "outputs") return [];
|
|
12779
|
+
const outputMappings = Object.fromEntries(Object.entries(node.outputMappings).map(([name, mapping]) => [name, renameOutputMapping(mapping, nodeIds, rename)]));
|
|
12780
|
+
return dequal(node.outputMappings, outputMappings) ? [] : [{
|
|
12781
|
+
kind: "graph.node.replace",
|
|
12782
|
+
nodeId,
|
|
12783
|
+
before: node,
|
|
12784
|
+
node: {
|
|
12785
|
+
...node,
|
|
12786
|
+
outputMappings
|
|
12787
|
+
}
|
|
12788
|
+
}];
|
|
12789
|
+
});
|
|
12790
|
+
}
|
|
12791
|
+
//#endregion
|
|
12792
|
+
//#region src/workflow/common/workflow.ts
|
|
12793
|
+
var portSchema = object$1({
|
|
12794
|
+
handle: string().min(1),
|
|
12795
|
+
jsonSchema: json$5(),
|
|
12796
|
+
nullable: boolean(),
|
|
12797
|
+
description: string().optional()
|
|
12798
|
+
});
|
|
12799
|
+
strictObject({
|
|
12800
|
+
inputs: array(portSchema).nullable(),
|
|
12801
|
+
outputs: array(portSchema).nullable()
|
|
12802
|
+
});
|
|
12803
|
+
object$1({
|
|
12804
|
+
version: literal(1),
|
|
12805
|
+
flowId: string().min(1),
|
|
12806
|
+
name: string(),
|
|
12807
|
+
revisionId: string().min(1),
|
|
12808
|
+
publicationId: string().min(1),
|
|
12809
|
+
inputs: array(portSchema),
|
|
12810
|
+
outputs: array(portSchema).nullable()
|
|
12811
|
+
});
|
|
12812
|
+
/** A selected target is durable even before its callable interface is available. */
|
|
12813
|
+
function workflowSelectionTask(candidate, contract, previous) {
|
|
12814
|
+
if (contract != null) return workflowTask(contract, candidate.name);
|
|
12815
|
+
if (previous?.executor.kind == "workflow" && previous.executor.flowId == candidate.flowId) return previous;
|
|
12816
|
+
return {
|
|
12817
|
+
name: candidate.name,
|
|
12818
|
+
inputs: [],
|
|
12819
|
+
outputs: [],
|
|
12820
|
+
executor: {
|
|
12821
|
+
kind: "workflow",
|
|
12822
|
+
flowId: candidate.flowId,
|
|
12823
|
+
revisionId: ""
|
|
12824
|
+
}
|
|
12825
|
+
};
|
|
12826
|
+
}
|
|
12827
|
+
function workflowTask(contract, name = contract.name) {
|
|
12828
|
+
return {
|
|
12829
|
+
name,
|
|
12830
|
+
executor: {
|
|
12831
|
+
kind: "workflow",
|
|
12832
|
+
flowId: contract.flowId,
|
|
12833
|
+
revisionId: contract.revisionId
|
|
12834
|
+
},
|
|
12835
|
+
inputs: contract.inputs,
|
|
12836
|
+
outputs: contract.outputs ?? []
|
|
12837
|
+
};
|
|
12838
|
+
}
|
|
12839
|
+
/** Refresh capability ports by exact name; removed outputs remain unresolved at consumers. */
|
|
12840
|
+
function withWorkflowTask(node, task) {
|
|
12841
|
+
return {
|
|
12842
|
+
...node,
|
|
12843
|
+
task,
|
|
12844
|
+
inputs: Object.fromEntries(Object.entries(node.inputs).filter(([handle]) => task.inputs.some((port) => "handle" in port && port.handle == handle)))
|
|
12845
|
+
};
|
|
12846
|
+
}
|
|
12847
|
+
object$1({
|
|
12848
|
+
version: literal(1),
|
|
12849
|
+
direction: _enum(["incoming", "outgoing"]),
|
|
12850
|
+
total: int().nonnegative(),
|
|
12851
|
+
nextOffset: int().nonnegative().optional(),
|
|
12852
|
+
references: array(object$1({
|
|
12853
|
+
flowId: string(),
|
|
12854
|
+
name: string().nullable(),
|
|
12855
|
+
available: boolean(),
|
|
12856
|
+
draft: boolean(),
|
|
12857
|
+
live: object$1({
|
|
12858
|
+
publicationId: string(),
|
|
12859
|
+
enabled: boolean()
|
|
12860
|
+
}).nullable()
|
|
12861
|
+
}))
|
|
12862
|
+
});
|
|
12568
12863
|
//#endregion
|
|
12569
12864
|
//#region src/control/common/authoringCondition.ts
|
|
12570
12865
|
/** Preserve empty groups in invalid drafts; do not turn them into unconditional branches. */
|
|
@@ -12681,8 +12976,9 @@ function portField(ports, path, parent) {
|
|
|
12681
12976
|
}
|
|
12682
12977
|
}
|
|
12683
12978
|
/** Accept a decoded JSON Pointer, including or omitting its initial empty component. */
|
|
12684
|
-
function authoringDiagnosticField(
|
|
12979
|
+
function authoringDiagnosticField(node, parts) {
|
|
12685
12980
|
const path = parts[0] == "" ? parts.slice(1) : parts;
|
|
12981
|
+
if (node == null) return "config";
|
|
12686
12982
|
if (path[0] == "modules") return "code";
|
|
12687
12983
|
let location = path[0] == "document" && path[1] == "graph" && path[2] == "nodes" ? path.slice(4) : path;
|
|
12688
12984
|
const inlineDefinition = node.kind == "task" && location[0] == "task";
|
|
@@ -12690,6 +12986,9 @@ function authoringDiagnosticField(_content, node, parts) {
|
|
|
12690
12986
|
if (location.length == 0) return "config";
|
|
12691
12987
|
const head = location[0];
|
|
12692
12988
|
if (!inlineDefinition && metadata.has(head)) return location.join(".");
|
|
12989
|
+
if (node.kind == "start" && head == "inputDefs") return portField(node.inputDefs, location.slice(1), "config.inputDefs");
|
|
12990
|
+
if (node.kind == "outputs" && head == "outputDefs") return portField(node.outputDefs, location.slice(1), "config.outputDefs");
|
|
12991
|
+
if (node.kind == "outputs" && head == "outputMappings") return ["inputs", ...location.slice(1)].join(".");
|
|
12693
12992
|
if (head == "prompt") return "prompt";
|
|
12694
12993
|
if (head == "inputs" && !inlineDefinition) {
|
|
12695
12994
|
if (node.kind == "condition" && location[1] != null) {
|
|
@@ -12736,6 +13035,7 @@ function authoringDiagnosticField(_content, node, parts) {
|
|
|
12736
13035
|
const field = location[1];
|
|
12737
13036
|
if (field == null || field == "kind") return "config";
|
|
12738
13037
|
if (field == "prompt") return "prompt";
|
|
13038
|
+
if (executor?.kind == "workflow" && field == "revisionId") return "config.flowId";
|
|
12739
13039
|
if (executor?.kind == "openapi") {
|
|
12740
13040
|
if (field == "document") return "config";
|
|
12741
13041
|
if (field == "auth") return "config.authentication";
|
|
@@ -12769,6 +13069,7 @@ function authoringDiagnosticField(_content, node, parts) {
|
|
|
12769
13069
|
case "condition": return head == "cases" || head == "matchMode" ? ["config", ...conditionConfigurationFieldPath(node, location)].join(".") : "config";
|
|
12770
13070
|
case "wait":
|
|
12771
13071
|
case "approval": return head == "inputDefinitions" ? portField(node.inputDefinitions, location.slice(1), "config.inputs") : "config";
|
|
13072
|
+
case "start": return "config";
|
|
12772
13073
|
case "webhook":
|
|
12773
13074
|
if (head == "bodyFields") return portField(node.bodyFields, location.slice(1), "config.body");
|
|
12774
13075
|
return head == "method" || head == "options" ? ["config", ...location].join(".") : "config";
|
|
@@ -12884,6 +13185,7 @@ async function prepareAgentTools(tools, previous, action, id) {
|
|
|
12884
13185
|
/** Shared business configuration for authoring and published entry inspection. */
|
|
12885
13186
|
function triggerConfiguration(node) {
|
|
12886
13187
|
switch (node.kind) {
|
|
13188
|
+
case "start": return { inputDefs: fieldsView(node.inputDefs) };
|
|
12887
13189
|
case "manual": return {};
|
|
12888
13190
|
case "webhook": return {
|
|
12889
13191
|
body: fieldsView(node.bodyFields),
|
|
@@ -12936,7 +13238,7 @@ function inputMappings(node) {
|
|
|
12936
13238
|
}
|
|
12937
13239
|
function typeOf(node) {
|
|
12938
13240
|
const task = taskAt(node);
|
|
12939
|
-
return node.kind != "task" ? node.kind : task != null && "executor" in task ? task.executor.kind : "code";
|
|
13241
|
+
return node.kind == "manual" ? "start" : node.kind != "task" ? node.kind : task != null && "executor" in task ? task.executor.kind : "code";
|
|
12940
13242
|
}
|
|
12941
13243
|
function outwardSource(content, value) {
|
|
12942
13244
|
if (Array.isArray(value)) return value.map((v) => outwardSource(content, v));
|
|
@@ -12993,6 +13295,7 @@ function authoringNode(content, ref) {
|
|
|
12993
13295
|
...llmConfigurationView(task),
|
|
12994
13296
|
inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
|
|
12995
13297
|
};
|
|
13298
|
+
else if (task.executor.kind == "workflow") config = { flowId: task.executor.flowId };
|
|
12996
13299
|
else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
|
|
12997
13300
|
} else if (node.kind == "task" && "moduleId" in node.task) {
|
|
12998
13301
|
config = {
|
|
@@ -13002,6 +13305,9 @@ function authoringNode(content, ref) {
|
|
|
13002
13305
|
};
|
|
13003
13306
|
texts.code = content.modules[node.task.moduleId]?.source ?? "";
|
|
13004
13307
|
} else switch (node.kind) {
|
|
13308
|
+
case "outputs":
|
|
13309
|
+
config = { outputDefs: fieldsView(node.outputDefs) };
|
|
13310
|
+
break;
|
|
13005
13311
|
case "condition":
|
|
13006
13312
|
config = { ...conditionConfigurationView(node, (value) => outwardSource(content, value)) };
|
|
13007
13313
|
break;
|
|
@@ -13017,6 +13323,9 @@ function authoringNode(content, ref) {
|
|
|
13017
13323
|
texts.prompt = node.prompt;
|
|
13018
13324
|
break;
|
|
13019
13325
|
case "manual":
|
|
13326
|
+
config = {};
|
|
13327
|
+
break;
|
|
13328
|
+
case "start":
|
|
13020
13329
|
case "webhook":
|
|
13021
13330
|
case "cron":
|
|
13022
13331
|
case "error":
|
|
@@ -13168,7 +13477,8 @@ function clearPath(value, path) {
|
|
|
13168
13477
|
}
|
|
13169
13478
|
async function compileAuthoring(base, request, host) {
|
|
13170
13479
|
const parsed = authoringRequestSchema.parse(request);
|
|
13171
|
-
|
|
13480
|
+
const upgraded = upgradeRevisionContent(base);
|
|
13481
|
+
let content = upgraded, index = 0, sequence = 0;
|
|
13172
13482
|
const operations = [], aliases = {};
|
|
13173
13483
|
const touchedModules = /* @__PURE__ */ new Set();
|
|
13174
13484
|
const explicitMessages = /* @__PURE__ */ new Set();
|
|
@@ -13216,12 +13526,16 @@ async function compileAuthoring(base, request, host) {
|
|
|
13216
13526
|
}
|
|
13217
13527
|
function replace(ref, node) {
|
|
13218
13528
|
const before = nodeAt(content, ref);
|
|
13219
|
-
if (!dequal(before, node))
|
|
13220
|
-
kind
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
|
|
13529
|
+
if (!dequal(before, node)) {
|
|
13530
|
+
const previous = before.kind == "task" ? before.task.outputs : before.kind == "value" ? before.values : [];
|
|
13531
|
+
const next = node.kind == "task" ? node.task.outputs : node.kind == "value" ? node.values : [];
|
|
13532
|
+
apply([{
|
|
13533
|
+
kind: "graph.node.replace",
|
|
13534
|
+
nodeId: ref,
|
|
13535
|
+
before,
|
|
13536
|
+
node
|
|
13537
|
+
}, ...node.kind == "task" && "executor" in node.task && node.task.executor.kind == "workflow" ? [] : renameFlowOutputSources(content, /* @__PURE__ */ new Set([ref]), previous, next)]);
|
|
13538
|
+
}
|
|
13225
13539
|
}
|
|
13226
13540
|
function taskNode(ref, task) {
|
|
13227
13541
|
const node = nodeAt(content, ref);
|
|
@@ -13245,6 +13559,14 @@ async function compileAuthoring(base, request, host) {
|
|
|
13245
13559
|
outputs: Object.entries(action.outputs).map(([handle, port]) => Object.assign({ handle }, port))
|
|
13246
13560
|
};
|
|
13247
13561
|
}
|
|
13562
|
+
async function resolveWorkflow(flowId, name, previous) {
|
|
13563
|
+
if (host.workflow == null) fail("workflow.unavailable", "Workflow calls are unavailable.");
|
|
13564
|
+
const target = await host.workflow(flowId);
|
|
13565
|
+
return "inputs" in target ? workflowTask(target, name) : workflowSelectionTask({
|
|
13566
|
+
...target,
|
|
13567
|
+
name
|
|
13568
|
+
}, void 0, previous);
|
|
13569
|
+
}
|
|
13248
13570
|
async function configure(ref, patch = {}, clear = []) {
|
|
13249
13571
|
const node = nodeAt(content, ref), view = authoringNode(content, ref), type = view.type;
|
|
13250
13572
|
const update = record(merge({
|
|
@@ -13266,12 +13588,19 @@ async function compileAuthoring(base, request, host) {
|
|
|
13266
13588
|
...rest,
|
|
13267
13589
|
...metadata
|
|
13268
13590
|
};
|
|
13269
|
-
if (
|
|
13591
|
+
if (!isTriggerNode(node)) {
|
|
13270
13592
|
const clean = { ...next };
|
|
13271
13593
|
if (!Object.hasOwn(update, "timeoutMs")) delete clean.timeoutMs;
|
|
13272
13594
|
if (!Object.hasOwn(update, "maxExecutions")) delete clean.maxExecutions;
|
|
13273
13595
|
next = clean;
|
|
13274
13596
|
} else if (update.timeoutMs != null || update.maxExecutions != null) fail("node.invalid-field", "Trigger nodes do not have execution limits.");
|
|
13597
|
+
if (node.kind == "start" || node.kind == "outputs") {
|
|
13598
|
+
replace(ref, next);
|
|
13599
|
+
const ports = fieldsToPorts(node.kind == "start" ? config.inputDefs : config.outputDefs, node.kind == "start" ? node.inputDefs : node.outputDefs).filter((port) => "handle" in port);
|
|
13600
|
+
const changes = node.kind == "start" ? updateStartInputDefs(content, ref, ports) : updateOutputsDefs(content, ref, ports);
|
|
13601
|
+
if (changes.length > 0) apply(changes);
|
|
13602
|
+
return;
|
|
13603
|
+
}
|
|
13275
13604
|
function taskInputs(task, reserved = []) {
|
|
13276
13605
|
if (node.kind != "task") throw new Error("Expected a task.");
|
|
13277
13606
|
const fields = record(config.inputs);
|
|
@@ -13307,7 +13636,16 @@ async function compileAuthoring(base, request, host) {
|
|
|
13307
13636
|
} else if (node.kind == "task" && "executor" in node.task) {
|
|
13308
13637
|
const before = node.task;
|
|
13309
13638
|
let task;
|
|
13310
|
-
if (type == "
|
|
13639
|
+
if (type == "workflow") {
|
|
13640
|
+
task = before.executor.kind == "workflow" && before.executor.flowId == config.flowId ? {
|
|
13641
|
+
...before,
|
|
13642
|
+
name: String(update.name)
|
|
13643
|
+
} : await resolveWorkflow(String(config.flowId), String(update.name));
|
|
13644
|
+
next = withWorkflowTask({
|
|
13645
|
+
...node,
|
|
13646
|
+
...metadata
|
|
13647
|
+
}, task);
|
|
13648
|
+
} else if (type == "connector") {
|
|
13311
13649
|
if (before.executor.kind == "connector" && config.action == before.executor.action) {
|
|
13312
13650
|
const { connectionId: _connectionId, ...executor } = before.executor;
|
|
13313
13651
|
task = {
|
|
@@ -13547,6 +13885,18 @@ async function compileAuthoring(base, request, host) {
|
|
|
13547
13885
|
for (const edit of parsed.edits) {
|
|
13548
13886
|
try {
|
|
13549
13887
|
switch (edit.op) {
|
|
13888
|
+
case "node.refresh": {
|
|
13889
|
+
const ref = resolve(edit.node);
|
|
13890
|
+
const node = nodeAt(content, ref);
|
|
13891
|
+
if (node.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "workflow") fail("node.invalid-type", "Only workflow call nodes support refresh.");
|
|
13892
|
+
apply([{
|
|
13893
|
+
kind: "graph.node.replace",
|
|
13894
|
+
nodeId: ref,
|
|
13895
|
+
before: node,
|
|
13896
|
+
node: withWorkflowTask(node, await resolveWorkflow(node.task.executor.flowId, node.name ?? node.task.name, node.task))
|
|
13897
|
+
}]);
|
|
13898
|
+
break;
|
|
13899
|
+
}
|
|
13550
13900
|
case "node.add": {
|
|
13551
13901
|
if (Object.hasOwn(aliases, edit.as)) fail("node.alias-duplicate", `Duplicate alias ${edit.as}.`);
|
|
13552
13902
|
const nodeId = host.id(`node:${edit.as}`), identity = {
|
|
@@ -13557,6 +13907,21 @@ async function compileAuthoring(base, request, host) {
|
|
|
13557
13907
|
const config = edit.config ?? {};
|
|
13558
13908
|
let changes;
|
|
13559
13909
|
switch (edit.type) {
|
|
13910
|
+
case "workflow":
|
|
13911
|
+
changes = createManagedTask(identity, await resolveWorkflow(String(authoringConfigurations.workflow.parse(config).flowId), name));
|
|
13912
|
+
break;
|
|
13913
|
+
case "outputs":
|
|
13914
|
+
changes = [{
|
|
13915
|
+
kind: "graph.node.create",
|
|
13916
|
+
nodeId,
|
|
13917
|
+
node: {
|
|
13918
|
+
outputDefs: [],
|
|
13919
|
+
outputMappings: {},
|
|
13920
|
+
kind: "outputs",
|
|
13921
|
+
name
|
|
13922
|
+
}
|
|
13923
|
+
}];
|
|
13924
|
+
break;
|
|
13560
13925
|
case "code":
|
|
13561
13926
|
changes = createCodeTask(identity, name, void 0, {
|
|
13562
13927
|
inputs: [],
|
|
@@ -13609,6 +13974,7 @@ async function compileAuthoring(base, request, host) {
|
|
|
13609
13974
|
node: {
|
|
13610
13975
|
kind: edit.type,
|
|
13611
13976
|
name,
|
|
13977
|
+
...edit.type == "start" ? { inputDefs: [] } : {},
|
|
13612
13978
|
...edit.type == "cron" ? { cronTimes: [{
|
|
13613
13979
|
type: "every",
|
|
13614
13980
|
unit: "hour",
|
|
@@ -13689,10 +14055,10 @@ async function compileAuthoring(base, request, host) {
|
|
|
13689
14055
|
kind: "module.delete",
|
|
13690
14056
|
moduleId
|
|
13691
14057
|
}]);
|
|
13692
|
-
const cleaned = cleanVariableBindings(
|
|
14058
|
+
const cleaned = cleanVariableBindings(upgraded, operations);
|
|
13693
14059
|
return {
|
|
13694
14060
|
operations: cleaned,
|
|
13695
|
-
content: cleaned.length == 0 ?
|
|
14061
|
+
content: cleaned.length == 0 ? upgraded : applyFlowChanges(upgraded, cleaned),
|
|
13696
14062
|
nodes: aliases
|
|
13697
14063
|
};
|
|
13698
14064
|
}
|
|
@@ -13715,7 +14081,7 @@ function authoringDiagnostics(content, diagnostics) {
|
|
|
13715
14081
|
code: diagnostic.code,
|
|
13716
14082
|
message,
|
|
13717
14083
|
nodes: affected.map(([id]) => id),
|
|
13718
|
-
field:
|
|
14084
|
+
field: authoringDiagnosticField(affected[0]?.[1], parts),
|
|
13719
14085
|
...diagnostic.line ? {
|
|
13720
14086
|
line: diagnostic.line,
|
|
13721
14087
|
column: diagnostic.column
|
|
@@ -13797,7 +14163,7 @@ var eventSourceRevisionSchema = strictObject({
|
|
|
13797
14163
|
//#endregion
|
|
13798
14164
|
//#region src/control/common/authoringExamples.ts
|
|
13799
14165
|
var descriptions = {
|
|
13800
|
-
"
|
|
14166
|
+
"start": "A Start node with a required message parameter. Supply it through trigger.outputs.",
|
|
13801
14167
|
"error": "A Flow Error node. Select upstream Flows, then publish and enable this Flow to listen for failures in their automatic runs.",
|
|
13802
14168
|
"webhook": "A Webhook start node.",
|
|
13803
14169
|
"cron": "An hourly scheduled start node.",
|
|
@@ -13805,7 +14171,7 @@ var descriptions = {
|
|
|
13805
14171
|
"integration": "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.",
|
|
13806
14172
|
"decision": "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.",
|
|
13807
14173
|
"openapi": "A fixed JSON API operation. Replace the example document and URL before running.",
|
|
13808
|
-
"connector": "A Connector Task and its node. Replace ACTION_ID, CONNECTION_ID and port definitions using connector_get / connector show.",
|
|
14174
|
+
"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.",
|
|
13809
14175
|
"code": "A JavaScript module and its node. Use Code for custom computation; use Connector Tasks for existing actions.",
|
|
13810
14176
|
"condition": "A condition with true and false execution branches.",
|
|
13811
14177
|
"value": "A fixed value node.",
|
|
@@ -13845,11 +14211,16 @@ function authoringExample(name) {
|
|
|
13845
14211
|
} } } } } } } }
|
|
13846
14212
|
}, "https://api.example.com/openapi.json", "/items", "get")));
|
|
13847
14213
|
break;
|
|
13848
|
-
case "
|
|
13849
|
-
operations = createBuiltinTrigger("start", {
|
|
13850
|
-
|
|
14214
|
+
case "start":
|
|
14215
|
+
operations = [...createBuiltinTrigger("start", {
|
|
14216
|
+
inputDefs: [{
|
|
14217
|
+
handle: "message",
|
|
14218
|
+
jsonSchema: { type: "string" },
|
|
14219
|
+
nullable: false
|
|
14220
|
+
}],
|
|
14221
|
+
kind: "start",
|
|
13851
14222
|
name: "Start"
|
|
13852
|
-
});
|
|
14223
|
+
})];
|
|
13853
14224
|
break;
|
|
13854
14225
|
case "webhook":
|
|
13855
14226
|
operations = createBuiltinTrigger("start", {
|
|
@@ -14109,6 +14480,10 @@ var schemas = {
|
|
|
14109
14480
|
expectedRevisionId: id,
|
|
14110
14481
|
version
|
|
14111
14482
|
}),
|
|
14483
|
+
upgradeDraft: strictObject({
|
|
14484
|
+
expectedRevisionId: id,
|
|
14485
|
+
version
|
|
14486
|
+
}),
|
|
14112
14487
|
setEnabled: strictObject({
|
|
14113
14488
|
enabled: boolean(),
|
|
14114
14489
|
expectedPublicationId: id,
|
|
@@ -14205,6 +14580,7 @@ var controlRequests = {
|
|
|
14205
14580
|
};
|
|
14206
14581
|
},
|
|
14207
14582
|
repairDraft: decoder(schemas.repairDraft),
|
|
14583
|
+
upgradeDraft: decoder(schemas.upgradeDraft),
|
|
14208
14584
|
setEnabled: decoder(schemas.setEnabled),
|
|
14209
14585
|
updatePresentation: decoder(schemas.updatePresentation),
|
|
14210
14586
|
checkFlow: decoder(schemas.checkFlow),
|
|
@@ -14233,4 +14609,4 @@ function controlRequestSchema(name) {
|
|
|
14233
14609
|
return schema;
|
|
14234
14610
|
}
|
|
14235
14611
|
//#endregion
|
|
14236
|
-
export { AuthoringError, authoringCheckResponse, authoringCheckSchema, authoringConfigurations, authoringDiagnosticSchema, authoringDiagnostics, authoringEditResponse, authoringEditSchema, authoringExample, authoringExamples, authoringNode, authoringReadResponse, authoringReadSchema, authoringRequestContract, authoringRequestSchema, authoringSchema, authoringSchemaQuery, authoringSearchResponse, authoringSearchSchema, authoringSourceSchema, authoringTypes, canvasCommandSchema, compileAuthoring, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, readAuthoring, resolveDraftOperations, searchAuthoring, waitActionBodySchema };
|
|
14612
|
+
export { AuthoringError, authoringCheckResponse, authoringCheckSchema, authoringConfigurations, authoringDiagnosticSchema, authoringDiagnostics, authoringEditResponse, authoringEditSchema, authoringExample, authoringExamples, authoringNode, authoringReadResponse, authoringReadSchema, authoringRequestContract, authoringRequestSchema, authoringSchema, authoringSchemaQuery, authoringSearchResponse, authoringSearchSchema, authoringSourceSchema, authoringTypes, canvasCommandSchema, compileAuthoring, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, flowInputFields, flowInputFieldsView, flowOutputFields, readAuthoring, resolveDraftOperations, searchAuthoring, waitActionBodySchema };
|