@uipath/maestro-builder-sdk 6.63.0 → 6.65.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 +22 -21
- package/dist/api-members.md +82 -81
- package/dist/case/case-expr-check.d.ts +2 -1
- package/dist/case/case-expr-check.js +4 -2
- package/dist/case/case-sdk.js +11 -10
- package/dist/case/load.js +4 -3
- package/dist/case/serialize.js +52 -50
- package/dist/cli/commands/flow.js +4 -2
- package/dist/compile-cli.js +55 -45
- package/dist/core/event-filters.d.ts +20 -0
- package/dist/core/event-filters.js +27 -0
- package/dist/core/refusals.d.ts +88 -1
- package/dist/core/refusals.js +94 -7
- package/dist/decompile-cli.js +2 -2
- package/dist/decompile.js +36 -11
- package/dist/flow-node-type.d.ts +9 -0
- package/dist/flow-sdk.d.ts +24 -3
- package/dist/flow-sdk.js +1 -1
- package/dist/nodes/agent/flow/check.js +4 -4
- package/dist/nodes/connector/flow/node-type.js +36 -1
- package/dist/serialize.d.ts +24 -0
- package/dist/serialize.js +114 -4
- package/package.json +2 -2
|
@@ -340,15 +340,15 @@ export function checkInlineAgent(inputs, ctx) {
|
|
|
340
340
|
//
|
|
341
341
|
// An artifact that compiles and can never validate is the worst of the two
|
|
342
342
|
// failures, so this is said here — before the emit — rather than left to a rung.
|
|
343
|
-
// It is an ERROR because there is no spelling that works today
|
|
344
|
-
//
|
|
343
|
+
// It is an ERROR because there is no spelling that works today. `compile` does
|
|
344
|
+
// not run check, so a tenant whose manifest does declare the handle still compiles it.
|
|
345
345
|
if (inputs?.memory !== undefined) {
|
|
346
346
|
at('AGENT_MEMORY_NOT_AUTHORABLE', `Inline agent step "${step}" attaches \`memory\`, which the platform cannot resolve: the tenant's `
|
|
347
347
|
+ `\`uipath.agent.autonomous\` manifest declares no \`memory\` handle (only escalation, context, tool, `
|
|
348
348
|
+ `success, error) and the registry serves no \`uipath.agent.resource.memory.*\` node type. The flow `
|
|
349
349
|
+ `compiles and then fails \`uip maestro flow validate\` as RetryWillNotFix. Drop \`memory\`; for `
|
|
350
350
|
+ `retrieval over a knowledge source use a context index instead (\`tools\`/context grounding). `
|
|
351
|
-
+ `
|
|
351
|
+
+ `On a tenant whose manifest does declare the handle, ignore this finding: \`compile\` does not run check.`);
|
|
352
352
|
}
|
|
353
353
|
// A context `query` is what the RUNTIME searches with, and it is not an
|
|
354
354
|
// expression slot. A plain string is the model-invoked `dynamic` variant: the
|
|
@@ -468,7 +468,7 @@ export function checkInlineAgent(inputs, ctx) {
|
|
|
468
468
|
+ `of the prompt) with one line per field, in the platform's own wording: "${rewrite}" Declare a field \`'object'\` or `
|
|
469
469
|
+ `\`'array'\` if it should carry structure. \`uip maestro flow validate\` accepts this prompt, so `
|
|
470
470
|
+ `nothing later catches it. If this is a false positive (the prompt only mentions JSON as data), `
|
|
471
|
-
+ `compile
|
|
471
|
+
+ `ignore this finding: \`compile\` does not run check.`);
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
474
|
// The prompts-vs-variables agreement, in both directions. Both prompts are
|
|
@@ -270,6 +270,40 @@ function liftConnector(node, ctx) {
|
|
|
270
270
|
missing,
|
|
271
271
|
};
|
|
272
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Whether a connector operation node is a draft the canvas saved, by what the
|
|
275
|
+
* file itself shows: no connection or folder (`BINDING_MISSING`), or a field its
|
|
276
|
+
* own definition marks `required` that the node gives no value
|
|
277
|
+
* (`CONNECTOR_INPUT_MISSING`). For instance a Slack send saved before a
|
|
278
|
+
* connection was picked has `detail.connectionId: null`. An operation with no
|
|
279
|
+
* object picked is not one: `compile` can only stand in for it, so it is never
|
|
280
|
+
* written either way.
|
|
281
|
+
*/
|
|
282
|
+
function isConnectorDraft(node, definition) {
|
|
283
|
+
const detail = (node.inputs?.detail ?? {});
|
|
284
|
+
const label = (v) => (typeof v === 'string' ? v : undefined);
|
|
285
|
+
if (missingBindingLabels({ connection: label(detail.connectionId), folder: label(detail.connectionFolderKey) }).length > 0)
|
|
286
|
+
return true;
|
|
287
|
+
const fields = definition?.inputDefinition?.fields;
|
|
288
|
+
if (!Array.isArray(fields))
|
|
289
|
+
return false;
|
|
290
|
+
const slots = ['bodyParameters', 'queryParameters', 'pathParameters']
|
|
291
|
+
.map((slot) => detail[slot])
|
|
292
|
+
.filter((m) => !!m && typeof m === 'object' && !Array.isArray(m));
|
|
293
|
+
const parts = Array.isArray(detail.multipartParameters) ? detail.multipartParameters : [];
|
|
294
|
+
const given = (name) => parts.some((p) => p?.name === name) || slots.some((m) => {
|
|
295
|
+
if (Object.prototype.hasOwnProperty.call(m, name))
|
|
296
|
+
return true;
|
|
297
|
+
let at = m;
|
|
298
|
+
for (const seg of name.split('.')) {
|
|
299
|
+
if (!at || typeof at !== 'object' || !Object.prototype.hasOwnProperty.call(at, seg))
|
|
300
|
+
return false;
|
|
301
|
+
at = at[seg];
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
});
|
|
305
|
+
return fields.some((f) => f?.required === true && typeof f.name === 'string' && !given(f.name));
|
|
306
|
+
}
|
|
273
307
|
function printConnector(l, ctx) {
|
|
274
308
|
// A present input whose value is `undefined` (the inputs check accepts one, and
|
|
275
309
|
// serialize keeps it in memory) prints as `undefined`, as it did before the port.
|
|
@@ -284,7 +318,7 @@ function printConnector(l, ctx) {
|
|
|
284
318
|
['object', optional(l.object)],
|
|
285
319
|
],
|
|
286
320
|
...(l.missing.length > 0
|
|
287
|
-
? { comment: `TODO: bind ${l.missing.join(' and ')};
|
|
321
|
+
? { comment: `TODO: bind ${l.missing.join(' and ')}; check refuses this node until it has both labels (BINDING_MISSING)` }
|
|
288
322
|
: {}),
|
|
289
323
|
};
|
|
290
324
|
}
|
|
@@ -302,6 +336,7 @@ const connector10 = {
|
|
|
302
336
|
},
|
|
303
337
|
serialize: (spec, ctx) => serializeConnector(spec, ctx),
|
|
304
338
|
deserialize: (node, ctx) => liftConnector(node, ctx),
|
|
339
|
+
isDraft: (node, definition) => isConnectorDraft(node, definition),
|
|
305
340
|
print: (spec, ctx) => printConnector(spec, ctx),
|
|
306
341
|
check: (spec, ctx) => ctx.connector(spec),
|
|
307
342
|
// Every Expr in the inputs, nested ones included, resolves against the flow's names.
|
package/dist/serialize.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export type DraftCode = BindingRefusalCode | typeof CONNECTOR_INPUT_MISSING | 'C
|
|
|
29
29
|
export interface DraftFinding {
|
|
30
30
|
/** The emitted node's id. */
|
|
31
31
|
nodeId: string;
|
|
32
|
+
/** The step whose node it is. Set by a carried-drafts compile ({@link SerializeOpts.carriedDrafts}). */
|
|
33
|
+
step?: string;
|
|
32
34
|
/** A {@link DraftCode}, or a node-type package's own code reported through `ctx.draft`. */
|
|
33
35
|
code: DraftCode | string;
|
|
34
36
|
/** The sentence the strict compile refuses with. */
|
|
@@ -71,6 +73,28 @@ export interface SerializeOpts {
|
|
|
71
73
|
* ordinary compile), behaviour is unchanged.
|
|
72
74
|
*/
|
|
73
75
|
draft?: (finding: DraftFinding) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Carried drafts, for `compile` (docs/CHECK_COMPILE_CONTRACT_DESIGN.md D2).
|
|
78
|
+
*
|
|
79
|
+
* A step marked `{ draft: true }` ({@link StepOptions.draft}) that the
|
|
80
|
+
* ordinary compile refuses only for draft findings ({@link DraftCode}: a
|
|
81
|
+
* connector with no connection, an empty required input) is written anyway
|
|
82
|
+
* when the flow CARRIES the definition of the node it emits
|
|
83
|
+
* (`.definitions([...])`). Decompile sets both for a canvas draft node. The
|
|
84
|
+
* node is written with that definition and the inputs it has, and each
|
|
85
|
+
* finding is reported here. A draft with no flag, or no carried definition,
|
|
86
|
+
* or one the node type can only stand in for (a generic operation with no
|
|
87
|
+
* object), is refused exactly as without this option. So is any other
|
|
88
|
+
* refusal. A flow with no draft compiles byte for byte as without it.
|
|
89
|
+
*
|
|
90
|
+
* For instance, a decompiled canvas flow whose Slack send has no `messageToSend`
|
|
91
|
+
* compiles with a `CONNECTOR_INPUT_MISSING` finding here, and a second Slack
|
|
92
|
+
* send written by hand with no `messageToSend` (no flag) is refused, though
|
|
93
|
+
* the flow carries the definition of that operation.
|
|
94
|
+
*
|
|
95
|
+
* Ignored when {@link draft} is given (merge's compile tolerates every draft).
|
|
96
|
+
*/
|
|
97
|
+
carriedDrafts?: (finding: DraftFinding) => void;
|
|
74
98
|
/**
|
|
75
99
|
* Collect mode, for `check` (docs/CHECK_COMPILE_CONTRACT_DESIGN.md §3.5).
|
|
76
100
|
*
|
package/dist/serialize.js
CHANGED
|
@@ -2542,6 +2542,76 @@ function serializeFlow(built, opts) {
|
|
|
2542
2542
|
}
|
|
2543
2543
|
return [{ node: id, port }];
|
|
2544
2544
|
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Run a node type's `serialize`, and in a carried-drafts compile
|
|
2547
|
+
* ({@link SerializeOpts.carriedDrafts}) try a refused `{ draft: true }` step
|
|
2548
|
+
* once more as a draft. The ordinary emission runs first, so a flow with no draft compiles
|
|
2549
|
+
* exactly as it would without the option. When it throws a refusal and the flow
|
|
2550
|
+
* carries any definition, what that emission bound is undone and the node is
|
|
2551
|
+
* emitted again with `drafting` on. That second contribution is returned with
|
|
2552
|
+
* the first refusal as `strict` when it reported a draft finding; the caller
|
|
2553
|
+
* writes it only with a carried definition, and throws `strict` otherwise. A
|
|
2554
|
+
* second emission that throws, or reports no finding, ends in `strict` too, so
|
|
2555
|
+
* a refusal that is not a draft reads as it always has.
|
|
2556
|
+
*/
|
|
2557
|
+
function serializeCarriedDraft(impl, spec, ctx, scope, id, bound, stepOptions, findings, enableDrafting, warnings) {
|
|
2558
|
+
if (!opts.carriedDrafts || opts.draft || opts.collect || carriedDefs.size === 0 || stepOptions?.draft !== true) {
|
|
2559
|
+
return { contribution: impl.serialize(spec, ctx) };
|
|
2560
|
+
}
|
|
2561
|
+
const mark = {
|
|
2562
|
+
resources: new Set(resourceBindings.keys()), sidecars: sidecars.length,
|
|
2563
|
+
agentSchemas: scope.agentSchemas.length, unbound: unboundDrafts.has(id),
|
|
2564
|
+
};
|
|
2565
|
+
// Each emission's warnings are held, so a node emitted twice reports only
|
|
2566
|
+
// the warnings of the emission that is kept (or of the refused one).
|
|
2567
|
+
const flush = (held) => { for (const w of held)
|
|
2568
|
+
opts.warn?.(w); };
|
|
2569
|
+
const first = [];
|
|
2570
|
+
warnings.held = first;
|
|
2571
|
+
try {
|
|
2572
|
+
const contribution = impl.serialize(spec, ctx);
|
|
2573
|
+
warnings.held = undefined;
|
|
2574
|
+
flush(first);
|
|
2575
|
+
return { contribution };
|
|
2576
|
+
}
|
|
2577
|
+
catch (error) {
|
|
2578
|
+
warnings.held = undefined;
|
|
2579
|
+
if (!(error instanceof CompileRefusal)) {
|
|
2580
|
+
flush(first);
|
|
2581
|
+
throw error;
|
|
2582
|
+
}
|
|
2583
|
+
for (const key of [...resourceBindings.keys()])
|
|
2584
|
+
if (!mark.resources.has(key))
|
|
2585
|
+
resourceBindings.delete(key);
|
|
2586
|
+
for (const f of sidecars.splice(mark.sidecars)) {
|
|
2587
|
+
if (!sidecars.some((kept) => kept.path === f.path))
|
|
2588
|
+
explicitSidecars.delete(f.path);
|
|
2589
|
+
}
|
|
2590
|
+
scope.agentSchemas.length = mark.agentSchemas;
|
|
2591
|
+
if (!mark.unbound)
|
|
2592
|
+
unboundDrafts.delete(id);
|
|
2593
|
+
bound.length = 0;
|
|
2594
|
+
enableDrafting();
|
|
2595
|
+
const second = [];
|
|
2596
|
+
warnings.held = second;
|
|
2597
|
+
let contribution;
|
|
2598
|
+
try {
|
|
2599
|
+
contribution = impl.serialize(spec, ctx);
|
|
2600
|
+
}
|
|
2601
|
+
catch {
|
|
2602
|
+
flush(first);
|
|
2603
|
+
throw error;
|
|
2604
|
+
}
|
|
2605
|
+
finally {
|
|
2606
|
+
warnings.held = undefined;
|
|
2607
|
+
}
|
|
2608
|
+
if (findings.length === 0) {
|
|
2609
|
+
flush(first);
|
|
2610
|
+
throw error;
|
|
2611
|
+
}
|
|
2612
|
+
return { contribution, strict: error, strictWarnings: first, draftWarnings: second };
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2545
2615
|
/**
|
|
2546
2616
|
* Lower a step whose kind is a registered node type (flow-node-registry.ts):
|
|
2547
2617
|
* the node type serializes its spec through a context, and this owns the rest —
|
|
@@ -2572,6 +2642,19 @@ function serializeFlow(built, opts) {
|
|
|
2572
2642
|
rendered.add(copy);
|
|
2573
2643
|
return copy;
|
|
2574
2644
|
};
|
|
2645
|
+
// Merge's compile drafts every node; `compile` (carriedDrafts) drafts a node
|
|
2646
|
+
// only on a second try, after the ordinary emission refused it.
|
|
2647
|
+
let drafting = opts.draft !== undefined;
|
|
2648
|
+
const carriedFindings = [];
|
|
2649
|
+
// Where this step's warnings go: `opts.warn`, or held while a carried-drafts
|
|
2650
|
+
// compile does not yet know which emission it keeps (serializeCarriedDraft).
|
|
2651
|
+
const warnings = {};
|
|
2652
|
+
const bindingOpts = opts.warn
|
|
2653
|
+
? { ...opts, warn: (w) => { if (warnings.held)
|
|
2654
|
+
warnings.held.push(w);
|
|
2655
|
+
else
|
|
2656
|
+
opts.warn(w); } }
|
|
2657
|
+
: opts;
|
|
2575
2658
|
const ctx = {
|
|
2576
2659
|
step: step.name,
|
|
2577
2660
|
nodeId: id,
|
|
@@ -2598,7 +2681,7 @@ function serializeFlow(built, opts) {
|
|
|
2598
2681
|
? resolved.carried
|
|
2599
2682
|
: bundledDefinition(typeName, v) ?? carriedFor(typeName, v)),
|
|
2600
2683
|
bindings: resourceBindings,
|
|
2601
|
-
resolveBinding: ((name, attribute, at, target) => resolveBinding(
|
|
2684
|
+
resolveBinding: ((name, attribute, at, target) => resolveBinding(bindingOpts, name, attribute, at, target)),
|
|
2602
2685
|
bindConnection: (c) => {
|
|
2603
2686
|
const { entries } = connectionResourceBindings({
|
|
2604
2687
|
def: { model: c.model },
|
|
@@ -2625,15 +2708,26 @@ function serializeFlow(built, opts) {
|
|
|
2625
2708
|
const out = renderDeep(value, scope.rename, rendered);
|
|
2626
2709
|
return out !== null && typeof out === 'object' ? fileCopy(out) : out;
|
|
2627
2710
|
},
|
|
2628
|
-
drafting
|
|
2711
|
+
get drafting() { return drafting; },
|
|
2629
2712
|
draft: (code, message) => {
|
|
2630
2713
|
if (code === 'BINDING_MISSING')
|
|
2631
2714
|
unboundDrafts.add(id);
|
|
2632
|
-
opts.draft
|
|
2715
|
+
if (opts.draft)
|
|
2716
|
+
opts.draft({ nodeId: id, code: code, message });
|
|
2717
|
+
else
|
|
2718
|
+
carriedFindings.push({ nodeId: id, step: step.name, code: code, message });
|
|
2633
2719
|
},
|
|
2634
2720
|
};
|
|
2635
2721
|
const bound = [];
|
|
2636
|
-
const contribution = impl
|
|
2722
|
+
const { contribution, strict, strictWarnings, draftWarnings } = serializeCarriedDraft(impl, spec, ctx, scope, id, bound, step.options, carriedFindings, () => { drafting = true; }, warnings);
|
|
2723
|
+
// A carried draft refused after all reports the warnings of the refused emission.
|
|
2724
|
+
const refuse = () => {
|
|
2725
|
+
for (const w of strictWarnings ?? [])
|
|
2726
|
+
opts.warn?.(w);
|
|
2727
|
+
throw strict;
|
|
2728
|
+
};
|
|
2729
|
+
if (strict !== undefined && contribution.standIn !== undefined)
|
|
2730
|
+
refuse();
|
|
2637
2731
|
if (contribution.standIn !== undefined) {
|
|
2638
2732
|
// A draft stand-in: the node as the draft has it, with no definition to
|
|
2639
2733
|
// place it against (see FlowNodeContribution.standIn).
|
|
@@ -2677,6 +2771,22 @@ function serializeFlow(built, opts) {
|
|
|
2677
2771
|
const origin = entry.family.package;
|
|
2678
2772
|
def = { ...def, source: { package: origin.name, ...(origin.version !== undefined ? { version: origin.version } : {}) } };
|
|
2679
2773
|
}
|
|
2774
|
+
// A draft `compile` writes: only a step marked `{ draft: true }` (checked in
|
|
2775
|
+
// serializeCarriedDraft) with the definition the flow carries for the node it
|
|
2776
|
+
// emits (decompile's copy of the canvas file's entry), else refused as the
|
|
2777
|
+
// ordinary emission refused it (SerializeOpts.carriedDrafts).
|
|
2778
|
+
if (strict !== undefined) {
|
|
2779
|
+
const carried = typeof def?.nodeType === 'string' && typeof def?.version === 'string'
|
|
2780
|
+
? carriedFor(def.nodeType, def.version)
|
|
2781
|
+
: undefined;
|
|
2782
|
+
if (carried === undefined)
|
|
2783
|
+
refuse();
|
|
2784
|
+
def = carried;
|
|
2785
|
+
for (const w of draftWarnings ?? [])
|
|
2786
|
+
opts.warn?.(w);
|
|
2787
|
+
for (const f of carriedFindings)
|
|
2788
|
+
opts.carriedDrafts?.(f);
|
|
2789
|
+
}
|
|
2680
2790
|
// A type that owns a family of names (`typeNamePrefix`) is placed under the
|
|
2681
2791
|
// name its definition carries — `uipath.core.function.<key>`, not the prefix.
|
|
2682
2792
|
// The bare prefix is allowed: an empty `key` builds it, check refuses that
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.65.0",
|
|
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",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"@types/node": "^22.7.0",
|
|
101
101
|
"esbuild": "^0.28.1"
|
|
102
102
|
},
|
|
103
|
-
"gitref": "
|
|
103
|
+
"gitref": "cef5c166db15d92f544e04c9817e280551ecc9dd"
|
|
104
104
|
}
|