@uipath/maestro-builder-sdk 6.16.13 → 6.17.0
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/api-index.md +108 -107
- 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.js +219 -37
- package/dist/cli-result.d.ts +9 -0
- package/dist/cli-result.js +12 -0
- package/dist/compile-cli.js +78 -53
- package/dist/core/actions.d.ts +70 -16
- 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/comment-text.d.ts +29 -0
- package/dist/core/comment-text.js +40 -0
- package/dist/core/contribution-bindings.d.ts +73 -0
- package/dist/core/contribution-bindings.js +105 -0
- package/dist/core/expr-check.js +7 -2
- package/dist/core/json-file.d.ts +1 -0
- package/dist/core/json-file.js +12 -0
- 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 +14 -9
- package/dist/flow-sdk.js +14 -4
- 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 +409 -275
- package/dist/workdir.js +1 -1
- package/package.json +3 -3
package/dist/serialize.js
CHANGED
|
@@ -14,6 +14,7 @@ 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';
|
|
17
18
|
import { isAnswerField } from './core/hitl-answers.js';
|
|
18
19
|
import { connectionConnectors } from './bindings-v2.js';
|
|
19
20
|
import { BindingRefusal, GUID_RE, bindingMissingMessage, bindingSelfNameMessage, bindingUndeclaredMessage, missingBindingLabels, undeclaredBinding } from './core/binding-messages.js';
|
|
@@ -49,6 +50,8 @@ import { resolveSchemaVersion } from './schema-version.js';
|
|
|
49
50
|
import { planFlowGlobals, planSharedInputs, sharedInputRoots } from './flow-variables.js';
|
|
50
51
|
import { prepareCommand } from './core/cli-spelling.js';
|
|
51
52
|
import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
|
|
53
|
+
import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
|
|
54
|
+
import { types } from './core/expr.js';
|
|
52
55
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
53
56
|
// core-definitions.json is an object keyed by "<nodeType>@<version>".
|
|
54
57
|
const DEFS = JSON.parse(readFileSync(join(HERE, 'core-definitions.json'), 'utf8'));
|
|
@@ -143,6 +146,53 @@ const SUBFLOW_OUTPUT = {
|
|
|
143
146
|
};
|
|
144
147
|
/** The RPA-workflow node type family. The process's release key is the suffix. */
|
|
145
148
|
const RPA_WORKFLOW_PREFIX = 'uipath.core.rpa-workflow.';
|
|
149
|
+
/**
|
|
150
|
+
* Where a process resource lives, as ONE slot every process-resource definition
|
|
151
|
+
* shares. In the platform model "in this solution" is orthogonal to the
|
|
152
|
+
* resource type: flow-core's single `createModel` (`@uipath/flow-core`
|
|
153
|
+
* `manifest/mappers/node-manifest-builder.ts`, what `uip maestro flow registry
|
|
154
|
+
* get --local` and Studio Web both run) adds `projectId`, `projectName` and
|
|
155
|
+
* `isInSolution: true` to the model of ANY process resource built from a sibling
|
|
156
|
+
* project.
|
|
157
|
+
*
|
|
158
|
+
* The in-solution shape, transcribed from `registry get --local` for a sibling
|
|
159
|
+
* Flow (2026-10-08) and from uipath-cli's `buildInSolutionNodeManifests`:
|
|
160
|
+
* - `resourceKey` is the bare key (the sibling's `resource.key`), not
|
|
161
|
+
* `<folderPath>.<name>`; the folder default is `''`;
|
|
162
|
+
* - no `section: 'Published'`;
|
|
163
|
+
* - `projectId` on the definition AND on the model, with `projectName` and
|
|
164
|
+
* `isInSolution: true` (the marker the canvas reads);
|
|
165
|
+
* - description `(In-solution) <name>`, tags `in-solution` / `local`, and the
|
|
166
|
+
* `open-workflow` toolbar action.
|
|
167
|
+
*/
|
|
168
|
+
function processResourceLocation(spec) {
|
|
169
|
+
if (spec.location === 'in-solution') {
|
|
170
|
+
return {
|
|
171
|
+
inSolution: true,
|
|
172
|
+
folderPath: '',
|
|
173
|
+
resourceKey: spec.key,
|
|
174
|
+
description: `(In-solution) ${spec.name}`,
|
|
175
|
+
tags: ['in-solution', 'local'],
|
|
176
|
+
definitionExtras: {
|
|
177
|
+
toolbarExtensions: {
|
|
178
|
+
design: { actions: [{ id: 'open-workflow', icon: 'external-link', label: 'Open' }] },
|
|
179
|
+
},
|
|
180
|
+
projectId: spec.projectId,
|
|
181
|
+
},
|
|
182
|
+
modelExtras: { projectId: spec.projectId, projectName: spec.name, isInSolution: true },
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const folderPath = spec.folderPath ?? '';
|
|
186
|
+
return {
|
|
187
|
+
inSolution: false,
|
|
188
|
+
folderPath,
|
|
189
|
+
resourceKey: `${folderPath}.${spec.name}`,
|
|
190
|
+
description: `(${folderPath})`,
|
|
191
|
+
tags: [],
|
|
192
|
+
definitionExtras: {},
|
|
193
|
+
modelExtras: {},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
146
196
|
/**
|
|
147
197
|
* Build the definition for one deployed RPA process.
|
|
148
198
|
*
|
|
@@ -177,7 +227,8 @@ const RPA_WORKFLOW_PREFIX = 'uipath.core.rpa-workflow.';
|
|
|
177
227
|
* element while publishing a null step output.
|
|
178
228
|
*/
|
|
179
229
|
function rpaWorkflowDef(spec) {
|
|
180
|
-
const
|
|
230
|
+
const loc = processResourceLocation(spec);
|
|
231
|
+
const { resourceKey } = loc;
|
|
181
232
|
const properties = {};
|
|
182
233
|
for (const [k, v] of Object.entries(spec.inputs)) {
|
|
183
234
|
properties[k] = { type: typeof v === 'number' ? 'number' : typeof v === 'boolean' ? 'boolean' : 'string' };
|
|
@@ -187,8 +238,8 @@ function rpaWorkflowDef(spec) {
|
|
|
187
238
|
version: '1.0.0',
|
|
188
239
|
category: 'rpa-workflow',
|
|
189
240
|
runtimeConstraints: { exclude: ['api-function'] },
|
|
190
|
-
description:
|
|
191
|
-
tags:
|
|
241
|
+
description: loc.description,
|
|
242
|
+
tags: loc.tags,
|
|
192
243
|
sortOrder: 530,
|
|
193
244
|
supportsErrorHandling: true,
|
|
194
245
|
display: { label: spec.name, icon: 'rpa' },
|
|
@@ -196,11 +247,12 @@ function rpaWorkflowDef(spec) {
|
|
|
196
247
|
{ position: 'left', handles: [{ id: 'input', type: 'target', handleType: 'input' }] },
|
|
197
248
|
{ position: 'right', handles: [{ id: 'output', type: 'source', handleType: 'output' }] },
|
|
198
249
|
],
|
|
250
|
+
...loc.definitionExtras,
|
|
199
251
|
model: {
|
|
200
252
|
type: 'bpmn:ServiceTask',
|
|
201
253
|
serviceType: 'Orchestrator.StartJob',
|
|
202
254
|
version: 'v2',
|
|
203
|
-
section: 'Published',
|
|
255
|
+
...(loc.inSolution ? {} : { section: 'Published' }),
|
|
204
256
|
bindings: {
|
|
205
257
|
resource: 'process',
|
|
206
258
|
resourceSubType: 'Process',
|
|
@@ -208,9 +260,10 @@ function rpaWorkflowDef(spec) {
|
|
|
208
260
|
orchestratorType: 'process',
|
|
209
261
|
values: [
|
|
210
262
|
{ name: 'name', propertyAttribute: 'name', default: spec.name },
|
|
211
|
-
{ name: 'folderPath', propertyAttribute: 'folderPath', default:
|
|
263
|
+
{ name: 'folderPath', propertyAttribute: 'folderPath', default: loc.folderPath },
|
|
212
264
|
],
|
|
213
265
|
},
|
|
266
|
+
...loc.modelExtras,
|
|
214
267
|
context: [
|
|
215
268
|
{ name: 'name', type: 'string', value: '<bindings.name>' },
|
|
216
269
|
{ name: 'folderPath', type: 'string', value: '<bindings.folderPath>' },
|
|
@@ -453,41 +506,6 @@ function publishedFunctionDef(spec) {
|
|
|
453
506
|
debug: { runtime: 'bpmnEngine' },
|
|
454
507
|
};
|
|
455
508
|
}
|
|
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
509
|
/**
|
|
492
510
|
* Build the definition for one deployed agentic process (a Maestro process
|
|
493
511
|
* orchestration).
|
|
@@ -529,7 +547,8 @@ const AGENTIC_PROCESS_FORMS = {
|
|
|
529
547
|
*/
|
|
530
548
|
function agenticProcessDef(spec) {
|
|
531
549
|
const form = AGENTIC_PROCESS_FORMS[spec.form ?? 'bpmn'];
|
|
532
|
-
const
|
|
550
|
+
const loc = processResourceLocation(spec);
|
|
551
|
+
const { resourceKey } = loc;
|
|
533
552
|
const properties = {};
|
|
534
553
|
for (const [k, v] of Object.entries(spec.inputs)) {
|
|
535
554
|
properties[k] = { type: typeof v === 'number' ? 'number' : typeof v === 'boolean' ? 'boolean' : 'string' };
|
|
@@ -539,8 +558,8 @@ function agenticProcessDef(spec) {
|
|
|
539
558
|
version: '1.0.0',
|
|
540
559
|
category: form.category,
|
|
541
560
|
runtimeConstraints: { exclude: ['api-function'] },
|
|
542
|
-
description:
|
|
543
|
-
tags:
|
|
561
|
+
description: loc.description,
|
|
562
|
+
tags: loc.tags,
|
|
544
563
|
sortOrder: 507,
|
|
545
564
|
supportsErrorHandling: true,
|
|
546
565
|
display: { label: spec.name, icon: form.icon },
|
|
@@ -548,11 +567,12 @@ function agenticProcessDef(spec) {
|
|
|
548
567
|
{ position: 'left', handles: [{ id: 'input', type: 'target', handleType: 'input' }] },
|
|
549
568
|
{ position: 'right', handles: [{ id: 'output', type: 'source', handleType: 'output' }] },
|
|
550
569
|
],
|
|
570
|
+
...loc.definitionExtras,
|
|
551
571
|
model: {
|
|
552
572
|
type: 'bpmn:ServiceTask',
|
|
553
573
|
serviceType: form.serviceType,
|
|
554
574
|
version: 'v2',
|
|
555
|
-
section: 'Published',
|
|
575
|
+
...(loc.inSolution ? {} : { section: 'Published' }),
|
|
556
576
|
bindings: {
|
|
557
577
|
resource: 'process',
|
|
558
578
|
resourceSubType: form.resourceSubType,
|
|
@@ -560,9 +580,10 @@ function agenticProcessDef(spec) {
|
|
|
560
580
|
orchestratorType: form.orchestratorType,
|
|
561
581
|
values: [
|
|
562
582
|
{ name: 'name', propertyAttribute: 'name', default: spec.name },
|
|
563
|
-
{ name: 'folderPath', propertyAttribute: 'folderPath', default:
|
|
583
|
+
{ name: 'folderPath', propertyAttribute: 'folderPath', default: loc.folderPath },
|
|
564
584
|
],
|
|
565
585
|
},
|
|
586
|
+
...loc.modelExtras,
|
|
566
587
|
context: [
|
|
567
588
|
{ name: 'name', type: 'string', value: '<bindings.name>' },
|
|
568
589
|
{ name: 'folderPath', type: 'string', value: '<bindings.folderPath>' },
|
|
@@ -741,28 +762,6 @@ function agentDef(spec) {
|
|
|
741
762
|
debug: { runtime: 'bpmnEngine' },
|
|
742
763
|
};
|
|
743
764
|
}
|
|
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
765
|
/**
|
|
767
766
|
* The definition for ONE Context Grounding index resource, transcribed from the
|
|
768
767
|
* platform's own registry entry (`uip maestro flow registry get
|
|
@@ -984,6 +983,45 @@ const CONNECTOR_TOOL_RESOURCE_TYPE = 'integration';
|
|
|
984
983
|
* on its own it says nothing about who owns a file: `properties.toolType` does.
|
|
985
984
|
*/
|
|
986
985
|
const INTERNAL_TOOL_RESOURCE_TYPE = 'internal';
|
|
986
|
+
/**
|
|
987
|
+
* Where an agent schema property points to declare "this is a FILE":
|
|
988
|
+
* `{ $ref: JOB_ATTACHMENT_REF }`, with {@link jobAttachmentDefinition} under the
|
|
989
|
+
* same schema's `definitions['job-attachment']`.
|
|
990
|
+
*/
|
|
991
|
+
const JOB_ATTACHMENT_REF = '#/definitions/job-attachment';
|
|
992
|
+
/**
|
|
993
|
+
* The canonical `job-attachment` definition an agent schema's file field
|
|
994
|
+
* `$ref`s into — the uipath-agents skill's `agent-definition.md` § File
|
|
995
|
+
* Attachments ("Schema is fixed — copy verbatim"), and the same block the
|
|
996
|
+
* platform's own analyze-attachments tool contract carries.
|
|
997
|
+
*
|
|
998
|
+
* It tells the agent runtime that an input is an Orchestrator attachment, so a
|
|
999
|
+
* file tool (Analyze Files) can resolve the attachment's `ID`.
|
|
1000
|
+
*
|
|
1001
|
+
* A function, not a shared object: each schema gets its own copy, so an edit
|
|
1002
|
+
* to one emitted file cannot reach another.
|
|
1003
|
+
*
|
|
1004
|
+
* (The case serializer keeps its own copy in `case/entry-points.ts`: that one
|
|
1005
|
+
* mirrors the platform's `entry-points.json` packager byte for byte, and its
|
|
1006
|
+
* `MimeType` description differs.)
|
|
1007
|
+
*/
|
|
1008
|
+
function jobAttachmentDefinition() {
|
|
1009
|
+
return {
|
|
1010
|
+
type: 'object',
|
|
1011
|
+
properties: {
|
|
1012
|
+
ID: { type: 'string', description: 'Orchestrator attachment key' },
|
|
1013
|
+
FullName: { type: 'string', description: 'File name' },
|
|
1014
|
+
MimeType: { type: 'string', description: 'MIME type, e.g. "application/pdf", "image/png"' },
|
|
1015
|
+
Metadata: {
|
|
1016
|
+
type: 'object',
|
|
1017
|
+
description: 'Dictionary<string, string> of metadata',
|
|
1018
|
+
additionalProperties: { type: 'string' },
|
|
1019
|
+
},
|
|
1020
|
+
},
|
|
1021
|
+
required: ['ID'],
|
|
1022
|
+
'x-uipath-resource-kind': 'JobAttachment',
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
987
1025
|
/** The `properties.toolType` of the built-in HTTP-request tool's file (#935). */
|
|
988
1026
|
const HTTP_REQUEST_TOOL_TYPE = 'http-request';
|
|
989
1027
|
/**
|
|
@@ -1139,29 +1177,13 @@ function builtinToolResourceJson(tool, label, inputs, spec) {
|
|
|
1139
1177
|
properties: {
|
|
1140
1178
|
attachments: {
|
|
1141
1179
|
type: 'array',
|
|
1142
|
-
items: { $ref:
|
|
1180
|
+
items: { $ref: JOB_ATTACHMENT_REF },
|
|
1143
1181
|
description: String(inputs.attachmentsDescription ?? ''),
|
|
1144
1182
|
},
|
|
1145
1183
|
analysisTask: { type: 'string', description: String(inputs.analysisTaskDescription ?? '') },
|
|
1146
1184
|
},
|
|
1147
1185
|
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
|
-
},
|
|
1186
|
+
definitions: { 'job-attachment': jobAttachmentDefinition() },
|
|
1165
1187
|
},
|
|
1166
1188
|
outputSchema: {
|
|
1167
1189
|
type: 'object',
|
|
@@ -1324,6 +1346,24 @@ const QUICK_FORM_FIELD_SCHEMA = {
|
|
|
1324
1346
|
text: { type: 'string' }, number: { type: 'number' }, boolean: { type: 'boolean' },
|
|
1325
1347
|
'date-time': { type: 'string', format: 'date-time' },
|
|
1326
1348
|
};
|
|
1349
|
+
/**
|
|
1350
|
+
* The folder an app escalation names: the author's `folderPath`, or
|
|
1351
|
+
* `solution_folder` when they gave none — an app that ships in this solution.
|
|
1352
|
+
*
|
|
1353
|
+
* `solution_folder` is the platform's own spelling for that case: it is the
|
|
1354
|
+
* `Folder` that `uip solution resources list` reports for a solution-internal
|
|
1355
|
+
* app, and what the agents skill tells authors to copy into
|
|
1356
|
+
* `channels[].properties.folderName`. The SDK used to write `""`, which no
|
|
1357
|
+
* product writer produces (flow-builder-sdk#967). Measured, the two are the
|
|
1358
|
+
* same everywhere it counts: the agent tool's binding generator drops both
|
|
1359
|
+
* from the App binding (`resolveFolderPathBindingValue`), `uip agent refresh`
|
|
1360
|
+
* plus `uip solution resources refresh` derive byte-identical files from
|
|
1361
|
+
* either, and a live debug resolves the app in the debug folder for both. So
|
|
1362
|
+
* this changes the vocabulary, not the behaviour.
|
|
1363
|
+
*/
|
|
1364
|
+
function escalationAppFolder(app) {
|
|
1365
|
+
return app.folderPath ? app.folderPath : 'solution_folder';
|
|
1366
|
+
}
|
|
1327
1367
|
/**
|
|
1328
1368
|
* The `resources/<id>/resource.json` an inline agent's ESCALATION needs — the
|
|
1329
1369
|
* escalation half of what `toolResourceJson` does for a tool, and inert without
|
|
@@ -1400,7 +1440,7 @@ function escalationResourceJson(esc, spec) {
|
|
|
1400
1440
|
// refresh` imports; `folderName` is the app's Orchestrator folder.
|
|
1401
1441
|
resourceKey: app.key,
|
|
1402
1442
|
appName: app.name,
|
|
1403
|
-
folderName: app
|
|
1443
|
+
folderName: escalationAppFolder(app),
|
|
1404
1444
|
// The app's deploy version (its action schema's `version`). The SDK does
|
|
1405
1445
|
// not read the action schema, so this is the platform's own default — the
|
|
1406
1446
|
// storage migration that introduced the field writes `1` when absent.
|
|
@@ -2183,134 +2223,88 @@ function memoryResourceDef(spec) {
|
|
|
2183
2223
|
},
|
|
2184
2224
|
};
|
|
2185
2225
|
}
|
|
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
|
-
};
|
|
2226
|
+
/** Numeric dotted compare: '1.10' > '1.9'. */
|
|
2227
|
+
function compareVersions(a, b) {
|
|
2228
|
+
const pa = a.split('.').map(Number);
|
|
2229
|
+
const pb = b.split('.').map(Number);
|
|
2230
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
2231
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
2232
|
+
if (d !== 0)
|
|
2233
|
+
return d;
|
|
2234
|
+
}
|
|
2235
|
+
return 0;
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* The inline agent's bundled versions, oldest first, and the newest of them.
|
|
2239
|
+
* The newest bundled pair is the default, so there is no version literal in
|
|
2240
|
+
* this file: when the registry serves a newer version, `check:definitions`
|
|
2241
|
+
* reports the missing pair, `sync:definitions` adds it, and the default follows.
|
|
2242
|
+
*/
|
|
2243
|
+
const INLINE_AGENT_VERSIONS = Object.keys(DEFS)
|
|
2244
|
+
.filter((k) => k.startsWith(`${INLINE_AGENT_TYPE}@`))
|
|
2245
|
+
.map((k) => k.slice(INLINE_AGENT_TYPE.length + 1))
|
|
2246
|
+
.sort(compareVersions);
|
|
2247
|
+
const INLINE_AGENT_DEFAULT_VERSION = INLINE_AGENT_VERSIONS[INLINE_AGENT_VERSIONS.length - 1];
|
|
2248
|
+
/** True when a definition declares the agent's `memory` artifact handle. */
|
|
2249
|
+
function declaresMemoryHandle(def) {
|
|
2250
|
+
return (def?.handleConfiguration ?? []).some((g) => (g?.handles ?? []).some((h) => h?.id === 'memory'));
|
|
2251
|
+
}
|
|
2252
|
+
/**
|
|
2253
|
+
* The definition for the INLINE autonomous agent: the bundled pair for
|
|
2254
|
+
* `version` (the newest by default), plus an explicit overlay of the details
|
|
2255
|
+
* the registry payload does not carry.
|
|
2256
|
+
*
|
|
2257
|
+
* This is the one node type in the agent family that is the SAME on every
|
|
2258
|
+
* tenant — it carries its own configuration instead of referencing a resource —
|
|
2259
|
+
* so `uip maestro flow registry get uipath.agent.autonomous` is a direct oracle
|
|
2260
|
+
* and the bundle entry is the registry's definition as last synced
|
|
2261
|
+
* (`sync:definitions` writes it through unchanged; `check:definitions --deep`
|
|
2262
|
+
* reports content that has moved since). Versions and content both come from
|
|
2263
|
+
* there.
|
|
2264
|
+
*
|
|
2265
|
+
* The overlay, and nothing else:
|
|
2266
|
+
*
|
|
2267
|
+
* * `outputDefinition.output.source` is `=result.response`. The registry's
|
|
2268
|
+
* definition declares no `source`; the deployed corpus (29 `uipath.agent.autonomous` nodes, 05-18 → 07-29) has
|
|
2269
|
+
* `=result.response` in 27 of 27 that declare outputs, and the engine's own
|
|
2270
|
+
* inline dispatch returns `{ response: { …declared keys } }`. Without it the
|
|
2271
|
+
* node's `output` is the whole result envelope rather than the declared keys.
|
|
2272
|
+
* It is applied at every version; the registry payload has no `source`.
|
|
2273
|
+
* * The `memory` handle is kept only when the flow attaches memory. It is
|
|
2274
|
+
* LOCAL content (#431) on the bundled 1.4, absent from the registry's 1.4
|
|
2275
|
+
* (`check.ts` AGENT_MEMORY_NOT_AUTHORABLE), so an agent without memory gets
|
|
2276
|
+
* the registry's handle set.
|
|
2277
|
+
*
|
|
2278
|
+
* NO per-instance schema goes on the definition: `definitions[]` is keyed by
|
|
2279
|
+
* node TYPE, and every inline agent in a flow shares this one entry. A flow
|
|
2280
|
+
* with two agents (an analyst and a writer, say) therefore cannot have both
|
|
2281
|
+
* contracts here — whichever was emitted last would win, and every read against
|
|
2282
|
+
* the other resolved to the wrong shape (GA row 7's port: 25 undeclared-field
|
|
2283
|
+
* errors on a correct flow). The authored contract goes on the NODE
|
|
2284
|
+
* (`node.outputs.output.schema`, in the `inlineAgent` arm), where a reader that
|
|
2285
|
+
* refines per node picks it up.
|
|
2286
|
+
*
|
|
2287
|
+
* The bundled 1.2 is the pre-#956 default, kept so a flow this SDK compiled
|
|
2288
|
+
* before — and a decompile of one, which pins `{ version: '1.2' }` — still
|
|
2289
|
+
* compiles. The corpus also carries 1.1 and 1.3; `shared/sample-flows/
|
|
2290
|
+
* inline-agent.flow` says 1.0, which appears in none of the 29.
|
|
2291
|
+
*/
|
|
2292
|
+
function inlineAgentDef(version, withMemory) {
|
|
2293
|
+
const bundled = DEFS[`${INLINE_AGENT_TYPE}@${version}`];
|
|
2294
|
+
if (!bundled)
|
|
2295
|
+
return undefined;
|
|
2296
|
+
const def = clone(bundled);
|
|
2297
|
+
const output = def.outputDefinition?.output;
|
|
2298
|
+
if (output)
|
|
2299
|
+
output.source = '=result.response';
|
|
2300
|
+
if (!withMemory) {
|
|
2301
|
+
for (const group of def.handleConfiguration ?? []) {
|
|
2302
|
+
if (Array.isArray(group?.handles))
|
|
2303
|
+
group.handles = group.handles.filter((h) => h?.id !== 'memory');
|
|
2304
|
+
}
|
|
2305
|
+
def.handleConfiguration = (def.handleConfiguration ?? []).filter((g) => g?.handles?.length);
|
|
2306
|
+
}
|
|
2307
|
+
return def;
|
|
2314
2308
|
}
|
|
2315
2309
|
/**
|
|
2316
2310
|
* Classify a RENDERED input value (the output of {@link renderValue}).
|
|
@@ -2379,6 +2373,19 @@ function renderAgentSidecarPrompt(template, plan) {
|
|
|
2379
2373
|
return whole;
|
|
2380
2374
|
});
|
|
2381
2375
|
}
|
|
2376
|
+
/**
|
|
2377
|
+
* The `version` every `agent.json` sidecar declares — the agent tool's
|
|
2378
|
+
* `AGENT_SCHEMA_VERSION` (uipath-cli `packages/agent-tool/src/templates/agent-template.ts`).
|
|
2379
|
+
*
|
|
2380
|
+
* It is not a free label. The agents backend reads an on-file `outputSchema`
|
|
2381
|
+
* only at `version >= 1.2.0` (UiPath/Agents#5705), and since uipath-cli#3753
|
|
2382
|
+
* `uip agent init` writes `1.2.0` and `uip agent validate` refuses anything else
|
|
2383
|
+
* with `AgentValidationOutdated` ("Agent version "1.1.0" is outdated; latest is
|
|
2384
|
+
* "1.2.0""). The bump is a version change only: `uip agent refresh` rewrites
|
|
2385
|
+
* the field and nothing else. All three writers below share this one constant
|
|
2386
|
+
* so they cannot fall behind separately (flow-builder-sdk#962).
|
|
2387
|
+
*/
|
|
2388
|
+
const AGENT_DEFINITION_VERSION = '1.2.0';
|
|
2382
2389
|
/**
|
|
2383
2390
|
* The `agent.json` an inline agent's `source` directory must hold.
|
|
2384
2391
|
*
|
|
@@ -2389,8 +2396,9 @@ function renderAgentSidecarPrompt(template, plan) {
|
|
|
2389
2396
|
* inline-agent node and no such file references a definition that is not there.
|
|
2390
2397
|
*
|
|
2391
2398
|
* Shape transcribed from deployed agents under `runs/` (e.g. the four DevCon
|
|
2392
|
-
* billing agents, `
|
|
2393
|
-
* `uip agent init --inline-in-flow` scaffolds.
|
|
2399
|
+
* billing agents, `type: 'lowCode'`), which is also what
|
|
2400
|
+
* `uip agent init --inline-in-flow` scaffolds. The `version` is
|
|
2401
|
+
* {@link AGENT_DEFINITION_VERSION}, not the `1.1.0` those older agents carry. `contentTokens` mirrors `content` as
|
|
2394
2402
|
* one `simpleText` run: the designer uses those tokens to render a prompt with
|
|
2395
2403
|
* inline variable chips, and a single run is the faithful encoding of a plain
|
|
2396
2404
|
* string.
|
|
@@ -2406,7 +2414,7 @@ function renderAgentSidecarPrompt(template, plan) {
|
|
|
2406
2414
|
*/
|
|
2407
2415
|
function conversationalAgentJson(spec) {
|
|
2408
2416
|
return {
|
|
2409
|
-
version:
|
|
2417
|
+
version: AGENT_DEFINITION_VERSION,
|
|
2410
2418
|
settings: {
|
|
2411
2419
|
model: spec.model,
|
|
2412
2420
|
// Required by the platform's agent.json schema, same as the inline
|
|
@@ -2458,7 +2466,7 @@ function voiceAgentJson(spec) {
|
|
|
2458
2466
|
const DEFAULT_PERSONA = 'Aoede';
|
|
2459
2467
|
const v = spec.voice ?? {};
|
|
2460
2468
|
return {
|
|
2461
|
-
version:
|
|
2469
|
+
version: AGENT_DEFINITION_VERSION,
|
|
2462
2470
|
settings: {
|
|
2463
2471
|
engine: 'conversational-v1',
|
|
2464
2472
|
mode: 'voice',
|
|
@@ -2490,7 +2498,7 @@ function voiceAgentJson(spec) {
|
|
|
2490
2498
|
}
|
|
2491
2499
|
function inlineAgentJson(spec) {
|
|
2492
2500
|
return {
|
|
2493
|
-
version:
|
|
2501
|
+
version: AGENT_DEFINITION_VERSION,
|
|
2494
2502
|
settings: {
|
|
2495
2503
|
model: spec.model,
|
|
2496
2504
|
// `maxTokens` and `temperature` are REQUIRED by the platform's own
|
|
@@ -3920,7 +3928,7 @@ function describeDeclared(bindings) {
|
|
|
3920
3928
|
* exactly (design §2.6/§4.2): the named version resolves or compilation fails,
|
|
3921
3929
|
* and a contributor that ignored the author's requested version is rejected.
|
|
3922
3930
|
*/
|
|
3923
|
-
function resolveContributionDefinition(ref, requestedVersion, where) {
|
|
3931
|
+
export function resolveContributionDefinition(ref, requestedVersion, where) {
|
|
3924
3932
|
if (!ref || typeof ref.nodeType !== 'string' || !ref.nodeType || typeof ref.version !== 'string' || !ref.version) {
|
|
3925
3933
|
throw new Error(`${where}: contribute() returned a DefinitionReference without an exact nodeType + version.`);
|
|
3926
3934
|
}
|
|
@@ -4405,10 +4413,16 @@ function typeAgentInputSchemas(scope, globals) {
|
|
|
4405
4413
|
if (g.direction === 'in' && g.triggerNodeId)
|
|
4406
4414
|
lookup.set(`${g.triggerNodeId}.output.${g.id}`, { type: g.type, schema: g.schema });
|
|
4407
4415
|
}
|
|
4408
|
-
for (const {
|
|
4416
|
+
for (const { schema, refs } of scope.agentSchemas) {
|
|
4409
4417
|
for (const r of refs) {
|
|
4410
|
-
properties[r.flatName] = jsonSchemaForRef(r.binding, lookup);
|
|
4418
|
+
schema.properties[r.flatName] = jsonSchemaForRef(r.binding, lookup);
|
|
4411
4419
|
}
|
|
4420
|
+
// A file property is a `$ref`, and a `$ref` resolves against THIS schema's
|
|
4421
|
+
// `definitions` — so the block is added exactly when a file property is
|
|
4422
|
+
// present (a schema with no file keeps the shape it always had).
|
|
4423
|
+
const hasFile = Object.values(schema.properties).some((p) => p?.$ref === JOB_ATTACHMENT_REF);
|
|
4424
|
+
if (hasFile)
|
|
4425
|
+
schema.definitions = { ...schema.definitions, 'job-attachment': jobAttachmentDefinition() };
|
|
4412
4426
|
}
|
|
4413
4427
|
}
|
|
4414
4428
|
/** One property's schema — `{}` when the type cannot be established. See {@link typeAgentInputSchemas}. */
|
|
@@ -4498,17 +4512,58 @@ function walkSchemaType(schema, segments) {
|
|
|
4498
4512
|
}
|
|
4499
4513
|
return typeof current?.type === 'string' ? current.type : undefined;
|
|
4500
4514
|
}
|
|
4501
|
-
/**
|
|
4515
|
+
/**
|
|
4516
|
+
* A resolved type → its JSON-Schema property.
|
|
4517
|
+
*
|
|
4518
|
+
* Every type a flow can DECLARE (`types.*`) has its own case, and the switch is
|
|
4519
|
+
* exhaustive over {@link TypeDesc}: adding a type to `types` without deciding
|
|
4520
|
+
* what an agent sees for it is a compile error here, not a silent `{}`.
|
|
4521
|
+
*
|
|
4522
|
+
* `file` → `{ $ref: '#/definitions/job-attachment' }`; the caller adds the
|
|
4523
|
+
* definition (see `typeAgentInputSchemas`).
|
|
4524
|
+
*
|
|
4525
|
+
* Typeless `{}` is the answer for `any` and for "unknown" (`undefined`,
|
|
4526
|
+
* or a type string from a node definition that is not in the SDK's
|
|
4527
|
+
* vocabulary): that is v1's own rule for a type it cannot establish
|
|
4528
|
+
* (`buildAgentInputTypeResolver` → `'any'` → a property with no `type`), and it
|
|
4529
|
+
* keeps the runtime's pydantic model from refusing a value the SDK only
|
|
4530
|
+
* guessed at.
|
|
4531
|
+
*/
|
|
4502
4532
|
function jsonSchemaForType(type) {
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
// sidecar does not carry.)
|
|
4507
|
-
if (!type || type === 'any' || type === 'file' || type === 'octet-stream')
|
|
4533
|
+
if (type === 'octet-stream')
|
|
4534
|
+
return { $ref: JOB_ATTACHMENT_REF }; // v1's alias for file
|
|
4535
|
+
if (type === undefined || !isTypeDesc(type))
|
|
4508
4536
|
return {};
|
|
4509
|
-
|
|
4510
|
-
return {
|
|
4511
|
-
|
|
4537
|
+
switch (type) {
|
|
4538
|
+
case 'file': return { $ref: JOB_ATTACHMENT_REF };
|
|
4539
|
+
case 'any': return {};
|
|
4540
|
+
// A bare `type: 'array'` makes the runtime's `jsonschema_to_pydantic`
|
|
4541
|
+
// reject a valid array (v1's note at `uipath.ts:118-123`, MST-9544).
|
|
4542
|
+
case 'array': return { type: 'array', items: {} };
|
|
4543
|
+
case 'string':
|
|
4544
|
+
case 'number':
|
|
4545
|
+
case 'integer':
|
|
4546
|
+
case 'boolean':
|
|
4547
|
+
case 'object':
|
|
4548
|
+
return { type };
|
|
4549
|
+
// The case vocabulary's widths and date kinds, as JSON Schema spells them
|
|
4550
|
+
// (the same table `case/entry-points.ts` projects with).
|
|
4551
|
+
case 'float': return { type: 'number', format: 'float' };
|
|
4552
|
+
case 'double': return { type: 'number', format: 'double' };
|
|
4553
|
+
case 'date': return { type: 'string', format: 'date' };
|
|
4554
|
+
case 'datetime': return { type: 'string', format: 'date-time' };
|
|
4555
|
+
// A case `jsonSchema` variable's shape lives in its `body`, which this
|
|
4556
|
+
// lookup does not carry — so its type is not established here.
|
|
4557
|
+
case 'jsonSchema': return {};
|
|
4558
|
+
default: {
|
|
4559
|
+
const unmapped = type;
|
|
4560
|
+
throw new Error(`jsonSchemaForType: no agent schema mapping for type '${String(unmapped)}'`);
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
const TYPE_DESCS = new Set(Object.values(types));
|
|
4565
|
+
function isTypeDesc(type) {
|
|
4566
|
+
return TYPE_DESCS.has(type);
|
|
4512
4567
|
}
|
|
4513
4568
|
/**
|
|
4514
4569
|
* An End node's `outputs` map: every variable this scope exposes as a flow
|
|
@@ -4624,6 +4679,61 @@ export function serialize(built, opts = {}) {
|
|
|
4624
4679
|
* A bindings entry the node does not reference is not a bound resource.
|
|
4625
4680
|
*/
|
|
4626
4681
|
const resourceBindings = new Map();
|
|
4682
|
+
/**
|
|
4683
|
+
* Hoist a contribution's own bindings, then close every `<bindings.NAME>` its
|
|
4684
|
+
* definition references and it did not supply, from the definition's own
|
|
4685
|
+
* `model.bindings` (flow-builder-sdk#942). Shared by the three contribution
|
|
4686
|
+
* sites (step, trigger, entry point), so a `rawNode` and a hand-written
|
|
4687
|
+
* subclass get the same entries a typed emitter would. `check` runs the same
|
|
4688
|
+
* plan dry (`checkContribution` in `check.ts`), so it reports what this throws.
|
|
4689
|
+
*/
|
|
4690
|
+
function hoistContributionBindings(def, supplied, where) {
|
|
4691
|
+
for (const b of supplied ?? [])
|
|
4692
|
+
resourceBindings.set(b.id, b);
|
|
4693
|
+
const plan = planContributionBindings(def, supplied);
|
|
4694
|
+
if (plan.problems.length) {
|
|
4695
|
+
throw new BindingRefusal('CONTRIBUTION_BINDING_UNRESOLVED', `${where}: ${plan.problems.join(' ')}`);
|
|
4696
|
+
}
|
|
4697
|
+
if (plan.entries.length === 0)
|
|
4698
|
+
return;
|
|
4699
|
+
// A process reference is the name + folderPath pair every typed process step
|
|
4700
|
+
// emits: go through the same builder, so a raw node and a typed step on ONE
|
|
4701
|
+
// process share one pair instead of shadowing each other.
|
|
4702
|
+
const byName = new Map(plan.entries.map((e) => [e.name, e]));
|
|
4703
|
+
const pairName = byName.get('name');
|
|
4704
|
+
const pairFolder = byName.get('folderPath');
|
|
4705
|
+
if (plan.resource === 'process' && plan.entries.length === 2 && pairName?.propertyAttribute === 'name'
|
|
4706
|
+
&& pairFolder?.propertyAttribute === 'folderPath' && pairName.default !== undefined
|
|
4707
|
+
&& pairFolder.default !== undefined) {
|
|
4708
|
+
const { entries } = processResourceBindings({
|
|
4709
|
+
name: pairName.default,
|
|
4710
|
+
folderPath: pairFolder.default,
|
|
4711
|
+
resourceSubType: pairName.resourceSubType,
|
|
4712
|
+
resourceKey: plan.resourceKey,
|
|
4713
|
+
}, resourceBindings);
|
|
4714
|
+
for (const b of entries) {
|
|
4715
|
+
// processResourceBindings types the subtype to the families it knows; keep
|
|
4716
|
+
// the definition's own spelling (or none) verbatim.
|
|
4717
|
+
if (pairName.resourceSubType === undefined)
|
|
4718
|
+
delete b.resourceSubType;
|
|
4719
|
+
resourceBindings.set(b.id, b);
|
|
4720
|
+
}
|
|
4721
|
+
return;
|
|
4722
|
+
}
|
|
4723
|
+
for (const e of plan.entries) {
|
|
4724
|
+
const same = [...resourceBindings.values()].some((b) => b.resource === e.resource
|
|
4725
|
+
&& b.resourceKey === e.resourceKey && b.name === e.name && b.propertyAttribute === e.propertyAttribute);
|
|
4726
|
+
if (same)
|
|
4727
|
+
continue;
|
|
4728
|
+
const slug = e.resourceKey.replace(/[^A-Za-z0-9]/g, '') || 'Resource';
|
|
4729
|
+
const cap = (t) => t.charAt(0).toUpperCase() + t.slice(1);
|
|
4730
|
+
const stem = `b${cap(slug)}${cap(e.name.replace(/[^A-Za-z0-9]/g, ''))}`;
|
|
4731
|
+
let id = stem;
|
|
4732
|
+
for (let n = 2; resourceBindings.has(id); n++)
|
|
4733
|
+
id = `${stem}${n}`;
|
|
4734
|
+
resourceBindings.set(id, { id, ...e });
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4627
4737
|
/**
|
|
4628
4738
|
* Extra files the flow needs beside the `.flow` — see `SerializeOpts.sidecars`.
|
|
4629
4739
|
* Written into the caller's array when one was passed, so a caller that wants them
|
|
@@ -4719,13 +4829,15 @@ export function serialize(built, opts = {}) {
|
|
|
4719
4829
|
* (design §2.6): resolution is exact — `<type>@<version>` from the bundle, or
|
|
4720
4830
|
* the version of the definition already in hand — and a version the SDK
|
|
4721
4831
|
* cannot resolve exactly fails compilation rather than floating to a default.
|
|
4832
|
+
* An undefined `label` takes the definition's `display.label`, which is what
|
|
4833
|
+
* the canvas shows on a freshly dropped node.
|
|
4722
4834
|
*/
|
|
4723
4835
|
function makeNode(type, id, label, o = {}) {
|
|
4724
4836
|
let def = o.def ?? defByType.get(type);
|
|
4725
4837
|
if (o.requestedVersion !== undefined && def?.version !== o.requestedVersion) {
|
|
4726
4838
|
const exact = o.def ? undefined : DEFS[`${type}@${o.requestedVersion}`];
|
|
4727
4839
|
if (!exact) {
|
|
4728
|
-
throw new Error(`"${label}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
|
|
4840
|
+
throw new Error(`"${label ?? id}" requests ${type}@${o.requestedVersion}, but this SDK resolves only `
|
|
4729
4841
|
+ `${type}@${def?.version ?? '<none>'}. Versions are exact — omit { version } to use `
|
|
4730
4842
|
+ `the pinned default, or request a version this SDK ships.`);
|
|
4731
4843
|
}
|
|
@@ -4738,7 +4850,7 @@ export function serialize(built, opts = {}) {
|
|
|
4738
4850
|
type,
|
|
4739
4851
|
typeVersion: def?.version ?? '1.0.0',
|
|
4740
4852
|
ui: { position: { x: 256 + col * 288, y: 144 + (o.parentId ? 160 : 0) }, size: { width: 96, height: 96 }, collapsed: false },
|
|
4741
|
-
display: { label, ...(def?.display?.icon ? { icon: def.display.icon } : {}) },
|
|
4853
|
+
display: { label: label ?? def?.display?.label ?? id, ...(def?.display?.icon ? { icon: def.display.icon } : {}) },
|
|
4742
4854
|
};
|
|
4743
4855
|
col++;
|
|
4744
4856
|
// A Data Fabric node gets no node-level `model`, whichever path emits it
|
|
@@ -4862,7 +4974,7 @@ export function serialize(built, opts = {}) {
|
|
|
4862
4974
|
if (customTrigger) {
|
|
4863
4975
|
const contribution = customTrigger.contribute(built.triggerOptions?.version !== undefined ? { requestedVersion: built.triggerOptions.version } : {});
|
|
4864
4976
|
const def = resolveContributionDefinition(contribution.definition, built.triggerOptions?.version, 'trigger');
|
|
4865
|
-
const node = makeNode(def.nodeType, triggerId, def.display?.label ?? 'Start', { def, requestedVersion: built.triggerOptions?.version });
|
|
4977
|
+
const node = makeNode(def.nodeType, triggerId, built.triggerOptions?.label ?? def.display?.label ?? 'Start', { def, requestedVersion: built.triggerOptions?.version });
|
|
4866
4978
|
const inputs = renderDeep(contribution.inputs ?? {}, NO_RENAME);
|
|
4867
4979
|
if (def.model?.entryPointId === true && inputs.entryPointId === undefined) {
|
|
4868
4980
|
inputs.entryPointId = stableId(`${built.id}:start:entryPoint`);
|
|
@@ -4870,25 +4982,26 @@ export function serialize(built, opts = {}) {
|
|
|
4870
4982
|
inputs.isDefaultEntryPoint = true;
|
|
4871
4983
|
}
|
|
4872
4984
|
node.inputs = inputs;
|
|
4873
|
-
|
|
4874
|
-
resourceBindings.set(b.id, b);
|
|
4985
|
+
hoistContributionBindings(def, contribution.bindings, 'trigger');
|
|
4875
4986
|
root.nodes.push(node);
|
|
4876
4987
|
}
|
|
4988
|
+
// The author's `.trigger(spec, { label })`; makeNode falls back to the definition's label.
|
|
4989
|
+
const rootLabel = built.triggerOptions?.label;
|
|
4877
4990
|
const trigger = customTrigger
|
|
4878
4991
|
? root.nodes[root.nodes.length - 1]
|
|
4879
4992
|
: eventTriggerRc
|
|
4880
|
-
? makeNode(eventTriggerRc.nodeType, triggerId,
|
|
4993
|
+
? makeNode(eventTriggerRc.nodeType, triggerId, rootLabel, { def: eventTriggerRc.v1def, requestedVersion: built.triggerOptions?.version })
|
|
4881
4994
|
: built.trigger?.kind === 'scheduled'
|
|
4882
|
-
? makeNode(NODE_TYPE.scheduledTrigger, triggerId,
|
|
4995
|
+
? makeNode(NODE_TYPE.scheduledTrigger, triggerId, rootLabel, {
|
|
4883
4996
|
requestedVersion: scheduledVersion(built.trigger.inputs, built.triggerOptions?.version),
|
|
4884
4997
|
})
|
|
4885
4998
|
: built.trigger?.kind === 'form'
|
|
4886
|
-
? makeNode(NODE_TYPE.formTrigger, triggerId,
|
|
4999
|
+
? makeNode(NODE_TYPE.formTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
4887
5000
|
: built.trigger?.kind === 'conversation'
|
|
4888
|
-
? makeNode(NODE_TYPE.conversationTrigger, triggerId,
|
|
5001
|
+
? makeNode(NODE_TYPE.conversationTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
4889
5002
|
: built.trigger?.kind === 'voice'
|
|
4890
|
-
? makeNode(NODE_TYPE.voiceTrigger, triggerId,
|
|
4891
|
-
: makeNode(NODE_TYPE.trigger, triggerId,
|
|
5003
|
+
? makeNode(NODE_TYPE.voiceTrigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version })
|
|
5004
|
+
: makeNode(NODE_TYPE.trigger, triggerId, rootLabel, { requestedVersion: built.triggerOptions?.version });
|
|
4892
5005
|
if (!customTrigger) {
|
|
4893
5006
|
trigger.inputs = eventTriggerRc && built.trigger?.kind === 'event'
|
|
4894
5007
|
? {
|
|
@@ -5006,8 +5119,7 @@ export function serialize(built, opts = {}) {
|
|
|
5006
5119
|
if (contribution.outputs) {
|
|
5007
5120
|
node.outputs = { ...(node.outputs ?? {}), ...subNodeId(clone(contribution.outputs), id) };
|
|
5008
5121
|
}
|
|
5009
|
-
|
|
5010
|
-
resourceBindings.set(b.id, b);
|
|
5122
|
+
hoistContributionBindings(def, contribution.bindings, where);
|
|
5011
5123
|
scope.nodes.push(node);
|
|
5012
5124
|
for (const t of tails)
|
|
5013
5125
|
addEdge(scope, t, id);
|
|
@@ -5165,16 +5277,30 @@ export function serialize(built, opts = {}) {
|
|
|
5165
5277
|
// required: it is what the platform scaffolds, so a flow that reads
|
|
5166
5278
|
// `content` is a real (if toy) flow. `check` says so.
|
|
5167
5279
|
: { content: 'string' };
|
|
5168
|
-
//
|
|
5169
|
-
//
|
|
5170
|
-
//
|
|
5171
|
-
//
|
|
5172
|
-
//
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5280
|
+
// ONE default version for every call shape — the newest bundled pair (see
|
|
5281
|
+
// `inlineAgentDef`). `mode` and `memory` used to pick the version too (1.3
|
|
5282
|
+
// and 1.4), so a plain agent got a superseded 1.2 and each option moved
|
|
5283
|
+
// the node to another version as a side effect (#956). Both now live in
|
|
5284
|
+
// the sidecar and on edges; neither selects a definition. An explicit
|
|
5285
|
+
// `{ version }` (what decompile writes back) resolves exactly.
|
|
5286
|
+
const version = step.options?.version ?? INLINE_AGENT_DEFAULT_VERSION;
|
|
5287
|
+
// `definitions[]` holds one entry per type@version, so a flow where any
|
|
5288
|
+
// agent attaches memory keeps the handle for all of them.
|
|
5289
|
+
const withMemory = s.memory !== undefined
|
|
5290
|
+
|| declaresMemoryHandle(emittedDefs.get(`${INLINE_AGENT_TYPE}@${version}`));
|
|
5291
|
+
const def = inlineAgentDef(version, withMemory);
|
|
5292
|
+
if (!def) {
|
|
5293
|
+
throw new Error(`"${step.name}" requests ${INLINE_AGENT_TYPE}@${version}, but this SDK resolves only `
|
|
5294
|
+
+ `${INLINE_AGENT_VERSIONS.map((v) => `${INLINE_AGENT_TYPE}@${v}`).join(', ')}. Versions are exact — `
|
|
5295
|
+
+ `omit { version } to use the default (${INLINE_AGENT_DEFAULT_VERSION}), or request a version this SDK ships.`);
|
|
5296
|
+
}
|
|
5297
|
+
if (s.memory !== undefined && !declaresMemoryHandle(def)) {
|
|
5298
|
+
throw new Error(`"${step.name}" attaches \`memory\`, but ${INLINE_AGENT_TYPE}@${version} declares no \`memory\` handle. `
|
|
5299
|
+
+ (version === INLINE_AGENT_DEFAULT_VERSION
|
|
5300
|
+
? `Pin a version that has it with inlineAgent({ ..., version: '<x.y>' }) `
|
|
5301
|
+
+ `(bundled with memory: ${INLINE_AGENT_VERSIONS.filter((v) => declaresMemoryHandle(DEFS[`${INLINE_AGENT_TYPE}@${v}`])).join(', ') || 'none'}), or drop \`memory\`.`
|
|
5302
|
+
: `Drop { version: '${version}' } to use ${INLINE_AGENT_DEFAULT_VERSION}, or drop \`memory\`.`));
|
|
5303
|
+
}
|
|
5178
5304
|
const id = stepUid(scope, step.name);
|
|
5179
5305
|
// `source` is the agent's directory name. Derived from the flow id + step
|
|
5180
5306
|
// name rather than random so a recompile is byte-identical — a v4-shaped uuid
|
|
@@ -5263,7 +5389,7 @@ export function serialize(built, opts = {}) {
|
|
|
5263
5389
|
// The schema's property TYPES need this scope's finished variables, which
|
|
5264
5390
|
// do not exist yet — park them (the `properties` object is filled in
|
|
5265
5391
|
// place when the scope closes). See `typeAgentInputSchemas`.
|
|
5266
|
-
scope.agentSchemas.push({
|
|
5392
|
+
scope.agentSchemas.push({ schema: agentJson.inputSchema, refs: plan.refs });
|
|
5267
5393
|
// GROUNDING — one resource node per context index, joined to the agent's own
|
|
5268
5394
|
// `context` handle. An ARTIFACT, not a step: it takes no incoming control
|
|
5269
5395
|
// flow, produces no output, and never reaches the End node. The edge runs OUT
|
|
@@ -5612,7 +5738,7 @@ export function serialize(built, opts = {}) {
|
|
|
5612
5738
|
name: app.name,
|
|
5613
5739
|
appName: app.name,
|
|
5614
5740
|
displayName: app.name,
|
|
5615
|
-
folderPath: app
|
|
5741
|
+
folderPath: escalationAppFolder(app),
|
|
5616
5742
|
inputSchema: fieldSchema(app.inputs),
|
|
5617
5743
|
outputSchema: fieldSchema(app.outputs),
|
|
5618
5744
|
},
|
|
@@ -5679,21 +5805,28 @@ export function serialize(built, opts = {}) {
|
|
|
5679
5805
|
// downstream in the engine.
|
|
5680
5806
|
const s = spec.inputs;
|
|
5681
5807
|
const nodeInputs = s.inputs ?? {};
|
|
5682
|
-
const subType = spec.kind === 'apiWorkflow' ? 'Api'
|
|
5683
|
-
: spec.kind === 'agenticProcess' ? 'ProcessOrchestration'
|
|
5684
|
-
: spec.kind === 'publishedFunction' ? 'Function'
|
|
5685
|
-
: 'Process';
|
|
5686
5808
|
const fireAndForget = spec.kind === 'agenticProcess' && spec.inputs.completion === 'fire-and-forget';
|
|
5687
5809
|
const def = spec.kind === 'publishedFunction'
|
|
5688
|
-
? publishedFunctionDef({ key: spec.inputs.key, name: s.name, folderPath:
|
|
5810
|
+
? publishedFunctionDef({ key: spec.inputs.key, name: s.name, folderPath: spec.inputs.folderPath, inputs: nodeInputs, returns: spec.inputs.returns })
|
|
5689
5811
|
: spec.kind === 'apiWorkflow'
|
|
5690
|
-
? apiWorkflowDef({ key: spec.inputs.key, name: s.name, folderPath:
|
|
5812
|
+
? apiWorkflowDef({ key: spec.inputs.key, name: s.name, folderPath: spec.inputs.folderPath, inputs: nodeInputs, returns: spec.inputs.returns })
|
|
5691
5813
|
: spec.kind === 'agenticProcess'
|
|
5692
|
-
? agenticProcessDef({
|
|
5693
|
-
|
|
5814
|
+
? agenticProcessDef({
|
|
5815
|
+
key: spec.inputs.key, name: s.name, folderPath: s.folderPath, location: spec.inputs.location,
|
|
5816
|
+
projectId: spec.inputs.projectId, inputs: nodeInputs, returns: spec.inputs.returns, form: spec.inputs.form,
|
|
5817
|
+
})
|
|
5818
|
+
: rpaWorkflowDef({
|
|
5819
|
+
key: spec.inputs.key, name: s.name, folderPath: s.folderPath, location: spec.inputs.location,
|
|
5820
|
+
projectId: spec.inputs.projectId, inputs: nodeInputs, returns: spec.inputs.returns,
|
|
5821
|
+
});
|
|
5694
5822
|
// The bindings first: two steps on the same process share ONE pair, and the
|
|
5695
5823
|
// definition's `model.context` names ids that have to exist.
|
|
5696
|
-
|
|
5824
|
+
// Read off the definition: one kind carries several subtypes (agenticProcess by `form`).
|
|
5825
|
+
// The pair's key and folder come off it too: an in-solution step's resourceKey is the
|
|
5826
|
+
// bare sibling key and its folder is `''`.
|
|
5827
|
+
const subType = def.model.bindings.resourceSubType;
|
|
5828
|
+
const pairFolder = def.model.bindings.values.find((v) => v.name === 'folderPath').default;
|
|
5829
|
+
const { entries } = processResourceBindings({ name: s.name, folderPath: pairFolder, resourceSubType: subType, resourceKey: def.model.bindings.resourceKey }, resourceBindings);
|
|
5697
5830
|
for (const b of entries)
|
|
5698
5831
|
resourceBindings.set(b.id, b);
|
|
5699
5832
|
const id = stepUid(scope, step.name);
|
|
@@ -5903,7 +6036,7 @@ export function serialize(built, opts = {}) {
|
|
|
5903
6036
|
});
|
|
5904
6037
|
if (plan.refs.length > 0) {
|
|
5905
6038
|
const agentJson = sidecars[sidecars.length - 1].json;
|
|
5906
|
-
scope.agentSchemas.push({
|
|
6039
|
+
scope.agentSchemas.push({ schema: agentJson.inputSchema, refs: plan.refs });
|
|
5907
6040
|
}
|
|
5908
6041
|
for (const t of tails)
|
|
5909
6042
|
addEdge(scope, t, id);
|
|
@@ -6871,19 +7004,20 @@ export function serialize(built, opts = {}) {
|
|
|
6871
7004
|
takenIds.add(ep.id);
|
|
6872
7005
|
const spec = ep.trigger;
|
|
6873
7006
|
const requestedVersion = ep.options?.version;
|
|
7007
|
+
// The author's label; makeNode falls back to the definition's label.
|
|
7008
|
+
const epLabel = ep.options?.label;
|
|
6874
7009
|
const customEp = spec instanceof FlowTrigger && !('kind' in spec) ? spec : undefined;
|
|
6875
7010
|
const epSpec = spec;
|
|
6876
7011
|
let node;
|
|
6877
7012
|
if (customEp) {
|
|
6878
7013
|
const contribution = customEp.contribute(requestedVersion !== undefined ? { requestedVersion } : {});
|
|
6879
7014
|
const def = resolveContributionDefinition(contribution.definition, requestedVersion, `entryPoint "${ep.id}"`);
|
|
6880
|
-
node = makeNode(def.nodeType, ep.id, def.display?.label ?? ep.id, { def, requestedVersion });
|
|
7015
|
+
node = makeNode(def.nodeType, ep.id, ep.options?.label ?? def.display?.label ?? ep.id, { def, requestedVersion });
|
|
6881
7016
|
node.inputs = {
|
|
6882
7017
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6883
7018
|
...renderDeep(contribution.inputs ?? {}, NO_RENAME),
|
|
6884
7019
|
};
|
|
6885
|
-
|
|
6886
|
-
resourceBindings.set(b.id, b);
|
|
7020
|
+
hoistContributionBindings(def, contribution.bindings, `entryPoint "${ep.id}"`);
|
|
6887
7021
|
}
|
|
6888
7022
|
else if (epSpec.kind === 'event') {
|
|
6889
7023
|
if (!opts.library)
|
|
@@ -6891,7 +7025,7 @@ export function serialize(built, opts = {}) {
|
|
|
6891
7025
|
const sub = epSpec.subscription;
|
|
6892
7026
|
const rc = opts.library.resolveEvent('trigger', sub.connector, sub.event, sub.version, sub.object);
|
|
6893
7027
|
refuseUnverifiedByoa(opts, 'trigger', sub);
|
|
6894
|
-
node = makeNode(rc.nodeType, ep.id,
|
|
7028
|
+
node = makeNode(rc.nodeType, ep.id, epLabel, { def: rc.v1def, requestedVersion });
|
|
6895
7029
|
node.inputs = {
|
|
6896
7030
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6897
7031
|
detail: eventDetail(rc, sub, ep.id, opts, `onEvent() entry point "${ep.id}"`),
|
|
@@ -6906,7 +7040,7 @@ export function serialize(built, opts = {}) {
|
|
|
6906
7040
|
resourceBindings.set(b.id, b);
|
|
6907
7041
|
}
|
|
6908
7042
|
else if (epSpec.kind === 'scheduled') {
|
|
6909
|
-
node = makeNode(NODE_TYPE.scheduledTrigger, ep.id,
|
|
7043
|
+
node = makeNode(NODE_TYPE.scheduledTrigger, ep.id, epLabel, {
|
|
6910
7044
|
requestedVersion: scheduledVersion(epSpec.inputs, requestedVersion),
|
|
6911
7045
|
});
|
|
6912
7046
|
node.inputs = {
|
|
@@ -6915,22 +7049,22 @@ export function serialize(built, opts = {}) {
|
|
|
6915
7049
|
};
|
|
6916
7050
|
}
|
|
6917
7051
|
else if (epSpec.kind === 'form') {
|
|
6918
|
-
node = makeNode(NODE_TYPE.formTrigger, ep.id,
|
|
7052
|
+
node = makeNode(NODE_TYPE.formTrigger, ep.id, epLabel, { requestedVersion });
|
|
6919
7053
|
node.inputs = {
|
|
6920
7054
|
entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`),
|
|
6921
7055
|
schema: { fields: formTriggerFields(ep.inputs), outcomes: [] },
|
|
6922
7056
|
};
|
|
6923
7057
|
}
|
|
6924
7058
|
else if (epSpec.kind === 'conversation') {
|
|
6925
|
-
node = makeNode(NODE_TYPE.conversationTrigger, ep.id,
|
|
7059
|
+
node = makeNode(NODE_TYPE.conversationTrigger, ep.id, epLabel, { requestedVersion });
|
|
6926
7060
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6927
7061
|
}
|
|
6928
7062
|
else if (epSpec.kind === 'voice') {
|
|
6929
|
-
node = makeNode(NODE_TYPE.voiceTrigger, ep.id,
|
|
7063
|
+
node = makeNode(NODE_TYPE.voiceTrigger, ep.id, epLabel, { requestedVersion });
|
|
6930
7064
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6931
7065
|
}
|
|
6932
7066
|
else if (epSpec.kind === 'manual') {
|
|
6933
|
-
node = makeNode(NODE_TYPE.trigger, ep.id,
|
|
7067
|
+
node = makeNode(NODE_TYPE.trigger, ep.id, epLabel, { requestedVersion });
|
|
6934
7068
|
node.inputs = { entryPointId: stableId(`${built.id}:${ep.id}:entryPoint`) };
|
|
6935
7069
|
}
|
|
6936
7070
|
else {
|