@uipath/maestro-builder-sdk 6.17.3 → 6.17.5

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/check.js CHANGED
@@ -9,7 +9,7 @@ import { Expr, SCHEDULE_PRESETS, DELAY_PRESETS, VARIANT_OPERATION, parseIxpProje
9
9
  import { FlowNode } from './core/node-classes.js';
10
10
  import { planContributionBindings } from './core/contribution-bindings.js';
11
11
  import { definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
12
- import { resolveContributionDefinition } from './serialize.js';
12
+ import { bundledActionNodeType, bundledDefinition, resolveContributionDefinition } from './serialize.js';
13
13
  import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
14
14
  import { AGENTIC_PROCESS_FORMS } from './core/agentic-process-forms.js';
15
15
  import { checkEventResolution, checkEventSubscription, eventParamsFor, } from './core/event-checks.js';
@@ -5341,29 +5341,24 @@ function collectActionExprs(s, out, errorSource) {
5341
5341
  }
5342
5342
  }
5343
5343
  /**
5344
- * The node types that HAVE an error port — the definitions that carry
5345
- * `supportsErrorHandling: true`, plus the families whose def is per-tenant and
5346
- * declares it too (rpa / api-workflow / agentic-process / agent / connector).
5344
+ * The families whose definition is built per tenant or per call, so there is no
5345
+ * bundled definition to ask, and whose definitions all have
5346
+ * an error port (the SDK's own `rpaWorkflowDef` / `apiWorkflowDef` /
5347
+ * `agenticProcessDef` / `agentDef` / `ixpExtractDef` set
5348
+ * `supportsErrorHandling: true`; Integration Service connector activities
5349
+ * declare the `error` handle).
5347
5350
  *
5348
- * Read as a list rather than off the bundled defs because three of these have no
5349
- * bundled def at all: their definitions are synthesized per call from the tenant.
5351
+ * Every family with a bundled definition is NOT listed: its answer comes from
5352
+ * that definition (`bundledActionNodeType` + `definitionHasErrorPort`), so a
5353
+ * family cannot drift from its definition again (#1011: `documentClassify` was
5354
+ * missing here although `uipath.document.classify@1.0` sets the flag).
5355
+ *
5356
+ * Not listed, deliberately: `publishedFunction` (its synthesized definition sets
5357
+ * the flag, but no run has measured a function failure routing; it stays
5358
+ * refused until one does) and `waitEvent` (an event wait resumes or does not).
5350
5359
  */
5351
- const ERROR_PORT_SPEC_KINDS = new Set([
5352
- 'http', 'script', 'transform', 'subflow', 'connector',
5353
- 'queueItem', 'rpaWorkflow', 'apiWorkflow', 'agenticProcess', 'agent', 'inlineAgent',
5354
- // The two AI patterns. Both definitions have always carried
5355
- // `supportsErrorHandling: true` — the bundled copies just did not declare the
5356
- // `error` HANDLE to go with it, so nothing here could have been read off them
5357
- // (fixed in the same card). Their failures are the ones most worth routing: the
5358
- // service refuses a file it cannot read, and the reason arrives in
5359
- // `err('<step>', 'detail')` verbatim — e.g. "No valid files to use for
5360
- // Summarization."
5361
- 'summarize', 'batchTransform',
5362
- // Document extraction. Every extractor's definition declares
5363
- // `supportsErrorHandling: true` and an `error` handle gated on
5364
- // `errorHandlingEnabled` — and its failures are the ones most worth routing
5365
- // (an unreadable document, or a classification with no match).
5366
- 'ixpExtract',
5360
+ const PER_TENANT_ERROR_PORT_KINDS = new Set([
5361
+ 'connector', 'rpaWorkflow', 'apiWorkflow', 'agenticProcess', 'agent', 'ixpExtract',
5367
5362
  ]);
5368
5363
  /** The five fields the platform's error envelope declares — no more, no less. */
5369
5364
  // The five the definitions declare, plus the two every probed runtime envelope
@@ -5428,11 +5423,23 @@ function checkOnError(_handler, step, diags) {
5428
5423
  return;
5429
5424
  }
5430
5425
  const spec = step.spec;
5431
- if (!ERROR_PORT_SPEC_KINDS.has(spec.kind)) {
5426
+ // A typed family with a bundled definition: ask the definition serialize will
5427
+ // emit, at the version it will emit (#1011). For instance `voiceAgent()`
5428
+ // defaults to uipath.agent.voice@1.0 (no error port) and `{ version: '1.1' }`
5429
+ // selects @1.1 (which has one).
5430
+ // A version the SDK does not bundle (an inline agent's registry version) has
5431
+ // no definition here to ask; version resolution reports that, not this check.
5432
+ const bundledType = bundledActionNodeType(spec);
5433
+ const bundledDef = bundledType ? bundledDefinition(bundledType, step.options?.version) : undefined;
5434
+ const noPort = bundledType
5435
+ ? bundledDef !== undefined && !definitionHasErrorPort(bundledDef)
5436
+ : !PER_TENANT_ERROR_PORT_KINDS.has(spec.kind);
5437
+ if (noPort) {
5438
+ const nodeType = bundledDef ? ` (${bundledDef.nodeType}@${bundledDef.version})` : '';
5432
5439
  diags.push({
5433
5440
  level: 'error',
5434
5441
  code: 'ONERROR_NO_ERROR_PORT',
5435
- message: `Step "${step.name}" is a ${spec.kind} step, and that node type has no error port — its definition does not `
5442
+ message: `Step "${step.name}" is a ${spec.kind} step${nodeType}, and that node type has no error port — its definition does not `
5436
5443
  + `set supportsErrorHandling, so the edge would leave a handle the node does not have. Handle the failure `
5437
5444
  + `downstream instead (a delay cannot fail; a wait resumes or does not).`,
5438
5445
  step: step.name,
@@ -96,7 +96,8 @@ export function connectorCheckOpts(library, bindings, inputErrors = (rc, inputs,
96
96
  },
97
97
  // The refusal compile throws for an operation it cannot resolve, with its
98
98
  // code and text: CONNECTOR_NOT_IN_LIBRARY, CONNECTOR_OBJECT_REQUIRED,
99
- // CONNECTOR_OBJECT_NOT_GENERIC.
99
+ // CONNECTOR_OBJECT_NOT_GENERIC, CONNECTOR_LIBRARY_ENTRY_UNREADABLE, or
100
+ // CONNECTOR_RESOLVE_FAILED for any other throw.
100
101
  connectorResolveError: (spec) => {
101
102
  const r = resolve(spec);
102
103
  return 'error' in r ? r.error : undefined;
@@ -114,11 +115,19 @@ export function connectorCheckOpts(library, bindings, inputErrors = (rc, inputs,
114
115
  ...(bindings ? { bindings } : {}),
115
116
  };
116
117
  }
118
+ /** `check`'s code for an untyped throw from `library.resolve`; see {@link connectorResolver}. */
119
+ const CONNECTOR_RESOLVE_FAILED = 'CONNECTOR_RESOLVE_FAILED';
117
120
  /**
118
121
  * `library.resolve` for one connector step, memoized per step for the life of
119
- * one check's options. A {@link ConnectorResolveError} is the refusal compile
120
- * throws and becomes `error`; anything else thrown is not a verdict about the
121
- * author's source and stays "unknown", as before.
122
+ * one check's options.
123
+ *
124
+ * This is the exact call `serialize` makes, so ANY throw here is a throw compile
125
+ * makes too, and becomes `error`. A {@link ConnectorResolveError} keeps its own
126
+ * code (CONNECTOR_NOT_IN_LIBRARY, CONNECTOR_LIBRARY_ENTRY_UNREADABLE, …).
127
+ * Anything else, which `library.resolve` does not throw on purpose, is reported
128
+ * as CONNECTOR_RESOLVE_FAILED with its message. Treating an untyped throw as
129
+ * "unknown" used to let `check` pass a step `compile` then died on (#1015); the
130
+ * event twin, `eventResolveErrorFor`, already reported every throw.
122
131
  */
123
132
  function connectorResolver(library) {
124
133
  const memo = new Map();
@@ -132,7 +141,7 @@ function connectorResolver(library) {
132
141
  catch (error) {
133
142
  r = error instanceof ConnectorResolveError
134
143
  ? { error: { code: error.code, message: error.message } }
135
- : { unknown: true };
144
+ : { error: { code: CONNECTOR_RESOLVE_FAILED, message: error instanceof Error ? error.message : String(error) } };
136
145
  }
137
146
  memo.set(id, r);
138
147
  }
@@ -22,4 +22,6 @@ export declare function definitionHasErrorPort(def: any): boolean;
22
22
  * The ONERROR_NO_ERROR_PORT sentence for a definition-backed node, naming its
23
23
  * node type. Shared with serialize, which throws it for the same node.
24
24
  */
25
- export declare function errorPortRefusal(stepName: string, def: any): string;
25
+ export declare function errorPortRefusal(stepName: string, def: any, o?: {
26
+ bundled?: boolean;
27
+ }): string;
@@ -28,9 +28,9 @@ export function definitionHasErrorPort(def) {
28
28
  * The ONERROR_NO_ERROR_PORT sentence for a definition-backed node, naming its
29
29
  * node type. Shared with serialize, which throws it for the same node.
30
30
  */
31
- export function errorPortRefusal(stepName, def) {
31
+ export function errorPortRefusal(stepName, def, o = {}) {
32
32
  return `Step "${stepName}" is a ${def?.nodeType}@${def?.version} node, and its definition has no error port: `
33
33
  + `it does not set supportsErrorHandling: true and declares no "error" source handle, so the edge would leave a `
34
- + `handle the node does not have. Handle the failure downstream instead, or pass the definition exactly as `
35
- + `\`uip maestro flow registry get\` returns it.`;
34
+ + `handle the node does not have. Handle the failure downstream instead`
35
+ + (o.bundled ? '.' : `, or pass the definition exactly as \`uip maestro flow registry get\` returns it.`);
36
36
  }
@@ -225,7 +225,12 @@ export type ConnectorResolveCode =
225
225
  /** A GENERIC operation (one entry per object) named without an `object`. */
226
226
  | 'CONNECTOR_OBJECT_REQUIRED'
227
227
  /** An `object` on a single, non-generic operation. */
228
- | 'CONNECTOR_OBJECT_NOT_GENERIC';
228
+ | 'CONNECTOR_OBJECT_NOT_GENERIC'
229
+ /**
230
+ * The index lists the operation, but its entry file or `.v1def.json` sidecar is
231
+ * missing or not valid JSON: the library on disk is incomplete (#1015).
232
+ */
233
+ | 'CONNECTOR_LIBRARY_ENTRY_UNREADABLE';
229
234
  /**
230
235
  * The refusal {@link Library.resolve} throws, with a `code` for each reason.
231
236
  *
@@ -827,8 +827,13 @@ export class Library {
827
827
  }
828
828
  build(dir, e, nodeType, opts = {}) {
829
829
  const entryPath = join(dir, e.path);
830
- const entry = JSON.parse(readFileSync(entryPath, 'utf8'));
831
- const v1def = readV1def(entryPath);
830
+ // The two files the index row promises. A missing or corrupt one is a fault in
831
+ // the library on disk, not in the author's source, but compile cannot go on
832
+ // without it, so it is a typed refusal like the others: `check` reports it with
833
+ // the same code and text instead of passing a step compile then dies on with a
834
+ // bare ENOENT (#1015).
835
+ const entry = readLibraryFile(nodeType, entryPath, () => JSON.parse(readFileSync(entryPath, 'utf8')));
836
+ const v1def = readLibraryFile(nodeType, v1defPathOf(entryPath), () => readV1def(entryPath));
832
837
  // A stamped object (case 4) reaches here with the index entry's `objectName`
833
838
  // replaced but the sibling's FILE on disk — so restate the object and derive
834
839
  // the endpoint from the sibling's own template, rather than shipping a node
@@ -944,6 +949,33 @@ function deriveObjectPath(operation, objectName) {
944
949
  }
945
950
  return out;
946
951
  }
952
+ /** The `.v1def.json` sidecar path beside a library entry file. */
953
+ function v1defPathOf(entryPath) {
954
+ return entryPath.replace(/\.json$/, '.v1def.json');
955
+ }
956
+ /**
957
+ * Read one file an index row points at, turning a missing or unparsable file
958
+ * into {@link ConnectorResolveError} `CONNECTOR_LIBRARY_ENTRY_UNREADABLE`.
959
+ *
960
+ * The library build refuses to write an entry without its sidecar
961
+ * (`registry/library-build/plan.ts`), so this only fires for a library that was
962
+ * damaged after it was built: an interrupted pull, a hand-edited overlay. The
963
+ * remedy is the same either way: rebuild the layer the file belongs to.
964
+ */
965
+ function readLibraryFile(nodeType, path, read) {
966
+ try {
967
+ return read();
968
+ }
969
+ catch (error) {
970
+ const message = error instanceof Error ? error.message : String(error);
971
+ // ENOENT already names the path; a JSON SyntaxError does not.
972
+ const reason = message.includes(path) ? message : `${path}: ${message}`;
973
+ throw new ConnectorResolveError('CONNECTOR_LIBRARY_ENTRY_UNREADABLE', `connector library entry for ${nodeType} is unreadable: ${reason}. The library index lists `
974
+ + `this operation, but the file is missing or not valid JSON, so the library on disk is incomplete. `
975
+ + `Refresh it with \`${PULL_COMMAND}\`; if the file is in the \`connectors-local\` overlay, `
976
+ + `re-run the \`${prepareCommand()}\` that wrote it.`);
977
+ }
978
+ }
947
979
  /**
948
980
  * Read the `.v1def.json` sidecar beside a library entry file, with a connection
949
981
  * definition's `model.bindings.resource` in the designer's canonical casing.
@@ -961,7 +993,7 @@ function deriveObjectPath(operation, objectName) {
961
993
  * validate and debug — which fold the case — passed.
962
994
  */
963
995
  function readV1def(entryPath) {
964
- const raw = JSON.parse(readFileSync(entryPath.replace(/\.json$/, '.v1def.json'), 'utf8'));
996
+ const raw = JSON.parse(readFileSync(v1defPathOf(entryPath), 'utf8'));
965
997
  const v1def = Array.isArray(raw) ? raw[0] : raw;
966
998
  const bindings = v1def?.model?.bindings;
967
999
  if (typeof bindings?.resource === 'string' && bindings.resource.toLowerCase() === 'connection') {
@@ -88,6 +88,30 @@ export declare function serializeWithSidecars(built: BuiltFlow, opts?: Serialize
88
88
  json: unknown;
89
89
  }>;
90
90
  };
91
+ /**
92
+ * The node type a typed action compiles to, when that type's definition is
93
+ * bundled in `core-definitions.json`. `undefined` for a family whose definition
94
+ * is built per tenant or per call (connector, rpaWorkflow, apiWorkflow,
95
+ * agenticProcess, publishedFunction, agent, ixpExtract) and for a spec this SDK
96
+ * does not lower by kind.
97
+ *
98
+ * The http / transform / delay / script emit path reads its type from here too,
99
+ * so the answer `check` gets is the type `serialize` writes.
100
+ */
101
+ export declare function bundledActionNodeType(spec: {
102
+ kind?: string;
103
+ inputs?: any;
104
+ } | undefined): string | undefined;
105
+ /**
106
+ * The bundled definition of `nodeType` that `makeNode` resolves: the author's
107
+ * exact `{ version }` when given, otherwise the pinned default (the first
108
+ * bundled entry). `undefined` when the SDK does not ship that type or version.
109
+ *
110
+ * For instance, `uipath.agent.voice` resolves to `@1.0` by default (no
111
+ * `supportsErrorHandling`) and to `@1.1` with `{ version: '1.1' }` (which sets
112
+ * it), so the error-port answer depends on the version.
113
+ */
114
+ export declare function bundledDefinition(nodeType: string, requestedVersion?: string): any | undefined;
91
115
  /**
92
116
  * Resolve a contribution's {@link DefinitionReference} to a concrete manifest —
93
117
  * exactly (design §2.6/§4.2): the named version resolves or compilation fails,
package/dist/serialize.js CHANGED
@@ -651,8 +651,12 @@ const INLINE_AGENT_TYPE = 'uipath.agent.autonomous';
651
651
  * - **61 deployed, debug-green agent instances** across 61 dated
652
652
  * `skill-flow-{coded,lowcode}-agent` artifacts (05-18 → 07-29): `sortOrder: 505`
653
653
  * in 61/61, the `<folderPath>.<name>` resourceKey in 58/61 (the 3 exceptions are
654
- * the in-solution shape — a bare project GUID and an EMPTY folderPath — which
655
- * 404s at job start, so they are not a second convention), and the descriptor
654
+ * the in-solution shape — a bare key and an EMPTY folderPath — which 404'd at
655
+ * job start in those runs; that is the shape of `location: 'in-solution'`,
656
+ * built by `processResourceLocation`, and it starts the job when the sibling is
657
+ * in the solution: 54 v1 `skill-flow-coded-agent` runs, 09-01 → 10-08, carry
658
+ * `isInSolution: true`, 45 score 1.0 and none of the other 9 fails on a
659
+ * job-start 404, #1012), and the descriptor
656
660
  * ARRAY `bindings.values` in 59/61 (2 early runs used the object form);
657
661
  * - flow-v1's own generator, which is where those come from:
658
662
  * `node-manifest-builder.ts::createModel` hard-codes `bpmn:ServiceTask` for every
@@ -676,9 +680,11 @@ const INLINE_AGENT_TYPE = 'uipath.agent.autonomous';
676
680
  * `display.icon` — which is why one factory serves both.
677
681
  */
678
682
  function agentDef(spec) {
679
- const inSolution = spec.location === 'in-solution';
680
- const folderPath = inSolution ? '' : (spec.folderPath ?? '');
681
- const resourceKey = inSolution ? spec.key : `${folderPath}.${spec.name}`;
683
+ // One location slot with the other process resources: the in-solution
684
+ // model carries `projectId`, `projectName` AND `isInSolution: true`, as
685
+ // flow-core's `createModel` writes for every sibling-project resource.
686
+ const loc = processResourceLocation(spec);
687
+ const { inSolution, resourceKey } = loc;
682
688
  const properties = {};
683
689
  for (const [k, v] of Object.entries(spec.inputs)) {
684
690
  properties[k] = { type: typeof v === 'number' ? 'number' : typeof v === 'boolean' ? 'boolean' : 'string' };
@@ -688,8 +694,8 @@ function agentDef(spec) {
688
694
  version: '1.0.0',
689
695
  category: 'agent',
690
696
  runtimeConstraints: { exclude: ['api-function'] },
691
- description: inSolution ? `(In-solution) ${spec.name}` : `(${folderPath})`,
692
- tags: inSolution ? ['in-solution', 'local'] : [],
697
+ description: loc.description,
698
+ tags: loc.tags,
693
699
  sortOrder: 505,
694
700
  supportsErrorHandling: true,
695
701
  display: {
@@ -700,19 +706,12 @@ function agentDef(spec) {
700
706
  { position: 'left', handles: [{ id: 'input', type: 'target', handleType: 'input' }] },
701
707
  { position: 'right', handles: [{ id: 'output', type: 'source', handleType: 'output' }] },
702
708
  ],
703
- ...(inSolution
704
- ? {
705
- toolbarExtensions: {
706
- design: { actions: [{ id: 'open-workflow', icon: 'external-link', label: 'Open' }] },
707
- },
708
- projectId: spec.projectId,
709
- }
710
- : {}),
709
+ ...loc.definitionExtras,
711
710
  model: {
712
711
  type: 'bpmn:ServiceTask',
713
712
  serviceType: 'Orchestrator.StartAgentJob',
714
713
  version: 'v2',
715
- ...(!inSolution ? { section: 'Published' } : {}),
714
+ ...(inSolution ? {} : { section: 'Published' }),
716
715
  bindings: {
717
716
  resource: 'process',
718
717
  resourceSubType: 'Agent',
@@ -720,10 +719,10 @@ function agentDef(spec) {
720
719
  orchestratorType: 'agent',
721
720
  values: [
722
721
  { name: 'name', propertyAttribute: 'name', default: spec.name },
723
- { name: 'folderPath', propertyAttribute: 'folderPath', default: folderPath },
722
+ { name: 'folderPath', propertyAttribute: 'folderPath', default: loc.folderPath },
724
723
  ],
725
724
  },
726
- ...(inSolution ? { projectId: spec.projectId, projectName: spec.name } : {}),
725
+ ...loc.modelExtras,
727
726
  context: [
728
727
  { name: 'name', type: 'string', value: '<bindings.name>' },
729
728
  { name: 'folderPath', type: 'string', value: '<bindings.folderPath>' },
@@ -3924,6 +3923,58 @@ function describeDeclared(bindings) {
3924
3923
  return ' (no bindings.json was loaded)';
3925
3924
  return names.length ? ` (bindings.json declares: ${names.join(', ')})` : ' (bindings.json declares no entries)';
3926
3925
  }
3926
+ /**
3927
+ * The node type a typed action compiles to, when that type's definition is
3928
+ * bundled in `core-definitions.json`. `undefined` for a family whose definition
3929
+ * is built per tenant or per call (connector, rpaWorkflow, apiWorkflow,
3930
+ * agenticProcess, publishedFunction, agent, ixpExtract) and for a spec this SDK
3931
+ * does not lower by kind.
3932
+ *
3933
+ * The http / transform / delay / script emit path reads its type from here too,
3934
+ * so the answer `check` gets is the type `serialize` writes.
3935
+ */
3936
+ export function bundledActionNodeType(spec) {
3937
+ switch (spec?.kind) {
3938
+ case 'http': return spec.inputs?.managed ? NODE_TYPE.httpV2 : NODE_TYPE.http;
3939
+ case 'transform': return transformNodeType(spec.inputs);
3940
+ case 'hitl': return hitlNodeType(spec.inputs);
3941
+ case 'queueItem': return spec.inputs?.wait ? NODE_TYPE.queueCreateAndWait : NODE_TYPE.queueCreate;
3942
+ case 'inlineAgent': return INLINE_AGENT_TYPE;
3943
+ case 'delay':
3944
+ case 'script':
3945
+ case 'mock':
3946
+ case 'subflow':
3947
+ case 'summarize':
3948
+ case 'batchTransform':
3949
+ case 'documentClassify':
3950
+ case 'dynamicExtract':
3951
+ case 'dataFabricRead':
3952
+ case 'dataFabricCreate':
3953
+ case 'dataFabricUpdate':
3954
+ case 'dataFabricDelete':
3955
+ case 'sendMessage':
3956
+ case 'waitForMessage':
3957
+ case 'conversationContext':
3958
+ case 'createOutgoingCall':
3959
+ case 'endCall':
3960
+ case 'voiceAgent':
3961
+ case 'conversationalAgent':
3962
+ return NODE_TYPE[spec.kind];
3963
+ default: return undefined;
3964
+ }
3965
+ }
3966
+ /**
3967
+ * The bundled definition of `nodeType` that `makeNode` resolves: the author's
3968
+ * exact `{ version }` when given, otherwise the pinned default (the first
3969
+ * bundled entry). `undefined` when the SDK does not ship that type or version.
3970
+ *
3971
+ * For instance, `uipath.agent.voice` resolves to `@1.0` by default (no
3972
+ * `supportsErrorHandling`) and to `@1.1` with `{ version: '1.1' }` (which sets
3973
+ * it), so the error-port answer depends on the version.
3974
+ */
3975
+ export function bundledDefinition(nodeType, requestedVersion) {
3976
+ return requestedVersion !== undefined ? DEFS[`${nodeType}@${requestedVersion}`] : defByType.get(nodeType);
3977
+ }
3927
3978
  /**
3928
3979
  * Resolve a contribution's {@link DefinitionReference} to a concrete manifest —
3929
3980
  * exactly (design §2.6/§4.2): the named version resolves or compilation fails,
@@ -4687,11 +4738,24 @@ export function serialize(built, opts = {}) {
4687
4738
  * families are not recorded: their definitions are the SDK's own.
4688
4739
  */
4689
4740
  const contributionDefs = new Map();
4690
- /** Refuse an `error` edge from a contribution-lowered node whose definition has no error port. */
4741
+ /**
4742
+ * The bundled definition of every node `makeNode` resolved from
4743
+ * `core-definitions.json` (no definition passed in), by node id (#1011). A
4744
+ * definition built per tenant or per call (connector, rpa, queue, ixp) is not
4745
+ * recorded: `check` answers for those from its per-tenant kind list.
4746
+ */
4747
+ const bundledNodeDefs = new Map();
4748
+ /**
4749
+ * Refuse an `error` edge from a node whose definition has no error port: a
4750
+ * contribution-lowered node (#943) or a typed node with a bundled definition
4751
+ * (#1011). Same predicate as `check`, so `compile --no-check` agrees with it.
4752
+ */
4691
4753
  function refuseErrorEdgeWithoutPort(nodeId, stepName) {
4692
- const def = contributionDefs.get(nodeId);
4693
- if (def !== undefined && !definitionHasErrorPort(def))
4694
- throw new Error(errorPortRefusal(stepName, def));
4754
+ const contributed = contributionDefs.get(nodeId);
4755
+ const def = contributed ?? bundledNodeDefs.get(nodeId);
4756
+ if (def !== undefined && !definitionHasErrorPort(def)) {
4757
+ throw new Error(errorPortRefusal(stepName, def, { bundled: contributed === undefined }));
4758
+ }
4695
4759
  }
4696
4760
  /**
4697
4761
  * Hoist a contribution's own bindings, then close every `<bindings.NAME>` its
@@ -4859,6 +4923,8 @@ export function serialize(built, opts = {}) {
4859
4923
  }
4860
4924
  if (def)
4861
4925
  emittedDefs.set(`${type}@${def.version}`, def);
4926
+ if (def && !o.def)
4927
+ bundledNodeDefs.set(id, def);
4862
4928
  const node = {
4863
4929
  id,
4864
4930
  type,
@@ -5265,17 +5331,14 @@ export function serialize(built, opts = {}) {
5265
5331
  // `AgentInputs.inputs`) and because the emitted binding subtype is `Agent`.
5266
5332
  const s = spec.inputs;
5267
5333
  const inSolution = s.location === 'in-solution';
5268
- const folderPath = inSolution ? '' : (s.folderPath ?? '');
5269
5334
  const def = agentDef({
5270
- key: s.key, name: s.name, folderPath, location: s.location, projectId: s.projectId,
5335
+ key: s.key, name: s.name, folderPath: s.folderPath, location: s.location, projectId: s.projectId,
5271
5336
  inputs: s.inputs, returns: s.returns, flavour: s.flavour,
5272
5337
  });
5273
- const { entries } = processResourceBindings({
5274
- name: s.name,
5275
- folderPath,
5276
- resourceSubType: 'Agent',
5277
- ...(inSolution ? { resourceKey: s.key } : {}),
5278
- }, resourceBindings);
5338
+ // The pair's key and folder come off the definition, as for rpa / agentic
5339
+ // steps: one place decides the in-solution shape.
5340
+ const pairFolder = def.model.bindings.values.find((v) => v.name === 'folderPath').default;
5341
+ const { entries } = processResourceBindings({ name: s.name, folderPath: pairFolder, resourceSubType: 'Agent', resourceKey: def.model.bindings.resourceKey }, resourceBindings);
5279
5342
  for (const b of entries)
5280
5343
  resourceBindings.set(b.id, b);
5281
5344
  const id = stepUid(scope, step.name);
@@ -6428,10 +6491,7 @@ export function serialize(built, opts = {}) {
6428
6491
  if (!['http', 'transform', 'delay', 'script'].includes(spec.kind)) {
6429
6492
  throw new Error(`step "${step.name}": unknown action kind "${spec.kind}".`);
6430
6493
  }
6431
- const type = spec.kind === 'http' ? (spec.inputs.managed ? NODE_TYPE.httpV2 : NODE_TYPE.http)
6432
- : spec.kind === 'transform' ? transformNodeType(spec.inputs)
6433
- : spec.kind === 'delay' ? NODE_TYPE.delay
6434
- : NODE_TYPE.script;
6494
+ const type = bundledActionNodeType(spec);
6435
6495
  const id = stepUid(scope, step.name);
6436
6496
  const node = makeNode(type, id, step.name, { parentId, requestedVersion: step.options?.version });
6437
6497
  // Record the failure-envelope boundary BEFORE any expression is rendered, so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.17.3",
3
+ "version": "6.17.5",
4
4
  "description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.uipath.com/maestro",
@@ -92,5 +92,5 @@
92
92
  "@types/node": "^22.7.0",
93
93
  "esbuild": "^0.28.1"
94
94
  },
95
- "gitref": "8da4aeeb1592a342b2ac705939e646cd77baa891"
95
+ "gitref": "5c050c27fe72360970e28b811ad581442140544f"
96
96
  }