@uipath/maestro-builder-sdk 6.16.3 → 6.16.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/api-index.md +99 -99
- package/dist/api-members.md +255 -255
- package/dist/check.js +12 -13
- package/dist/core/actions.d.ts +29 -15
- package/dist/decompile-cli.js +10 -1
- package/dist/decompile.d.ts +11 -0
- package/dist/decompile.js +89 -8
- package/dist/serialize.js +39 -71
- package/package.json +2 -2
package/dist/check.js
CHANGED
|
@@ -3206,14 +3206,14 @@ function checkInlineAgent(step, inputs, diags, opts = {}) {
|
|
|
3206
3206
|
: `inputs: { ${undeclared[0]}: input('${undeclared[0]}') }`);
|
|
3207
3207
|
}
|
|
3208
3208
|
// Direction 3: an input bound to a COMPUTED EXPRESSION rather than to one
|
|
3209
|
-
// reference. The platform names an agent's arguments
|
|
3210
|
-
//
|
|
3211
|
-
// several references has no single argument —
|
|
3212
|
-
// `{{input.<x>}}` token could address.
|
|
3213
|
-
//
|
|
3214
|
-
//
|
|
3215
|
-
//
|
|
3216
|
-
//
|
|
3209
|
+
// reference. The platform names each of an agent's arguments after the
|
|
3210
|
+
// reference path it is bound to (the shell node's `agentInputVariables`), so
|
|
3211
|
+
// an expression spanning zero or several references has no single argument —
|
|
3212
|
+
// and therefore no name a `{{input.<x>}}` token could address. The compiler
|
|
3213
|
+
// declares no argument for it, so its value does not reach the agent, and the
|
|
3214
|
+
// placeholder reaches the model as literal text. An error rather than a
|
|
3215
|
+
// warning, and for the same reason `INLINE_AGENT_UNDECLARED_PLACEHOLDER` is
|
|
3216
|
+
// one: the value never arrives.
|
|
3217
3217
|
for (const [name, val] of Object.entries(inputs?.inputs ?? {})) {
|
|
3218
3218
|
if (!(val instanceof Expr) || val.literal)
|
|
3219
3219
|
continue;
|
|
@@ -3223,11 +3223,10 @@ function checkInlineAgent(step, inputs, diags, opts = {}) {
|
|
|
3223
3223
|
continue;
|
|
3224
3224
|
at('INLINE_AGENT_COMPOSITE_INPUT', `Inline agent step "${step}"'s input \`${name}\` is bound to a computed expression `
|
|
3225
3225
|
+ `(\`${val.js.length > 60 ? `${val.js.slice(0, 60)}…` : val.js}\`), and a prompt references it as `
|
|
3226
|
-
+ `\`{{input.${name}}}\`. The platform does not send the agent the names you declared: it
|
|
3227
|
-
+ `
|
|
3228
|
-
+ `
|
|
3229
|
-
+ `
|
|
3230
|
-
+ `that literal text.`, `compute it in a script step first, then bind the step's output: `
|
|
3226
|
+
+ `\`{{input.${name}}}\`. The platform does not send the agent the names you declared: it names each `
|
|
3227
|
+
+ `argument after the REFERENCE PATH the input is bound to (\`$vars.a.output.b\` → \`a__output__b\`). `
|
|
3228
|
+
+ `A computed expression is not one reference, so it gets no argument: its value does not reach the `
|
|
3229
|
+
+ `agent, and the placeholder reaches the model as that literal text.`, `compute it in a script step first, then bind the step's output: `
|
|
3231
3230
|
+ `.step('${name}Value', script({ code: 'return …;' })) … inputs: { ${name}: out('${name}Value') }`);
|
|
3232
3231
|
}
|
|
3233
3232
|
// A step id containing `__` makes the flat name AMBIGUOUS on the platform: the
|
package/dist/core/actions.d.ts
CHANGED
|
@@ -699,15 +699,24 @@ export interface ConversationalAgentInputs {
|
|
|
699
699
|
*/
|
|
700
700
|
settings: ConversationalAgentSettings;
|
|
701
701
|
/**
|
|
702
|
-
* Whether the agent's reply CLOSES the exchange.
|
|
703
|
-
*
|
|
702
|
+
* Whether the agent's reply CLOSES the exchange.
|
|
703
|
+
*
|
|
704
|
+
* @deprecated Has no effect and is not emitted. The platform retired the input:
|
|
705
|
+
* the conversational agent's v1.7 node migration removes it, and the converter
|
|
706
|
+
* always sends `conversationalService.endExchange = ''`. Wait-for-message and
|
|
707
|
+
* the end of the conversation close open exchanges.
|
|
704
708
|
*/
|
|
705
709
|
endExchange?: boolean;
|
|
706
710
|
/** Sampling temperature, 0–1. */
|
|
707
711
|
temperature?: number;
|
|
708
712
|
/** Max tokens in one response. */
|
|
709
713
|
maxTokenPerResponse?: number;
|
|
710
|
-
/**
|
|
714
|
+
/**
|
|
715
|
+
* The model's own context ceiling.
|
|
716
|
+
*
|
|
717
|
+
* @deprecated Has no effect and is not emitted. Studio Web derives it from the
|
|
718
|
+
* selected model.
|
|
719
|
+
*/
|
|
711
720
|
modelMaxTokens?: number;
|
|
712
721
|
/** How many tool-calling rounds one turn may take, 1–100. */
|
|
713
722
|
maxIterations?: number;
|
|
@@ -1407,20 +1416,19 @@ export interface InlineAgentInputs {
|
|
|
1407
1416
|
* ```
|
|
1408
1417
|
*
|
|
1409
1418
|
* Why a placeholder rather than an interpolated expression: an inline agent is two
|
|
1410
|
-
* artifacts, and its prompt exists in
|
|
1411
|
-
* emits the other
|
|
1419
|
+
* artifacts, and its prompt exists in TWO dialects. You write one; the compiler
|
|
1420
|
+
* emits the other into the `agent.json` sidecar. The `.flow` node carries no copy
|
|
1421
|
+
* of the prompt: it is a shell, so Studio Web reads the sidecar.
|
|
1412
1422
|
*
|
|
1413
1423
|
* 1. yours `{{input.claim}}`
|
|
1414
|
-
* 2. the
|
|
1415
|
-
* 3. the AGENT.JSON `{{input.prepare__output__claimRef}}` ← what the runtime SENDS
|
|
1424
|
+
* 2. the AGENT.JSON `{{input.prepare__output__claimRef}}` ← what the runtime SENDS
|
|
1416
1425
|
*
|
|
1417
|
-
* The
|
|
1418
|
-
* declared: it
|
|
1419
|
-
*
|
|
1420
|
-
*
|
|
1421
|
-
*
|
|
1422
|
-
*
|
|
1423
|
-
* §"The three prompt DIALECTS".
|
|
1426
|
+
* The second exists because the platform does not send an agent the names you
|
|
1427
|
+
* declared: it names each argument after the bound reference PATH, `__`-joined.
|
|
1428
|
+
* For a flow input the two coincide (`$vars.notes` → `notes`); for a step output
|
|
1429
|
+
* they do not, and a sidecar still saying `{{input.claim}}` templates against a key
|
|
1430
|
+
* that is not there — the literal text reaches the model. See the inline-agent
|
|
1431
|
+
* node reference (`website/reference/inline-agent.md`) §"The prompt dialects".
|
|
1424
1432
|
*
|
|
1425
1433
|
* **The answer's shape is `returns`, not the prompt.** `returns` becomes the node's
|
|
1426
1434
|
* `agentOutputVariables` and the `agent.json` `outputSchema` — what Studio Web's
|
|
@@ -1506,7 +1514,13 @@ export interface InlineAgentInputs {
|
|
|
1506
1514
|
temperature?: number;
|
|
1507
1515
|
/** Max tokens in one response, 0–16384. */
|
|
1508
1516
|
maxTokenPerResponse?: number;
|
|
1509
|
-
/**
|
|
1517
|
+
/**
|
|
1518
|
+
* The model's own context ceiling, e.g. `128000`.
|
|
1519
|
+
*
|
|
1520
|
+
* @deprecated Has no effect and is not emitted. Studio Web derives it from the
|
|
1521
|
+
* selected model each time the agent is opened, and the sidecar has no field
|
|
1522
|
+
* for it.
|
|
1523
|
+
*/
|
|
1510
1524
|
modelMaxTokens?: number;
|
|
1511
1525
|
/** How many tool-calling rounds the agent may take, 1–100. */
|
|
1512
1526
|
maxIterations?: number;
|
package/dist/decompile-cli.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { reportResult } from './cli-result.js';
|
|
21
21
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
22
|
-
import { basename, join, resolve } from 'node:path';
|
|
22
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
23
23
|
import { defaultSourceOut, workDirBeside, writeSource } from './workdir.js';
|
|
24
24
|
import { decompile } from './decompile.js';
|
|
25
25
|
import { resolveFlowRefs } from './ref-resolve.js';
|
|
@@ -65,6 +65,15 @@ export function run(argv) {
|
|
|
65
65
|
// writable band) go to stderr, where the agent running the brownfield loop
|
|
66
66
|
// reads them before compile refuses.
|
|
67
67
|
warn: (message) => console.error(`flow-decompile: warning: ${message}`),
|
|
68
|
+
// A shell agent node's prompts live in `<source>/agent.json` beside the .flow.
|
|
69
|
+
readSidecar: (relativePath) => {
|
|
70
|
+
try {
|
|
71
|
+
return readFileSync(join(dirname(resolve(pos)), relativePath), 'utf8');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
},
|
|
68
77
|
});
|
|
69
78
|
const out = opt(argv, '-o') ?? defaultSourceOut(`${baseName(flow)}.flow.ts`);
|
|
70
79
|
writeSource(out, ts);
|
package/dist/decompile.d.ts
CHANGED
|
@@ -133,6 +133,17 @@ export interface DecompileOptions {
|
|
|
133
133
|
* `compile` will refuse it). The CLI prints these on stderr.
|
|
134
134
|
*/
|
|
135
135
|
warn?: (message: string) => void;
|
|
136
|
+
/**
|
|
137
|
+
* Reads a file of the flow's project, by path relative to the `.flow`'s
|
|
138
|
+
* directory; returns `undefined` when it is absent. Used for an agent node
|
|
139
|
+
* that is a SHELL (no prompts on the node, the shape compile writes since
|
|
140
|
+
* #927): its prompts, model and voice settings are read back from
|
|
141
|
+
* `<source>/agent.json`. The sidecar speaks flat input names
|
|
142
|
+
* (`{{input.start__output__notes}}`), so the recovered source declares its
|
|
143
|
+
* inputs under those names — the same flow, not the same spelling. Without a
|
|
144
|
+
* reader, a shell agent decompiles with empty prompts and a warning.
|
|
145
|
+
*/
|
|
146
|
+
readSidecar?: (relativePath: string) => string | undefined;
|
|
136
147
|
}
|
|
137
148
|
export declare function decompile(flow: FlowFile, options?: DecompileOptions): string;
|
|
138
149
|
export {};
|
package/dist/decompile.js
CHANGED
|
@@ -79,6 +79,8 @@ let runStrict = false;
|
|
|
79
79
|
/** `DecompileOptions.warn` for the current run, and the messages already sent to it (one line per finding). */
|
|
80
80
|
let runWarn;
|
|
81
81
|
let runWarned = new Set();
|
|
82
|
+
/** `DecompileOptions.readSidecar` for the current run. */
|
|
83
|
+
let runReadSidecar;
|
|
82
84
|
function warnOnce(message) {
|
|
83
85
|
if (runWarned.has(message))
|
|
84
86
|
return;
|
|
@@ -1021,6 +1023,84 @@ function connectorObjectName(configuration) {
|
|
|
1021
1023
|
* Returns `undefined` when the node is not one of them, so the caller can fall
|
|
1022
1024
|
* through to the next arm.
|
|
1023
1025
|
*/
|
|
1026
|
+
/** The `maxIterations` Studio Web writes into every inline agent's `agent.json` (flow-workbench `getDefaultAgentContent()`). */
|
|
1027
|
+
const STUDIO_WEB_DEFAULT_MAX_ITERATIONS = 25;
|
|
1028
|
+
/**
|
|
1029
|
+
* The agent configuration a SHELL agent node keeps in its sidecar, read from
|
|
1030
|
+
* `<source>/agent.json` in the node's own input names: the prompts, the model,
|
|
1031
|
+
* the run settings (`temperature`, `maxTokenPerResponse`, `maxIterations`,
|
|
1032
|
+
* `mode`), the `guardrails` and (voice) the `voice` settings. Empty when the
|
|
1033
|
+
* node carries prompts itself (an embedded node, e.g. a `.flow` saved by Studio
|
|
1034
|
+
* Web with the self-contained flag on), or when no sidecar can be read.
|
|
1035
|
+
*
|
|
1036
|
+
* A run setting equal to the default a sidecar writer fills in (`temperature`
|
|
1037
|
+
* 0, `maxTokens` 16384, `mode` `'standard'`) is not recovered: recompiling
|
|
1038
|
+
* without it writes the same sidecar, and recovering it would add an argument
|
|
1039
|
+
* the author never wrote to every agent. `mode: 'standard'` is the exception on
|
|
1040
|
+
* a 1.3 node, where naming it is what selected that definition. The same goes
|
|
1041
|
+
* for the inline agent's `maxIterations` 25: the SDK omits it when unset, but
|
|
1042
|
+
* Studio Web always writes it (its `getDefaultAgentContent()` default), so
|
|
1043
|
+
* every Studio Web-saved agent would otherwise decompile with `maxIterations: 25`.
|
|
1044
|
+
*/
|
|
1045
|
+
function sidecarAgentInputs(node) {
|
|
1046
|
+
const inputs = (node.inputs ?? {});
|
|
1047
|
+
if (typeof inputs.systemPrompt === 'string' || typeof inputs.userPrompt === 'string')
|
|
1048
|
+
return {};
|
|
1049
|
+
const source = unwrapSource(inputs.source);
|
|
1050
|
+
if (!source)
|
|
1051
|
+
return {};
|
|
1052
|
+
const path = `${source}/agent.json`;
|
|
1053
|
+
const raw = runReadSidecar?.(path);
|
|
1054
|
+
if (raw === undefined) {
|
|
1055
|
+
warnOnce(`agent step "${node.id}" carries no prompts and ${path} was not found beside the .flow, `
|
|
1056
|
+
+ 'so its prompts, model and run settings decompile empty. Keep <source>/agent.json beside the .flow '
|
|
1057
|
+
+ '(download the whole project, not just the .flow).');
|
|
1058
|
+
return {};
|
|
1059
|
+
}
|
|
1060
|
+
let agent;
|
|
1061
|
+
try {
|
|
1062
|
+
agent = JSON.parse(raw);
|
|
1063
|
+
}
|
|
1064
|
+
catch {
|
|
1065
|
+
warnOnce(`agent step "${node.id}": ${path} is not valid JSON, so its prompts, model and run settings decompile empty.`);
|
|
1066
|
+
return {};
|
|
1067
|
+
}
|
|
1068
|
+
const messages = (Array.isArray(agent?.messages) ? agent.messages : []);
|
|
1069
|
+
const content = (role) => {
|
|
1070
|
+
const c = messages.find((m) => m.role === role)?.content;
|
|
1071
|
+
return typeof c === 'string' ? c : undefined;
|
|
1072
|
+
};
|
|
1073
|
+
const settings = (agent?.settings ?? {});
|
|
1074
|
+
const system = content('system');
|
|
1075
|
+
const user = content('user');
|
|
1076
|
+
const isVoice = node.type === T.voiceAgent;
|
|
1077
|
+
const numberUnless = (v, dflt) => typeof v === 'number' && v !== dflt ? v : undefined;
|
|
1078
|
+
// The voice agent's temperature and token cap live in `settings.voice`, not here.
|
|
1079
|
+
const temperature = isVoice ? undefined : numberUnless(settings.temperature, 0);
|
|
1080
|
+
const maxTokenPerResponse = isVoice ? undefined : numberUnless(settings.maxTokens, 16384);
|
|
1081
|
+
// Studio Web's default for the inline agent; the other families keep any value.
|
|
1082
|
+
const maxIterations = node.type === T.inlineAgent
|
|
1083
|
+
? numberUnless(settings.maxIterations, STUDIO_WEB_DEFAULT_MAX_ITERATIONS)
|
|
1084
|
+
: typeof settings.maxIterations === 'number' ? settings.maxIterations : undefined;
|
|
1085
|
+
// `mode` is a harness choice on the inline agent only; the conversational and
|
|
1086
|
+
// voice sidecars always carry their family's fixed value. Naming it is also
|
|
1087
|
+
// what selects the 1.3 definition, so on a 1.3 node even `'standard'` was the
|
|
1088
|
+
// author's.
|
|
1089
|
+
const mode = node.type === T.inlineAgent && typeof settings.mode === 'string'
|
|
1090
|
+
&& (settings.mode !== 'standard' || node.typeVersion === '1.3')
|
|
1091
|
+
? settings.mode : undefined;
|
|
1092
|
+
return {
|
|
1093
|
+
...(system === undefined ? {} : { systemPrompt: system }),
|
|
1094
|
+
...(user === undefined ? {} : { userPrompt: user }),
|
|
1095
|
+
...(typeof settings.model === 'string' ? { model: settings.model } : {}),
|
|
1096
|
+
...(temperature === undefined ? {} : { temperature }),
|
|
1097
|
+
...(maxTokenPerResponse === undefined ? {} : { maxTokenPerResponse }),
|
|
1098
|
+
...(maxIterations === undefined ? {} : { maxIterations }),
|
|
1099
|
+
...(mode === undefined ? {} : { mode }),
|
|
1100
|
+
...(Array.isArray(agent?.guardrails) && agent.guardrails.length > 0 ? { guardrails: agent.guardrails } : {}),
|
|
1101
|
+
...(isVoice && settings.voice && typeof settings.voice === 'object' ? { voice: settings.voice } : {}),
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1024
1104
|
/**
|
|
1025
1105
|
* An AGENT and its attached resources — the inline autonomous agent, the
|
|
1026
1106
|
* conversational agent, and the voice agent.
|
|
@@ -1038,7 +1118,8 @@ function connectorObjectName(configuration) {
|
|
|
1038
1118
|
* preserved exactly; only these logical names change.)
|
|
1039
1119
|
*/
|
|
1040
1120
|
function emitAgentCluster(node, imp, inputNames, graph) {
|
|
1041
|
-
|
|
1121
|
+
// A key on the node wins over the sidecar's copy of it.
|
|
1122
|
+
const i = { ...sidecarAgentInputs(node), ...(node.inputs ?? {}) };
|
|
1042
1123
|
const plain = (v) => {
|
|
1043
1124
|
const raw = unwrapSource(v);
|
|
1044
1125
|
return raw === undefined || raw === '' ? undefined : raw;
|
|
@@ -1047,10 +1128,12 @@ function emitAgentCluster(node, imp, inputNames, graph) {
|
|
|
1047
1128
|
const raw = unwrapPlain(v);
|
|
1048
1129
|
return typeof raw === 'number' ? String(raw) : undefined;
|
|
1049
1130
|
};
|
|
1050
|
-
// Prompts
|
|
1051
|
-
//
|
|
1052
|
-
//
|
|
1053
|
-
//
|
|
1131
|
+
// Prompts. A sidecar prompt already speaks `{{input.<flatName>}}`, so this
|
|
1132
|
+
// leaves it alone. An EMBEDDED node's prompt (Studio Web with the
|
|
1133
|
+
// self-contained flag on, or an SDK before #927) carries each input as its
|
|
1134
|
+
// rendered binding instead; the bindings in `agentInputVariables` are exactly
|
|
1135
|
+
// what to put back — longest first, so a shorter binding cannot eat a longer
|
|
1136
|
+
// one's prefix.
|
|
1054
1137
|
const vars = (Array.isArray(i.agentInputVariables) ? i.agentInputVariables : []);
|
|
1055
1138
|
const refs = vars
|
|
1056
1139
|
.filter((v) => typeof v.id === 'string' && typeof v.binding === 'string')
|
|
@@ -1312,10 +1395,8 @@ function emitAgentCluster(node, imp, inputNames, graph) {
|
|
|
1312
1395
|
// `settings` is required on ConversationalAgentInputs, so an empty one
|
|
1313
1396
|
// stays as `{}`, which check then reports as CONV_AGENT_NO_TURN.
|
|
1314
1397
|
['settings', settingsSrc || '{}'],
|
|
1315
|
-
['endExchange', unwrapPlain(i.endExchange) === false ? 'false' : undefined],
|
|
1316
1398
|
['temperature', num(i.temperature)],
|
|
1317
1399
|
['maxTokenPerResponse', num(i.maxTokenPerResponse)],
|
|
1318
|
-
['modelMaxTokens', num(i.modelMaxTokens)],
|
|
1319
1400
|
['maxIterations', num(i.maxIterations)],
|
|
1320
1401
|
['guardrails', guardrails],
|
|
1321
1402
|
['source', str(plain(i.source) ?? '')],
|
|
@@ -1329,7 +1410,6 @@ function emitAgentCluster(node, imp, inputNames, graph) {
|
|
|
1329
1410
|
['returns', returns],
|
|
1330
1411
|
['temperature', num(i.temperature)],
|
|
1331
1412
|
['maxTokenPerResponse', num(i.maxTokenPerResponse)],
|
|
1332
|
-
['modelMaxTokens', num(i.modelMaxTokens)],
|
|
1333
1413
|
['maxIterations', num(i.maxIterations)],
|
|
1334
1414
|
['mode', plain(i.mode) !== undefined ? str(plain(i.mode)) : undefined],
|
|
1335
1415
|
['guardrails', guardrails],
|
|
@@ -2616,6 +2696,7 @@ export function decompile(flow, options = {}) {
|
|
|
2616
2696
|
const importSpecifier = options.importSpecifier ?? './flow-sdk.js';
|
|
2617
2697
|
runStrict = options.bestEffort === false;
|
|
2618
2698
|
runWarn = options.warn;
|
|
2699
|
+
runReadSidecar = options.readSidecar;
|
|
2619
2700
|
runWarned = new Set();
|
|
2620
2701
|
runDefPairs = new Set((flow.definitions ?? [])
|
|
2621
2702
|
.filter((d) => typeof d?.nodeType === 'string' && typeof d?.version === 'string')
|
package/dist/serialize.js
CHANGED
|
@@ -2204,10 +2204,9 @@ function inlineAgentDef(spec) {
|
|
|
2204
2204
|
/**
|
|
2205
2205
|
* Classify a RENDERED input value (the output of {@link renderValue}).
|
|
2206
2206
|
*
|
|
2207
|
-
*
|
|
2208
|
-
*
|
|
2209
|
-
*
|
|
2210
|
-
* there.
|
|
2207
|
+
* A rendered value is an expression exactly when it starts with `=js:` — the
|
|
2208
|
+
* same test the rest of the serializer applies, so a literal string that
|
|
2209
|
+
* happens to begin with `=js:` is treated as one everywhere.
|
|
2211
2210
|
*/
|
|
2212
2211
|
function classifyAgentInput(rendered) {
|
|
2213
2212
|
if (typeof rendered !== 'string' || !rendered.startsWith('=js:')) {
|
|
@@ -2471,40 +2470,6 @@ function promptTokens(content) {
|
|
|
2471
2470
|
tokens.push({ type: 'simpleText', rawString: content.slice(last) });
|
|
2472
2471
|
return tokens.length ? tokens : [{ type: 'simpleText', rawString: content }];
|
|
2473
2472
|
}
|
|
2474
|
-
/**
|
|
2475
|
-
* Render an inline agent's prompt for the NODE, which speaks a different dialect
|
|
2476
|
-
* from the `agent.json`.
|
|
2477
|
-
*
|
|
2478
|
-
* The author writes `{{input.<name>}}`, which is what the agent's own template
|
|
2479
|
-
* language uses and what goes into `agent.json` verbatim. The node's copy has to
|
|
2480
|
-
* carry the FLOW expression instead: flow-v1's `preDeriveAgentInputDefinitions`
|
|
2481
|
-
* builds the deployed input list by scanning the node's prompts for `$vars.*`
|
|
2482
|
-
* references, and — when its caller prunes — drops any `agentInputVariables` entry no
|
|
2483
|
-
* such reference points at. A prompt with no references can therefore deploy an agent
|
|
2484
|
-
* that receives nothing, with the authored list sitting in the file unused.
|
|
2485
|
-
*
|
|
2486
|
-
* So each placeholder becomes the rendered binding of that input, `=js:`-prefixed the
|
|
2487
|
-
* way an embedded expression is read. One caveat that comes with that encoding:
|
|
2488
|
-
* an embedded run has no terminator, so it is read to
|
|
2489
|
-
* end-of-line and then backed off token by token until a prefix evaluates. That
|
|
2490
|
-
* resolves `"Notes: =js:$vars.notes and then some"` correctly, but a placeholder
|
|
2491
|
-
* followed by more text on the same line is doing more work than one at end of line.
|
|
2492
|
-
*
|
|
2493
|
-
* A placeholder naming something `inputs` does not declare is left ALONE rather than
|
|
2494
|
-
* silently deleted: it reaches the model as literal `{{input.x}}`, which is visible,
|
|
2495
|
-
* and `check` names it.
|
|
2496
|
-
*/
|
|
2497
|
-
function renderInlineAgentPrompt(template, inputs, rename) {
|
|
2498
|
-
return template.replace(INPUT_PLACEHOLDER, (whole, name) => {
|
|
2499
|
-
if (!Object.prototype.hasOwnProperty.call(inputs, name))
|
|
2500
|
-
return whole;
|
|
2501
|
-
const rendered = renderValue(inputs[name], rename);
|
|
2502
|
-
// A literal binding needs no expression at all — inline the value.
|
|
2503
|
-
if (typeof rendered === 'string' && rendered.startsWith('=js:'))
|
|
2504
|
-
return rendered;
|
|
2505
|
-
return String(rendered);
|
|
2506
|
-
});
|
|
2507
|
-
}
|
|
2508
2473
|
/**
|
|
2509
2474
|
* The parts every `uipath.ixp.*` definition shares, bundled verbatim from
|
|
2510
2475
|
* `uip maestro flow registry get` (2026-07-31, after `registry pull --force`).
|
|
@@ -5136,29 +5101,35 @@ export function serialize(built, opts = {}) {
|
|
|
5136
5101
|
// What the PLATFORM will call each of these — computed once and shared by
|
|
5137
5102
|
// the descriptor array below and the sidecar. See `agentInputPlan`.
|
|
5138
5103
|
const plan = agentInputPlan(nodeInputs, scope.rename);
|
|
5104
|
+
// A SHELL node (#927): the prompts and the model live only in the
|
|
5105
|
+
// `<source>/agent.json` sidecar written below, never on the node. Studio
|
|
5106
|
+
// Web decides which copy wins by `hasEmbeddedAgentContent`
|
|
5107
|
+
// (@uipath/flow-schema): any `systemPrompt`/`userPrompt` string on the node
|
|
5108
|
+
// makes the `.flow` authoritative and the sidecar is skipped, so a node copy
|
|
5109
|
+
// shadowed the sidecar and lost the input tokens and the tool configuration
|
|
5110
|
+
// on the first save. With no prompt strings the converter also keeps the
|
|
5111
|
+
// `agentInputVariables` below as written (`canPruneAgentInputs` is false),
|
|
5112
|
+
// and `uip maestro flow debug` reconciles them against the sidecar's
|
|
5113
|
+
// `inputSchema`.
|
|
5114
|
+
//
|
|
5115
|
+
// The run settings (`mode`, `temperature`, `maxTokenPerResponse`,
|
|
5116
|
+
// `maxIterations`, `guardrails`) live in the sidecar too. The node keeps
|
|
5117
|
+
// exactly the keys Studio Web's own strip keeps (`toAgentShellInputs`,
|
|
5118
|
+
// @uipath/flow-schema): anything else is discarded on hydrate, and while
|
|
5119
|
+
// present it makes Studio Web "trust the .flow" when the sidecar folder is
|
|
5120
|
+
// missing (`flowNodeHasRealInputs`), flushing a prompt-less agent.json.
|
|
5121
|
+
// `modelMaxTokens` is written nowhere: the designer derives it from the
|
|
5122
|
+
// selected model.
|
|
5139
5123
|
node.inputs = {
|
|
5140
5124
|
source,
|
|
5141
|
-
// The NODE's dialect: `{{input.x}}` → the flow expression, so flow-v1's
|
|
5142
|
-
// input-derivation pre-pass can see the reference. See
|
|
5143
|
-
// `renderInlineAgentPrompt`.
|
|
5144
|
-
systemPrompt: renderInlineAgentPrompt(s.systemPrompt, nodeInputs, scope.rename),
|
|
5145
|
-
userPrompt: renderInlineAgentPrompt(s.userPrompt, nodeInputs, scope.rename),
|
|
5146
|
-
model: s.model,
|
|
5147
|
-
...(s.mode === undefined ? {} : { mode: s.mode }),
|
|
5148
|
-
...(s.temperature === undefined ? {} : { temperature: s.temperature }),
|
|
5149
|
-
...(s.maxTokenPerResponse === undefined ? {} : { maxTokenPerResponse: s.maxTokenPerResponse }),
|
|
5150
|
-
...(s.modelMaxTokens === undefined ? {} : { modelMaxTokens: s.modelMaxTokens }),
|
|
5151
|
-
...(s.maxIterations === undefined ? {} : { maxIterations: s.maxIterations }),
|
|
5152
|
-
...(s.guardrails === undefined ? {} : { guardrails: s.guardrails }),
|
|
5153
5125
|
// The two DESCRIPTOR ARRAYS. `agentInputVariables` entries carry the
|
|
5154
5126
|
// binding expression; `agentOutputVariables` entries are name + type only,
|
|
5155
5127
|
// and the runtime's structured final call fills exactly these keys.
|
|
5156
5128
|
//
|
|
5157
|
-
// `id` is the FLAT NAME, not the author's — the
|
|
5158
|
-
//
|
|
5159
|
-
//
|
|
5160
|
-
//
|
|
5161
|
-
// claim one argument rather than two.
|
|
5129
|
+
// `id` is the FLAT NAME, not the author's — the name the runtime's
|
|
5130
|
+
// JobArguments are keyed by, and the key the CLI reconciles against the
|
|
5131
|
+
// sidecar's `inputSchema`. One entry per flatName, so two logical names
|
|
5132
|
+
// bound to the same reference claim one argument rather than two.
|
|
5162
5133
|
agentInputVariables: plan.refs.map((r) => ({
|
|
5163
5134
|
id: r.flatName,
|
|
5164
5135
|
type: 'string',
|
|
@@ -5727,19 +5698,15 @@ export function serialize(built, opts = {}) {
|
|
|
5727
5698
|
if (v !== undefined)
|
|
5728
5699
|
settings[key] = v;
|
|
5729
5700
|
}
|
|
5701
|
+
// A SHELL node, like the inline agent's (#927): exactly the keys
|
|
5702
|
+
// `toAgentShellInputs` keeps. The system prompt, the model and the run
|
|
5703
|
+
// settings live only in the sidecar (`metadata.isConversational` there is
|
|
5704
|
+
// the family flag). `endExchange` is written nowhere: the platform retired
|
|
5705
|
+
// it (the node's v1.7 migration drops it, and the converter always sends
|
|
5706
|
+
// `conversationalService.endExchange = ''`).
|
|
5730
5707
|
node.inputs = {
|
|
5731
5708
|
source,
|
|
5732
|
-
systemPrompt: s.systemPrompt,
|
|
5733
|
-
model: s.model,
|
|
5734
|
-
// The family's own flag — every instance of this node IS conversational.
|
|
5735
|
-
isConversational: true,
|
|
5736
5709
|
conversationalAgentSettings: settings,
|
|
5737
|
-
...(s.endExchange === undefined ? {} : { endExchange: s.endExchange }),
|
|
5738
|
-
...(s.temperature === undefined ? {} : { temperature: s.temperature }),
|
|
5739
|
-
...(s.maxTokenPerResponse === undefined ? {} : { maxTokenPerResponse: s.maxTokenPerResponse }),
|
|
5740
|
-
...(s.modelMaxTokens === undefined ? {} : { modelMaxTokens: s.modelMaxTokens }),
|
|
5741
|
-
...(s.maxIterations === undefined ? {} : { maxIterations: s.maxIterations }),
|
|
5742
|
-
...(s.guardrails === undefined ? {} : { guardrails: s.guardrails }),
|
|
5743
5710
|
};
|
|
5744
5711
|
scope.nodes.push(node);
|
|
5745
5712
|
sidecars.push({
|
|
@@ -5797,15 +5764,16 @@ export function serialize(built, opts = {}) {
|
|
|
5797
5764
|
delete node.model;
|
|
5798
5765
|
const nodeInputs = s.inputs ?? {};
|
|
5799
5766
|
const plan = agentInputPlan(nodeInputs, scope.rename);
|
|
5767
|
+
// A SHELL node (#927): the system prompt and the `voice` settings live only
|
|
5768
|
+
// in the sidecar's `messages` and `settings.voice`. On a voice node either
|
|
5769
|
+
// one makes Studio Web treat the `.flow` as authoritative and skip the
|
|
5770
|
+
// sidecar (`hasEmbeddedAgentContent`). `uip maestro flow debug` builds the
|
|
5771
|
+
// voice agent from the sidecar (`packageInlineAgents`).
|
|
5772
|
+
// The node keeps exactly the keys `toAgentShellInputs` keeps;
|
|
5773
|
+
// `maxIterations` and `metadata.isConversational` are in the sidecar.
|
|
5800
5774
|
node.inputs = {
|
|
5801
5775
|
source,
|
|
5802
|
-
systemPrompt: renderInlineAgentPrompt(s.systemPrompt, nodeInputs, scope.rename),
|
|
5803
5776
|
callContext: renderValue(toExpr(s.callContext), scope.rename),
|
|
5804
|
-
// The platform's own flag for this family — every voice agent IS
|
|
5805
|
-
// conversational, and the definition declares the field.
|
|
5806
|
-
isConversational: true,
|
|
5807
|
-
...(s.maxIterations === undefined ? {} : { maxIterations: s.maxIterations }),
|
|
5808
|
-
...(s.voice === undefined ? {} : { voice: { ...s.voice } }),
|
|
5809
5777
|
...(plan.refs.length === 0 ? {} : {
|
|
5810
5778
|
agentInputVariables: plan.refs.map((r) => ({
|
|
5811
5779
|
id: r.flatName,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.16.
|
|
3
|
+
"version": "6.16.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": "
|
|
95
|
+
"gitref": "b6731e22dc81fb2ca34f4463bc1785aaae16d174"
|
|
96
96
|
}
|