@uipath/maestro-builder-sdk 6.41.2 → 6.43.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.
Files changed (73) hide show
  1. package/dist/api-index.md +99 -99
  2. package/dist/api-members.md +307 -307
  3. package/dist/check.d.ts +0 -19
  4. package/dist/check.js +40 -1036
  5. package/dist/cli/commands/registry.js +15 -0
  6. package/dist/compile-cli.js +2 -1
  7. package/dist/core/actions.d.ts +1 -713
  8. package/dist/core/actions.js +0 -193
  9. package/dist/core/agent-sidecar.d.ts +186 -0
  10. package/dist/core/agent-sidecar.js +409 -0
  11. package/dist/core/agent-tool-resources.d.ts +62 -0
  12. package/dist/core/agent-tool-resources.js +81 -0
  13. package/dist/core/cli-spelling.d.ts +9 -0
  14. package/dist/core/cli-spelling.js +9 -0
  15. package/dist/{config.js → core/connector-configuration.js} +2 -2
  16. package/dist/core/library-cache.d.ts +0 -9
  17. package/dist/core/library-cache.js +0 -9
  18. package/dist/core/library.d.ts +47 -0
  19. package/dist/core/library.js +135 -34
  20. package/dist/core/list-envelope.d.ts +36 -1
  21. package/dist/core/list-envelope.js +24 -19
  22. package/dist/core/lookup-store.d.ts +4 -3
  23. package/dist/core/lookup-store.js +46 -38
  24. package/dist/core/node-id-placeholder.d.ts +8 -0
  25. package/dist/core/node-id-placeholder.js +10 -0
  26. package/dist/core/read-text.d.ts +26 -0
  27. package/dist/core/read-text.js +43 -0
  28. package/dist/core/ts-literal.d.ts +6 -0
  29. package/dist/core/ts-literal.js +15 -0
  30. package/dist/core/typed-raw-node.js +0 -5
  31. package/dist/decompile.js +34 -822
  32. package/dist/flow-node-registry.js +2 -1
  33. package/dist/flow-node-type.d.ts +130 -6
  34. package/dist/flow-sdk.d.ts +1 -0
  35. package/dist/flow-sdk.js +1 -0
  36. package/dist/nodes/agent/flow/check.d.ts +88 -0
  37. package/dist/nodes/agent/flow/check.js +873 -0
  38. package/dist/nodes/agent/flow/factories.d.ts +134 -0
  39. package/dist/nodes/agent/flow/factories.js +143 -0
  40. package/dist/nodes/agent/flow/family.d.ts +3 -0
  41. package/dist/nodes/agent/flow/family.js +8 -0
  42. package/dist/nodes/agent/flow/index.d.ts +3 -0
  43. package/dist/nodes/agent/flow/index.js +3 -0
  44. package/dist/nodes/agent/flow/inline-agent-lift.d.ts +44 -0
  45. package/dist/nodes/agent/flow/inline-agent-lift.js +572 -0
  46. package/dist/nodes/agent/flow/inline-agent.d.ts +15 -0
  47. package/dist/nodes/agent/flow/inline-agent.js +526 -0
  48. package/dist/nodes/agent/flow/node-type.d.ts +20 -0
  49. package/dist/nodes/agent/flow/node-type.js +422 -0
  50. package/dist/nodes/agent/flow/resources.d.ts +502 -0
  51. package/dist/nodes/agent/flow/resources.js +1409 -0
  52. package/dist/nodes/agent/flow/spec.d.ts +448 -0
  53. package/dist/nodes/agent/flow/spec.js +1 -0
  54. package/dist/nodes/process/flow/check.d.ts +40 -2
  55. package/dist/nodes/process/flow/check.js +156 -0
  56. package/dist/nodes/process/flow/factories.d.ts +58 -3
  57. package/dist/nodes/process/flow/factories.js +59 -2
  58. package/dist/nodes/process/flow/node-type.d.ts +4 -1
  59. package/dist/nodes/process/flow/node-type.js +181 -10
  60. package/dist/nodes/process/flow/spec.d.ts +112 -5
  61. package/dist/registry/describe-cli.d.ts +10 -0
  62. package/dist/registry/describe-cli.js +41 -0
  63. package/dist/registry/library-reader.d.ts +12 -2
  64. package/dist/registry/library-reader.js +17 -16
  65. package/dist/registry/lookup-specs.d.ts +17 -1
  66. package/dist/registry/lookup-specs.js +3 -7
  67. package/dist/registry/path-cli.js +2 -1
  68. package/dist/registry/search-cli.js +2 -1
  69. package/dist/serialize.d.ts +9 -54
  70. package/dist/serialize.js +47 -2763
  71. package/package.json +2 -2
  72. /package/dist/{config.d.ts → core/connector-configuration.d.ts} +0 -0
  73. /package/dist/{ixp-definition.json → core/ixp-definition.json} +0 -0
