@uipath/maestro-builder-sdk 6.17.4 → 6.17.6

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,
@@ -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
  }
package/dist/decompile.js CHANGED
@@ -1959,45 +1959,44 @@ function emitVariables(e, depth, flow, imp, epTriggers = new Set(), shared) {
1959
1959
  }
1960
1960
  }
1961
1961
  // ─── Trigger ──────────────────────────────────────────────────────────────────
1962
+ /**
1963
+ * The trigger factory call for a root trigger node, or `undefined` for a type
1964
+ * this file cannot read back. Both the default root (`.trigger(...)`) and every
1965
+ * extra root (`.entryPoint(id, ...)`) read it.
1966
+ */
1967
+ function triggerFactory(t, imp, inputNames) {
1968
+ // Decompiled source spells the default `manual()` out on purpose: it is more
1969
+ // explicit than hand-authored source so the node's exact definition version
1970
+ // survives recompilation (design §5.3).
1971
+ if (t.type === T.triggerManual)
1972
+ return `${imp.use('manual')}()`;
1973
+ if (t.type === T.triggerScheduled)
1974
+ return `${imp.use('scheduled')}(${opts([['every', str(scheduleEvery(t))]])})`;
1975
+ // The form schema is DERIVED from the root's inputs at compile time, so
1976
+ // nothing of it needs recovering — the factory takes no arguments.
1977
+ if (t.type === T.triggerForm)
1978
+ return `${imp.use('formTrigger')}()`;
1979
+ if (t.type === T.triggerConversation)
1980
+ return `${imp.use('conversationTrigger')}()`;
1981
+ if (t.type === T.triggerVoice)
1982
+ return `${imp.use('voiceTrigger')}()`;
1983
+ // A connector EVENT trigger — the same subscription body as a mid-flow wait.
1984
+ const sub = emitEventSubscription(t, imp, inputNames);
1985
+ if (sub !== undefined)
1986
+ return `${imp.use('onEvent')}(${sub})`;
1987
+ return undefined;
1988
+ }
1962
1989
  function emitTrigger(e, depth, trigger, imp, o, inputNames = new Set()) {
1963
1990
  // The trigger's id is addressable — a flow's inputs are published as its
1964
1991
  // output — so a renamed one has to survive the round trip. `start` is the
1965
1992
  // default and stays implicit.
1966
1993
  if (trigger.id && trigger.id !== DEFAULT_TRIGGER_ID)
1967
1994
  e.line(depth, `.triggerId(${str(trigger.id)})`);
1968
- if (trigger.type === T.triggerManual) {
1969
- // The default trigger, spelled out: decompiled source is deliberately more
1970
- // explicit than hand-authored source so the node's exact definition version
1971
- // survives recompilation (design §5.3).
1972
- e.line(depth, `.trigger(${imp.use('manual')}()${triggerOptsArg(trigger)})`);
1973
- return;
1974
- }
1975
- if (trigger.type === T.triggerScheduled) {
1976
- e.line(depth, `.trigger(${imp.use('scheduled')}(${opts([['every', str(scheduleEvery(trigger))]])})${triggerOptsArg(trigger)})`);
1977
- return;
1978
- }
1979
- if (trigger.type === T.triggerForm) {
1980
- // The schema is DERIVED from the flow's inputs at compile time, so nothing
1981
- // of it needs recovering — the factory takes no arguments.
1982
- e.line(depth, `.trigger(${imp.use('formTrigger')}()${triggerOptsArg(trigger)})`);
1995
+ const factory = triggerFactory(trigger, imp, inputNames);
1996
+ if (factory !== undefined) {
1997
+ e.line(depth, `.trigger(${factory}${triggerOptsArg(trigger)})`);
1983
1998
  return;
1984
1999
  }
1985
- if (trigger.type === T.triggerConversation) {
1986
- e.line(depth, `.trigger(${imp.use('conversationTrigger')}()${triggerOptsArg(trigger)})`);
1987
- return;
1988
- }
1989
- if (trigger.type === T.triggerVoice) {
1990
- e.line(depth, `.trigger(${imp.use('voiceTrigger')}()${triggerOptsArg(trigger)})`);
1991
- return;
1992
- }
1993
- // A connector EVENT trigger — the same subscription body as a mid-flow wait.
1994
- {
1995
- const sub = emitEventSubscription(trigger, imp, inputNames);
1996
- if (sub !== undefined) {
1997
- e.line(depth, `.trigger(${imp.use('onEvent')}(${sub})${triggerOptsArg(trigger)})`);
1998
- return;
1999
- }
2000
- }
2001
2000
  if (o.bestEffort === false) {
2002
2001
  throw new Error(`decompile: unsupported trigger type "${trigger.type}".`);
2003
2002
  }
@@ -2930,21 +2929,11 @@ function scheduleEvery(t) {
2930
2929
  }
2931
2930
  /** One `.entryPoint(id, trigger, { inputs, version }, prefix)` segment for a non-default root. */
2932
2931
  function entryPointSeg(t, scope, ipdom, ctx) {
2933
- const factory = t.type === T.triggerScheduled
2934
- ? `${ctx.imp.use('scheduled')}(${opts([['every', str(scheduleEvery(t))]])})`
2935
- : t.type === T.triggerForm
2936
- ? `${ctx.imp.use('formTrigger')}()`
2937
- : t.type === T.triggerConversation
2938
- ? `${ctx.imp.use('conversationTrigger')}()`
2939
- : t.type === T.triggerVoice
2940
- ? `${ctx.imp.use('voiceTrigger')}()`
2941
- : t.type === T.triggerManual
2942
- ? `${ctx.imp.use('manual')}()`
2943
- : (() => {
2944
- if (ctx.o.bestEffort === false)
2945
- throw new Error(`decompile: unsupported entry-point trigger type "${t.type}".`);
2946
- return `${ctx.imp.use('manual')}() /* TODO: unsupported trigger type ${commentText(t.type)} */`;
2947
- })();
2932
+ const known = triggerFactory(t, ctx.imp, ctx.inputNames);
2933
+ if (known === undefined && ctx.o.bestEffort === false) {
2934
+ throw new Error(`decompile: unsupported entry-point trigger type "${t.type}".`);
2935
+ }
2936
+ const factory = known ?? `${ctx.imp.use('manual')}() /* TODO: unsupported trigger type ${commentText(t.type)} */`;
2948
2937
  const scoped = readFlowGlobals(ctx.flow.variables, runStrict)
2949
2938
  .filter((g) => g.direction === 'in' && g.triggerNodeId === t.id);
2950
2939
  const optParts = [];
@@ -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.4",
3
+ "version": "6.17.6",
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": "6a0dfa03e18d92bd2452c96704c1c80fa122fc11"
95
+ "gitref": "ff4d7f22f587af64ccdf9c28c70572e7bab2852a"
96
96
  }