@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.
- package/dist/api-index.md +104 -103
- package/dist/api-members.md +319 -317
- package/dist/check.d.ts +0 -19
- package/dist/check.js +140 -1042
- package/dist/compile-cli.js +2 -1
- package/dist/core/actions.d.ts +10 -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/{config.js → core/connector-configuration.js} +2 -2
- package/dist/core/form-field-type.d.ts +7 -0
- package/dist/core/form-field-type.js +12 -2
- package/dist/core/node-id-placeholder.d.ts +8 -0
- package/dist/core/node-id-placeholder.js +10 -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 +239 -857
- package/dist/flow-expr-check.js +5 -0
- package/dist/flow-node-registry.js +2 -1
- package/dist/flow-node-type.d.ts +139 -6
- package/dist/flow-sdk.d.ts +41 -5
- package/dist/flow-sdk.js +15 -1
- package/dist/flow-step-variables.d.ts +4 -0
- package/dist/flow-step-variables.js +22 -0
- package/dist/loop-version.d.ts +23 -6
- package/dist/loop-version.js +37 -15
- 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/hitl/flow/check.js +15 -0
- package/dist/nodes/hitl/flow/node-type.js +18 -3
- 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 +198 -12
- package/dist/nodes/process/flow/spec.d.ts +112 -5
- package/dist/serialize.d.ts +9 -54
- package/dist/serialize.js +102 -2777
- 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
package/dist/flow-expr-check.js
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { Expr, cookedEscapesOf } from './core/expr.js';
|
|
31
31
|
import { checkExpression, cookedEscapeDiagnostics } from './core/expr-check.js';
|
|
32
|
+
import { stepDeclaredVariables } from './flow-step-variables.js';
|
|
32
33
|
const NOUN = 'input, variable, or step';
|
|
33
34
|
/**
|
|
34
35
|
* Every `$vars` root a reference may legitimately resolve to, across the WHOLE
|
|
@@ -77,6 +78,10 @@ function addStepNames(steps, roots) {
|
|
|
77
78
|
// they are edges, not nodes, so there is nothing to reference them by.
|
|
78
79
|
if (s.kind !== 'return' && s.kind !== 'stepToRef' && s.kind !== 'stepToList' && s.kind !== 'break' && s.kind !== 'continue')
|
|
79
80
|
roots.add(s.name);
|
|
81
|
+
// A step declares the variables its fields land in too (`check.ts` mirrors this, #1309).
|
|
82
|
+
if (s.kind === 'action' || s.kind === 'stepSwitch')
|
|
83
|
+
for (const v of stepDeclaredVariables(s.spec, s.options?.version))
|
|
84
|
+
roots.add(v);
|
|
80
85
|
switch (s.kind) {
|
|
81
86
|
case 'stepToList':
|
|
82
87
|
addStepNames(s.body, roots);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { NodeTypeRegistry } from './core/nodes/registry.js';
|
|
10
10
|
import { hasBundledDefinition } from './flow-definitions.js';
|
|
11
|
+
import { agentFlowFamily } from './nodes/agent/flow/family.js';
|
|
11
12
|
import { aiPatternsFlowFamily } from './nodes/ai-patterns/flow/family.js';
|
|
12
13
|
import { conversationFlowFamily } from './nodes/conversation/flow/family.js';
|
|
13
14
|
import { dataFabricFlowFamily } from './nodes/data-fabric/flow/family.js';
|
|
@@ -21,5 +22,5 @@ import { queueFlowFamily } from './nodes/queue/flow/family.js';
|
|
|
21
22
|
import { scriptFlowFamily } from './nodes/script/flow/family.js';
|
|
22
23
|
import { transformFlowFamily } from './nodes/transform/flow/family.js';
|
|
23
24
|
/** The families, in no significant order. Adding one is the whole of registering it. */
|
|
24
|
-
export const FLOW_NODE_FAMILIES = [aiPatternsFlowFamily, conversationFlowFamily, dataFabricFlowFamily, delayFlowFamily, documentFlowFamily, hitlFlowFamily, httpFlowFamily, mockFlowFamily, processFlowFamily, queueFlowFamily, scriptFlowFamily, transformFlowFamily];
|
|
25
|
+
export const FLOW_NODE_FAMILIES = [agentFlowFamily, aiPatternsFlowFamily, conversationFlowFamily, dataFabricFlowFamily, delayFlowFamily, documentFlowFamily, hitlFlowFamily, httpFlowFamily, mockFlowFamily, processFlowFamily, queueFlowFamily, scriptFlowFamily, transformFlowFamily];
|
|
25
26
|
export const FLOW_NODE_TYPES = new NodeTypeRegistry('flow', FLOW_NODE_FAMILIES, { hasBundledDefinition });
|
package/dist/flow-node-type.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { VersionedNodeType } from './core/nodes/versioned.js';
|
|
|
14
14
|
import type { NodeFamily, Placement } from './core/nodes/family.js';
|
|
15
15
|
import type { DefinitionReference, NodeContribution } from './core/node-classes.js';
|
|
16
16
|
import type { CheckOpts } from './check.js';
|
|
17
|
+
import type { SerializeOpts } from './serialize.js';
|
|
17
18
|
import type { DeclaredExit, NoExits } from './core/step-ports.js';
|
|
18
19
|
/**
|
|
19
20
|
* What a Flow node type's `serialize` returns: the node's type-owned fields.
|
|
@@ -65,6 +66,27 @@ export interface FlowNodeContribution extends Omit<NodeContribution, 'definition
|
|
|
65
66
|
* `{nodeId}` substitution, which a merged contribution's outputs get.
|
|
66
67
|
*/
|
|
67
68
|
replaceOutputs?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Resource nodes this node carries on its artifact handles — an agent's
|
|
71
|
+
* contexts, tools, escalations and memory. Each is placed after this node and
|
|
72
|
+
* before the edges into it, drawn as a circle, with no node-level `model`, and
|
|
73
|
+
* joined by an edge from this node's `port` to the resource's `input`. Its
|
|
74
|
+
* inputs are written as given (render them first), and its definition is
|
|
75
|
+
* emitted into `definitions[]` like a per-tenant node's. A resource is not a
|
|
76
|
+
* step: it takes no control flow and never reaches an End.
|
|
77
|
+
*/
|
|
78
|
+
attach?: ReadonlyArray<{
|
|
79
|
+
/** Its node id, from {@link FlowSerializeContext.resourceNodeId}. */
|
|
80
|
+
readonly id: string;
|
|
81
|
+
/** Its definition (the manifest). */
|
|
82
|
+
readonly definition: unknown;
|
|
83
|
+
readonly label: string;
|
|
84
|
+
readonly inputs: Readonly<Record<string, unknown>>;
|
|
85
|
+
/** The artifact handle on THIS node the edge leaves from (`context`, `tool`, `escalation`, `memory`). */
|
|
86
|
+
readonly port: string;
|
|
87
|
+
/** Display fields set over the definition's, after `shape: 'circle'` (a tool's `description`). */
|
|
88
|
+
readonly display?: Readonly<Record<string, unknown>>;
|
|
89
|
+
}>;
|
|
68
90
|
}
|
|
69
91
|
/** What `serialize` may ask of the serializer, for one placement. */
|
|
70
92
|
export interface FlowSerializeContext {
|
|
@@ -95,10 +117,12 @@ export interface FlowSerializeContext {
|
|
|
95
117
|
/** A deterministic id for `seed`, unique to this flow and node. */
|
|
96
118
|
mint(seed: string): string;
|
|
97
119
|
/**
|
|
98
|
-
* Hoist a binding entry into the flow's `bindings`, deduplicated by `id`.
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
120
|
+
* Hoist a binding entry into the flow's `bindings`, deduplicated by `id`. It is
|
|
121
|
+
* in {@link bindings} at once, so a second resource of this step sees the
|
|
122
|
+
* first one's pair. With the contribution's own `bindings`, these must close
|
|
123
|
+
* every `<bindings.NAME>` the node's definition references: serialize refuses
|
|
124
|
+
* a name left open (`CONTRIBUTION_BINDING_UNRESOLVED`), and `check` does not
|
|
125
|
+
* see bindings.
|
|
102
126
|
*/
|
|
103
127
|
bind(entry: {
|
|
104
128
|
readonly id: string;
|
|
@@ -122,7 +146,15 @@ export interface FlowSerializeContext {
|
|
|
122
146
|
* refusal check reports, and a value that cannot be a tenant id is warned about
|
|
123
147
|
* (`CONNECTION_STUB`). `where` names the site in both, e.g. `managed http "fetch"`.
|
|
124
148
|
*/
|
|
125
|
-
resolveBinding(name: string, attribute: 'connection' | 'folder', where: string
|
|
149
|
+
resolveBinding(name: string, attribute: 'connection' | 'folder', where: string, target?: {
|
|
150
|
+
key: string;
|
|
151
|
+
action?: string;
|
|
152
|
+
}): string;
|
|
153
|
+
/** An unset label resolves to nothing. */
|
|
154
|
+
resolveBinding(name: string | undefined, attribute: 'connection' | 'folder', where: string, target?: {
|
|
155
|
+
key: string;
|
|
156
|
+
action?: string;
|
|
157
|
+
}): string | undefined;
|
|
126
158
|
/**
|
|
127
159
|
* Hoist the Integration Service connection pair a definition's `model`
|
|
128
160
|
* references (`<bindings.NAME>` for its connection id and folder key), deduped
|
|
@@ -133,11 +165,54 @@ export interface FlowSerializeContext {
|
|
|
133
165
|
bindConnection(o: {
|
|
134
166
|
model: unknown;
|
|
135
167
|
connectorKey: string;
|
|
136
|
-
|
|
168
|
+
/** Undefined for an unresolved connection: the entries still close the references, with no `default`. */
|
|
169
|
+
connectionId: string | undefined;
|
|
137
170
|
folderKey?: string;
|
|
138
171
|
/** The entries' `resourceKey`; defaults to `connectionId`. */
|
|
139
172
|
resourceKey?: string;
|
|
140
173
|
}): void;
|
|
174
|
+
/**
|
|
175
|
+
* The folder an agent step's files live in (`<source>/agent.json`), a uuid:
|
|
176
|
+
* `carried` when the author or the file gave one, else one derived from the
|
|
177
|
+
* flow id and step name, so a recompile is byte-identical — then moved by the
|
|
178
|
+
* compile's `agentSource` option when it owns the folders (#1184).
|
|
179
|
+
*/
|
|
180
|
+
agentSource(carried: string | undefined): string;
|
|
181
|
+
/**
|
|
182
|
+
* Write a file beside the `.flow` (an agent's `agent.json`), at a path relative
|
|
183
|
+
* to it. The same file twice is not a clash (a subflow body emitted for two
|
|
184
|
+
* callers); two different contents at a path an explicit `source` chose are
|
|
185
|
+
* refused (`INLINE_AGENT_RESOURCE_SOURCE_DUP`). The `json` object is kept, not
|
|
186
|
+
* copied, so `typeAgentInputs` can still fill it in.
|
|
187
|
+
*/
|
|
188
|
+
sidecar(file: {
|
|
189
|
+
path: string;
|
|
190
|
+
json: unknown;
|
|
191
|
+
}, explicitSource?: boolean): void;
|
|
192
|
+
/**
|
|
193
|
+
* Type an agent sidecar's `inputSchema` once this scope's variables are known:
|
|
194
|
+
* each ref's `flatName` property gets the JSON Schema of the variable its
|
|
195
|
+
* `binding` reads, which no step can know while it is serialized (a later step
|
|
196
|
+
* may declare it).
|
|
197
|
+
*/
|
|
198
|
+
typeAgentInputs(schema: {
|
|
199
|
+
properties: Record<string, unknown>;
|
|
200
|
+
definitions?: Record<string, unknown>;
|
|
201
|
+
}, refs: ReadonlyArray<{
|
|
202
|
+
flatName: string;
|
|
203
|
+
binding: string;
|
|
204
|
+
}>): void;
|
|
205
|
+
/**
|
|
206
|
+
* Claim the node id of a resource this step attaches: `explicit` exactly as
|
|
207
|
+
* written (decompile writes the file's id), refused when blank or already
|
|
208
|
+
* another node's (`INLINE_AGENT_RESOURCE_NODE_ID`); else `<seed>`, deduped
|
|
209
|
+
* file-wide (`<seed>2`, …).
|
|
210
|
+
*/
|
|
211
|
+
resourceNodeId(explicit: string | undefined, seed: string, where: string): string;
|
|
212
|
+
/** The definition this flow has already emitted for `type@version`, if any (definitions[] holds one per pair). */
|
|
213
|
+
emitted(typeName: string, version: string): unknown;
|
|
214
|
+
/** The connector library serialize was given, for a type that resolves a connector operation. */
|
|
215
|
+
readonly library: SerializeOpts['library'];
|
|
141
216
|
}
|
|
142
217
|
/** What `deserialize` may ask of the decompiler, for one serialized node. */
|
|
143
218
|
export interface FlowDeserializeContext {
|
|
@@ -168,6 +243,33 @@ export interface FlowDeserializeContext {
|
|
|
168
243
|
* decompile.
|
|
169
244
|
*/
|
|
170
245
|
lossy(message: string): void;
|
|
246
|
+
/**
|
|
247
|
+
* A file beside the `.flow` (an agent's `<source>/agent.json`) as text, by its
|
|
248
|
+
* path relative to it; undefined when decompile was given no reader or the
|
|
249
|
+
* file is not there.
|
|
250
|
+
*/
|
|
251
|
+
sidecar(path: string): string | undefined;
|
|
252
|
+
/** The id of the flow being decompiled, as the source will name it: compile derives a resource's folder from it. */
|
|
253
|
+
readonly flowId: string;
|
|
254
|
+
/** Another node's definition: the file's own `definitions[]` entry for its type and version. */
|
|
255
|
+
definitionOf(node: {
|
|
256
|
+
type: string;
|
|
257
|
+
typeVersion?: string;
|
|
258
|
+
}): unknown;
|
|
259
|
+
/**
|
|
260
|
+
* The nodes attached to this one on an artifact handle (`tool`, `context`,
|
|
261
|
+
* `escalation`, `memory`), in edge order, at most `limit` of them. Their edges
|
|
262
|
+
* are carried by this node's spec, so they are not reported as dropped.
|
|
263
|
+
*/
|
|
264
|
+
attached(port: string, limit?: number): readonly unknown[];
|
|
265
|
+
/** The ids of every node attached on that handle, without claiming their edges. */
|
|
266
|
+
attachedIds(port: string): readonly string[];
|
|
267
|
+
/**
|
|
268
|
+
* Record that an attached node folds into this node's spec, and the id
|
|
269
|
+
* compile will give it (undefined: compile will not emit it again), so what
|
|
270
|
+
* decompile writes about it — a layout entry — names the recompiled node.
|
|
271
|
+
*/
|
|
272
|
+
absorb(nodeId: string, compiledId: string | undefined): void;
|
|
171
273
|
/** The source ports this node's out-edges leave from, in edge order (an empty list outside a graph). */
|
|
172
274
|
outPorts(): readonly string[];
|
|
173
275
|
/**
|
|
@@ -233,7 +335,29 @@ export interface FlowCheckContext {
|
|
|
233
335
|
}, use?: {
|
|
234
336
|
id: string;
|
|
235
337
|
connector: string | undefined;
|
|
338
|
+
},
|
|
339
|
+
/** The connector operation the labels are for, so a refusal names the `prepare` command for it. */
|
|
340
|
+
target?: {
|
|
341
|
+
key: string;
|
|
342
|
+
action?: string;
|
|
236
343
|
}): void;
|
|
344
|
+
/**
|
|
345
|
+
* The node ids and folders this step's attached resources take, recorded
|
|
346
|
+
* file-wide — across the root flow and every subflow, as compile claims them.
|
|
347
|
+
* An explicit id equal to one another node gets is reported once the whole
|
|
348
|
+
* file is checked (`INLINE_AGENT_RESOURCE_NODE_ID`).
|
|
349
|
+
*/
|
|
350
|
+
readonly resources: {
|
|
351
|
+
/** An id compile derives for one of this step's resources, and what it is, for that report. */
|
|
352
|
+
derivedNodeId(id: string, what: string): void;
|
|
353
|
+
/** Claim an explicit node id: the earlier claimant when one already has it (and nothing is recorded), else undefined. */
|
|
354
|
+
claimNodeId(id: string, what: string): {
|
|
355
|
+
step: string;
|
|
356
|
+
what: string;
|
|
357
|
+
} | undefined;
|
|
358
|
+
/** Claim an agent's folder (its `source`, compared lower-cased): the other step that has it, else undefined. */
|
|
359
|
+
claimFolder(source: string): string | undefined;
|
|
360
|
+
};
|
|
237
361
|
}
|
|
238
362
|
/** What a family-level `check` may ask of the checker. */
|
|
239
363
|
export interface FlowFamilyCheckContext {
|
|
@@ -317,6 +441,15 @@ export interface FlowNodeType<Spec> extends NodeType<Spec, FlowNodeContribution,
|
|
|
317
441
|
* one of these (`.onError()` routes it).
|
|
318
442
|
*/
|
|
319
443
|
exits?(spec: Spec, pinnedVersion?: string): DeclaredExit[] | NoExits;
|
|
444
|
+
/**
|
|
445
|
+
* The flow variables a step of this type DECLARES by running: names a later
|
|
446
|
+
* `$vars.<name>` read resolves to that are neither a `.var()` nor a step
|
|
447
|
+
* name. A quick form's asked field lands its answer in its `variable`
|
|
448
|
+
* (`vars.<Step>_<field>`, as the designer names it), so the task declares
|
|
449
|
+
* that variable. `check` adds them to its declared set (#1309). Omitted: the
|
|
450
|
+
* type declares none.
|
|
451
|
+
*/
|
|
452
|
+
declares?(spec: Spec, pinnedVersion?: string): string[];
|
|
320
453
|
/**
|
|
321
454
|
* Whether `port` is a forward handle the PRODUCT derives for this spec, which
|
|
322
455
|
* the definition does not list — a human task's `outcome-<id>` handles, drawn
|
package/dist/flow-sdk.d.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export * from './core/expr.js';
|
|
20
20
|
export * from './core/actions.js';
|
|
21
|
+
export * from './nodes/agent/flow/index.js';
|
|
21
22
|
export * from './nodes/ai-patterns/flow/index.js';
|
|
22
23
|
export * from './nodes/conversation/flow/index.js';
|
|
23
24
|
export * from './nodes/data-fabric/flow/index.js';
|
|
@@ -443,6 +444,39 @@ export interface NodeOptions {
|
|
|
443
444
|
*/
|
|
444
445
|
label?: string;
|
|
445
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* The options of `.parallel()`: the join's {@link NodeOptions}, plus the fork
|
|
449
|
+
* node when the flow has one.
|
|
450
|
+
*/
|
|
451
|
+
export interface ParallelOptions extends NodeOptions {
|
|
452
|
+
/**
|
|
453
|
+
* A FORK node the arms leave from: a `core.logic.merge` with one incoming
|
|
454
|
+
* edge and one edge per arm, which is how Studio Web draws a parallel split
|
|
455
|
+
* (its "Parallel" gateway). Without it the arms leave from the previous
|
|
456
|
+
* step's own port, one edge per arm, which the platform runs the same way.
|
|
457
|
+
* Name it to round-trip a flow the canvas drew with a fork node; `label` is
|
|
458
|
+
* the canvas text, defaulting to the name, and `version` the fork node's
|
|
459
|
+
* exact `core.logic.merge` version when it differs from the join's.
|
|
460
|
+
*
|
|
461
|
+
* ```ts
|
|
462
|
+
* .parallel('join', [(a) => a.step('t1', …), (b) => b.step('t2', …)], { fork: 'split' })
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
fork?: string | {
|
|
466
|
+
name: string;
|
|
467
|
+
label?: string;
|
|
468
|
+
version?: string;
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* The fork node a `.parallel()` asks for, normalized, or `undefined`.
|
|
473
|
+
* @internal
|
|
474
|
+
*/
|
|
475
|
+
export declare function parallelFork(options: ParallelOptions | undefined): {
|
|
476
|
+
name: string;
|
|
477
|
+
label?: string;
|
|
478
|
+
version?: string;
|
|
479
|
+
} | undefined;
|
|
446
480
|
/**
|
|
447
481
|
* `.return(...)`-specific options.
|
|
448
482
|
*
|
|
@@ -587,15 +621,16 @@ export type Step = {
|
|
|
587
621
|
/**
|
|
588
622
|
* A fan-out and its join. `arms` is one step list per arm — an ARRAY, because
|
|
589
623
|
* arms are positional and carry no author-supplied keys — and `name` names the
|
|
590
|
-
* Merge node the arms converge on (the only node this step creates
|
|
591
|
-
*
|
|
624
|
+
* Merge node the arms converge on (the only node this step creates unless
|
|
625
|
+
* `options.fork` names a fork node too; otherwise the fork is just N edges
|
|
626
|
+
* out of one port).
|
|
592
627
|
*/
|
|
593
628
|
| {
|
|
594
629
|
kind: 'parallel';
|
|
595
630
|
name: string;
|
|
596
631
|
label?: string;
|
|
597
632
|
arms: Step[][];
|
|
598
|
-
options?:
|
|
633
|
+
options?: ParallelOptions;
|
|
599
634
|
}
|
|
600
635
|
/**
|
|
601
636
|
* A hard stop: `core.logic.terminate`, a BPMN End event carrying a
|
|
@@ -1136,11 +1171,12 @@ declare class StepList {
|
|
|
1136
1171
|
* @param arms - One callback per parallel arm, each receiving its own
|
|
1137
1172
|
* sub-builder. Two or more.
|
|
1138
1173
|
* @param options - Node options; `version` selects the exact definition
|
|
1139
|
-
* version (see {@link NodeOptions})
|
|
1174
|
+
* version (see {@link NodeOptions}), and `fork` names a fork node the arms
|
|
1175
|
+
* leave from (see {@link ParallelOptions}).
|
|
1140
1176
|
* @returns This builder, positioned after the Merge — so what you chain next
|
|
1141
1177
|
* runs once, when every arm has finished.
|
|
1142
1178
|
*/
|
|
1143
|
-
parallel(name: string, arms: ((b: StepList) => void)[], options?:
|
|
1179
|
+
parallel(name: string, arms: ((b: StepList) => void)[], options?: ParallelOptions): this;
|
|
1144
1180
|
/**
|
|
1145
1181
|
* Iterate `collection`; `bodyFn` receives a sub-builder for the loop body.
|
|
1146
1182
|
*
|
package/dist/flow-sdk.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
export * from './core/expr.js';
|
|
23
23
|
export * from './core/actions.js';
|
|
24
24
|
// Node families' public surfaces (docs/NODE_TYPE_ARCHITECTURE_DESIGN.md §8).
|
|
25
|
+
export * from './nodes/agent/flow/index.js';
|
|
25
26
|
export * from './nodes/ai-patterns/flow/index.js';
|
|
26
27
|
export * from './nodes/conversation/flow/index.js';
|
|
27
28
|
export * from './nodes/data-fabric/flow/index.js';
|
|
@@ -263,6 +264,18 @@ export function conversationTrigger() {
|
|
|
263
264
|
export function voiceTrigger() {
|
|
264
265
|
return builtinTriggerSpec({ kind: 'voice' });
|
|
265
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* The fork node a `.parallel()` asks for, normalized, or `undefined`.
|
|
269
|
+
* @internal
|
|
270
|
+
*/
|
|
271
|
+
export function parallelFork(options) {
|
|
272
|
+
const fork = options?.fork;
|
|
273
|
+
if (fork === undefined)
|
|
274
|
+
return undefined;
|
|
275
|
+
return typeof fork === 'string'
|
|
276
|
+
? { name: fork }
|
|
277
|
+
: { name: fork.name, ...(fork.label !== undefined ? { label: fork.label } : {}), ...(fork.version !== undefined ? { version: fork.version } : {}) };
|
|
278
|
+
}
|
|
266
279
|
/**
|
|
267
280
|
* A node's layout at a canvas position — the short form of a {@link NodeLayout}
|
|
268
281
|
* for the `nodes` map of {@link FlowBuilder.layout}.
|
|
@@ -763,7 +776,8 @@ class StepList {
|
|
|
763
776
|
* @param arms - One callback per parallel arm, each receiving its own
|
|
764
777
|
* sub-builder. Two or more.
|
|
765
778
|
* @param options - Node options; `version` selects the exact definition
|
|
766
|
-
* version (see {@link NodeOptions})
|
|
779
|
+
* version (see {@link NodeOptions}), and `fork` names a fork node the arms
|
|
780
|
+
* leave from (see {@link ParallelOptions}).
|
|
767
781
|
* @returns This builder, positioned after the Merge — so what you chain next
|
|
768
782
|
* runs once, when every arm has finished.
|
|
769
783
|
*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flow variables a step DECLARES by running (`FlowNodeType.declares`): a
|
|
3
|
+
* quick form's asked fields land in their `variable` (`vars.<Step>_<field>` as
|
|
4
|
+
* the designer names it), and later steps read `$vars.<name>`. Resolved at the
|
|
5
|
+
* version the step resolves to, the way `stepExits` does, so `check` and
|
|
6
|
+
* `flow-expr-check` agree on what a step publishes (#1309).
|
|
7
|
+
*/
|
|
8
|
+
import { resolveVersion } from './core/nodes/versioned.js';
|
|
9
|
+
import { FLOW_NODE_TYPES } from './flow-node-registry.js';
|
|
10
|
+
export function stepDeclaredVariables(spec, pinnedVersion) {
|
|
11
|
+
const entry = typeof spec?.kind === 'string' ? FLOW_NODE_TYPES.byKind(spec.kind, spec) : undefined;
|
|
12
|
+
if (!entry)
|
|
13
|
+
return [];
|
|
14
|
+
let impl;
|
|
15
|
+
try {
|
|
16
|
+
impl = resolveVersion(entry.type, spec, pinnedVersion, 'declares');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
impl = resolveVersion(entry.type, spec, undefined, 'declares');
|
|
20
|
+
}
|
|
21
|
+
return impl.declares?.(spec, pinnedVersion) ?? [];
|
|
22
|
+
}
|
package/dist/loop-version.d.ts
CHANGED
|
@@ -3,28 +3,45 @@ import type { LoopOptions, Step } from './flow-sdk.js';
|
|
|
3
3
|
export declare const LOOP_NODE_TYPE = "core.logic.loop";
|
|
4
4
|
/** The `core.logic.loop` version `.loop()` emits unless `{ version }` pins another. */
|
|
5
5
|
export declare const LOOP_DEFAULT_VERSION = "2.4";
|
|
6
|
+
/**
|
|
7
|
+
* The definition a loop at `version` compiles against: the bundled one, else
|
|
8
|
+
* the one the flow carries (`carried`, a `.definitions()` lookup), else
|
|
9
|
+
* `undefined`. `serialize` and `check` both resolve through this, so they agree
|
|
10
|
+
* on a carried `core.logic.loop@1.0`'s handles and inputs (#1311).
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveLoopDefinition(version: string, carried?: (type: string, version: string) => unknown): unknown;
|
|
6
13
|
/** The version `.loop()` emits for these options. */
|
|
7
14
|
export declare function loopVersion(options: LoopOptions | undefined): string;
|
|
8
15
|
/**
|
|
9
16
|
* True when this loop version's body runs from the inner `start` handle and goes
|
|
10
17
|
* back through `continue` (2.x); false for the legacy `output`/`loopBack` shape.
|
|
11
|
-
*
|
|
18
|
+
*
|
|
19
|
+
* The answer is read off the definition's target handles. `definition` is the
|
|
20
|
+
* one the loop compiles against: the bundled one for `version` by default, or
|
|
21
|
+
* the one the flow carries (`.definitions([...])`) when the SDK bundles none —
|
|
22
|
+
* a designer-saved `core.logic.loop@1.0` keeps its `output`/`loopBack` handles
|
|
23
|
+
* only because its carried definition says so (#1311). A version with no
|
|
24
|
+
* definition at all counts as 2.x; its lookup fails later.
|
|
12
25
|
*/
|
|
13
|
-
export declare function loopHasInnerHandles(version: string): boolean;
|
|
26
|
+
export declare function loopHasInnerHandles(version: string, definition?: unknown): boolean;
|
|
14
27
|
/**
|
|
15
28
|
* The features this loop uses that its version's definition cannot express, in
|
|
16
29
|
* a fixed order (`parallel`, `completionCondition`, `breakEnabled`, `break()`).
|
|
17
30
|
* Empty when all are supported, or when no definition is bundled for the version
|
|
18
31
|
* (an unknown version is reported elsewhere, by the definition lookup).
|
|
19
32
|
*/
|
|
20
|
-
export declare function unsupportedLoopFeatures(options: LoopOptions | undefined, usesBreak: boolean): string[];
|
|
33
|
+
export declare function unsupportedLoopFeatures(options: LoopOptions | undefined, usesBreak: boolean, definition?: unknown): string[];
|
|
34
|
+
/** The inputs a loop definition declares (`collection`, `parallel`, `completionCondition`, `breakEnabled`, …). */
|
|
35
|
+
export declare function loopDeclaredInputs(definition: unknown): Record<string, unknown>;
|
|
21
36
|
/**
|
|
22
37
|
* The refusal for a loop whose options or body need a definition the requested
|
|
23
38
|
* version does not have, or `undefined` when there is nothing to refuse.
|
|
24
39
|
* `serialize` throws it; `check` reports it as `LOOP_VERSION_UNSUPPORTED` with
|
|
25
|
-
* the same text, so the author reads one message in both places.
|
|
40
|
+
* the same text, so the author reads one message in both places. `definition`
|
|
41
|
+
* is the one the loop compiles against (bundled, else carried), as for
|
|
42
|
+
* `loopHasInnerHandles`.
|
|
26
43
|
*/
|
|
27
|
-
export declare function loopVersionRefusal(name: string, options: LoopOptions | undefined, usesBreak: boolean): string | undefined;
|
|
44
|
+
export declare function loopVersionRefusal(name: string, options: LoopOptions | undefined, usesBreak: boolean, definition?: unknown): string | undefined;
|
|
28
45
|
/**
|
|
29
46
|
* The warning for `parallel: true` on a 1.0.0 loop, or `undefined`. The 1.0.0
|
|
30
47
|
* definition declares the input, so the loop compiles and a canvas 1.0.0 loop
|
|
@@ -32,7 +49,7 @@ export declare function loopVersionRefusal(name: string, options: LoopOptions |
|
|
|
32
49
|
* confirmed, so a new loop that needs that should use the default version.
|
|
33
50
|
* `check` reports it as `LOOP_PARALLEL_LEGACY`.
|
|
34
51
|
*/
|
|
35
|
-
export declare function loopParallelWarning(name: string, options: LoopOptions | undefined): string | undefined;
|
|
52
|
+
export declare function loopParallelWarning(name: string, options: LoopOptions | undefined, definition?: unknown): string | undefined;
|
|
36
53
|
/**
|
|
37
54
|
* True when a container body (or an arm/handler inside it, but not a NESTED
|
|
38
55
|
* container's body) breaks: a nested `.loop()`/`.doWhile()` owns its own
|
package/dist/loop-version.js
CHANGED
|
@@ -11,6 +11,15 @@ import { BUNDLED_DEFINITIONS } from './flow-definitions.js';
|
|
|
11
11
|
export const LOOP_NODE_TYPE = 'core.logic.loop';
|
|
12
12
|
/** The `core.logic.loop` version `.loop()` emits unless `{ version }` pins another. */
|
|
13
13
|
export const LOOP_DEFAULT_VERSION = '2.4';
|
|
14
|
+
/**
|
|
15
|
+
* The definition a loop at `version` compiles against: the bundled one, else
|
|
16
|
+
* the one the flow carries (`carried`, a `.definitions()` lookup), else
|
|
17
|
+
* `undefined`. `serialize` and `check` both resolve through this, so they agree
|
|
18
|
+
* on a carried `core.logic.loop@1.0`'s handles and inputs (#1311).
|
|
19
|
+
*/
|
|
20
|
+
export function resolveLoopDefinition(version, carried) {
|
|
21
|
+
return loopDefinition(version) ?? carried?.(LOOP_NODE_TYPE, version);
|
|
22
|
+
}
|
|
14
23
|
/** The version `.loop()` emits for these options. */
|
|
15
24
|
export function loopVersion(options) {
|
|
16
25
|
return options?.version ?? LOOP_DEFAULT_VERSION;
|
|
@@ -18,10 +27,16 @@ export function loopVersion(options) {
|
|
|
18
27
|
/**
|
|
19
28
|
* True when this loop version's body runs from the inner `start` handle and goes
|
|
20
29
|
* back through `continue` (2.x); false for the legacy `output`/`loopBack` shape.
|
|
21
|
-
*
|
|
30
|
+
*
|
|
31
|
+
* The answer is read off the definition's target handles. `definition` is the
|
|
32
|
+
* one the loop compiles against: the bundled one for `version` by default, or
|
|
33
|
+
* the one the flow carries (`.definitions([...])`) when the SDK bundles none —
|
|
34
|
+
* a designer-saved `core.logic.loop@1.0` keeps its `output`/`loopBack` handles
|
|
35
|
+
* only because its carried definition says so (#1311). A version with no
|
|
36
|
+
* definition at all counts as 2.x; its lookup fails later.
|
|
22
37
|
*/
|
|
23
|
-
export function loopHasInnerHandles(version) {
|
|
24
|
-
return
|
|
38
|
+
export function loopHasInnerHandles(version, definition = loopDefinition(version)) {
|
|
39
|
+
return definition ? targetHandleIdsOf(definition).has('continue') : true;
|
|
25
40
|
}
|
|
26
41
|
/** The loop options whose support depends on the version, in message order. */
|
|
27
42
|
const VERSIONED_OPTIONS = ['parallel', 'completionCondition', 'breakEnabled'];
|
|
@@ -31,24 +46,29 @@ const VERSIONED_OPTIONS = ['parallel', 'completionCondition', 'breakEnabled'];
|
|
|
31
46
|
* Empty when all are supported, or when no definition is bundled for the version
|
|
32
47
|
* (an unknown version is reported elsewhere, by the definition lookup).
|
|
33
48
|
*/
|
|
34
|
-
export function unsupportedLoopFeatures(options, usesBreak) {
|
|
35
|
-
|
|
36
|
-
if (!def)
|
|
49
|
+
export function unsupportedLoopFeatures(options, usesBreak, definition = loopDefinition(loopVersion(options))) {
|
|
50
|
+
if (!definition)
|
|
37
51
|
return [];
|
|
38
|
-
const inputs =
|
|
52
|
+
const inputs = loopDeclaredInputs(definition);
|
|
39
53
|
const out = VERSIONED_OPTIONS.filter((k) => options?.[k] !== undefined && !(k in inputs));
|
|
40
|
-
if (usesBreak && !
|
|
54
|
+
if (usesBreak && !targetHandleIdsOf(definition).has('break'))
|
|
41
55
|
out.push('break()');
|
|
42
56
|
return out;
|
|
43
57
|
}
|
|
58
|
+
/** The inputs a loop definition declares (`collection`, `parallel`, `completionCondition`, `breakEnabled`, …). */
|
|
59
|
+
export function loopDeclaredInputs(definition) {
|
|
60
|
+
return definition?.inputDefinition?.properties ?? {};
|
|
61
|
+
}
|
|
44
62
|
/**
|
|
45
63
|
* The refusal for a loop whose options or body need a definition the requested
|
|
46
64
|
* version does not have, or `undefined` when there is nothing to refuse.
|
|
47
65
|
* `serialize` throws it; `check` reports it as `LOOP_VERSION_UNSUPPORTED` with
|
|
48
|
-
* the same text, so the author reads one message in both places.
|
|
66
|
+
* the same text, so the author reads one message in both places. `definition`
|
|
67
|
+
* is the one the loop compiles against (bundled, else carried), as for
|
|
68
|
+
* `loopHasInnerHandles`.
|
|
49
69
|
*/
|
|
50
|
-
export function loopVersionRefusal(name, options, usesBreak) {
|
|
51
|
-
const missing = unsupportedLoopFeatures(options, usesBreak);
|
|
70
|
+
export function loopVersionRefusal(name, options, usesBreak, definition = loopDefinition(loopVersion(options))) {
|
|
71
|
+
const missing = unsupportedLoopFeatures(options, usesBreak, definition);
|
|
52
72
|
if (missing.length === 0)
|
|
53
73
|
return undefined;
|
|
54
74
|
const version = loopVersion(options);
|
|
@@ -63,8 +83,8 @@ export function loopVersionRefusal(name, options, usesBreak) {
|
|
|
63
83
|
* confirmed, so a new loop that needs that should use the default version.
|
|
64
84
|
* `check` reports it as `LOOP_PARALLEL_LEGACY`.
|
|
65
85
|
*/
|
|
66
|
-
export function loopParallelWarning(name, options) {
|
|
67
|
-
if (options?.parallel !== true || loopHasInnerHandles(loopVersion(options)))
|
|
86
|
+
export function loopParallelWarning(name, options, definition = loopDefinition(loopVersion(options))) {
|
|
87
|
+
if (options?.parallel !== true || loopHasInnerHandles(loopVersion(options), definition))
|
|
68
88
|
return undefined;
|
|
69
89
|
return `loop "${name}": parallel: true on { version: '${loopVersion(options)}' } is written to the node, but `
|
|
70
90
|
+ `that version is not confirmed to run iterations in parallel, so the loop may run them one by one. `
|
|
@@ -86,9 +106,11 @@ export function bodyUsesBreak(steps) {
|
|
|
86
106
|
function loopDefinition(version) {
|
|
87
107
|
return BUNDLED_DEFINITIONS[`${LOOP_NODE_TYPE}@${version}`];
|
|
88
108
|
}
|
|
89
|
-
|
|
109
|
+
/** The ids of a definition's target handles (`input`, `loopBack`, `continue`, `break`, …). */
|
|
110
|
+
function targetHandleIdsOf(definition) {
|
|
90
111
|
const ids = new Set();
|
|
91
|
-
|
|
112
|
+
const groups = definition?.handleConfiguration ?? [];
|
|
113
|
+
for (const group of groups) {
|
|
92
114
|
for (const h of group.handles ?? [])
|
|
93
115
|
if (h.type === 'target')
|
|
94
116
|
ids.add(h.id);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agents family's rules: what is decidable from a call to
|
|
3
|
+
* `conversationalAgent()`, `voiceAgent()`, `createOutgoingCall()`, `endCall()`
|
|
4
|
+
* or `inlineAgent()` — the turn wiring, the call's numbers, the `callContext`
|
|
5
|
+
* the voice steps share, and an inline agent's prompts, inputs, guardrails and
|
|
6
|
+
* resources. Moved from check.ts in Phase 4 of
|
|
7
|
+
* docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; codes and messages unchanged.
|
|
8
|
+
*/
|
|
9
|
+
import type { DiagnosticCatalog } from '../../../core/nodes/family.js';
|
|
10
|
+
import type { OutputPathRead } from '../../../core/nodes/node-type.js';
|
|
11
|
+
import type { FlowCheckContext } from '../../../flow-node-type.js';
|
|
12
|
+
import type { InlineAgentInputs } from './spec.js';
|
|
13
|
+
export declare const AGENT_DIAGNOSTICS: DiagnosticCatalog;
|
|
14
|
+
/**
|
|
15
|
+
* A conversational AGENT step (Phase 5).
|
|
16
|
+
*
|
|
17
|
+
* The turn wiring is the whole risk: `'simple'` mode reads everything out of
|
|
18
|
+
* ONE conversation-context binding, so a flow that names neither the context
|
|
19
|
+
* nor the individual fields deploys an agent with no transcript to answer.
|
|
20
|
+
*/
|
|
21
|
+
export declare function checkConversationalAgent(inputs: Record<string, unknown> | undefined, ctx: FlowCheckContext): void;
|
|
22
|
+
/**
|
|
23
|
+
* A VOICE step (Phase 5D): create-outgoing-call, end-call, or the voice agent.
|
|
24
|
+
*
|
|
25
|
+
* Two things are decidable offline and expensive later: a call needs both
|
|
26
|
+
* numbers in a form the telephony provider accepts, and every voice step needs
|
|
27
|
+
* the `callContext` OBJECT — binding a bare conversation id instead is the
|
|
28
|
+
* classic mistake, because the field is typed `object` and a string passes the
|
|
29
|
+
* file's schema while failing at dispatch.
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkVoice(kind: 'createOutgoingCall' | 'endCall' | 'voiceAgent', inputs: Record<string, unknown> | undefined, ctx: FlowCheckContext): void;
|
|
32
|
+
/**
|
|
33
|
+
* The phrase in `text` that tells a model to answer in JSON TEXT, or `undefined`.
|
|
34
|
+
*
|
|
35
|
+
* `check` uses it for `INLINE_AGENT_PROMPT_JSON_TEXT`, passing the step's `returns`
|
|
36
|
+
* keys so the brace form only counts a brace that spells one of them. Without
|
|
37
|
+
* `returnKeys` (the example and doc sweeps) any quoted identifier key counts.
|
|
38
|
+
* `{{input.*}}` placeholders are removed first, so an input named `json` never
|
|
39
|
+
* matches.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* jsonTextDirective('Return ONLY a JSON object with keys "subject" and "body".'); // 'Return ONLY a JSON'
|
|
44
|
+
* jsonTextDirective('Return ONLY {"category","priority"}.', ['category']); // '{"category",'
|
|
45
|
+
* jsonTextDirective('Return a result conforming to the output schema.'); // undefined
|
|
46
|
+
* jsonTextDirective('Do not return JSON.'); // undefined
|
|
47
|
+
* jsonTextDirective('Answer the question using the JSON data below.'); // undefined
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function jsonTextDirective(text: string, returnKeys?: readonly string[]): string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Check an `inlineAgent(...)` call.
|
|
53
|
+
*
|
|
54
|
+
* The interesting difference from every other node this SDK authors: **nothing here
|
|
55
|
+
* lives on a tenant.** An inline agent's whole contract is in the call, so these
|
|
56
|
+
* rules can be certain rather than best-effort — the definition's own `required`
|
|
57
|
+
* list is checkable, and so is whether the prompts and the declared variables agree.
|
|
58
|
+
*
|
|
59
|
+
* Three rules exist because the PLATFORM does something with what you wrote:
|
|
60
|
+
*
|
|
61
|
+
* - `INLINE_AGENT_SCAFFOLD_MODEL` — the model the platform's own scaffold ships is
|
|
62
|
+
* stale, and v1's smoke check for this node type fails a flow that keeps it. A
|
|
63
|
+
* warning, not an error: it is a real model id, it just should not be a default
|
|
64
|
+
* nobody chose.
|
|
65
|
+
* - `INLINE_AGENT_UNREFERENCED_INPUT` — flow-v1 derives the deployed input list by
|
|
66
|
+
* scanning the PROMPTS for `$vars.*` references and only falls back to the
|
|
67
|
+
* authored `agentInputVariables` when that pre-pass did not run. So a declared
|
|
68
|
+
* input the prompts never mention is pruned deployed while arriving locally: a
|
|
69
|
+
* disagreement between rungs and the platform, which is the one class that has to
|
|
70
|
+
* be said out loud rather than left to a run.
|
|
71
|
+
* - `INLINE_AGENT_PROMPT_JSON_TEXT` — the platform returns `returns` as a typed
|
|
72
|
+
* object: it becomes the `agent.json` `outputSchema`, and the agent runtime ends
|
|
73
|
+
* a run with a structured call that fills exactly those fields. A prompt that
|
|
74
|
+
* ALSO asks for JSON text makes the model pack its whole answer, serialized, into
|
|
75
|
+
* one string field. See {@link jsonTextDirective}.
|
|
76
|
+
*/
|
|
77
|
+
export declare function checkInlineAgent(inputs: InlineAgentInputs | undefined, ctx: FlowCheckContext): void;
|
|
78
|
+
/**
|
|
79
|
+
* A read of an inline agent's output: `out('<step>', '<field>')`.
|
|
80
|
+
*
|
|
81
|
+
* Stricter than the published families' equivalent, and it can afford to be: the
|
|
82
|
+
* declared `returns` IS the contract (there is no tenant to disagree with), and it
|
|
83
|
+
* is what any runner has to coerce the model's completion to: build
|
|
84
|
+
* `{ <declared keys> }` and put the raw completion in the first one if the model
|
|
85
|
+
* ignored the shape. So a read outside the set is undefined by construction, not
|
|
86
|
+
* merely probably.
|
|
87
|
+
*/
|
|
88
|
+
export declare function checkInlineAgentRead({ node: name, field, rest, reader: step }: OutputPathRead, spec: InlineAgentInputs, report: (code: string, message: string, suggestion?: string) => void): void;
|