@uipath/maestro-builder-sdk 6.42.0 → 6.44.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 (61) hide show
  1. package/dist/api-index.md +104 -103
  2. package/dist/api-members.md +319 -317
  3. package/dist/check.d.ts +0 -19
  4. package/dist/check.js +140 -1042
  5. package/dist/compile-cli.js +2 -1
  6. package/dist/core/actions.d.ts +10 -713
  7. package/dist/core/actions.js +0 -193
  8. package/dist/core/agent-sidecar.d.ts +186 -0
  9. package/dist/core/agent-sidecar.js +409 -0
  10. package/dist/core/agent-tool-resources.d.ts +62 -0
  11. package/dist/core/agent-tool-resources.js +81 -0
  12. package/dist/{config.js → core/connector-configuration.js} +2 -2
  13. package/dist/core/form-field-type.d.ts +7 -0
  14. package/dist/core/form-field-type.js +12 -2
  15. package/dist/core/node-id-placeholder.d.ts +8 -0
  16. package/dist/core/node-id-placeholder.js +10 -0
  17. package/dist/core/ts-literal.d.ts +6 -0
  18. package/dist/core/ts-literal.js +15 -0
  19. package/dist/core/typed-raw-node.js +0 -5
  20. package/dist/decompile.js +239 -857
  21. package/dist/flow-expr-check.js +5 -0
  22. package/dist/flow-node-registry.js +2 -1
  23. package/dist/flow-node-type.d.ts +139 -6
  24. package/dist/flow-sdk.d.ts +41 -5
  25. package/dist/flow-sdk.js +15 -1
  26. package/dist/flow-step-variables.d.ts +4 -0
  27. package/dist/flow-step-variables.js +22 -0
  28. package/dist/loop-version.d.ts +23 -6
  29. package/dist/loop-version.js +37 -15
  30. package/dist/nodes/agent/flow/check.d.ts +88 -0
  31. package/dist/nodes/agent/flow/check.js +873 -0
  32. package/dist/nodes/agent/flow/factories.d.ts +134 -0
  33. package/dist/nodes/agent/flow/factories.js +143 -0
  34. package/dist/nodes/agent/flow/family.d.ts +3 -0
  35. package/dist/nodes/agent/flow/family.js +8 -0
  36. package/dist/nodes/agent/flow/index.d.ts +3 -0
  37. package/dist/nodes/agent/flow/index.js +3 -0
  38. package/dist/nodes/agent/flow/inline-agent-lift.d.ts +44 -0
  39. package/dist/nodes/agent/flow/inline-agent-lift.js +572 -0
  40. package/dist/nodes/agent/flow/inline-agent.d.ts +15 -0
  41. package/dist/nodes/agent/flow/inline-agent.js +526 -0
  42. package/dist/nodes/agent/flow/node-type.d.ts +20 -0
  43. package/dist/nodes/agent/flow/node-type.js +422 -0
  44. package/dist/nodes/agent/flow/resources.d.ts +502 -0
  45. package/dist/nodes/agent/flow/resources.js +1409 -0
  46. package/dist/nodes/agent/flow/spec.d.ts +448 -0
  47. package/dist/nodes/agent/flow/spec.js +1 -0
  48. package/dist/nodes/hitl/flow/check.js +15 -0
  49. package/dist/nodes/hitl/flow/node-type.js +18 -3
  50. package/dist/nodes/process/flow/check.d.ts +40 -2
  51. package/dist/nodes/process/flow/check.js +156 -0
  52. package/dist/nodes/process/flow/factories.d.ts +58 -3
  53. package/dist/nodes/process/flow/factories.js +59 -2
  54. package/dist/nodes/process/flow/node-type.d.ts +4 -1
  55. package/dist/nodes/process/flow/node-type.js +198 -12
  56. package/dist/nodes/process/flow/spec.d.ts +112 -5
  57. package/dist/serialize.d.ts +9 -54
  58. package/dist/serialize.js +102 -2777
  59. package/package.json +2 -2
  60. /package/dist/{config.d.ts → core/connector-configuration.d.ts} +0 -0
  61. /package/dist/{ixp-definition.json → core/ixp-definition.json} +0 -0
