@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.
- package/dist/api-index.md +99 -99
- package/dist/api-members.md +307 -307
- package/dist/check.d.ts +0 -19
- package/dist/check.js +40 -1036
- package/dist/cli/commands/registry.js +15 -0
- package/dist/compile-cli.js +2 -1
- package/dist/core/actions.d.ts +1 -713
- package/dist/core/actions.js +0 -193
- package/dist/core/agent-sidecar.d.ts +186 -0
- package/dist/core/agent-sidecar.js +409 -0
- package/dist/core/agent-tool-resources.d.ts +62 -0
- package/dist/core/agent-tool-resources.js +81 -0
- package/dist/core/cli-spelling.d.ts +9 -0
- package/dist/core/cli-spelling.js +9 -0
- package/dist/{config.js → core/connector-configuration.js} +2 -2
- package/dist/core/library-cache.d.ts +0 -9
- package/dist/core/library-cache.js +0 -9
- package/dist/core/library.d.ts +47 -0
- package/dist/core/library.js +135 -34
- package/dist/core/list-envelope.d.ts +36 -1
- package/dist/core/list-envelope.js +24 -19
- package/dist/core/lookup-store.d.ts +4 -3
- package/dist/core/lookup-store.js +46 -38
- package/dist/core/node-id-placeholder.d.ts +8 -0
- package/dist/core/node-id-placeholder.js +10 -0
- package/dist/core/read-text.d.ts +26 -0
- package/dist/core/read-text.js +43 -0
- package/dist/core/ts-literal.d.ts +6 -0
- package/dist/core/ts-literal.js +15 -0
- package/dist/core/typed-raw-node.js +0 -5
- package/dist/decompile.js +34 -822
- package/dist/flow-node-registry.js +2 -1
- package/dist/flow-node-type.d.ts +130 -6
- package/dist/flow-sdk.d.ts +1 -0
- package/dist/flow-sdk.js +1 -0
- package/dist/nodes/agent/flow/check.d.ts +88 -0
- package/dist/nodes/agent/flow/check.js +873 -0
- package/dist/nodes/agent/flow/factories.d.ts +134 -0
- package/dist/nodes/agent/flow/factories.js +143 -0
- package/dist/nodes/agent/flow/family.d.ts +3 -0
- package/dist/nodes/agent/flow/family.js +8 -0
- package/dist/nodes/agent/flow/index.d.ts +3 -0
- package/dist/nodes/agent/flow/index.js +3 -0
- package/dist/nodes/agent/flow/inline-agent-lift.d.ts +44 -0
- package/dist/nodes/agent/flow/inline-agent-lift.js +572 -0
- package/dist/nodes/agent/flow/inline-agent.d.ts +15 -0
- package/dist/nodes/agent/flow/inline-agent.js +526 -0
- package/dist/nodes/agent/flow/node-type.d.ts +20 -0
- package/dist/nodes/agent/flow/node-type.js +422 -0
- package/dist/nodes/agent/flow/resources.d.ts +502 -0
- package/dist/nodes/agent/flow/resources.js +1409 -0
- package/dist/nodes/agent/flow/spec.d.ts +448 -0
- package/dist/nodes/agent/flow/spec.js +1 -0
- package/dist/nodes/process/flow/check.d.ts +40 -2
- package/dist/nodes/process/flow/check.js +156 -0
- package/dist/nodes/process/flow/factories.d.ts +58 -3
- package/dist/nodes/process/flow/factories.js +59 -2
- package/dist/nodes/process/flow/node-type.d.ts +4 -1
- package/dist/nodes/process/flow/node-type.js +181 -10
- package/dist/nodes/process/flow/spec.d.ts +112 -5
- package/dist/registry/describe-cli.d.ts +10 -0
- package/dist/registry/describe-cli.js +41 -0
- package/dist/registry/library-reader.d.ts +12 -2
- package/dist/registry/library-reader.js +17 -16
- package/dist/registry/lookup-specs.d.ts +17 -1
- package/dist/registry/lookup-specs.js +3 -7
- package/dist/registry/path-cli.js +2 -1
- package/dist/registry/search-cli.js +2 -1
- package/dist/serialize.d.ts +9 -54
- package/dist/serialize.js +47 -2763
- package/package.json +2 -2
- /package/dist/{config.d.ts → core/connector-configuration.d.ts} +0 -0
- /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];
|