@uipath/maestro-builder-sdk 6.16.14 → 6.17.1
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 -2
- package/dist/api-index.md +115 -114
- package/dist/api-members.md +295 -291
- package/dist/bindings-v2.d.ts +39 -1
- package/dist/bindings-v2.js +289 -9
- package/dist/bpmn/compile-cli.js +11 -2
- package/dist/bpmn/decompile.js +2 -1
- package/dist/bpmn/registry-fallback.js +9 -7
- package/dist/case/compile-cli.js +16 -6
- package/dist/case/decompile-cli.js +2 -1
- package/dist/case/decompile.js +3 -2
- package/dist/case/merge-cli.js +3 -2
- package/dist/check-cli.js +2 -30
- package/dist/check.js +278 -55
- package/dist/cli-library.d.ts +18 -4
- package/dist/cli-library.js +24 -6
- package/dist/cli-result.d.ts +9 -0
- package/dist/cli-result.js +12 -0
- package/dist/compile-cli.js +82 -86
- package/dist/core/actions.d.ts +71 -17
- package/dist/core/agentic-process-forms.d.ts +51 -0
- package/dist/core/agentic-process-forms.js +49 -0
- package/dist/core/binding-messages.d.ts +5 -0
- package/dist/core/cli-library.d.ts +16 -7
- package/dist/core/cli-library.js +53 -19
- package/dist/core/comment-text.d.ts +29 -0
- package/dist/core/comment-text.js +40 -0
- package/dist/core/connector-checks.d.ts +18 -2
- package/dist/core/connector-checks.js +15 -5
- package/dist/core/contribution-bindings.d.ts +73 -0
- package/dist/core/contribution-bindings.js +105 -0
- package/dist/core/error-port.d.ts +25 -0
- package/dist/core/error-port.js +36 -0
- package/dist/core/expr-check.js +7 -2
- package/dist/core/expr.d.ts +11 -5
- package/dist/core/expr.js +9 -3
- package/dist/core/json-file.d.ts +1 -0
- package/dist/core/json-file.js +12 -0
- package/dist/core/library.d.ts +19 -0
- package/dist/core/library.js +22 -6
- package/dist/core/script-return.js +4 -1
- package/dist/core/typed-raw-node.js +1 -0
- package/dist/core/typescript-module.d.ts +2 -0
- package/dist/core/typescript-module.js +18 -0
- package/dist/core-definitions.json +210 -0
- package/dist/decompile-cli.js +2 -1
- package/dist/decompile.js +64 -24
- package/dist/emit.js +4 -3
- package/dist/flow-sdk.d.ts +18 -12
- package/dist/flow-sdk.js +19 -8
- package/dist/flow-step-tree.d.ts +2 -3
- package/dist/flow-step-tree.js +2 -3
- package/dist/load.js +1 -1
- package/dist/merge-cli.js +3 -2
- package/dist/merge.d.ts +2 -1
- package/dist/merge.js +0 -0
- package/dist/path-within.d.ts +33 -0
- package/dist/path-within.js +41 -0
- package/dist/registry/archive/extract.js +2 -5
- package/dist/registry/curated-overlay.js +3 -2
- package/dist/registry/generators/descriptors.js +20 -18
- package/dist/registry/generators/triggers.js +4 -4
- package/dist/registry/prepare/messages.js +2 -1
- package/dist/registry/prepare/source-labels.js +60 -1
- package/dist/registry/prepare-cli.js +14 -4
- package/dist/registry/pull-cli.js +3 -2
- package/dist/registry/uip/client.d.ts +28 -3
- package/dist/registry/uip/client.js +95 -34
- package/dist/registry/uip/host.d.ts +41 -0
- package/dist/registry/uip/host.js +312 -0
- package/dist/serialize.d.ts +7 -0
- package/dist/serialize.js +414 -277
- package/dist/workdir.js +1 -1
- package/package.json +3 -3
package/dist/serialize.js
CHANGED
|
@@ -14,6 +14,8 @@ import { Expr, toExpr, SCHEDULE_PRESETS, DELAY_PRESETS, parseIxpProjectType, fla
|
|
|
14
14
|
import { FlowAction, FlowTrigger } from './core/node-classes.js';
|
|
15
15
|
import { connectorRawNodeRefusal } from './core/connector-raw-node.js';
|
|
16
16
|
import { dataFabricUnknownInputs } from './core/typed-raw-node.js';
|
|
17
|
+
import { planContributionBindings } from './core/contribution-bindings.js';
|
|
18
|
+
import { definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
|
|
17
19
|
import { isAnswerField } from './core/hitl-answers.js';
|
|
18
20
|
import { connectionConnectors } from './bindings-v2.js';
|
|
19
21
|
import { BindingRefusal, GUID_RE, bindingMissingMessage, bindingSelfNameMessage, bindingUndeclaredMessage, missingBindingLabels, undeclaredBinding } from './core/binding-messages.js';
|
|
@@ -49,6 +51,8 @@ import { resolveSchemaVersion } from './schema-version.js';
|
|
|
49
51
|
import { planFlowGlobals, planSharedInputs, sharedInputRoots } from './flow-variables.js';
|
|
50
52
|
import { prepareCommand } from './core/cli-spelling.js';
|
|
51
53
|
import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
|
|
54
|
+
import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
|
|
55
|
+
import { types } from './core/expr.js';
|
|
52
56
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
53
57
|
// core-definitions.json is an object keyed by "<nodeType>@<version>".
|
|
54
58
|
const DEFS = JSON.parse(readFileSync(join(HERE, 'core-definitions.json'), 'utf8'));
|
|
@@ -143,6 +147,53 @@ const SUBFLOW_OUTPUT = {
|
|
|
143
147
|
};
|
|
144
148
|
/** The RPA-workflow node type family. The process's release key is the suffix. */
|
|
145
149
|
const RPA_WORKFLOW_PREFIX = 'uipath.core.rpa-workflow.';
|
|
150
|
+
/**
|
|
151
|
+
* Where a process resource lives, as ONE slot every process-resource definition
|
|
152
|
+
* shares. In the platform model "in this solution" is orthogonal to the
|
|
153
|
+
* resource type: flow-core's single `createModel` (`@uipath/flow-core`
|
|
154
|
+
* `manifest/mappers/node-manifest-builder.ts`, what `uip maestro flow registry
|
|
155
|
+
* get --local` and Studio Web both run) adds `projectId`, `projectName` and
|
|
156
|
+
* `isInSolution: true` to the model of ANY process resource built from a sibling
|
|
157
|
+
* project.
|
|
158
|
+
*
|
|
159
|
+
* The in-solution shape, transcribed from `registry get --local` for a sibling
|
|
160
|
+
* Flow (2026-10-08) and from uipath-cli's `buildInSolutionNodeManifests`:
|
|
161
|
+
* - `resourceKey` is the bare key (the sibling's `resource.key`), not
|
|
162
|
+
* `<folderPath>.<name>`; the folder default is `''`;
|
|
163
|
+
* - no `section: 'Published'`;
|
|
164
|
+
* - `projectId` on the definition AND on the model, with `projectName` and
|
|
165
|
+
* `isInSolution: true` (the marker the canvas reads);
|
|
166
|
+
* - description `(In-solution) <name>`, tags `in-solution` / `local`, and the
|
|
167
|
+
* `open-workflow` toolbar action.
|
|
168
|
+
*/
|
|
169
|
+
function processResourceLocation(spec) {
|
|
170
|
+
if (spec.location === 'in-solution') {
|
|
171
|
+
return {
|
|
172
|
+
inSolution: true,
|
|
173
|
+
folderPath: '',
|
|
174
|
+
resourceKey: spec.key,
|
|
175
|
+
description: `(In-solution) ${spec.name}`,
|
|
176
|
+
tags: ['in-solution', 'local'],
|
|
177
|
+
definitionExtras: {
|
|
178
|
+
toolbarExtensions: {
|
|
179
|
+
design: { actions: [{ id: 'open-workflow', icon: 'external-link', label: 'Open' }] },
|
|
180
|
+
},
|
|
181
|
+
projectId: spec.projectId,
|
|
182
|
+
},
|
|
183
|
+
modelExtras: { projectId: spec.projectId, projectName: spec.name, isInSolution: true },
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const folderPath = spec.folderPath ?? '';
|
|
187
|
+
return {
|
|
188
|
+
inSolution: false,
|
|
189
|
+
folderPath,
|
|
190
|
+
resourceKey: `${folderPath}.${spec.name}`,
|
|
191
|
+
description: `(${folderPath})`,
|
|
192
|
+
tags: [],
|
|
193
|
+
definitionExtras: {},
|
|
194
|
+
modelExtras: {},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
146
197
|
/**
|
|
147
198
|
* Build the definition for one deployed RPA process.
|
|
148
199
|
*
|
|
@@ -177,7 +228,8 @@ const RPA_WORKFLOW_PREFIX = 'uipath.core.rpa-workflow.';
|
|
|
177
228
|
* element while publishing a null step output.
|
|
178
229
|
*/
|
|
179
230
|
function rpaWorkflowDef(spec) {
|
|
180
|
-
const
|
|
231
|
+
const loc = processResourceLocation(spec);
|
|
232
|
+
const { resourceKey } = loc;
|
|
181
233
|
const properties = {};
|
|
182
234
|
for (const [k, v] of Object.entries(spec.inputs)) {
|
|
183
235
|
properties[k] = { type: typeof v === 'number' ? 'number' : typeof v === 'boolean' ? 'boolean' : 'string' };
|
|
@@ -187,8 +239,8 @@ function rpaWorkflowDef(spec) {
|
|
|
187
239
|
version: '1.0.0',
|
|
188
240
|
category: 'rpa-workflow',
|
|
189
241
|
runtimeConstraints: { exclude: ['api-function'] },
|
|
190
|
-
description:
|
|
191
|
-
tags:
|
|
242
|
+
description: loc.description,
|
|
243
|
+
tags: loc.tags,
|
|
192
244
|
sortOrder: 530,
|
|
193
245
|
supportsErrorHandling: true,
|
|
194
246
|
display: { label: spec.name, icon: 'rpa' },
|
|
@@ -196,11 +248,12 @@ function rpaWorkflowDef(spec) {
|
|
|
196
248
|
{ position: 'left', handles: [{ id: 'input', type: 'target', handleType: 'input' }] },
|
|
197
249
|
{ position: 'right', handles: [{ id: 'output', type: 'source', handleType: 'output' }] },
|
|
198
250
|
],
|
|
251
|
+
...loc.definitionExtras,
|
|
199
252
|
model: {
|
|
200
253
|
type: 'bpmn:ServiceTask',
|
|
201
254
|
serviceType: 'Orchestrator.StartJob',
|
|
202
255
|
version: 'v2',
|
|
203
|
-
section: 'Published',
|
|
256
|
+
...(loc.inSolution ? {} : { section: 'Published' }),
|
|
204
257
|
bindings: {
|
|
205
258
|
resource: 'process',
|
|
206
259
|
resourceSubType: 'Process',
|
|
@@ -208,9 +261,10 @@ function rpaWorkflowDef(spec) {
|
|
|
208
261
|
orchestratorType: 'process',
|
|
209
262
|
values: [
|
|
210
263
|
{ name: 'name', propertyAttribute: 'name', default: spec.name },
|
|
211
|
-
{ name: 'folderPath', propertyAttribute: 'folderPath', default:
|
|
264
|
+
{ name: 'folderPath', propertyAttribute: 'folderPath', default: loc.folderPath },
|
|
212
265
|
],
|
|
213
266
|
},
|
|
267
|
+
...loc.modelExtras,
|
|
214
268
|
context: [
|
|
215
269
|
{ name: 'name', type: 'string', value: '<bindings.name>' },
|
|
216
270
|
{ name: 'folderPath', type: 'string', value: '<bindings.folderPath>' },
|
|
@@ -453,41 +507,6 @@ function publishedFunctionDef(spec) {
|
|
|
453
507
|
debug: { runtime: 'bpmnEngine' },
|
|
454
508
|
};
|
|
455
509
|
}
|
|
456
|
-
const AGENTIC_PROCESS_PREFIX = 'uipath.core.agentic-process.';
|
|
457
|
-
/**
|
|
458
|
-
* The three published forms under the Agentic Process umbrella (design §2.1).
|
|
459
|
-
* One public factory, three wire identities — transcribed from flow-v1's
|
|
460
|
-
* `RESOURCE_TYPE_METADATA` (ProcessOrchestration / Flow / CaseManagement):
|
|
461
|
-
* node-type segment, category, icon, resource subtype, `orchestratorType`
|
|
462
|
-
* (`resourceType.toLowerCase()`, per `createModel`), and the sync/async
|
|
463
|
-
* service-type pair. All three declare the fire-and-forget switch.
|
|
464
|
-
*/
|
|
465
|
-
const AGENTIC_PROCESS_FORMS = {
|
|
466
|
-
bpmn: {
|
|
467
|
-
prefix: AGENTIC_PROCESS_PREFIX,
|
|
468
|
-
category: 'agentic-process',
|
|
469
|
-
icon: 'agentic-process',
|
|
470
|
-
resourceSubType: 'ProcessOrchestration',
|
|
471
|
-
orchestratorType: 'processorchestration',
|
|
472
|
-
serviceType: 'Orchestrator.StartAgenticProcess',
|
|
473
|
-
},
|
|
474
|
-
flow: {
|
|
475
|
-
prefix: 'uipath.core.flow.',
|
|
476
|
-
category: 'flow',
|
|
477
|
-
icon: 'flow-project',
|
|
478
|
-
resourceSubType: 'Flow',
|
|
479
|
-
orchestratorType: 'flow',
|
|
480
|
-
serviceType: 'Orchestrator.StartFlowProcess',
|
|
481
|
-
},
|
|
482
|
-
case: {
|
|
483
|
-
prefix: 'uipath.core.case-management.',
|
|
484
|
-
category: 'case-management',
|
|
485
|
-
icon: 'case-management',
|
|
486
|
-
resourceSubType: 'CaseManagement',
|
|
487
|
-
orchestratorType: 'casemanagement',
|
|
488
|
-
serviceType: 'Orchestrator.StartCaseMgmtProcess',
|
|
489
|
-
},
|
|
490
|
-
};
|
|
491
510
|
/**
|
|
492
511
|
* Build the definition for one deployed agentic process (a Maestro process
|
|
493
512
|
* orchestration).
|
|
@@ -529,7 +548,8 @@ const AGENTIC_PROCESS_FORMS = {
|
|
|
529
548
|
*/
|
|
530
549
|
function agenticProcessDef(spec) {
|
|
531
550
|
const form = AGENTIC_PROCESS_FORMS[spec.form ?? 'bpmn'];
|
|
532
|
-
const
|
|
551
|
+
const loc = processResourceLocation(spec);
|
|
552
|
+
const { resourceKey } = loc;
|
|
533
553
|
const properties = {};
|
|
534
554
|
for (const [k, v] of Object.entries(spec.inputs)) {
|
|
535
555
|
properties[k] = { type: typeof v === 'number' ? 'number' : typeof v === 'boolean' ? 'boolean' : 'string' };
|
|
@@ -539,8 +559,8 @@ function agenticProcessDef(spec) {
|
|
|
539
559
|
version: '1.0.0',
|
|
540
560
|
category: form.category,
|
|
541
561
|
runtimeConstraints: { exclude: ['api-function'] },
|
|
542
|
-
description:
|
|
543
|
-
tags:
|
|
562
|
+
description: loc.description,
|
|
563
|
+
tags: loc.tags,
|
|
544
564
|
sortOrder: 507,
|
|
545
565
|
supportsErrorHandling: true,
|
|
546
566
|
display: { label: spec.name, icon: form.icon },
|
|
@@ -548,11 +568,12 @@ function agenticProcessDef(spec) {
|
|
|
548
568
|
{ position: 'left', handles: [{ id: 'input', type: 'target', handleType: 'input' }] },
|
|
549
569
|
{ position: 'right', handles: [{ id: 'output', type: 'source', handleType: 'output' }] },
|
|
550
570
|
],
|
|
571
|
+
...loc.definitionExtras,
|
|
551
572
|
model: {
|
|
552
573
|
type: 'bpmn:ServiceTask',
|
|
553
574
|
serviceType: form.serviceType,
|
|
554
575
|
version: 'v2',
|
|
555
|
-
section: 'Published',
|
|
576
|
+
...(loc.inSolution ? {} : { section: 'Published' }),
|
|
556
577
|
bindings: {
|
|
557
578
|
resource: 'process',
|
|
558
579
|
resourceSubType: form.resourceSubType,
|
|
@@ -560,9 +581,10 @@ function agenticProcessDef(spec) {
|
|
|
560
581
|
orchestratorType: form.orchestratorType,
|
|
561
582
|
values: [
|
|
562
583
|
{ name: 'name', propertyAttribute: 'name', default: spec.name },
|
|
563
|
-
{ name: 'folderPath', propertyAttribute: 'folderPath', default:
|
|
584
|
+
{ name: 'folderPath', propertyAttribute: 'folderPath', default: loc.folderPath },
|
|
564
585
|
],
|
|
565
586
|
},
|
|
587
|
+
...loc.modelExtras,
|
|
566
588
|
context: [
|
|
567
589
|
{ name: 'name', type: 'string', value: '<bindings.name>' },
|
|
568
590
|
{ name: 'folderPath', type: 'string', value: '<bindings.folderPath>' },
|
|
@@ -741,28 +763,6 @@ function agentDef(spec) {
|
|
|
741
763
|
debug: { runtime: 'bpmnEngine' },
|
|
742
764
|
};
|
|
743
765
|
}
|
|
744
|
-
/**
|
|
745
|
-
* Build the definition for the INLINE autonomous agent.
|
|
746
|
-
*
|
|
747
|
-
* This is the one node type in the agent family that is the SAME on every tenant —
|
|
748
|
-
* it carries its own configuration instead of referencing a resource — so
|
|
749
|
-
* `uip maestro flow registry get uipath.agent.autonomous` is a direct oracle rather
|
|
750
|
-
* than a per-instance answer, and the def can be built from constants without a
|
|
751
|
-
* corpus vote. Transcribed 2026-07-29: `version: '1.2'`, `sortOrder: 5`,
|
|
752
|
-
* `supportsErrorHandling: true`, `model.source: true`,
|
|
753
|
-
* `Orchestrator.StartInlineAgentJob`, the three required inputs, the artifact
|
|
754
|
-
* handles (escalation / context / tool) and `success` + `error` on the right with
|
|
755
|
-
* `isDefaultForType` on `success`.
|
|
756
|
-
*
|
|
757
|
-
* The deployed corpus (29 `uipath.agent.autonomous` nodes, 05-18 → 07-29) agrees on
|
|
758
|
-
* everything a `.flow` carries and settles the one thing the def leaves open:
|
|
759
|
-
* `outputs.output.source` is `=result.response` in 27 of 27 that declare outputs —
|
|
760
|
-
* unanimous here, unlike the published family, because the platform's
|
|
761
|
-
* append-`=this` fallback only fires for a node that declares no `output` at all.
|
|
762
|
-
* `typeVersion` in that corpus is 1.1 ×10, 1.2 ×15, 1.3 ×4; we emit the registry's
|
|
763
|
-
* 1.2. (`shared/sample-flows/inline-agent.flow` says 1.0, which appears in **none**
|
|
764
|
-
* of the 29 — the same bundled-sample era gap as the published family's.)
|
|
765
|
-
*/
|
|
766
766
|
/**
|
|
767
767
|
* The definition for ONE Context Grounding index resource, transcribed from the
|
|
768
768
|
* platform's own registry entry (`uip maestro flow registry get
|
|
@@ -984,6 +984,45 @@ const CONNECTOR_TOOL_RESOURCE_TYPE = 'integration';
|
|
|
984
984
|
* on its own it says nothing about who owns a file: `properties.toolType` does.
|
|
985
985
|
*/
|
|
986
986
|
const INTERNAL_TOOL_RESOURCE_TYPE = 'internal';
|
|
987
|
+
/**
|
|
988
|
+
* Where an agent schema property points to declare "this is a FILE":
|
|
989
|
+
* `{ $ref: JOB_ATTACHMENT_REF }`, with {@link jobAttachmentDefinition} under the
|
|
990
|
+
* same schema's `definitions['job-attachment']`.
|
|
991
|
+
*/
|
|
992
|
+
const JOB_ATTACHMENT_REF = '#/definitions/job-attachment';
|
|
993
|
+
/**
|
|
994
|
+
* The canonical `job-attachment` definition an agent schema's file field
|
|
995
|
+
* `$ref`s into — the uipath-agents skill's `agent-definition.md` § File
|
|
996
|
+
* Attachments ("Schema is fixed — copy verbatim"), and the same block the
|
|
997
|
+
* platform's own analyze-attachments tool contract carries.
|
|
998
|
+
*
|
|
999
|
+
* It tells the agent runtime that an input is an Orchestrator attachment, so a
|
|
1000
|
+
* file tool (Analyze Files) can resolve the attachment's `ID`.
|
|
1001
|
+
*
|
|
1002
|
+
* A function, not a shared object: each schema gets its own copy, so an edit
|
|
1003
|
+
* to one emitted file cannot reach another.
|
|
1004
|
+
*
|
|
1005
|
+
* (The case serializer keeps its own copy in `case/entry-points.ts`: that one
|
|
1006
|
+
* mirrors the platform's `entry-points.json` packager byte for byte, and its
|
|
1007
|
+
* `MimeType` description differs.)
|
|
1008
|
+
*/
|
|
1009
|
+
function jobAttachmentDefinition() {
|
|
1010
|
+
return {
|
|
1011
|
+
type: 'object',
|
|
1012
|
+
properties: {
|
|
1013
|
+
ID: { type: 'string', description: 'Orchestrator attachment key' },
|
|
1014
|
+
FullName: { type: 'string', description: 'File name' },
|
|
1015
|
+
MimeType: { type: 'string', description: 'MIME type, e.g. "application/pdf", "image/png"' },
|
|
1016
|
+
Metadata: {
|
|
1017
|
+
type: 'object',
|
|
1018
|
+
description: 'Dictionary<string, string> of metadata',
|
|
1019
|
+
additionalProperties: { type: 'string' },
|
|
1020
|
+
},
|
|
1021
|
+
},
|
|
1022
|
+
required: ['ID'],
|
|
1023
|
+
'x-uipath-resource-kind': 'JobAttachment',
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
987
1026
|
/** The `properties.toolType` of the built-in HTTP-request tool's file (#935). */
|
|
988
1027
|
const HTTP_REQUEST_TOOL_TYPE = 'http-request';
|
|
989
1028
|
/**
|
|
@@ -1139,29 +1178,13 @@ function builtinToolResourceJson(tool, label, inputs, spec) {
|
|
|
1139
1178
|
properties: {
|
|
1140
1179
|
attachments: {
|
|
1141
1180
|
type: 'array',
|
|
1142
|
-
items: { $ref:
|
|
1181
|
+
items: { $ref: JOB_ATTACHMENT_REF },
|
|
1143
1182
|
description: String(inputs.attachmentsDescription ?? ''),
|
|
1144
1183
|
},
|
|
1145
1184
|
analysisTask: { type: 'string', description: String(inputs.analysisTaskDescription ?? '') },
|
|
1146
1185
|
},
|
|
1147
1186
|
required: ['attachments', 'analysisTask'],
|
|
1148
|
-
definitions: {
|
|
1149
|
-
'job-attachment': {
|
|
1150
|
-
type: 'object',
|
|
1151
|
-
properties: {
|
|
1152
|
-
ID: { type: 'string', description: 'Orchestrator attachment key' },
|
|
1153
|
-
FullName: { type: 'string', description: 'File name' },
|
|
1154
|
-
MimeType: { type: 'string', description: 'MIME type, e.g. "application/pdf", "image/png"' },
|
|
1155
|
-
Metadata: {
|
|
1156
|
-
type: 'object',
|
|
1157
|
-
description: 'Dictionary<string, string> of metadata',
|
|
1158
|
-
additionalProperties: { type: 'string' },
|
|
1159
|
-
},
|
|
1160
|
-
},
|
|
1161
|
-
required: ['ID'],
|
|
1162
|
-
'x-uipath-resource-kind': 'JobAttachment',
|
|
1163
|
-
},
|
|
1164
|
-
},
|
|
1187
|
+
definitions: { 'job-attachment': jobAttachmentDefinition() },
|
|
1165
1188
|
},
|
|
1166
1189
|
outputSchema: {
|
|
1167
1190
|
type: 'object',
|
|
@@ -1324,6 +1347,24 @@ const QUICK_FORM_FIELD_SCHEMA = {
|
|
|
1324
1347
|
text: { type: 'string' }, number: { type: 'number' }, boolean: { type: 'boolean' },
|
|
1325
1348
|
'date-time': { type: 'string', format: 'date-time' },
|
|
1326
1349
|
};
|
|
1350
|
+
/**
|
|
1351
|
+
* The folder an app escalation names: the author's `folderPath`, or
|
|
1352
|
+
* `solution_folder` when they gave none — an app that ships in this solution.
|
|
1353
|
+
*
|
|
1354
|
+
* `solution_folder` is the platform's own spelling for that case: it is the
|
|
1355
|
+
* `Folder` that `uip solution resources list` reports for a solution-internal
|
|
1356
|
+
* app, and what the agents skill tells authors to copy into
|
|
1357
|
+
* `channels[].properties.folderName`. The SDK used to write `""`, which no
|
|
1358
|
+
* product writer produces (flow-builder-sdk#967). Measured, the two are the
|
|
1359
|
+
* same everywhere it counts: the agent tool's binding generator drops both
|
|
1360
|
+
* from the App binding (`resolveFolderPathBindingValue`), `uip agent refresh`
|
|
1361
|
+
* plus `uip solution resources refresh` derive byte-identical files from
|
|
1362
|
+
* either, and a live debug resolves the app in the debug folder for both. So
|
|
1363
|
+
* this changes the vocabulary, not the behaviour.
|
|
1364
|
+
*/
|
|
1365
|
+
function escalationAppFolder(app) {
|
|
1366
|
+
return app.folderPath ? app.folderPath : 'solution_folder';
|
|
1367
|
+
}
|
|
1327
1368
|
/**
|
|
1328
1369
|
* The `resources/<id>/resource.json` an inline agent's ESCALATION needs — the
|
|
1329
1370
|
* escalation half of what `toolResourceJson` does for a tool, and inert without
|
|
@@ -1400,7 +1441,7 @@ function escalationResourceJson(esc, spec) {
|
|
|
1400
1441
|
// refresh` imports; `folderName` is the app's Orchestrator folder.
|
|
1401
1442
|
resourceKey: app.key,
|
|
1402
1443
|
appName: app.name,
|
|
1403
|
-
folderName: app
|
|
1444
|
+
folderName: escalationAppFolder(app),
|
|
1404
1445
|
// The app's deploy version (its action schema's `version`). The SDK does
|
|
1405
1446
|
// not read the action schema, so this is the platform's own default — the
|
|
1406
1447
|
// storage migration that introduced the field writes `1` when absent.
|
|
@@ -2183,134 +2224,88 @@ function memoryResourceDef(spec) {
|
|
|
2183
2224
|
},
|
|
2184
2225
|
};
|
|
2185
2226
|
}
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
description: 'Agent response',
|
|
2269
|
-
// `=result.response`, not `=this` — 27 of 27 deployed instances, and the
|
|
2270
|
-
// engine's own inline dispatch returns `{ response: { …declared keys } }`.
|
|
2271
|
-
source: '=result.response',
|
|
2272
|
-
var: 'output',
|
|
2273
|
-
// NO per-instance schema here, and that is the whole point of this comment:
|
|
2274
|
-
// `definitions[]` is keyed by node TYPE, and every inline agent in a flow
|
|
2275
|
-
// shares this ONE entry. A flow with two agents (an analyst and a writer,
|
|
2276
|
-
// say) therefore cannot have both contracts here — whichever was emitted
|
|
2277
|
-
// last would win, and every read against the other resolved to the wrong
|
|
2278
|
-
// shape. Measured on GA row 7's port, whose four `.return()` mappings off
|
|
2279
|
-
// the ANALYST drew 25 undeclared-field errors quoting the WRITER's fields
|
|
2280
|
-
// (`Available at "$vars.disputeAnalystAgent.output": "subject", "body"`) on
|
|
2281
|
-
// a flow that is correct.
|
|
2282
|
-
//
|
|
2283
|
-
// The instance is where an authored contract belongs, and the SDK already
|
|
2284
|
-
// writes it there (`node.outputs.output.schema`, below). A reader that
|
|
2285
|
-
// refines per node then picks it up — applying an instance schema when the
|
|
2286
|
-
// definition's is GENERIC and never overriding a definition that declares
|
|
2287
|
-
// a shape, which is right in general and was
|
|
2288
|
-
// exactly what this def defeated.
|
|
2289
|
-
//
|
|
2290
|
-
// Deployed truth agrees: v1's own two-agent BillingDisputeResolution
|
|
2291
|
-
// artifact (1.0, 2026-07-15) carries `properties: { content: {…} }` on the
|
|
2292
|
-
// shared definition and `schema: null` on both agent nodes.
|
|
2293
|
-
},
|
|
2294
|
-
error: {
|
|
2295
|
-
type: 'object',
|
|
2296
|
-
description: 'Error information if the node fails',
|
|
2297
|
-
source: '=Error',
|
|
2298
|
-
var: 'error',
|
|
2299
|
-
},
|
|
2300
|
-
},
|
|
2301
|
-
model: {
|
|
2302
|
-
source: true,
|
|
2303
|
-
type: 'bpmn:ServiceTask',
|
|
2304
|
-
serviceType: 'Orchestrator.StartInlineAgentJob',
|
|
2305
|
-
version: 'v2',
|
|
2306
|
-
context: [
|
|
2307
|
-
{ name: '_label', type: 'string', value: '' },
|
|
2308
|
-
{ name: 'name', type: 'string', value: '' },
|
|
2309
|
-
{ name: 'entryPoint', type: 'string', value: '' },
|
|
2310
|
-
],
|
|
2311
|
-
},
|
|
2312
|
-
debug: { runtime: 'bpmnEngine' },
|
|
2313
|
-
};
|
|
2227
|
+
/** Numeric dotted compare: '1.10' > '1.9'. */
|
|
2228
|
+
function compareVersions(a, b) {
|
|
2229
|
+
const pa = a.split('.').map(Number);
|
|
2230
|
+
const pb = b.split('.').map(Number);
|
|
2231
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
2232
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
2233
|
+
if (d !== 0)
|
|
2234
|
+
return d;
|
|
2235
|
+
}
|
|
2236
|
+
return 0;
|
|
2237
|
+
}
|
|
2238
|
+
/**
|
|
2239
|
+
* The inline agent's bundled versions, oldest first, and the newest of them.
|
|
2240
|
+
* The newest bundled pair is the default, so there is no version literal in
|
|
2241
|
+
* this file: when the registry serves a newer version, `check:definitions`
|
|
2242
|
+
* reports the missing pair, `sync:definitions` adds it, and the default follows.
|
|
2243
|
+
*/
|
|
2244
|
+
const INLINE_AGENT_VERSIONS = Object.keys(DEFS)
|
|
2245
|
+
.filter((k) => k.startsWith(`${INLINE_AGENT_TYPE}@`))
|
|
2246
|
+
.map((k) => k.slice(INLINE_AGENT_TYPE.length + 1))
|
|
2247
|
+
.sort(compareVersions);
|
|
2248
|
+
const INLINE_AGENT_DEFAULT_VERSION = INLINE_AGENT_VERSIONS[INLINE_AGENT_VERSIONS.length - 1];
|
|
2249
|
+
/** True when a definition declares the agent's `memory` artifact handle. */
|
|
2250
|
+
function declaresMemoryHandle(def) {
|
|
2251
|
+
return (def?.handleConfiguration ?? []).some((g) => (g?.handles ?? []).some((h) => h?.id === 'memory'));
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* The definition for the INLINE autonomous agent: the bundled pair for
|
|
2255
|
+
* `version` (the newest by default), plus an explicit overlay of the details
|
|
2256
|
+
* the registry payload does not carry.
|
|
2257
|
+
*
|
|
2258
|
+
* This is the one node type in the agent family that is the SAME on every
|
|
2259
|
+
* tenant — it carries its own configuration instead of referencing a resource —
|
|
2260
|
+
* so `uip maestro flow registry get uipath.agent.autonomous` is a direct oracle
|
|
2261
|
+
* and the bundle entry is the registry's definition as last synced
|
|
2262
|
+
* (`sync:definitions` writes it through unchanged; `check:definitions --deep`
|
|
2263
|
+
* reports content that has moved since). Versions and content both come from
|
|
2264
|
+
* there.
|
|
2265
|
+
*
|
|
2266
|
+
* The overlay, and nothing else:
|
|
2267
|
+
*
|
|
2268
|
+
* * `outputDefinition.output.source` is `=result.response`. The registry's
|
|
2269
|
+
* definition declares no `source`; the deployed corpus (29 `uipath.agent.autonomous` nodes, 05-18 → 07-29) has
|
|
2270
|
+
* `=result.response` in 27 of 27 that declare outputs, and the engine's own
|
|
2271
|
+
* inline dispatch returns `{ response: { …declared keys } }`. Without it the
|
|
2272
|
+
* node's `output` is the whole result envelope rather than the declared keys.
|
|
2273
|
+
* It is applied at every version; the registry payload has no `source`.
|
|
2274
|
+
* * The `memory` handle is kept only when the flow attaches memory. It is
|
|
2275
|
+
* LOCAL content (#431) on the bundled 1.4, absent from the registry's 1.4
|
|
2276
|
+
* (`check.ts` AGENT_MEMORY_NOT_AUTHORABLE), so an agent without memory gets
|
|
2277
|
+
* the registry's handle set.
|
|
2278
|
+
*
|
|
2279
|
+
* NO per-instance schema goes on the definition: `definitions[]` is keyed by
|
|
2280
|
+
* node TYPE, and every inline agent in a flow shares this one entry. A flow
|
|
2281
|
+
* with two agents (an analyst and a writer, say) therefore cannot have both
|
|
2282
|
+
* contracts here — whichever was emitted last would win, and every read against
|
|
2283
|
+
* the other resolved to the wrong shape (GA row 7's port: 25 undeclared-field
|
|
2284
|
+
* errors on a correct flow). The authored contract goes on the NODE
|
|
2285
|
+
* (`node.outputs.output.schema`, in the `inlineAgent` arm), where a reader that
|
|
2286
|
+
* refines per node picks it up.
|
|
2287
|
+
*
|
|
2288
|
+
* The bundled 1.2 is the pre-#956 default, kept so a flow this SDK compiled
|
|
2289
|
+
* before — and a decompile of one, which pins `{ version: '1.2' }` — still
|
|
2290
|
+
* compiles. The corpus also carries 1.1 and 1.3; `shared/sample-flows/
|
|
2291
|
+
* inline-agent.flow` says 1.0, which appears in none of the 29.
|
|
2292
|
+
*/
|
|
2293
|
+
function inlineAgentDef(version, withMemory) {
|
|
2294
|
+
const bundled = DEFS[`${INLINE_AGENT_TYPE}@${version}`];
|
|
2295
|
+
if (!bundled)
|
|
2296
|
+
return undefined;
|
|
2297
|
+
const def = clone(bundled);
|
|
2298
|
+
const output = def.outputDefinition?.output;
|
|
2299
|
+
if (output)
|
|
2300
|
+
output.source = '=result.response';
|
|
2301
|
+
if (!withMemory) {
|
|
2302
|
+
for (const group of def.handleConfiguration ?? []) {
|
|
2303
|
+
if (Array.isArray(group?.handles))
|
|
2304
|
+
group.handles = group.handles.filter((h) => h?.id !== 'memory');
|
|
2305
|
+
}
|
|
2306
|
+
def.handleConfiguration = (def.handleConfiguration ?? []).filter((g) => g?.handles?.length);
|
|
2307
|
+
}
|
|
2308
|
+
return def;
|
|
2314
2309
|
}
|
|
2315
2310
|
/**
|
|
2316
2311
|
* Classify a RENDERED input value (the output of {@link renderValue}).
|
|
@@ -3934,7 +3929,7 @@ function describeDeclared(bindings) {
|
|
|
3934
3929
|
* exactly (design §2.6/§4.2): the named version resolves or compilation fails,
|
|
3935
3930
|
* and a contributor that ignored the author's requested version is rejected.
|
|
3936
3931
|
*/
|
|
3937
|
-
function resolveContributionDefinition(ref, requestedVersion, where) {
|
|
3932
|
+
export function resolveContributionDefinition(ref, requestedVersion, where) {
|
|
3938
3933
|
if (!ref || typeof ref.nodeType !== 'string' || !ref.nodeType || typeof ref.version !== 'string' || !ref.version) {
|
|
3939
3934
|
throw new Error(`${where}: contribute() returned a DefinitionReference without an exact nodeType + version.`);
|
|
3940
3935
|
}
|
|
@@ -4381,9 +4376,9 @@ function newScope(outputs, vars = []) {
|
|
|
4381
4376
|
* note at `uipath.ts:118-123`, MST-9544).
|
|
4382
4377
|
*/
|
|
4383
4378
|
/**
|
|
4384
|
-
* Wire every parked `.
|
|
4379
|
+
* Wire every parked `.stepToRef('<step>')` edge, now that the whole scope exists.
|
|
4385
4380
|
*
|
|
4386
|
-
* An unresolved target should be impossible — `check`'s
|
|
4381
|
+
* An unresolved target should be impossible — `check`'s REF_UNKNOWN_TARGET
|
|
4387
4382
|
* runs first and names the steps that do exist — but a serializer that silently
|
|
4388
4383
|
* dropped the edge would emit a flow whose handler goes nowhere, which is the
|
|
4389
4384
|
* exact class of failure `.onError` used to have (an error path that vanishes in
|
|
@@ -4419,10 +4414,16 @@ function typeAgentInputSchemas(scope, globals) {
|
|
|
4419
4414
|
if (g.direction === 'in' && g.triggerNodeId)
|
|
4420
4415
|
lookup.set(`${g.triggerNodeId}.output.${g.id}`, { type: g.type, schema: g.schema });
|
|
4421
4416
|
}
|
|
4422
|
-
for (const {
|
|
4417
|
+
for (const { schema, refs } of scope.agentSchemas) {
|
|
4423
4418
|
for (const r of refs) {
|
|
4424
|
-
properties[r.flatName] = jsonSchemaForRef(r.binding, lookup);
|
|
4419
|
+
schema.properties[r.flatName] = jsonSchemaForRef(r.binding, lookup);
|
|
4425
4420
|
}
|
|
4421
|
+
// A file property is a `$ref`, and a `$ref` resolves against THIS schema's
|
|
4422
|
+
// `definitions` — so the block is added exactly when a file property is
|
|
4423
|
+
// present (a schema with no file keeps the shape it always had).
|
|
4424
|
+
const hasFile = Object.values(schema.properties).some((p) => p?.$ref === JOB_ATTACHMENT_REF);
|
|
4425
|
+
if (hasFile)
|
|
4426
|
+
schema.definitions = { ...schema.definitions, 'job-attachment': jobAttachmentDefinition() };
|
|
4426
4427
|
}
|
|
4427
4428
|
}
|
|
4428
4429
|
/** One property's schema — `{}` when the type cannot be established. See {@link typeAgentInputSchemas}. */
|
|
@@ -4512,17 +4513,58 @@ function walkSchemaType(schema, segments) {
|
|
|
4512
4513
|
}
|
|
4513
4514
|
return typeof current?.type === 'string' ? current.type : undefined;
|
|
4514
4515
|
}
|
|
4515
|
-
/**
|
|
4516
|
+
/**
|
|
4517
|
+
* A resolved type → its JSON-Schema property.
|
|
4518
|
+
*
|
|
4519
|
+
* Every type a flow can DECLARE (`types.*`) has its own case, and the switch is
|
|
4520
|
+
* exhaustive over {@link TypeDesc}: adding a type to `types` without deciding
|
|
4521
|
+
* what an agent sees for it is a compile error here, not a silent `{}`.
|
|
4522
|
+
*
|
|
4523
|
+
* `file` → `{ $ref: '#/definitions/job-attachment' }`; the caller adds the
|
|
4524
|
+
* definition (see `typeAgentInputSchemas`).
|
|
4525
|
+
*
|
|
4526
|
+
* Typeless `{}` is the answer for `any` and for "unknown" (`undefined`,
|
|
4527
|
+
* or a type string from a node definition that is not in the SDK's
|
|
4528
|
+
* vocabulary): that is v1's own rule for a type it cannot establish
|
|
4529
|
+
* (`buildAgentInputTypeResolver` → `'any'` → a property with no `type`), and it
|
|
4530
|
+
* keeps the runtime's pydantic model from refusing a value the SDK only
|
|
4531
|
+
* guessed at.
|
|
4532
|
+
*/
|
|
4516
4533
|
function jsonSchemaForType(type) {
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
// sidecar does not carry.)
|
|
4521
|
-
if (!type || type === 'any' || type === 'file' || type === 'octet-stream')
|
|
4534
|
+
if (type === 'octet-stream')
|
|
4535
|
+
return { $ref: JOB_ATTACHMENT_REF }; // v1's alias for file
|
|
4536
|
+
if (type === undefined || !isTypeDesc(type))
|
|
4522
4537
|
return {};
|
|
4523
|
-
|
|
4524
|
-
return {
|
|
4525
|
-
|
|
4538
|
+
switch (type) {
|
|
4539
|
+
case 'file': return { $ref: JOB_ATTACHMENT_REF };
|
|
4540
|
+
case 'any': return {};
|
|
4541
|
+
// A bare `type: 'array'` makes the runtime's `jsonschema_to_pydantic`
|
|
4542
|
+
// reject a valid array (v1's note at `uipath.ts:118-123`, MST-9544).
|
|
4543
|
+
case 'array': return { type: 'array', items: {} };
|
|
4544
|
+
case 'string':
|
|
4545
|
+
case 'number':
|
|
4546
|
+
case 'integer':
|
|
4547
|
+
case 'boolean':
|
|
4548
|
+
case 'object':
|
|
4549
|
+
return { type };
|
|
4550
|
+
// The case vocabulary's widths and date kinds, as JSON Schema spells them
|
|
4551
|
+
// (the same table `case/entry-points.ts` projects with).
|
|
4552
|
+
case 'float': return { type: 'number', format: 'float' };
|
|
4553
|
+
case 'double': return { type: 'number', format: 'double' };
|
|
4554
|
+
case 'date': return { type: 'string', format: 'date' };
|
|
4555
|
+
case 'datetime': return { type: 'string', format: 'date-time' };
|
|
4556
|
+
// A case `jsonSchema` variable's shape lives in its `body`, which this
|
|
4557
|
+
// lookup does not carry — so its type is not established here.
|
|
4558
|
+
case 'jsonSchema': return {};
|
|
4559
|
+
default: {
|
|
4560
|
+
const unmapped = type;
|
|
4561
|
+
throw new Error(`jsonSchemaForType: no agent schema mapping for type '${String(unmapped)}'`);
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
}
|
|
4565
|
+
const TYPE_DESCS = new Set(Object.values(types));
|
|
4566
|
+
function isTypeDesc(type) {
|
|
4567
|
+
return TYPE_DESCS.has(type);
|
|
4526
4568
|
}
|
|
4527
4569
|
/**
|
|
4528
4570
|
* An End node's `outputs` map: every variable this scope exposes as a flow
|
|
@@ -4595,8 +4637,8 @@ function renameRefs(text, rename) {
|
|
|
4595
4637
|
/** Every step name a flow declares in its own scope (not its children's). */
|
|
4596
4638
|
function stepNamesOf(steps, out = []) {
|
|
4597
4639
|
for (const s of steps) {
|
|
4598
|
-
// `return`
|
|
4599
|
-
//
|
|
4640
|
+
// `return` carries a synthetic `name` but creates no node named after it (an
|
|
4641
|
+
// End id is claimed as `end`); `stepToRef` has no `name` at all (it is one edge).
|
|
4600
4642
|
if ('name' in s && s.kind !== 'return')
|
|
4601
4643
|
out.push(s.name);
|
|
4602
4644
|
if (s.kind === 'branch') {
|
|
@@ -4638,6 +4680,73 @@ export function serialize(built, opts = {}) {
|
|
|
4638
4680
|
* A bindings entry the node does not reference is not a bound resource.
|
|
4639
4681
|
*/
|
|
4640
4682
|
const resourceBindings = new Map();
|
|
4683
|
+
/**
|
|
4684
|
+
* The resolved definition of every contribution-lowered node, by node id, so an
|
|
4685
|
+
* `error` edge from one can be checked against its definition (#943). Typed
|
|
4686
|
+
* families are not recorded: their definitions are the SDK's own.
|
|
4687
|
+
*/
|
|
4688
|
+
const contributionDefs = new Map();
|
|
4689
|
+
/** Refuse an `error` edge from a contribution-lowered node whose definition has no error port. */
|
|
4690
|
+
function refuseErrorEdgeWithoutPort(nodeId, stepName) {
|
|
4691
|
+
const def = contributionDefs.get(nodeId);
|
|
4692
|
+
if (def !== undefined && !definitionHasErrorPort(def))
|
|
4693
|
+
throw new Error(errorPortRefusal(stepName, def));
|
|
4694
|
+
}
|
|
4695
|
+
/**
|
|
4696
|
+
* Hoist a contribution's own bindings, then close every `<bindings.NAME>` its
|
|
4697
|
+
* definition references and it did not supply, from the definition's own
|
|
4698
|
+
* `model.bindings` (flow-builder-sdk#942). Shared by the three contribution
|
|
4699
|
+
* sites (step, trigger, entry point), so a `rawNode` and a hand-written
|
|
4700
|
+
* subclass get the same entries a typed emitter would. `check` runs the same
|
|
4701
|
+
* plan dry (`checkContribution` in `check.ts`), so it reports what this throws.
|
|
4702
|
+
*/
|
|
4703
|
+
function hoistContributionBindings(def, supplied, where) {
|
|
4704
|
+
for (const b of supplied ?? [])
|
|
4705
|
+
resourceBindings.set(b.id, b);
|
|
4706
|
+
const plan = planContributionBindings(def, supplied);
|
|
4707
|
+
if (plan.problems.length) {
|
|
4708
|
+
throw new BindingRefusal('CONTRIBUTION_BINDING_UNRESOLVED', `${where}: ${plan.problems.join(' ')}`);
|
|
4709
|
+
}
|
|
4710
|
+
if (plan.entries.length === 0)
|
|
4711
|
+
return;
|
|
4712
|
+
// A process reference is the name + folderPath pair every typed process step
|
|
4713
|
+
// emits: go through the same builder, so a raw node and a typed step on ONE
|
|
4714
|
+
// process share one pair instead of shadowing each other.
|
|
4715
|
+
const byName = new Map(plan.entries.map((e) => [e.name, e]));
|
|
4716
|
+
const pairName = byName.get('name');
|
|
4717
|
+
const pairFolder = byName.get('folderPath');
|
|
4718
|
+
if (plan.resource === 'process' && plan.entries.length === 2 && pairName?.propertyAttribute === 'name'
|
|
4719
|
+
&& pairFolder?.propertyAttribute === 'folderPath' && pairName.default !== undefined
|
|
4720
|
+
&& pairFolder.default !== undefined) {
|
|
4721
|
+
const { entries } = processResourceBindings({
|
|
4722
|
+
name: pairName.default,
|
|
4723
|
+
folderPath: pairFolder.default,
|
|
4724
|
+
resourceSubType: pairName.resourceSubType,
|
|
4725
|
+
resourceKey: plan.resourceKey,
|
|
4726
|
+
}, resourceBindings);
|
|
4727
|
+
for (const b of entries) {
|
|
4728
|
+
// processResourceBindings types the subtype to the families it knows; keep
|
|
4729
|
+
// the definition's own spelling (or none) verbatim.
|
|
4730
|
+
if (pairName.resourceSubType === undefined)
|
|
4731
|
+
delete b.resourceSubType;
|
|
4732
|
+
resourceBindings.set(b.id, b);
|
|
4733
|
+
}
|
|
4734
|
+
return;
|
|
4735
|
+
}
|
|
4736
|
+
for (const e of plan.entries) {
|
|
4737
|
+
const same = [...resourceBindings.values()].some((b) => b.resource === e.resource
|
|
4738
|
+
&& b.resourceKey === e.resourceKey && b.name === e.name && b.propertyAttribute === e.propertyAttribute);
|
|
4739
|
+
if (same)
|
|
4740
|
+
continue;
|
|
4741
|
+
const slug = e.resourceKey.replace(/[^A-Za-z0-9]/g, '') || 'Resource';
|
|
4742
|
+
const cap = (t) => t.charAt(0).toUpperCase() + t.slice(1);
|
|
4743
|
+
const stem = `b${cap(slug)}${cap(e.name.replace(/[^A-Za-z0-9]/g, ''))}`;
|
|
4744
|
+
let id = stem;
|
|
4745
|
+
for (let n = 2; resourceBindings.has(id); n++)
|
|
4746
|
+
id = `${stem}${n}`;
|
|
4747
|
+
resourceBindings.set(id, { id, ...e });
|
|
4748
|
+
}
|
|
4749
|
+
}
|
|
4641
4750
|
/**
|
|
4642
4751
|
* Extra files the flow needs beside the `.flow` — see `SerializeOpts.sidecars`.
|
|
4643
4752
|
* Written into the caller's array when one was passed, so a caller that wants them
|
|
@@ -4689,7 +4798,7 @@ export function serialize(built, opts = {}) {
|
|
|
4689
4798
|
/**
|
|
4690
4799
|
* `uid` for a node that IS an author's step, recording which id that step got.
|
|
4691
4800
|
*
|
|
4692
|
-
* `.
|
|
4801
|
+
* `.stepToRef('<step>')` names a step, and the id it was emitted under is not
|
|
4693
4802
|
* derivable from the name: `uid` sanitizes, de-duplicates against every id in
|
|
4694
4803
|
* the file, and hands a subflow COPY a prefixed one from the rename map. So
|
|
4695
4804
|
* the mapping is recorded where it is decided rather than reconstructed later
|
|
@@ -4733,13 +4842,15 @@ export function serialize(built, opts = {}) {
|
|
|
4733
4842
|
* (design §2.6): resolution is exact — `<type>@<version>` from the bundle, or
|
|
4734
4843
|
* the version of the definition already in hand — and a version the SDK
|
|
4735
4844
|
* cannot resolve exactly fails compilation rather than floating to a default.
|
|
4845
|
+
* An undefined `label` takes the definition's `display.label`, which is what
|
|
4846
|
+
* the canvas shows on a freshly dropped node.
|
|
4736
4847
|
*/
|
|
4737
4848
|
function makeNode(type, id, label, o = {}) {
|
|
4738
4849
|
let def = o.def ?? defByType.get(type);
|
|
4739
4850
|
if (o.requestedVersion !== undefined && def?.version !== o.requestedVersion) {
|
|
4740
4851
|
const exact = o.def ? undefined : DEFS[`${type}@${o.requestedVersion}`];
|
|
4741
4852
|
if (!exact) {
|
|
4742
|
-
throw new Error(`"${label}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
|
|
4853
|
+
throw new Error(`"${label ?? id}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
|
|
4743
4854
|
+ `${type}@${def?.version ?? '<none>'}. Versions are exact — omit { version } to use `
|
|
4744
4855
|
+ `the pinned default, or request a version this SDK ships.`);
|
|
4745
4856
|
}
|
|
@@ -4752,7 +4863,7 @@ export function serialize(built, opts = {}) {
|
|
|
4752
4863
|
type,
|
|
4753
4864
|
typeVersion: def?.version ?? '1.0.0',
|
|
4754
4865
|
ui: { position: { x: 256 + col * 288, y: 144 + (o.parentId ? 160 : 0) }, size: { width: 96, height: 96 }, collapsed: false },
|
|
4755
|
-
display: { label, ...(def?.display?.icon ? { icon: def.display.icon } : {}) },
|
|
4866
|
+
display: { label: label ?? def?.display?.label ?? id, ...(def?.display?.icon ? { icon: def.display.icon } : {}) },
|
|
4756
4867
|
};
|
|
4757
4868
|
col++;
|
|
4758
4869
|
// A Data Fabric node gets no node-level `model`, whichever path emits it
|
|
@@ -4876,7 +4987,7 @@ export function serialize(built, opts = {}) {
|
|
|
4876
4987
|
if (customTrigger) {
|
|
4877
4988
|
const contribution = customTrigger.contribute(built.triggerOptions?.version !== undefined ? { requestedVersion: built.triggerOptions.version } : {});
|
|
4878
4989
|
const def = resolveContributionDefinition(contribution.definition, built.triggerOptions?.version, 'trigger');
|
|
4879
|
-
const node = makeNode(def.nodeType, triggerId, def.display?.label ?? 'Start', { def, requestedVersion: built.triggerOptions?.version });
|
|
4990
|
+
const node = makeNode(def.nodeType, triggerId, built.triggerOptions?.label ?? def.display?.label ?? 'Start', { def, requestedVersion: built.triggerOptions?.version });
|
|
4880
4991
|
const inputs = renderDeep(contribution.inputs ?? {}, NO_RENAME);
|
|
4881
4992
|
if (def.model?.entryPointId === true && inputs.entryPointId === undefined) {
|
|
4882
4993
|
inputs.entryPointId = stableId(`${built.id}:start:entryPoint`);
|
|
@@ -4884,25 +4995,26 @@ export function serialize(built, opts = {}) {
|
|
|
4884
4995
|
inputs.isDefaultEntryPoint = true;
|
|
4885
4996
|
}
|
|
4886
4997
|
node.inputs = inputs;
|
|
4887
|
-
|
|
4888
|
-
resourceBindings.set(b.id, b);
|
|
4998
|
+
hoistContributionBindings(def, contribution.bindings, 'trigger');
|
|
4889
4999
|
root.nodes.push(node);
|
|
4890
5000
|
}
|
|
5001
|
+
// The author's `.trigger(spec, { label })`; makeNode falls back to the definition's label.
|
|
5002
|
+
const rootLabel = built.triggerOptions?.label;
|
|
4891
5003
|
const trigger = customTrigger
|
|
4892
5004
|
? root.nodes[root.nodes.length - 1]
|
|
4893
5005
|
: eventTriggerRc
|
|
4894
|
-
? makeNode(eventTriggerRc.nodeType, triggerId,
|
|
5006
|
+
? makeNode(eventTriggerRc.nodeType, triggerId, rootLabel, { def: eventTriggerRc.v1def, requestedVersion: built.triggerOptions?.version })
|
|
4895
5007
|
: built.trigger?.kind === 'scheduled'
|
|
4896
|
-
? makeNode(NODE_TYPE.scheduledTrigger, triggerId,
|
|
5008
|
+
? makeNode(NODE_TYPE.scheduledTrigger, triggerId, rootLabel, {
|
|
4897
5009
|
requestedVersion: scheduledVersion(built.trigger.inputs, built.triggerOptions?.version),
|
|
4898
5010
|
})
|
|
4899
5011
|
: built.trigger?.kind === 'form'
|
|
4900
|
-
? makeNode(NODE_TYPE.formTrigger, triggerId,
|
|
5012
|
+
? makeNode(NODE_TYPE.formTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
4901
5013
|
: built.trigger?.kind === 'conversation'
|
|
4902
|
-
? makeNode(NODE_TYPE.conversationTrigger, triggerId,
|
|
5014
|
+
? makeNode(NODE_TYPE.conversationTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
4903
5015
|
: built.trigger?.kind === 'voice'
|
|
4904
|
-
? makeNode(NODE_TYPE.voiceTrigger, triggerId,
|
|
4905
|
-
: makeNode(NODE_TYPE.trigger, triggerId,
|
|
5016
|
+
? makeNode(NODE_TYPE.voiceTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
5017
|
+
: makeNode(NODE_TYPE.trigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version });
|
|
4906
5018
|
if (!customTrigger) {
|
|
4907
5019
|
trigger.inputs = eventTriggerRc && built.trigger?.kind === 'event'
|
|
4908
5020
|
? {
|
|
@@ -5020,8 +5132,8 @@ export function serialize(built, opts = {}) {
|
|
|
5020
5132
|
if (contribution.outputs) {
|
|
5021
5133
|
node.outputs = { ...(node.outputs ?? {}), ...subNodeId(clone(contribution.outputs), id) };
|
|
5022
5134
|
}
|
|
5023
|
-
|
|
5024
|
-
|
|
5135
|
+
hoistContributionBindings(def, contribution.bindings, where);
|
|
5136
|
+
contributionDefs.set(id, def);
|
|
5025
5137
|
scope.nodes.push(node);
|
|
5026
5138
|
for (const t of tails)
|
|
5027
5139
|
addEdge(scope, t, id);
|
|
@@ -5179,16 +5291,30 @@ export function serialize(built, opts = {}) {
|
|
|
5179
5291
|
// required: it is what the platform scaffolds, so a flow that reads
|
|
5180
5292
|
// `content` is a real (if toy) flow. `check` says so.
|
|
5181
5293
|
: { content: 'string' };
|
|
5182
|
-
//
|
|
5183
|
-
//
|
|
5184
|
-
//
|
|
5185
|
-
//
|
|
5186
|
-
//
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5294
|
+
// ONE default version for every call shape — the newest bundled pair (see
|
|
5295
|
+
// `inlineAgentDef`). `mode` and `memory` used to pick the version too (1.3
|
|
5296
|
+
// and 1.4), so a plain agent got a superseded 1.2 and each option moved
|
|
5297
|
+
// the node to another version as a side effect (#956). Both now live in
|
|
5298
|
+
// the sidecar and on edges; neither selects a definition. An explicit
|
|
5299
|
+
// `{ version }` (what decompile writes back) resolves exactly.
|
|
5300
|
+
const version = step.options?.version ?? INLINE_AGENT_DEFAULT_VERSION;
|
|
5301
|
+
// `definitions[]` holds one entry per type@version, so a flow where any
|
|
5302
|
+
// agent attaches memory keeps the handle for all of them.
|
|
5303
|
+
const withMemory = s.memory !== undefined
|
|
5304
|
+
|| declaresMemoryHandle(emittedDefs.get(`${INLINE_AGENT_TYPE}@${version}`));
|
|
5305
|
+
const def = inlineAgentDef(version, withMemory);
|
|
5306
|
+
if (!def) {
|
|
5307
|
+
throw new Error(`"${step.name}" requests ${INLINE_AGENT_TYPE}@${version}, but this SDK resolves only `
|
|
5308
|
+
+ `${INLINE_AGENT_VERSIONS.map((v) => `${INLINE_AGENT_TYPE}@${v}`).join(', ')}. Versions are exact — `
|
|
5309
|
+
+ `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}), or request a version this SDK ships.`);
|
|
5310
|
+
}
|
|
5311
|
+
if (s.memory !== undefined && !declaresMemoryHandle(def)) {
|
|
5312
|
+
throw new Error(`"${step.name}" attaches \`memory\`, but ${INLINE_AGENT_TYPE}@${version} declares no \`memory\` handle. `
|
|
5313
|
+
+ (version === INLINE_AGENT_DEFAULT_VERSION
|
|
5314
|
+
? `Pin a version that has it with inlineAgent({ ..., version: '<x.y>' }) `
|
|
5315
|
+
+ `(bundled with memory: ${INLINE_AGENT_VERSIONS.filter((v) => declaresMemoryHandle(DEFS[`${INLINE_AGENT_TYPE}@${v}`])).join(', ') || 'none'}), or drop \`memory\`.`
|
|
5316
|
+
: `Drop { version: '${version}' } to use ${INLINE_AGENT_DEFAULT_VERSION}, or drop \`memory\`.`));
|
|
5317
|
+
}
|
|
5192
5318
|
const id = stepUid(scope, step.name);
|
|
5193
5319
|
// `source` is the agent's directory name. Derived from the flow id + step
|
|
5194
5320
|
// name rather than random so a recompile is byte-identical — a v4-shaped uuid
|
|
@@ -5277,7 +5403,7 @@ export function serialize(built, opts = {}) {
|
|
|
5277
5403
|
// The schema's property TYPES need this scope's finished variables, which
|
|
5278
5404
|
// do not exist yet — park them (the `properties` object is filled in
|
|
5279
5405
|
// place when the scope closes). See `typeAgentInputSchemas`.
|
|
5280
|
-
scope.agentSchemas.push({
|
|
5406
|
+
scope.agentSchemas.push({ schema: agentJson.inputSchema, refs: plan.refs });
|
|
5281
5407
|
// GROUNDING — one resource node per context index, joined to the agent's own
|
|
5282
5408
|
// `context` handle. An ARTIFACT, not a step: it takes no incoming control
|
|
5283
5409
|
// flow, produces no output, and never reaches the End node. The edge runs OUT
|
|
@@ -5626,7 +5752,7 @@ export function serialize(built, opts = {}) {
|
|
|
5626
5752
|
name: app.name,
|
|
5627
5753
|
appName: app.name,
|
|
5628
5754
|
displayName: app.name,
|
|
5629
|
-
folderPath: app
|
|
5755
|
+
folderPath: escalationAppFolder(app),
|
|
5630
5756
|
inputSchema: fieldSchema(app.inputs),
|
|
5631
5757
|
outputSchema: fieldSchema(app.outputs),
|
|
5632
5758
|
},
|
|
@@ -5693,21 +5819,28 @@ export function serialize(built, opts = {}) {
|
|
|
5693
5819
|
// downstream in the engine.
|
|
5694
5820
|
const s = spec.inputs;
|
|
5695
5821
|
const nodeInputs = s.inputs ?? {};
|
|
5696
|
-
const subType = spec.kind === 'apiWorkflow' ? 'Api'
|
|
5697
|
-
: spec.kind === 'agenticProcess' ? 'ProcessOrchestration'
|
|
5698
|
-
: spec.kind === 'publishedFunction' ? 'Function'
|
|
5699
|
-
: 'Process';
|
|
5700
5822
|
const fireAndForget = spec.kind === 'agenticProcess' && spec.inputs.completion === 'fire-and-forget';
|
|
5701
5823
|
const def = spec.kind === 'publishedFunction'
|
|
5702
|
-
? publishedFunctionDef({ key: spec.inputs.key, name: s.name, folderPath:
|
|
5824
|
+
? publishedFunctionDef({ key: spec.inputs.key, name: s.name, folderPath: spec.inputs.folderPath, inputs: nodeInputs, returns: spec.inputs.returns })
|
|
5703
5825
|
: spec.kind === 'apiWorkflow'
|
|
5704
|
-
? apiWorkflowDef({ key: spec.inputs.key, name: s.name, folderPath:
|
|
5826
|
+
? apiWorkflowDef({ key: spec.inputs.key, name: s.name, folderPath: spec.inputs.folderPath, inputs: nodeInputs, returns: spec.inputs.returns })
|
|
5705
5827
|
: spec.kind === 'agenticProcess'
|
|
5706
|
-
? agenticProcessDef({
|
|
5707
|
-
|
|
5828
|
+
? agenticProcessDef({
|
|
5829
|
+
key: spec.inputs.key, name: s.name, folderPath: s.folderPath, location: spec.inputs.location,
|
|
5830
|
+
projectId: spec.inputs.projectId, inputs: nodeInputs, returns: spec.inputs.returns, form: spec.inputs.form,
|
|
5831
|
+
})
|
|
5832
|
+
: rpaWorkflowDef({
|
|
5833
|
+
key: spec.inputs.key, name: s.name, folderPath: s.folderPath, location: spec.inputs.location,
|
|
5834
|
+
projectId: spec.inputs.projectId, inputs: nodeInputs, returns: spec.inputs.returns,
|
|
5835
|
+
});
|
|
5708
5836
|
// The bindings first: two steps on the same process share ONE pair, and the
|
|
5709
5837
|
// definition's `model.context` names ids that have to exist.
|
|
5710
|
-
|
|
5838
|
+
// Read off the definition: one kind carries several subtypes (agenticProcess by `form`).
|
|
5839
|
+
// The pair's key and folder come off it too: an in-solution step's resourceKey is the
|
|
5840
|
+
// bare sibling key and its folder is `''`.
|
|
5841
|
+
const subType = def.model.bindings.resourceSubType;
|
|
5842
|
+
const pairFolder = def.model.bindings.values.find((v) => v.name === 'folderPath').default;
|
|
5843
|
+
const { entries } = processResourceBindings({ name: s.name, folderPath: pairFolder, resourceSubType: subType, resourceKey: def.model.bindings.resourceKey }, resourceBindings);
|
|
5711
5844
|
for (const b of entries)
|
|
5712
5845
|
resourceBindings.set(b.id, b);
|
|
5713
5846
|
const id = stepUid(scope, step.name);
|
|
@@ -5917,7 +6050,7 @@ export function serialize(built, opts = {}) {
|
|
|
5917
6050
|
});
|
|
5918
6051
|
if (plan.refs.length > 0) {
|
|
5919
6052
|
const agentJson = sidecars[sidecars.length - 1].json;
|
|
5920
|
-
scope.agentSchemas.push({
|
|
6053
|
+
scope.agentSchemas.push({ schema: agentJson.inputSchema, refs: plan.refs });
|
|
5921
6054
|
}
|
|
5922
6055
|
for (const t of tails)
|
|
5923
6056
|
addEdge(scope, t, id);
|
|
@@ -6338,7 +6471,7 @@ export function serialize(built, opts = {}) {
|
|
|
6338
6471
|
* The handler is its OWN path, and it still is: its leftover tails get their
|
|
6339
6472
|
* own End rather than rejoining the chain, because `.onError` must not
|
|
6340
6473
|
* SILENTLY change what runs after the step. What changed is that an author can
|
|
6341
|
-
* now ASK — `h.
|
|
6474
|
+
* now ASK — `h.stepToRef('<step>')` emits an edge into a step the success path
|
|
6342
6475
|
* also reaches, and returns no tail, so nothing is capped. Never inferred:
|
|
6343
6476
|
* a handler that just runs out of steps ends exactly as it always did.
|
|
6344
6477
|
*
|
|
@@ -6403,8 +6536,10 @@ export function serialize(built, opts = {}) {
|
|
|
6403
6536
|
throw new Error(`.stepToList('${step.port}', …) after step "${source}": emitted node "${nodeId}" not found in scope`);
|
|
6404
6537
|
// Only the error port carries this: without it the platform routes but Studio
|
|
6405
6538
|
// Web HIDES the handle, so no human can see the handler.
|
|
6406
|
-
if (step.port === 'error')
|
|
6539
|
+
if (step.port === 'error') {
|
|
6540
|
+
refuseErrorEdgeWithoutPort(nodeId, source);
|
|
6407
6541
|
node.inputs = { ...(node.inputs ?? {}), errorHandlingEnabled: true };
|
|
6542
|
+
}
|
|
6408
6543
|
const handlerTails = emit(handler, [{ node: nodeId, port: step.port }], scope, parentId, breakTarget);
|
|
6409
6544
|
if (handlerTails.length) {
|
|
6410
6545
|
const endId = uid(scope, `${source}${step.port === 'error' ? 'Error' : step.port.charAt(0).toUpperCase() + step.port.slice(1)}End`);
|
|
@@ -6805,6 +6940,7 @@ export function serialize(built, opts = {}) {
|
|
|
6805
6940
|
throw new Error(`.stepToRef('${step.port}', '${step.target}') has no step to leave from.`);
|
|
6806
6941
|
refuseRewire('.stepToRef', step.port, lastAction ?? '?', tails);
|
|
6807
6942
|
if (step.port === 'error') {
|
|
6943
|
+
refuseErrorEdgeWithoutPort(from.node, lastAction ?? from.node);
|
|
6808
6944
|
const node = scope.nodes.find((n) => n.id === from.node);
|
|
6809
6945
|
if (node)
|
|
6810
6946
|
node.inputs = { ...(node.inputs ?? {}), errorHandlingEnabled: true };
|
|
@@ -6885,19 +7021,20 @@ export function serialize(built, opts = {}) {
|
|
|
6885
7021
|
takenIds.add(ep.id);
|
|
6886
7022
|
const spec = ep.trigger;
|
|
6887
7023
|
const requestedVersion = ep.options?.version;
|
|
7024
|
+
// The author's label; makeNode falls back to the definition's label.
|
|
7025
|
+
const epLabel = ep.options?.label;
|
|
6888
7026
|
const customEp = spec instanceof FlowTrigger && !('kind' in spec) ? spec : undefined;
|
|
6889
7027
|
const epSpec = spec;
|
|
6890
7028
|
let node;
|
|
6891
7029
|
if (customEp) {
|
|
6892
7030
|
const contribution = customEp.contribute(requestedVersion !== undefined ? { requestedVersion } : {});
|
|
6893
7031
|
const def = resolveContributionDefinition(contribution.definition, requestedVersion, `entryPoint "${ep.id}"`);
|
|
6894
|
-
node = makeNode(def.nodeType, ep.id, def.display?.label ?? ep.id, { def, requestedVersion });
|
|
7032
|
+
node = makeNode(def.nodeType, ep.id, ep.options?.label ?? def.display?.label ?? ep.id, { def, requestedVersion });
|
|
6895
7033
|
node.inputs = {
|
|
6896
7034
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6897
7035
|
...renderDeep(contribution.inputs ?? {}, NO_RENAME),
|
|
6898
7036
|
};
|
|
6899
|
-
|
|
6900
|
-
resourceBindings.set(b.id, b);
|
|
7037
|
+
hoistContributionBindings(def, contribution.bindings, `entryPoint "${ep.id}"`);
|
|
6901
7038
|
}
|
|
6902
7039
|
else if (epSpec.kind === 'event') {
|
|
6903
7040
|
if (!opts.library)
|
|
@@ -6905,7 +7042,7 @@ export function serialize(built, opts = {}) {
|
|
|
6905
7042
|
const sub = epSpec.subscription;
|
|
6906
7043
|
const rc = opts.library.resolveEvent('trigger', sub.connector, sub.event, sub.version, sub.object);
|
|
6907
7044
|
refuseUnverifiedByoa(opts, 'trigger', sub);
|
|
6908
|
-
node = makeNode(rc.nodeType, ep.id,
|
|
7045
|
+
node = makeNode(rc.nodeType, ep.id, epLabel, { def: rc.v1def, requestedVersion });
|
|
6909
7046
|
node.inputs = {
|
|
6910
7047
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6911
7048
|
detail: eventDetail(rc, sub, ep.id, opts, `onEvent() entry point "${ep.id}"`),
|
|
@@ -6920,7 +7057,7 @@ export function serialize(built, opts = {}) {
|
|
|
6920
7057
|
resourceBindings.set(b.id, b);
|
|
6921
7058
|
}
|
|
6922
7059
|
else if (epSpec.kind === 'scheduled') {
|
|
6923
|
-
node = makeNode(NODE_TYPE.scheduledTrigger, ep.id,
|
|
7060
|
+
node = makeNode(NODE_TYPE.scheduledTrigger, ep.id, epLabel, {
|
|
6924
7061
|
requestedVersion: scheduledVersion(epSpec.inputs, requestedVersion),
|
|
6925
7062
|
});
|
|
6926
7063
|
node.inputs = {
|
|
@@ -6929,22 +7066,22 @@ export function serialize(built, opts = {}) {
|
|
|
6929
7066
|
};
|
|
6930
7067
|
}
|
|
6931
7068
|
else if (epSpec.kind === 'form') {
|
|
6932
|
-
node = makeNode(NODE_TYPE.formTrigger, ep.id,
|
|
7069
|
+
node = makeNode(NODE_TYPE.formTrigger, ep.id, epLabel, { requestedVersion });
|
|
6933
7070
|
node.inputs = {
|
|
6934
7071
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6935
7072
|
schema: { fields: formTriggerFields(ep.inputs), outcomes: [] },
|
|
6936
7073
|
};
|
|
6937
7074
|
}
|
|
6938
7075
|
else if (epSpec.kind === 'conversation') {
|
|
6939
|
-
node = makeNode(NODE_TYPE.conversationTrigger, ep.id,
|
|
7076
|
+
node = makeNode(NODE_TYPE.conversationTrigger, ep.id, epLabel, { requestedVersion });
|
|
6940
7077
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6941
7078
|
}
|
|
6942
7079
|
else if (epSpec.kind === 'voice') {
|
|
6943
|
-
node = makeNode(NODE_TYPE.voiceTrigger, ep.id,
|
|
7080
|
+
node = makeNode(NODE_TYPE.voiceTrigger, ep.id, epLabel, { requestedVersion });
|
|
6944
7081
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6945
7082
|
}
|
|
6946
7083
|
else if (epSpec.kind === 'manual') {
|
|
6947
|
-
node = makeNode(NODE_TYPE.trigger, ep.id,
|
|
7084
|
+
node = makeNode(NODE_TYPE.trigger, ep.id, epLabel, { requestedVersion });
|
|
6948
7085
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6949
7086
|
}
|
|
6950
7087
|
else {
|