@@ -0,0 +1,422 @@
1
+ /**
2
+ * The agents family's node types: the text conversational agent
3
+ * (`uipath.agent.conversational`, 1.6 and 1.7), the voice agent
4
+ * (`uipath.agent.voice`, 1.0 and 1.1), and the two voice call steps
5
+ * (`uipath.conversational.voice.create-outgoing-call` and `.end-call`, 1.0).
6
+ * Every one is bundled. The two agents are SHELL nodes: the node carries the
7
+ * agent's folder (`source`) and its turn wiring, and the prompt, model and run
8
+ * settings live in the `<source>/agent.json` sidecar it writes (#927). Moved
9
+ * from serialize.ts / check.ts / decompile.ts in Phase 4 of
10
+ * docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; serialized output, sidecars, printed
11
+ * source, codes and messages unchanged.
12
+ */
13
+ import { agentInputPlan, agentSidecarInputs, conversationalAgentJson, voiceAgentJson } from '../../../core/agent-sidecar.js';
14
+ import { Expr, toExpr } from '../../../core/expr.js';
15
+ import { wireExprBody } from '../../../core/wire-expr.js';
16
+ import { checkConversationalAgent, checkInlineAgent, checkInlineAgentRead, checkVoice } from './check.js';
17
+ import { INLINE_AGENT_DEFAULT_VERSION, INLINE_AGENT_VERSIONS, serializeInlineAgent } from './inline-agent.js';
18
+ import { liftInlineAgent, printInlineAgent } from './inline-agent-lift.js';
19
+ import { INLINE_AGENT } from './resources.js';
20
+ const CREATE_OUTGOING_CALL = 'uipath.conversational.voice.create-outgoing-call';
21
+ const END_CALL = 'uipath.conversational.voice.end-call';
22
+ const VOICE_AGENT = 'uipath.agent.voice';
23
+ const CONVERSATIONAL_AGENT = 'uipath.agent.conversational';
24
+ /** Neither call step nor agent reads anything back as an error: what they publish is the definition's. */
25
+ const opaque = () => ({ kind: 'opaque' });
26
+ /** An options object from present entries, as decompile spells one; '' when nothing is present. */
27
+ function opts(ctx, entries) {
28
+ const parts = entries.filter(([, v]) => v !== undefined).map(([k, v]) => `${ctx.key(k)}: ${v}`);
29
+ return parts.length ? `{ ${parts.join(', ')} }` : '';
30
+ }
31
+ // ─── the voice call steps ───────────────────────────────────────────────────
32
+ /**
33
+ * The two VOICE service tasks. Both keep the service model on the DEFINITION
34
+ * (the family convention) and write the author's fields over the definition's
35
+ * own empty defaults.
36
+ */
37
+ function serializeCall(spec, ctx, typeName) {
38
+ const def = ctx.definition(typeName, ctx.version);
39
+ const defaults = JSON.parse(JSON.stringify(def?.inputDefaults ?? {}));
40
+ const inputs = spec.kind === 'createOutgoingCall'
41
+ ? {
42
+ ...defaults,
43
+ from: ctx.render(toExpr(spec.inputs.from)),
44
+ to: typeof spec.inputs.to === 'string'
45
+ ? { type: 'literal', expression: spec.inputs.to, fieldType: 'string' }
46
+ : ctx.render(toExpr(spec.inputs.to)),
47
+ }
48
+ : {
49
+ ...defaults,
50
+ // The whole call-context OBJECT, not a scalar — bound from a trigger or a
51
+ // create-call step.
52
+ callContext: ctx.render(toExpr(spec.inputs.callContext)),
53
+ };
54
+ return { model: 'omit', inputs };
55
+ }
56
+ /**
57
+ * A call step's field as the author wrote it: a `=js:` expression, or a bare
58
+ * `$vars.` reference, back to an `Expr`; anything else as its text.
59
+ */
60
+ function liftCallValue(x) {
61
+ const raw = typeof x === 'string' ? x : String(x?.expression ?? x ?? '');
62
+ if (raw.startsWith('=js:'))
63
+ return new Expr(raw.slice(4));
64
+ if (raw.startsWith('$vars.'))
65
+ return new Expr(raw);
66
+ return raw;
67
+ }
68
+ function liftCall(node, kind) {
69
+ const i = (node.inputs ?? {});
70
+ return kind === 'createOutgoingCall'
71
+ ? { kind, inputs: { from: liftCallValue(i.from), to: liftCallValue(i.to) } }
72
+ : { kind, inputs: { callContext: liftCallValue(i.callContext) } };
73
+ }
74
+ function printCall(spec, ctx) {
75
+ const i = spec.inputs;
76
+ return spec.kind === 'createOutgoingCall'
77
+ ? { factory: 'createOutgoingCall', options: [['from', ctx.value(i.from)], ['to', ctx.value(i.to)]] }
78
+ : { factory: 'endCall', options: [['callContext', ctx.value(i.callContext)]] };
79
+ }
80
+ // ─── the shell agents ───────────────────────────────────────────────────────
81
+ /**
82
+ * Both agents leave on `success`. Named, because the definition's first handle
83
+ * is not it: `escalation`, `context` and `tool` are artifact handles a resource
84
+ * attaches to, and the default-handle rule would pick one of them.
85
+ */
86
+ const SHELL_FORWARD_PORT = 'success';
87
+ /**
88
+ * A VOICE agent: the inline agent's cluster shape (a `source` uuid plus an
89
+ * `agent.json` sidecar the platform resolves at `<source>/agent.json`), with the
90
+ * voice family's own inputs. There is no prompt templating and no declared
91
+ * `returns` — the turn comes from the live call, and the definition declares
92
+ * what comes back.
93
+ */
94
+ function serializeVoiceAgent(s, ctx) {
95
+ const source = ctx.agentSource(s.source);
96
+ const plan = agentInputPlan(s.inputs ?? {}, (v) => ctx.render(v));
97
+ // A SHELL node (#927): the system prompt and the `voice` settings live only
98
+ // in the sidecar's `messages` and `settings.voice`. On a voice node either
99
+ // one makes Studio Web treat the `.flow` as authoritative and skip the
100
+ // sidecar (`hasEmbeddedAgentContent`). `uip maestro flow debug` builds the
101
+ // voice agent from the sidecar (`packageInlineAgents`).
102
+ // The node keeps exactly the keys `toAgentShellInputs` keeps;
103
+ // `maxIterations` and `metadata.isConversational` are in the sidecar.
104
+ const inputs = {
105
+ source,
106
+ callContext: ctx.render(toExpr(s.callContext)),
107
+ ...(plan.refs.length === 0 ? {} : {
108
+ agentInputVariables: plan.refs.map((r) => ({ id: r.flatName, type: 'string', binding: r.binding })),
109
+ }),
110
+ };
111
+ // The sidecar half, in the voice dialect: `settings.voice` carries the audio
112
+ // configuration (the storage layer's own StoredVoiceSettings shape), and the
113
+ // messages carry the system prompt alone.
114
+ const json = voiceAgentJson({
115
+ systemPrompt: s.systemPrompt, plan, voice: s.voice, maxIterations: s.maxIterations, source, name: ctx.step,
116
+ });
117
+ ctx.sidecar({ path: `${source}/agent.json`, json });
118
+ if (plan.refs.length > 0)
119
+ ctx.typeAgentInputs(json.inputSchema, plan.refs);
120
+ // The resource model lives on the definition (its `model.source: true` is
121
+ // what makes `source` an input), as on the inline agent.
122
+ return { model: 'omit', port: SHELL_FORWARD_PORT, inputs };
123
+ }
124
+ /**
125
+ * The text CONVERSATIONAL agent: the inline agent's cluster shape (a minted
126
+ * `source` plus an `agent.json` sidecar) with the family's own turn wiring. The
127
+ * per-turn bindings live in `conversationalAgentSettings` — the platform's
128
+ * serializer reads that sub-object and turns it into the engine's
129
+ * `fpsProperties`, so the SDK writes the designer's shape and lets the platform
130
+ * do that translation.
131
+ */
132
+ function serializeConversationalAgent(s, ctx) {
133
+ const source = ctx.agentSource(s.source);
134
+ const st = s.settings ?? {};
135
+ // The FOUR individual fields are the runtime's source of truth — the
136
+ // platform's own editor says so ("they always reflect the current
137
+ // configuration regardless of mode; `mode` and `context` exist only to
138
+ // restore the editor UI"), and its validator refuses a node without
139
+ // `conversationId` even when a context binding is present. So `'simple'`
140
+ // mode DERIVES them from the context exactly as `deriveFieldsFromContext`
141
+ // does, appending each field's own context path (note `latestExchangeId`,
142
+ // which is not the field's own name).
143
+ const rendered = (v) => ctx.render(toExpr(v));
144
+ const ctxExpr = st.context === undefined ? undefined : toExpr(st.context);
145
+ const derive = (contextPath) => {
146
+ if (ctxExpr === undefined || ctxExpr.literal)
147
+ return undefined;
148
+ return ctx.render(new Expr(`${ctxExpr.js}.${contextPath}`));
149
+ };
150
+ const field = (authored, contextPath) => authored !== undefined ? rendered(authored) : derive(contextPath);
151
+ const settings = {
152
+ mode: st.mode ?? 'simple',
153
+ ...(st.context !== undefined ? { context: rendered(st.context) } : {}),
154
+ };
155
+ for (const [key, contextPath] of [
156
+ ['conversationId', 'conversationId'],
157
+ ['exchangeId', 'latestExchangeId'],
158
+ ['messages', 'messages'],
159
+ ['userSettings', 'userSettings'],
160
+ ]) {
161
+ const v = field(st[key], contextPath);
162
+ if (v !== undefined)
163
+ settings[key] = v;
164
+ }
165
+ ctx.sidecar({
166
+ path: `${source}/agent.json`,
167
+ json: conversationalAgentJson({
168
+ model: s.model, systemPrompt: s.systemPrompt, temperature: s.temperature,
169
+ maxTokenPerResponse: s.maxTokenPerResponse, maxIterations: s.maxIterations,
170
+ guardrails: s.guardrails, source, name: ctx.step,
171
+ }),
172
+ });
173
+ // A SHELL node, like the inline agent's (#927): exactly the keys
174
+ // `toAgentShellInputs` keeps. The system prompt, the model and the run
175
+ // settings live only in the sidecar (`metadata.isConversational` there is the
176
+ // family flag). `endExchange` is written nowhere: the platform retired it (the
177
+ // node's v1.7 migration drops it, and the converter always sends
178
+ // `conversationalService.endExchange = ''`).
179
+ return { model: 'omit', port: SHELL_FORWARD_PORT, inputs: { source, conversationalAgentSettings: settings } };
180
+ }
181
+ /**
182
+ * The node's inputs over its sidecar's (a key on the node wins), the prompt
183
+ * with each input's rendered binding put back as its placeholder, and the
184
+ * `agentInputVariables` as `{{input.<flatName>}}` refs in the file's order.
185
+ */
186
+ function liftShell(node, ctx, dialect) {
187
+ const own = (node.inputs ?? {});
188
+ const i = {
189
+ ...agentSidecarInputs({
190
+ nodeId: ctx.nodeId, inputs: own, source: ctx.sourceText(own.source), dialect,
191
+ read: (path) => ctx.sidecar(path), warn: (m) => ctx.warn(m),
192
+ }),
193
+ ...own,
194
+ };
195
+ // An EMBEDDED node's prompt (Studio Web with the self-contained flag on, or
196
+ // an SDK before #927) carries each input as its rendered binding; the
197
+ // bindings in `agentInputVariables` are exactly what to put back — longest
198
+ // first, so a shorter binding cannot eat a longer one's prefix.
199
+ const vars = (Array.isArray(i.agentInputVariables) ? i.agentInputVariables : []);
200
+ const refs = vars
201
+ .filter((v) => typeof v.id === 'string' && typeof v.binding === 'string')
202
+ .map((v) => ({ flatName: v.id, binding: v.binding }))
203
+ .sort((a, b) => b.binding.length - a.binding.length);
204
+ const unrender = (text) => {
205
+ let out = text;
206
+ for (const r of refs)
207
+ out = out.split(r.binding).join(`{{input.${r.flatName}}}`);
208
+ return out;
209
+ };
210
+ const inputs = refs
211
+ // In the file's own order, not the length-sorted one.
212
+ .slice()
213
+ .sort((a, b) => vars.findIndex((v) => v.id === a.flatName) - vars.findIndex((v) => v.id === b.flatName))
214
+ .map((r) => [r.flatName, new Expr(wireExprBody(r.binding))]);
215
+ const plain = (v) => {
216
+ const raw = ctx.sourceText(v);
217
+ return raw === undefined || raw === '' ? undefined : raw;
218
+ };
219
+ const num = (v) => {
220
+ const raw = ctx.plainValue(v);
221
+ return typeof raw === 'number' ? raw : undefined;
222
+ };
223
+ const prompt = (v) => {
224
+ const raw = plain(v);
225
+ return raw === undefined ? undefined : unrender(raw);
226
+ };
227
+ return { i, inputs, plain, num, prompt };
228
+ }
229
+ function liftVoiceAgent(node, ctx) {
230
+ const { i, inputs, plain, num, prompt } = liftShell(node, ctx, 'voice');
231
+ const v = (i.voice ?? {});
232
+ const raw = plain(i.callContext) ?? '';
233
+ return {
234
+ kind: 'voiceAgent',
235
+ inputs: {
236
+ systemPrompt: prompt(i.systemPrompt),
237
+ inputs,
238
+ callContext: { raw, js: wireExprBody(raw) },
239
+ voice: Object.keys(v).length === 0 ? undefined : {
240
+ model: v.model, persona: v.persona, temperature: num(v.temperature), maxTokens: num(v.maxTokens),
241
+ },
242
+ maxIterations: num(i.maxIterations),
243
+ source: plain(i.source),
244
+ },
245
+ };
246
+ }
247
+ function liftConversationalAgent(node, ctx) {
248
+ const { i, plain, num, prompt } = liftShell(node, ctx, 'conversational');
249
+ const st = (i.conversationalAgentSettings ?? {});
250
+ // `sourceText` rather than a string test: since the envelope reaches these
251
+ // five keys (migrate's `NESTED_BINDING_INPUTS`), a bare string is only what a
252
+ // pre-1.6 file carries. Reading strings alone made every modern file
253
+ // decompile to a conversational agent with no turn wiring.
254
+ const setting = (k) => {
255
+ const raw = ctx.sourceText(st[k]);
256
+ return raw === undefined || raw === '' || raw === '=js:' ? undefined : raw;
257
+ };
258
+ return {
259
+ kind: 'conversationalAgent',
260
+ inputs: {
261
+ model: plain(i.model),
262
+ systemPrompt: prompt(i.systemPrompt),
263
+ mode: typeof st.mode === 'string' ? st.mode : 'simple',
264
+ settings: {
265
+ context: setting('context'), conversationId: setting('conversationId'), exchangeId: setting('exchangeId'),
266
+ messages: setting('messages'), userSettings: setting('userSettings'),
267
+ },
268
+ temperature: num(i.temperature),
269
+ maxTokenPerResponse: num(i.maxTokenPerResponse),
270
+ maxIterations: num(i.maxIterations),
271
+ guardrails: Array.isArray(i.guardrails) && i.guardrails.length > 0 ? i.guardrails : undefined,
272
+ source: plain(i.source),
273
+ },
274
+ };
275
+ }
276
+ function printShellAgent(spec, ctx) {
277
+ const num = (n) => (n === undefined ? undefined : String(n));
278
+ if (spec.kind === 'voiceAgent') {
279
+ const a = spec.inputs;
280
+ const v = a.voice;
281
+ // `|| undefined`: a voice block naming none of the four settings prints no
282
+ // `voice` option rather than an empty `voice: `.
283
+ const voiceSrc = v === undefined ? undefined : opts(ctx, [
284
+ ['model', typeof v.model === 'string' ? ctx.string(v.model) : undefined],
285
+ ['persona', typeof v.persona === 'string' ? ctx.string(v.persona) : undefined],
286
+ ['temperature', num(v.temperature)],
287
+ ['maxTokens', num(v.maxTokens)],
288
+ ]) || undefined;
289
+ return {
290
+ factory: 'voiceAgent',
291
+ options: [
292
+ ['systemPrompt', ctx.string(a.systemPrompt ?? '')],
293
+ ['inputs', a.inputs.length ? `{ ${a.inputs.map(([k, e]) => `${ctx.key(k)}: ${ctx.value(e)}`).join(', ')} }` : undefined],
294
+ // Anything but a `$vars.` reference stays the wire text verbatim.
295
+ ['callContext', a.callContext.js.startsWith('$vars.') ? ctx.value(new Expr(a.callContext.js)) : ctx.string(a.callContext.raw)],
296
+ ['voice', voiceSrc],
297
+ ['maxIterations', num(a.maxIterations)],
298
+ ['source', ctx.string(a.source ?? '')],
299
+ ],
300
+ };
301
+ }
302
+ const a = spec.inputs;
303
+ // Only a `=js:` value is an expression, printed as `out(...)` for a single
304
+ // path and a `js` template for anything composite. Any other string is
305
+ // literal text, as the product reads it (flow-schema
306
+ // `coerceToExpressionValue`), even when it looks like `$vars.…`.
307
+ const setting = (raw) => raw === undefined ? undefined : raw.startsWith('=js:') ? ctx.value(new Expr(raw.slice(4))) : ctx.string(raw);
308
+ // `'simple'` mode DERIVES the four runtime fields from `context`, so only the
309
+ // context binding is the author's; recovering the derived ones would re-emit
310
+ // them as hand-bound custom fields.
311
+ const settingsSrc = a.mode === 'custom'
312
+ ? opts(ctx, [
313
+ ['mode', ctx.string('custom')],
314
+ ['conversationId', setting(a.settings.conversationId)],
315
+ ['exchangeId', setting(a.settings.exchangeId)],
316
+ ['messages', setting(a.settings.messages)],
317
+ ['userSettings', setting(a.settings.userSettings)],
318
+ ])
319
+ : opts(ctx, [['context', setting(a.settings.context)]]);
320
+ return {
321
+ factory: 'conversationalAgent',
322
+ options: [
323
+ ['model', ctx.string(a.model ?? '')],
324
+ ['systemPrompt', ctx.string(a.systemPrompt ?? '')],
325
+ // `settings` is required on ConversationalAgentInputs, so an empty one stays
326
+ // as `{}`, which check then reports as CONV_AGENT_NO_TURN.
327
+ ['settings', settingsSrc || '{}'],
328
+ ['temperature', num(a.temperature)],
329
+ ['maxTokenPerResponse', num(a.maxTokenPerResponse)],
330
+ ['maxIterations', num(a.maxIterations)],
331
+ ['guardrails', a.guardrails === undefined ? undefined : ctx.json(a.guardrails)],
332
+ ['source', ctx.string(a.source ?? '')],
333
+ ],
334
+ };
335
+ }
336
+ // ─── the node types ─────────────────────────────────────────────────────────
337
+ const createOutgoingCall10 = {
338
+ kind: 'createOutgoingCall', typeName: CREATE_OUTGOING_CALL, version: '1.0', factory: 'createOutgoingCall', definition: 'bundled',
339
+ rawNode: { factory: 'createOutgoingCall()' },
340
+ serialize: (spec, ctx) => serializeCall(spec, ctx, CREATE_OUTGOING_CALL),
341
+ deserialize: (node) => liftCall(node, 'createOutgoingCall'),
342
+ print: (spec, ctx) => printCall(spec, ctx),
343
+ check: (spec, ctx) => checkVoice('createOutgoingCall', spec.inputs, ctx),
344
+ // check collected no expressions for a voice step before the port; unchanged by it.
345
+ expressions: () => [],
346
+ output: opaque,
347
+ };
348
+ const endCall10 = {
349
+ kind: 'endCall', typeName: END_CALL, version: '1.0', factory: 'endCall', definition: 'bundled',
350
+ rawNode: { factory: 'endCall()' },
351
+ serialize: (spec, ctx) => serializeCall(spec, ctx, END_CALL),
352
+ deserialize: (node) => liftCall(node, 'endCall'),
353
+ print: (spec, ctx) => printCall(spec, ctx),
354
+ check: (spec, ctx) => checkVoice('endCall', spec.inputs, ctx),
355
+ expressions: () => [],
356
+ output: opaque,
357
+ };
358
+ function voiceAgentAt(version) {
359
+ return {
360
+ kind: 'voiceAgent', typeName: VOICE_AGENT, version, factory: 'voiceAgent', definition: 'bundled',
361
+ rawNode: { factory: 'voiceAgent()' },
362
+ serialize: (spec, ctx) => serializeVoiceAgent(spec.inputs, ctx),
363
+ deserialize: (node, ctx) => liftVoiceAgent(node, ctx),
364
+ print: (spec, ctx) => printShellAgent(spec, ctx),
365
+ check: (spec, ctx) => checkVoice('voiceAgent', spec.inputs, ctx),
366
+ expressions: () => [],
367
+ output: opaque,
368
+ };
369
+ }
370
+ function conversationalAgentAt(version) {
371
+ return {
372
+ kind: 'conversationalAgent', typeName: CONVERSATIONAL_AGENT, version, factory: 'conversationalAgent', definition: 'bundled',
373
+ rawNode: { factory: 'conversationalAgent()' },
374
+ serialize: (spec, ctx) => serializeConversationalAgent(spec.inputs, ctx),
375
+ deserialize: (node, ctx) => liftConversationalAgent(node, ctx),
376
+ print: (spec, ctx) => printShellAgent(spec, ctx),
377
+ check: (spec, ctx) => checkConversationalAgent(spec.inputs, ctx),
378
+ expressions: () => [],
379
+ output: opaque,
380
+ };
381
+ }
382
+ const voiceAgent = {
383
+ kind: 'voiceAgent', typeName: VOICE_AGENT, factory: 'voiceAgent',
384
+ // 1.0 is the first bundled entry, which is what the node was emitted at before
385
+ // the port; 1.1 adds the error port and is reached by `{ version: '1.1' }`.
386
+ defaultVersion: '1.0',
387
+ versions: { '1.0': voiceAgentAt('1.0'), '1.1': voiceAgentAt('1.1') },
388
+ };
389
+ const conversationalAgent = {
390
+ kind: 'conversationalAgent', typeName: CONVERSATIONAL_AGENT, factory: 'conversationalAgent',
391
+ defaultVersion: '1.6',
392
+ versions: { '1.6': conversationalAgentAt('1.6'), '1.7': conversationalAgentAt('1.7') },
393
+ };
394
+ /**
395
+ * The inline agent at one version. Per-tenant, for the queue's reason: each
396
+ * flow's definition is the bundled one plus edits (`inlineAgentDef` sets the
397
+ * output's source and keeps the `memory` handle only when an agent of the flow
398
+ * attaches memory), so serialize supplies the definition it built. Every
399
+ * bundled version declares an error port.
400
+ */
401
+ function inlineAgentAt(version) {
402
+ return {
403
+ kind: 'inlineAgent', typeName: INLINE_AGENT, version, factory: 'inlineAgent', definition: 'per-tenant',
404
+ errorPort: true,
405
+ rawNode: { factory: 'inlineAgent()' },
406
+ serialize: (spec, ctx) => serializeInlineAgent(spec.inputs, ctx),
407
+ deserialize: (node, ctx) => liftInlineAgent(node, ctx),
408
+ print: (spec, ctx) => printInlineAgent(spec, ctx),
409
+ check: (spec, ctx) => checkInlineAgent(spec.inputs, ctx),
410
+ // check collected no expressions for an inline agent before the port; unchanged by it.
411
+ expressions: () => [],
412
+ output: (spec) => ({ kind: 'reader', read: (read, report) => checkInlineAgentRead(read, spec.inputs, report) }),
413
+ };
414
+ }
415
+ const inlineAgent = {
416
+ kind: 'inlineAgent', typeName: INLINE_AGENT, factory: 'inlineAgent',
417
+ // The NEWEST bundled version, not the first (#956): `mode` and `memory` no
418
+ // longer pick one, so every call shape gets the current definition.
419
+ defaultVersion: INLINE_AGENT_DEFAULT_VERSION,
420
+ versions: Object.fromEntries(INLINE_AGENT_VERSIONS.map((v) => [v, inlineAgentAt(v)])),
421
+ };
422
+ export const agentNodeTypes = [createOutgoingCall10, endCall10, voiceAgent, conversationalAgent, inlineAgent];