@@ -0,0 +1,409 @@
1
+ /**
2
+ * The `agent.json` sidecar every agent step writes beside the `.flow` — the
3
+ * inline, conversational and voice agents' writers, the input plan they share
4
+ * with the node's `agentInputVariables`, and the prompt tokens the designer
5
+ * renders — and the reader decompile recovers an agent's configuration with.
6
+ * Moved from serialize.ts and decompile.ts so the agent node types, the
7
+ * serializer and the decompiler share one format.
8
+ */
9
+ import { flatNameOf } from './expr.js';
10
+ /**
11
+ * Classify a RENDERED input value (as serialize renders it).
12
+ *
13
+ * A rendered value is an expression exactly when it starts with `=js:` — the
14
+ * same test the rest of the serializer applies, so a literal string that
15
+ * happens to begin with `=js:` is treated as one everywhere.
16
+ */
17
+ function classifyAgentInput(rendered) {
18
+ if (typeof rendered !== 'string' || !rendered.startsWith('=js:')) {
19
+ return { kind: 'literal', text: String(rendered) };
20
+ }
21
+ const flatName = flatNameOf(rendered);
22
+ return flatName === undefined
23
+ ? { kind: 'expression', binding: rendered }
24
+ : { kind: 'ref', flatName, binding: rendered };
25
+ }
26
+ /**
27
+ * The platform-facing plan for one inline agent's declared inputs.
28
+ *
29
+ * Built once and used by all three agent-facing sites (the node's
30
+ * `agentInputVariables`, the sidecar's `inputSchema`, and both prompts), so they
31
+ * cannot drift apart.
32
+ *
33
+ * `refs` is DEDUPED BY FLAT NAME and keeps author order. Two logical names bound
34
+ * to the same reference are one JobArgument on the platform (v1 dedupes on a
35
+ * seen-set, `:490-522`), so emitting two descriptors would claim an argument that
36
+ * will not exist.
37
+ */
38
+ export function agentInputPlan(inputs, render) {
39
+ const byName = new Map();
40
+ const refs = [];
41
+ const seen = new Set();
42
+ for (const [name, val] of Object.entries(inputs)) {
43
+ const b = classifyAgentInput(render(val));
44
+ byName.set(name, b);
45
+ if (b.kind === 'ref' && !seen.has(b.flatName)) {
46
+ seen.add(b.flatName);
47
+ refs.push({ flatName: b.flatName, binding: b.binding });
48
+ }
49
+ }
50
+ return { byName, refs };
51
+ }
52
+ /**
53
+ * Render an agent prompt for the SIDECAR — the author's placeholders rewritten to
54
+ * the names the runtime will actually have.
55
+ *
56
+ * The three cases mirror {@link AgentInputBinding}; the fourth (a placeholder
57
+ * naming nothing `inputs` declares) is left ALONE rather than deleted, exactly as
58
+ * the node's renderer leaves it, so it reaches the model as visible literal text
59
+ * and `check`'s `INLINE_AGENT_UNDECLARED_PLACEHOLDER` can name it.
60
+ *
61
+ * `contentTokens` is NOT rewritten separately — {@link promptTokens} runs over the
62
+ * rewritten string, so the designer's chips and the runtime's template can't
63
+ * disagree about a name.
64
+ */
65
+ function renderAgentSidecarPrompt(template, plan) {
66
+ return template.replace(INPUT_PLACEHOLDER, (whole, name) => {
67
+ const b = plan.get(name);
68
+ if (!b)
69
+ return whole;
70
+ if (b.kind === 'literal')
71
+ return b.text;
72
+ if (b.kind === 'ref')
73
+ return `{{input.${b.flatName}}}`;
74
+ return whole;
75
+ });
76
+ }
77
+ /**
78
+ * The `version` every `agent.json` sidecar declares — the agent tool's
79
+ * `AGENT_SCHEMA_VERSION` (uipath-cli `packages/agent-tool/src/templates/agent-template.ts`).
80
+ *
81
+ * It is not a free label. The agents backend reads an on-file `outputSchema`
82
+ * only at `version >= 1.2.0` (UiPath/Agents#5705), and since uipath-cli#3753
83
+ * `uip agent init` writes `1.2.0` and `uip agent validate` refuses anything else
84
+ * with `AgentValidationOutdated` ("Agent version "1.1.0" is outdated; latest is
85
+ * "1.2.0""). The bump is a version change only: `uip agent refresh` rewrites
86
+ * the field and nothing else. All three writers below share this one constant
87
+ * so they cannot fall behind separately (flow-builder-sdk#962).
88
+ */
89
+ const AGENT_DEFINITION_VERSION = '1.2.0';
90
+ /**
91
+ * The `agent.json` sidecar for a text CONVERSATIONAL agent.
92
+ *
93
+ * The inline agent's shape minus the argument plumbing: the turn arrives as the
94
+ * conversation transcript, so there is no `inputSchema` keyed by flat names and
95
+ * no `outputSchema` (the definition declares
96
+ * `uipath__agent_response_messages`). `metadata.isConversational` is what tells
97
+ * the platform's own storage layer which kind of agent this is.
98
+ */
99
+ export function conversationalAgentJson(spec) {
100
+ return {
101
+ version: AGENT_DEFINITION_VERSION,
102
+ settings: {
103
+ model: spec.model,
104
+ // Required by the platform's agent.json schema, same as the inline
105
+ // agent's — a debug run without both is refused before it starts.
106
+ maxTokens: spec.maxTokenPerResponse ?? 16384,
107
+ temperature: spec.temperature ?? 0,
108
+ // `basic-v2` is the NON-conversational inline agent's engine (the other
109
+ // `agent.json` writer in this file, 100 lines down), and it was copied in
110
+ // with the rest of that shape. Every instance of THIS node is
111
+ // conversational — `metadata.isConversational` below says so
112
+ // unconditionally — and `voiceAgentJson`, the sibling conversational
113
+ // family, already spells it the other way. Measured across the 2026-09-23
114
+ // A/B run: every product-written `agent.json` with `isConversational: true`
115
+ // carries `conversational-v1` (3 of 3) and every one with `false` carries
116
+ // `basic-v2` (6 of 6). The SDK's own voice path agreed (2 of 2); only this
117
+ // path disagreed, and its task graded the sidecar as not conversational.
118
+ engine: 'conversational-v1',
119
+ ...(spec.maxIterations === undefined ? {} : { maxIterations: spec.maxIterations }),
120
+ mode: 'standard',
121
+ },
122
+ projectId: spec.source,
123
+ id: spec.source,
124
+ name: spec.name,
125
+ metadata: { storageVersion: '50.0.0', isConversational: true, showProjectCreationExperience: false },
126
+ type: 'lowCode',
127
+ guardrails: spec.guardrails ?? [],
128
+ messages: [
129
+ { role: 'system', content: spec.systemPrompt, contentTokens: promptTokens(spec.systemPrompt) },
130
+ ],
131
+ };
132
+ }
133
+ /**
134
+ * The `agent.json` sidecar for a VOICE agent.
135
+ *
136
+ * The text agent's shape with voice-specific settings. The turn arrives as
137
+ * audio, while optional flow context is delivered through `inputSchema` and
138
+ * `{{input.…}}` system-prompt placeholders. There is no `outputSchema` (the
139
+ * definition declares what comes back), and `settings.voice` carries the
140
+ * audio configuration in the storage layer's own `StoredVoiceSettings` shape
141
+ * (`model` / `maxTokens` / `temperature` / `persona`) — with the platform's
142
+ * catalog defaults filled in, because its own writer treats a partial voice
143
+ * block as incomplete.
144
+ */
145
+ export function voiceAgentJson(spec) {
146
+ // The platform's catalog default (`DEFAULT_CONVERSATIONAL_VOICE_SETTINGS`):
147
+ // the live Gemini model, its first persona, temperature 0.
148
+ const DEFAULT_MODEL = 'gemini-3.1-flash-live-preview';
149
+ const DEFAULT_MAX_TOKENS = 65536;
150
+ const DEFAULT_PERSONA = 'Aoede';
151
+ const v = spec.voice ?? {};
152
+ return {
153
+ version: AGENT_DEFINITION_VERSION,
154
+ settings: {
155
+ engine: 'conversational-v1',
156
+ mode: 'voice',
157
+ voice: {
158
+ model: v.model ?? DEFAULT_MODEL,
159
+ maxTokens: v.maxTokens ?? DEFAULT_MAX_TOKENS,
160
+ temperature: v.temperature ?? 0,
161
+ persona: v.persona ?? DEFAULT_PERSONA,
162
+ },
163
+ ...(spec.maxIterations === undefined ? {} : { maxIterations: spec.maxIterations }),
164
+ },
165
+ projectId: spec.source,
166
+ id: spec.source,
167
+ name: spec.name,
168
+ ...(spec.plan.refs.length === 0 ? {} : {
169
+ inputSchema: {
170
+ type: 'object',
171
+ properties: Object.fromEntries(spec.plan.refs.map((r) => [r.flatName, {}])),
172
+ },
173
+ }),
174
+ metadata: { storageVersion: '50.0.0', isConversational: true, showProjectCreationExperience: false },
175
+ type: 'lowCode',
176
+ guardrails: [],
177
+ messages: (() => {
178
+ const system = renderAgentSidecarPrompt(spec.systemPrompt, spec.plan.byName);
179
+ return [{ role: 'system', content: system, contentTokens: promptTokens(system) }];
180
+ })(),
181
+ };
182
+ }
183
+ /**
184
+ * The `agent.json` an inline agent's `source` directory must hold.
185
+ *
186
+ * The node is only half of an inline agent. flow-v1's `handleInlineAgentJob` emits
187
+ * `entryPoint: "<source>/agent.json"` into the BPMN context, and the runtime
188
+ * resolves the agent's real configuration — model settings, the message list, the
189
+ * input/output schemas — from that file relative to the project. A `.flow` with an
190
+ * inline-agent node and no such file references a definition that is not there.
191
+ *
192
+ * Shape transcribed from deployed agents under `runs/` (e.g. the four DevCon
193
+ * billing agents, `type: 'lowCode'`), which is also what
194
+ * `uip agent init --inline-in-flow` scaffolds. The `version` is
195
+ * {@link AGENT_DEFINITION_VERSION}, not the `1.1.0` those older agents carry. `contentTokens` mirrors `content` as
196
+ * one `simpleText` run: the designer uses those tokens to render a prompt with
197
+ * inline variable chips, and a single run is the faithful encoding of a plain
198
+ * string.
199
+ */
200
+ export function inlineAgentJson(spec) {
201
+ return {
202
+ version: AGENT_DEFINITION_VERSION,
203
+ settings: {
204
+ model: spec.model,
205
+ // `maxTokens` and `temperature` are REQUIRED by the platform's own
206
+ // agent.json schema, not optional as this used to treat them: a debug run of
207
+ // an agent without both is refused before it starts —
208
+ // settings.maxTokens → "expected number, received undefined"
209
+ // settings.temperature → "expected number, received undefined"
210
+ // (measured on the product runtime, GA row 7's port). Every SDK-authored
211
+ // inline agent hit it, and no local rung could: an offline runner calls no
212
+ // model and never reads agent.json, so the sidecar's platform contract had
213
+ // never been exercised.
214
+ //
215
+ // The defaults are what `uip agent init --inline-in-flow` writes and what
216
+ // v1's own reference agents for this scenario carry.
217
+ maxTokens: spec.maxTokenPerResponse ?? 16384,
218
+ temperature: spec.temperature ?? 0,
219
+ engine: 'basic-v2',
220
+ ...(spec.maxIterations === undefined ? {} : { maxIterations: spec.maxIterations }),
221
+ mode: spec.mode ?? 'standard',
222
+ },
223
+ // Also required, and also derived rather than authored: the agent's own
224
+ // directory uuid is its `projectId` and `id` (v1's scaffold writes the same
225
+ // value in all three places, and it is the node's `inputs.source`).
226
+ projectId: spec.source,
227
+ id: spec.source,
228
+ name: spec.name,
229
+ // Keyed by FLAT NAME, because that is what the runtime's JobArguments are
230
+ // keyed by (see the dialect note above). Literal- and expression-bound
231
+ // inputs are absent on purpose: neither has a JobArgument, so declaring one
232
+ // would promise an argument that never arrives.
233
+ //
234
+ // Each property is left EMPTY here and typed once the scope closes — see
235
+ // `typeAgentInputSchemas`, which also explains why a wrong type is fatal
236
+ // rather than untidy.
237
+ inputSchema: {
238
+ type: 'object',
239
+ properties: Object.fromEntries(spec.plan.refs.map((r) => [r.flatName, {}])),
240
+ },
241
+ outputSchema: {
242
+ type: 'object',
243
+ properties: Object.fromEntries(Object.entries(spec.returns).map(([k, t]) => [k, { type: t }])),
244
+ required: Object.keys(spec.returns),
245
+ },
246
+ metadata: { storageVersion: '50.0.0', isConversational: false, showProjectCreationExperience: false },
247
+ type: 'lowCode',
248
+ guardrails: spec.guardrails ?? [],
249
+ // `content` and `contentTokens` are the half the platform keeps EXACTLY as
250
+ // authored (the CLI regenerates neither), so this is where the flatName
251
+ // rewrite has to land. Tokens are derived from the rewritten string rather
252
+ // than rewritten in parallel — the designer renders from the tokens and the
253
+ // runtime templates the content, and the two must name the same thing.
254
+ messages: (() => {
255
+ const system = renderAgentSidecarPrompt(spec.systemPrompt, spec.plan.byName);
256
+ const user = renderAgentSidecarPrompt(spec.userPrompt, spec.plan.byName);
257
+ return [
258
+ { role: 'system', content: system, contentTokens: promptTokens(system) },
259
+ { role: 'user', content: user, contentTokens: promptTokens(user) },
260
+ ];
261
+ })(),
262
+ };
263
+ }
264
+ /** `{{input.<name>}}` — the agent-template placeholder, in both prompt directions. */
265
+ const INPUT_PLACEHOLDER = /\{\{\s*input\.([A-Za-z_$][A-Za-z0-9_$]*)\s*\}\}/g;
266
+ /**
267
+ * Split an agent prompt into the `contentTokens` the designer renders it from.
268
+ *
269
+ * The designer shows a prompt as prose with inline variable CHIPS, and `contentTokens`
270
+ * is that structure: alternating `simpleText` runs and `variable` entries whose
271
+ * `rawString` is `input.<name>`. Transcribed from deployed agents under `runs/` (the
272
+ * DevCon billing agents), where a prompt reading
273
+ * `"…Customer Name: {{input.customerName}}\nInvoice Number: {{input.invoiceNumber}}"`
274
+ * carries exactly that alternation.
275
+ *
276
+ * A prompt with no placeholders is one `simpleText` run, which is what a
277
+ * variable-free prompt looks like there too.
278
+ */
279
+ function promptTokens(content) {
280
+ const tokens = [];
281
+ let last = 0;
282
+ for (const m of content.matchAll(INPUT_PLACEHOLDER)) {
283
+ const at = m.index ?? 0;
284
+ if (at > last)
285
+ tokens.push({ type: 'simpleText', rawString: content.slice(last, at) });
286
+ tokens.push({ type: 'variable', rawString: `input.${m[1]}` });
287
+ last = at + m[0].length;
288
+ }
289
+ if (last < content.length)
290
+ tokens.push({ type: 'simpleText', rawString: content.slice(last) });
291
+ return tokens.length ? tokens : [{ type: 'simpleText', rawString: content }];
292
+ }
293
+ /** The `maxIterations` Studio Web writes into every inline agent's `agent.json` (flow-workbench `getDefaultAgentContent()`). */
294
+ const STUDIO_WEB_DEFAULT_MAX_ITERATIONS = 25;
295
+ /**
296
+ * The agent configuration a SHELL agent node keeps in its sidecar, read from
297
+ * `<source>/agent.json` in the node's own input names: the prompts, the model,
298
+ * the run settings (`temperature`, `maxTokenPerResponse`, `maxIterations`,
299
+ * `mode`), the `guardrails` and (voice) the `voice` settings. Empty when the
300
+ * node carries prompts itself (an embedded node, e.g. a `.flow` saved by Studio
301
+ * Web with the self-contained flag on), or when no sidecar can be read.
302
+ *
303
+ * A run setting equal to the default a sidecar writer fills in (`temperature`
304
+ * 0, `maxTokens` 16384, `mode` `'standard'`) is not recovered: recompiling
305
+ * without it writes the same sidecar, and recovering it would add an argument
306
+ * the author never wrote to every agent. `mode: 'standard'` is the exception on
307
+ * a 1.3 node, where naming it is what selected that definition. The same goes
308
+ * for the inline agent's `maxIterations` 25: the SDK omits it when unset, but
309
+ * Studio Web always writes it (its `getDefaultAgentContent()` default), so
310
+ * every Studio Web-saved agent would otherwise decompile with `maxIterations: 25`.
311
+ */
312
+ export function agentSidecarInputs(o) {
313
+ const { inputs, source, dialect } = o;
314
+ if (typeof inputs.systemPrompt === 'string' || typeof inputs.userPrompt === 'string')
315
+ return {};
316
+ if (!source)
317
+ return {};
318
+ const path = `${source}/agent.json`;
319
+ const raw = o.read?.(path);
320
+ if (raw === undefined) {
321
+ o.warn(`agent step "${o.nodeId}" carries no prompts and ${path} was not found beside the .flow, `
322
+ + 'so its prompts, model and run settings decompile empty. Keep <source>/agent.json beside the .flow '
323
+ + '(download the whole project, not just the .flow).');
324
+ return {};
325
+ }
326
+ let agent;
327
+ try {
328
+ agent = JSON.parse(raw);
329
+ }
330
+ catch {
331
+ o.warn(`agent step "${o.nodeId}": ${path} is not valid JSON, so its prompts, model and run settings decompile empty.`);
332
+ return {};
333
+ }
334
+ const messages = (Array.isArray(agent?.messages) ? agent.messages : []);
335
+ const content = (role) => {
336
+ const c = messages.find((m) => m.role === role)?.content;
337
+ return typeof c === 'string' ? c : undefined;
338
+ };
339
+ const settings = (agent?.settings ?? {});
340
+ const system = content('system');
341
+ const user = content('user');
342
+ const isVoice = dialect === 'voice';
343
+ const numberUnless = (v, dflt) => typeof v === 'number' && v !== dflt ? v : undefined;
344
+ // The voice agent's temperature and token cap live in `settings.voice`, not here.
345
+ const temperature = isVoice ? undefined : numberUnless(settings.temperature, 0);
346
+ const maxTokenPerResponse = isVoice ? undefined : numberUnless(settings.maxTokens, 16384);
347
+ // Studio Web's default for the inline agent; the other families keep any value.
348
+ const maxIterations = dialect === 'inline'
349
+ ? numberUnless(settings.maxIterations, STUDIO_WEB_DEFAULT_MAX_ITERATIONS)
350
+ : typeof settings.maxIterations === 'number' ? settings.maxIterations : undefined;
351
+ // `mode` is a harness choice on the inline agent only; the conversational and
352
+ // voice sidecars always carry their family's fixed value. `'standard'` is the
353
+ // sidecar's default, so only another value is the author's. (Naming it no
354
+ // longer selects a definition version — the node's `{ version }` carries that,
355
+ // flow-builder-sdk#956.)
356
+ const mode = dialect === 'inline' && typeof settings.mode === 'string'
357
+ && settings.mode !== 'standard'
358
+ ? settings.mode : undefined;
359
+ return {
360
+ ...(system === undefined ? {} : { systemPrompt: system }),
361
+ ...(user === undefined ? {} : { userPrompt: user }),
362
+ ...(typeof settings.model === 'string' ? { model: settings.model } : {}),
363
+ ...(temperature === undefined ? {} : { temperature }),
364
+ ...(maxTokenPerResponse === undefined ? {} : { maxTokenPerResponse }),
365
+ ...(maxIterations === undefined ? {} : { maxIterations }),
366
+ ...(mode === undefined ? {} : { mode }),
367
+ ...(Array.isArray(agent?.guardrails) && agent.guardrails.length > 0 ? { guardrails: agent.guardrails } : {}),
368
+ ...(isVoice && settings.voice && typeof settings.voice === 'object' ? { voice: settings.voice } : {}),
369
+ };
370
+ }
371
+ /**
372
+ * Where an agent schema property points to declare "this is a FILE":
373
+ * `{ $ref: JOB_ATTACHMENT_REF }`, with {@link jobAttachmentDefinition} under the
374
+ * same schema's `definitions['job-attachment']`.
375
+ */
376
+ export const JOB_ATTACHMENT_REF = '#/definitions/job-attachment';
377
+ /**
378
+ * The canonical `job-attachment` definition an agent schema's file field
379
+ * `$ref`s into — the uipath-agents skill's `agent-definition.md` § File
380
+ * Attachments ("Schema is fixed — copy verbatim"), and the same block the
381
+ * platform's own analyze-attachments tool contract carries.
382
+ *
383
+ * It tells the agent runtime that an input is an Orchestrator attachment, so a
384
+ * file tool (Analyze Files) can resolve the attachment's `ID`.
385
+ *
386
+ * A function, not a shared object: each schema gets its own copy, so an edit
387
+ * to one emitted file cannot reach another.
388
+ *
389
+ * (The case serializer keeps its own copy in `case/entry-points.ts`: that one
390
+ * mirrors the platform's `entry-points.json` packager byte for byte, and its
391
+ * `MimeType` description differs.)
392
+ */
393
+ export function jobAttachmentDefinition() {
394
+ return {
395
+ type: 'object',
396
+ properties: {
397
+ ID: { type: 'string', description: 'Orchestrator attachment key' },
398
+ FullName: { type: 'string', description: 'File name' },
399
+ MimeType: { type: 'string', description: 'MIME type, e.g. "application/pdf", "image/png"' },
400
+ Metadata: {
401
+ type: 'object',
402
+ description: 'Dictionary<string, string> of metadata',
403
+ additionalProperties: { type: 'string' },
404
+ },
405
+ },
406
+ required: ['ID'],
407
+ 'x-uipath-resource-kind': 'JobAttachment',
408
+ };
409
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Which `resources/<id>/resource.json` files an agent's tools write, by their
3
+ * resource `type`, and whether `compile` owns one (so a file it did not write
4
+ * this time is stale). Shared by the agents family, which writes the files, and
5
+ * `compile-cli.ts`, which prunes them; moved from serialize.ts.
6
+ */
7
+ /**
8
+ * The resource `type` each deployed-resource tool kind carries in the agent
9
+ * project, which is NOT its node-type namespace: `maestro` mints
10
+ * `…tool.processorchestration.*` and its resource type is `processOrchestration`.
11
+ * Read off the platform's `currentResourceStorageSchema`; flow-workbench's
12
+ * `CANVAS_TO_STORAGE_TOOL_TYPE` maps them the same way.
13
+ */
14
+ export declare const TOOL_RESOURCE_TYPE: Record<string, string>;
15
+ /** The resource `type` of a connector tool's file ({@link connectorToolResourceJson}). */
16
+ export declare const CONNECTOR_TOOL_RESOURCE_TYPE = "integration";
17
+ /**
18
+ * The resource `type` of every platform built-in tool. Shared with tools the
19
+ * DESIGNER writes and the SDK cannot (`load-attachments`, `create-file`, …), so
20
+ * on its own it says nothing about who owns a file: `properties.toolType` does.
21
+ */
22
+ export declare const INTERNAL_TOOL_RESOURCE_TYPE = "internal";
23
+ /** The `properties.toolType` of the built-in HTTP-request tool's file (#935). */
24
+ export declare const HTTP_REQUEST_TOOL_TYPE = "http-request";
25
+ /**
26
+ * The `properties.toolType` each platform built-in tool carries in the agent
27
+ * project. Neither the node type nor the label: `analyzefiles` is the
28
+ * designer's "Analyze Files" and its resource is `analyze-attachments`;
29
+ * `summarize` is the designer's DeepRAG node (`manifest_node_deepRag_display_label:
30
+ * "Summarize"` in the vendored workbench strings) and its resource is `deep-rag`.
31
+ * Read off the platform's `builtInToolPropertiesSchemaV40` discriminated union
32
+ * (vendored `flow-to-bpmn.mjs`), which also lists `load-attachments` and
33
+ * `http-request`, and the uipath-agents skill's built-in-tools reference, which
34
+ * owns the file's body. The runtime ignores an unknown toolType silently, so
35
+ * this table is the whole contract — one that is wrong selects no tool at all.
36
+ */
37
+ export declare const BUILTIN_TOOL_TYPE: Record<string, string>;
38
+ /**
39
+ * Every tool resource identity `compile` writes, read off the tables its
40
+ * writers use — so a tool kind cannot be written without being owned, or owned
41
+ * without being written (#935: the #920 built-in files were written as
42
+ * `internal` and never pruned, because ownership was a hand-kept list in
43
+ * `compile-cli.ts` that did not have them).
44
+ *
45
+ * * `types` — the resource `type`s compile owns OUTRIGHT: every deployed-resource
46
+ * kind's, and `integration` (connector tools, since #867).
47
+ * * `internalToolTypes` — `internal` is shared with designer-only built-ins
48
+ * (`load-attachments`, `create-file`, `jev-classifier`), so for it ownership
49
+ * is the `properties.toolType`, and only the ones compile writes.
50
+ */
51
+ export declare const COMPILE_WRITTEN_TOOL_RESOURCES: {
52
+ readonly types: ReadonlySet<string>;
53
+ readonly internalToolTypes: ReadonlySet<string>;
54
+ };
55
+ /**
56
+ * Does `compile` own this `resources/<id>/resource.json` — would a compile have
57
+ * written it, so one this compile did not write is stale rather than someone
58
+ * else's? Everything it says no to belongs to the designer or to `uip agent
59
+ * refresh` (escalation, mcp, designer-only built-ins, the kinds the SDK cannot
60
+ * derive), and is never deleted.
61
+ */
62
+ export declare function compileOwnsResource(body: Record<string, unknown> | undefined): boolean;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Which `resources/<id>/resource.json` files an agent's tools write, by their
3
+ * resource `type`, and whether `compile` owns one (so a file it did not write
4
+ * this time is stale). Shared by the agents family, which writes the files, and
5
+ * `compile-cli.ts`, which prunes them; moved from serialize.ts.
6
+ */
7
+ /**
8
+ * The resource `type` each deployed-resource tool kind carries in the agent
9
+ * project, which is NOT its node-type namespace: `maestro` mints
10
+ * `…tool.processorchestration.*` and its resource type is `processOrchestration`.
11
+ * Read off the platform's `currentResourceStorageSchema`; flow-workbench's
12
+ * `CANVAS_TO_STORAGE_TOOL_TYPE` maps them the same way.
13
+ */
14
+ export const TOOL_RESOURCE_TYPE = {
15
+ process: 'process', api: 'api', maestro: 'processOrchestration',
16
+ flow: 'flow', agent: 'agent', function: 'function',
17
+ };
18
+ /** The resource `type` of a connector tool's file ({@link connectorToolResourceJson}). */
19
+ export const CONNECTOR_TOOL_RESOURCE_TYPE = 'integration';
20
+ /**
21
+ * The resource `type` of every platform built-in tool. Shared with tools the
22
+ * DESIGNER writes and the SDK cannot (`load-attachments`, `create-file`, …), so
23
+ * on its own it says nothing about who owns a file: `properties.toolType` does.
24
+ */
25
+ export const INTERNAL_TOOL_RESOURCE_TYPE = 'internal';
26
+ /** The `properties.toolType` of the built-in HTTP-request tool's file (#935). */
27
+ export const HTTP_REQUEST_TOOL_TYPE = 'http-request';
28
+ /**
29
+ * The `properties.toolType` each platform built-in tool carries in the agent
30
+ * project. Neither the node type nor the label: `analyzefiles` is the
31
+ * designer's "Analyze Files" and its resource is `analyze-attachments`;
32
+ * `summarize` is the designer's DeepRAG node (`manifest_node_deepRag_display_label:
33
+ * "Summarize"` in the vendored workbench strings) and its resource is `deep-rag`.
34
+ * Read off the platform's `builtInToolPropertiesSchemaV40` discriminated union
35
+ * (vendored `flow-to-bpmn.mjs`), which also lists `load-attachments` and
36
+ * `http-request`, and the uipath-agents skill's built-in-tools reference, which
37
+ * owns the file's body. The runtime ignores an unknown toolType silently, so
38
+ * this table is the whole contract — one that is wrong selects no tool at all.
39
+ */
40
+ export const BUILTIN_TOOL_TYPE = {
41
+ analyzefiles: 'analyze-attachments',
42
+ summarize: 'deep-rag',
43
+ batchtransform: 'batch-transform',
44
+ };
45
+ /**
46
+ * Every tool resource identity `compile` writes, read off the tables its
47
+ * writers use — so a tool kind cannot be written without being owned, or owned
48
+ * without being written (#935: the #920 built-in files were written as
49
+ * `internal` and never pruned, because ownership was a hand-kept list in
50
+ * `compile-cli.ts` that did not have them).
51
+ *
52
+ * * `types` — the resource `type`s compile owns OUTRIGHT: every deployed-resource
53
+ * kind's, and `integration` (connector tools, since #867).
54
+ * * `internalToolTypes` — `internal` is shared with designer-only built-ins
55
+ * (`load-attachments`, `create-file`, `jev-classifier`), so for it ownership
56
+ * is the `properties.toolType`, and only the ones compile writes.
57
+ */
58
+ export const COMPILE_WRITTEN_TOOL_RESOURCES = {
59
+ types: new Set([...Object.values(TOOL_RESOURCE_TYPE), CONNECTOR_TOOL_RESOURCE_TYPE]),
60
+ internalToolTypes: new Set([...Object.values(BUILTIN_TOOL_TYPE), HTTP_REQUEST_TOOL_TYPE]),
61
+ };
62
+ /**
63
+ * Does `compile` own this `resources/<id>/resource.json` — would a compile have
64
+ * written it, so one this compile did not write is stale rather than someone
65
+ * else's? Everything it says no to belongs to the designer or to `uip agent
66
+ * refresh` (escalation, mcp, designer-only built-ins, the kinds the SDK cannot
67
+ * derive), and is never deleted.
68
+ */
69
+ export function compileOwnsResource(body) {
70
+ const kind = body?.$resourceType;
71
+ if (kind === 'context')
72
+ return true;
73
+ if (kind !== 'tool')
74
+ return false;
75
+ const type = String(body?.type);
76
+ if (type === INTERNAL_TOOL_RESOURCE_TYPE) {
77
+ const toolType = body?.properties?.toolType;
78
+ return COMPILE_WRITTEN_TOOL_RESOURCES.internalToolTypes.has(String(toolType));
79
+ }
80
+ return COMPILE_WRITTEN_TOOL_RESOURCES.types.has(type);
81
+ }
@@ -49,3 +49,12 @@ export declare function prepareCommand(connectorKey?: string, action?: string, .
49
49
  * @returns `channel:profile.email=d@x.com` as is; `'users[*]:profile.real_name=Coder Evals'` quoted.
50
50
  */
51
51
  export declare function resolveFlagArg(field: string, by: string, value: string): string;
52
+ /**
53
+ * The command a message tells a person or agent to run when the cache is
54
+ * empty. It is `uip`, not `npx flow-sdk registry pull`: `uip maestro registry
55
+ * pull` runs this package's pull and fills the same cache, and it is the one
56
+ * command the authoring skill teaches. Each message used to spell the command
57
+ * out by hand, so they kept naming the SDK's own entry point after the skill
58
+ * moved to `uip`. Name it here once.
59
+ */
60
+ export declare const PULL_COMMAND = "uip maestro registry pull";
@@ -88,3 +88,12 @@ export function resolveFlagArg(field, by, value) {
88
88
  return arg;
89
89
  return `'${arg.replaceAll("'", `'\\''`)}'`;
90
90
  }
91
+ /**
92
+ * The command a message tells a person or agent to run when the cache is
93
+ * empty. It is `uip`, not `npx flow-sdk registry pull`: `uip maestro registry
94
+ * pull` runs this package's pull and fills the same cache, and it is the one
95
+ * command the authoring skill teaches. Each message used to spell the command
96
+ * out by hand, so they kept naming the SDK's own entry point after the skill
97
+ * moved to `uip`. Name it here once.
98
+ */
99
+ export const PULL_COMMAND = 'uip maestro registry pull';
@@ -9,8 +9,8 @@
9
9
  * nodes already store. See {@link buildConfiguration} for why the split form
10
10
  * broke the designer (flow-builder-sdk#936).
11
11
  */
12
- import { parseCeql } from './core/ceql.js';
13
- import { transportHttpMethod } from './core/connector-inputs.js';
12
+ import { parseCeql } from './ceql.js';
13
+ import { transportHttpMethod } from './connector-inputs.js';
14
14
  /**
15
15
  * Defaults for the essential keys a library entry does not set. These are the
16
16
  * values Studio Web's own constructors give a new connector activity.
@@ -21,15 +21,6 @@
21
21
  export declare const LIBRARY_JSON_DIR = "library-json";
22
22
  export declare const LIBRARY_MARKDOWN_DIR = "library-md";
23
23
  export declare const CURRENT_LINK = "current";
24
- /**
25
- * The command a message tells a person or agent to run when the cache is
26
- * empty. It is `uip`, not `npx flow-sdk registry pull`: `uip maestro registry
27
- * pull` runs this package's pull and fills the same cache, and it is the one
28
- * command the authoring skill teaches. Each message used to spell the command
29
- * out by hand, so they kept naming the SDK's own entry point after the skill
30
- * moved to `uip`. Name it here once.
31
- */
32
- export declare const PULL_COMMAND = "uip maestro registry pull";
33
24
  /**
34
25
  * Root of the library cache. `UIP_FLOW_SDK_LIBRARY_CACHE` overrides it.
35
26
  *
@@ -24,15 +24,6 @@ import { join } from "node:path";
24
24
  export const LIBRARY_JSON_DIR = "library-json";
25
25
  export const LIBRARY_MARKDOWN_DIR = "library-md";
26
26
  export const CURRENT_LINK = "current";
27
- /**
28
- * The command a message tells a person or agent to run when the cache is
29
- * empty. It is `uip`, not `npx flow-sdk registry pull`: `uip maestro registry
30
- * pull` runs this package's pull and fills the same cache, and it is the one
31
- * command the authoring skill teaches. Each message used to spell the command
32
- * out by hand, so they kept naming the SDK's own entry point after the skill
33
- * moved to `uip`. Name it here once.
34
- */
35
- export const PULL_COMMAND = "uip maestro registry pull";
36
27
  /**
37
28
  * Root of the library cache. `UIP_FLOW_SDK_LIBRARY_CACHE` overrides it.
38
29
  *