@foresthubai/workflow-core 0.3.0 → 0.4.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/LICENSE +202 -202
- package/NOTICE +14 -14
- package/README.md +63 -63
- package/dist/api/workflow.d.ts +2 -2
- package/dist/api/workflow.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/index.ts +11 -11
- package/src/api/workflow.ts +607 -607
- package/src/channel/Channel.ts +11 -11
- package/src/channel/ChannelDefinition.ts +76 -76
- package/src/channel/index.ts +6 -6
- package/src/channel/serialization.ts +68 -68
- package/src/deploy/index.ts +1 -1
- package/src/deploy/requirements.test.ts +61 -61
- package/src/deploy/requirements.ts +41 -41
- package/src/diagnostics/__fixtures__/diagnosticFixtures.ts +158 -158
- package/src/diagnostics/diagnostics.test.ts +878 -878
- package/src/diagnostics/diagnostics.ts +936 -936
- package/src/diagnostics/index.ts +11 -11
- package/src/edge/Edge.ts +23 -23
- package/src/edge/EdgeDefinition.ts +45 -45
- package/src/edge/EdgeType.ts +19 -19
- package/src/edge/index.ts +8 -8
- package/src/edge/serialization.ts +83 -83
- package/src/expression/index.ts +4 -4
- package/src/expression/parser.ts +362 -362
- package/src/expression/types.ts +30 -30
- package/src/function/FunctionDeclaration.ts +54 -54
- package/src/function/index.ts +3 -3
- package/src/function/serialization.ts +40 -40
- package/src/globals.d.ts +9 -9
- package/src/id/index.ts +8 -8
- package/src/index.ts +22 -22
- package/src/memory/Memory.ts +15 -15
- package/src/memory/MemoryDefinition.ts +16 -16
- package/src/memory/MemoryFileDefinition.ts +37 -37
- package/src/memory/MemoryRegistry.ts +35 -35
- package/src/memory/VectorDatabaseDefinition.ts +21 -21
- package/src/memory/index.ts +8 -8
- package/src/memory/serialization.ts +47 -47
- package/src/migration/index.ts +4 -4
- package/src/migration/migrate.test.ts +44 -44
- package/src/migration/migrate.ts +58 -58
- package/src/migration/migrations.ts +24 -24
- package/src/migration/version.ts +9 -9
- package/src/model/LLMModelDefinition.ts +12 -12
- package/src/model/Model.ts +39 -39
- package/src/model/ModelDefinition.ts +15 -15
- package/src/model/ModelRegistry.ts +33 -33
- package/src/model/index.ts +7 -7
- package/src/model/serialization.ts +30 -30
- package/src/node/AgentNode.ts +82 -82
- package/src/node/DataNode.ts +41 -41
- package/src/node/FunctionNode.ts +76 -76
- package/src/node/InputNode.ts +185 -185
- package/src/node/LogicNode.ts +33 -33
- package/src/node/MqttNode.ts +127 -127
- package/src/node/Node.ts +61 -61
- package/src/node/NodeDefinition.ts +37 -37
- package/src/node/NodeRegistry.ts +85 -85
- package/src/node/OutputNode.ts +87 -87
- package/src/node/ToolNode.ts +32 -32
- package/src/node/TriggerNode.ts +272 -272
- package/src/node/constants.ts +16 -16
- package/src/node/index.ts +26 -26
- package/src/node/methods.ts +278 -278
- package/src/node/serialization.ts +544 -544
- package/src/parameter/OutputParameter.ts +68 -68
- package/src/parameter/Parameter.ts +243 -243
- package/src/parameter/index.ts +33 -33
- package/src/variable/Variable.ts +10 -10
- package/src/variable/index.ts +16 -16
- package/src/variable/operations.ts +106 -106
- package/src/workflow/Workflow.ts +41 -41
- package/src/workflow/index.ts +3 -3
- package/src/workflow/serialization.test.ts +240 -240
- package/src/workflow/serialization.ts +242 -242
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import type { Schemas } from "../api";
|
|
2
|
-
import type { Model, ModelCapability } from "./Model";
|
|
3
|
-
|
|
4
|
-
export type ApiModel = Schemas["Model"];
|
|
5
|
-
|
|
6
|
-
/** Serialize a domain Model to the API discriminated-union shape. */
|
|
7
|
-
export function serialize(model: Model): ApiModel {
|
|
8
|
-
const { id, label, type, arguments: args } = model;
|
|
9
|
-
switch (type) {
|
|
10
|
-
case "LLMModel":
|
|
11
|
-
return {
|
|
12
|
-
type,
|
|
13
|
-
id,
|
|
14
|
-
label,
|
|
15
|
-
capabilities: (args.capabilities as ModelCapability[]) ?? ["chat"],
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Convert an API Model into a domain Model. */
|
|
21
|
-
export function deserialize(api: ApiModel): Model {
|
|
22
|
-
const { id, label, type } = api;
|
|
23
|
-
const args: Record<string, unknown> = {};
|
|
24
|
-
switch (type) {
|
|
25
|
-
case "LLMModel":
|
|
26
|
-
args.capabilities = api.capabilities;
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
return { id, label, type, arguments: args };
|
|
30
|
-
}
|
|
1
|
+
import type { Schemas } from "../api";
|
|
2
|
+
import type { Model, ModelCapability } from "./Model";
|
|
3
|
+
|
|
4
|
+
export type ApiModel = Schemas["Model"];
|
|
5
|
+
|
|
6
|
+
/** Serialize a domain Model to the API discriminated-union shape. */
|
|
7
|
+
export function serialize(model: Model): ApiModel {
|
|
8
|
+
const { id, label, type, arguments: args } = model;
|
|
9
|
+
switch (type) {
|
|
10
|
+
case "LLMModel":
|
|
11
|
+
return {
|
|
12
|
+
type,
|
|
13
|
+
id,
|
|
14
|
+
label,
|
|
15
|
+
capabilities: (args.capabilities as ModelCapability[]) ?? ["chat"],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Convert an API Model into a domain Model. */
|
|
21
|
+
export function deserialize(api: ApiModel): Model {
|
|
22
|
+
const { id, label, type } = api;
|
|
23
|
+
const args: Record<string, unknown> = {};
|
|
24
|
+
switch (type) {
|
|
25
|
+
case "LLMModel":
|
|
26
|
+
args.capabilities = api.capabilities;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
return { id, label, type, arguments: args };
|
|
30
|
+
}
|
package/src/node/AgentNode.ts
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import { NodeBase } from "./Node";
|
|
2
|
-
import { OutputBinding, OutputDeclaration } from "../parameter";
|
|
3
|
-
import type { Schemas } from "../api";
|
|
4
|
-
import { NodeCategory } from "./constants";
|
|
5
|
-
import { NodeDefinition } from "./NodeDefinition";
|
|
6
|
-
|
|
7
|
-
export type MemoryRef = Schemas["MemoryRef"];
|
|
8
|
-
|
|
9
|
-
export interface AgentNode extends NodeBase {
|
|
10
|
-
type: "Agent";
|
|
11
|
-
arguments: {
|
|
12
|
-
name: string;
|
|
13
|
-
model: string;
|
|
14
|
-
instructions: string;
|
|
15
|
-
maxTurns: number | undefined;
|
|
16
|
-
outputDeclarations: OutputDeclaration[];
|
|
17
|
-
memoryRefs: MemoryRef[];
|
|
18
|
-
answer: OutputBinding;
|
|
19
|
-
toolDescription?: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type AgentNodeType = "Agent";
|
|
24
|
-
|
|
25
|
-
export const AgentNodeDefinition: NodeDefinition = {
|
|
26
|
-
type: "Agent",
|
|
27
|
-
label: "LLM Agent",
|
|
28
|
-
category: NodeCategory.AI,
|
|
29
|
-
description: "AI-powered agent for intelligent processing",
|
|
30
|
-
canBranch: true, // Control output may fan out to multiple branches (tool output is always multi-target).
|
|
31
|
-
outputs: [
|
|
32
|
-
{ id: "answer", label: "Answer", type: "static", dataType: "string" },
|
|
33
|
-
{ id: "outputDeclarations", label: "Structured Output", type: "list" },
|
|
34
|
-
],
|
|
35
|
-
parameters: [
|
|
36
|
-
{
|
|
37
|
-
id: "name",
|
|
38
|
-
label: "Name",
|
|
39
|
-
description: "Name of the agent",
|
|
40
|
-
optional: true,
|
|
41
|
-
type: "string",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
id: "model",
|
|
45
|
-
label: "Model",
|
|
46
|
-
description: "AI model to use for the agent",
|
|
47
|
-
type: "modelSelect",
|
|
48
|
-
modelType: ["LLMModel"],
|
|
49
|
-
capabilities: ["chat"],
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id: "instructions",
|
|
53
|
-
label: "Instructions",
|
|
54
|
-
description: "Instructions for the cloud agent that act as system prompt",
|
|
55
|
-
type: "string",
|
|
56
|
-
multiline: true,
|
|
57
|
-
optional: true,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
id: "maxTurns",
|
|
61
|
-
label: "Max Turns",
|
|
62
|
-
description: "Maximum number of agent runner turns",
|
|
63
|
-
type: "int",
|
|
64
|
-
optional: true,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
id: "memoryRefs",
|
|
68
|
-
label: "Memory Files",
|
|
69
|
-
description: "Project memory files this agent can access, with per-file read or read+write mode",
|
|
70
|
-
type: "memory-refs",
|
|
71
|
-
default: [],
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
id: "toolDescription",
|
|
75
|
-
label: "Tool Description",
|
|
76
|
-
description: "Description shown to the calling agent when this agent is wired as a tool",
|
|
77
|
-
type: "string",
|
|
78
|
-
multiline: true,
|
|
79
|
-
activationRules: [{ type: "isToolInput" }],
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
};
|
|
1
|
+
import { NodeBase } from "./Node";
|
|
2
|
+
import { OutputBinding, OutputDeclaration } from "../parameter";
|
|
3
|
+
import type { Schemas } from "../api";
|
|
4
|
+
import { NodeCategory } from "./constants";
|
|
5
|
+
import { NodeDefinition } from "./NodeDefinition";
|
|
6
|
+
|
|
7
|
+
export type MemoryRef = Schemas["MemoryRef"];
|
|
8
|
+
|
|
9
|
+
export interface AgentNode extends NodeBase {
|
|
10
|
+
type: "Agent";
|
|
11
|
+
arguments: {
|
|
12
|
+
name: string;
|
|
13
|
+
model: string;
|
|
14
|
+
instructions: string;
|
|
15
|
+
maxTurns: number | undefined;
|
|
16
|
+
outputDeclarations: OutputDeclaration[];
|
|
17
|
+
memoryRefs: MemoryRef[];
|
|
18
|
+
answer: OutputBinding;
|
|
19
|
+
toolDescription?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type AgentNodeType = "Agent";
|
|
24
|
+
|
|
25
|
+
export const AgentNodeDefinition: NodeDefinition = {
|
|
26
|
+
type: "Agent",
|
|
27
|
+
label: "LLM Agent",
|
|
28
|
+
category: NodeCategory.AI,
|
|
29
|
+
description: "AI-powered agent for intelligent processing",
|
|
30
|
+
canBranch: true, // Control output may fan out to multiple branches (tool output is always multi-target).
|
|
31
|
+
outputs: [
|
|
32
|
+
{ id: "answer", label: "Answer", type: "static", dataType: "string" },
|
|
33
|
+
{ id: "outputDeclarations", label: "Structured Output", type: "list" },
|
|
34
|
+
],
|
|
35
|
+
parameters: [
|
|
36
|
+
{
|
|
37
|
+
id: "name",
|
|
38
|
+
label: "Name",
|
|
39
|
+
description: "Name of the agent",
|
|
40
|
+
optional: true,
|
|
41
|
+
type: "string",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "model",
|
|
45
|
+
label: "Model",
|
|
46
|
+
description: "AI model to use for the agent",
|
|
47
|
+
type: "modelSelect",
|
|
48
|
+
modelType: ["LLMModel"],
|
|
49
|
+
capabilities: ["chat"],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "instructions",
|
|
53
|
+
label: "Instructions",
|
|
54
|
+
description: "Instructions for the cloud agent that act as system prompt",
|
|
55
|
+
type: "string",
|
|
56
|
+
multiline: true,
|
|
57
|
+
optional: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "maxTurns",
|
|
61
|
+
label: "Max Turns",
|
|
62
|
+
description: "Maximum number of agent runner turns",
|
|
63
|
+
type: "int",
|
|
64
|
+
optional: true,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "memoryRefs",
|
|
68
|
+
label: "Memory Files",
|
|
69
|
+
description: "Project memory files this agent can access, with per-file read or read+write mode",
|
|
70
|
+
type: "memory-refs",
|
|
71
|
+
default: [],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "toolDescription",
|
|
75
|
+
label: "Tool Description",
|
|
76
|
+
description: "Description shown to the calling agent when this agent is wired as a tool",
|
|
77
|
+
type: "string",
|
|
78
|
+
multiline: true,
|
|
79
|
+
activationRules: [{ type: "isToolInput" }],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
package/src/node/DataNode.ts
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { NodeBase } from "./Node";
|
|
2
|
-
import type { Expression, Reference } from "../api";
|
|
3
|
-
import { NodeCategory } from "./constants";
|
|
4
|
-
import { NodeDefinition } from "./NodeDefinition";
|
|
5
|
-
|
|
6
|
-
export interface SetVariableNode extends NodeBase {
|
|
7
|
-
type: "SetVariable";
|
|
8
|
-
arguments: {
|
|
9
|
-
variable: Reference | undefined;
|
|
10
|
-
value: Expression;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type DataNodeType = "SetVariable";
|
|
15
|
-
export type DataNode = SetVariableNode;
|
|
16
|
-
|
|
17
|
-
// Node Definitions
|
|
18
|
-
|
|
19
|
-
export const SetVariableNodeDefinition: NodeDefinition = {
|
|
20
|
-
type: "SetVariable",
|
|
21
|
-
label: "Set Variable",
|
|
22
|
-
category: NodeCategory.Data,
|
|
23
|
-
description: "Assign a new value to an existing variable",
|
|
24
|
-
parameters: [
|
|
25
|
-
{
|
|
26
|
-
id: "variable",
|
|
27
|
-
label: "Variable",
|
|
28
|
-
description: "The variable to update",
|
|
29
|
-
type: "variableSelect",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: "value",
|
|
33
|
-
label: "Value",
|
|
34
|
-
description: "Expression to assign",
|
|
35
|
-
type: "expression",
|
|
36
|
-
expressionType: "int", // fallback; actual type is derived from the target variable (see fromReference)
|
|
37
|
-
fromReference: "variable",
|
|
38
|
-
default: { expression: "", references: [], dataType: "int" },
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
};
|
|
1
|
+
import { NodeBase } from "./Node";
|
|
2
|
+
import type { Expression, Reference } from "../api";
|
|
3
|
+
import { NodeCategory } from "./constants";
|
|
4
|
+
import { NodeDefinition } from "./NodeDefinition";
|
|
5
|
+
|
|
6
|
+
export interface SetVariableNode extends NodeBase {
|
|
7
|
+
type: "SetVariable";
|
|
8
|
+
arguments: {
|
|
9
|
+
variable: Reference | undefined;
|
|
10
|
+
value: Expression;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type DataNodeType = "SetVariable";
|
|
15
|
+
export type DataNode = SetVariableNode;
|
|
16
|
+
|
|
17
|
+
// Node Definitions
|
|
18
|
+
|
|
19
|
+
export const SetVariableNodeDefinition: NodeDefinition = {
|
|
20
|
+
type: "SetVariable",
|
|
21
|
+
label: "Set Variable",
|
|
22
|
+
category: NodeCategory.Data,
|
|
23
|
+
description: "Assign a new value to an existing variable",
|
|
24
|
+
parameters: [
|
|
25
|
+
{
|
|
26
|
+
id: "variable",
|
|
27
|
+
label: "Variable",
|
|
28
|
+
description: "The variable to update",
|
|
29
|
+
type: "variableSelect",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "value",
|
|
33
|
+
label: "Value",
|
|
34
|
+
description: "Expression to assign",
|
|
35
|
+
type: "expression",
|
|
36
|
+
expressionType: "int", // fallback; actual type is derived from the target variable (see fromReference)
|
|
37
|
+
fromReference: "variable",
|
|
38
|
+
default: { expression: "", references: [], dataType: "int" },
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
package/src/node/FunctionNode.ts
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import { NodeBase } from "./Node";
|
|
2
|
-
import type { Expression } from "../api";
|
|
3
|
-
import type { FunctionInfo } from "../function";
|
|
4
|
-
import type { DataType } from "../api";
|
|
5
|
-
import { OutputBinding } from "../parameter";
|
|
6
|
-
import { NodeDefinition } from "./NodeDefinition";
|
|
7
|
-
import { NodeCategory } from "./constants";
|
|
8
|
-
import { paramKey } from "../variable";
|
|
9
|
-
|
|
10
|
-
// Function Call Node - invokes a user-defined function.
|
|
11
|
-
// Arguments are flat — keyed by Variable uid. Input argument uids map to Expression,
|
|
12
|
-
// return uids map to OutputBinding. Same shape as every other node, so the rest of
|
|
13
|
-
// the system (parameter editors, output bindings, merge/update) treats FunctionCall
|
|
14
|
-
// uniformly. Outputs are derived on-the-fly via buildFunctionNodeDef from
|
|
15
|
-
// functionInfo.returns — there is no registered NodeDefinition.
|
|
16
|
-
export interface FunctionCallNode extends NodeBase {
|
|
17
|
-
type: "FunctionCall";
|
|
18
|
-
functionInfo: FunctionInfo; // Snapshot at creation; may be stale vs registry
|
|
19
|
-
// Flat bag keyed by Variable uid (Expression for args, OutputBinding for returns),
|
|
20
|
-
// plus the reserved `toolDescription` key (string) for the tool-mode parameter.
|
|
21
|
-
arguments: Record<string, Expression | OutputBinding | string>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type FunctionCallNodeType = "FunctionCall";
|
|
25
|
-
|
|
26
|
-
// FunctionNodeDefinition extends NodeDefinition with function-specific fields
|
|
27
|
-
// Used by NodeLibrary to create new FunctionCall nodes
|
|
28
|
-
export interface FunctionNodeDefinition extends NodeDefinition {
|
|
29
|
-
type: "FunctionCall";
|
|
30
|
-
functionInfo: FunctionInfo; // Metadata about the function being called
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Build a FunctionCall NodeDefinition from FunctionInfo. Pure — takes an
|
|
35
|
-
* optional translator function so the headless validator can call it without
|
|
36
|
-
* an i18n runtime; workflow-builder passes `i18n.t.bind(i18n)` to get
|
|
37
|
-
* translated descriptions. Defaults to identity (returns the key) when no
|
|
38
|
-
* translator is supplied; validation logic ignores description strings.
|
|
39
|
-
*/
|
|
40
|
-
export function buildFunctionNodeDef(
|
|
41
|
-
fn: FunctionInfo,
|
|
42
|
-
t: (key: string, params?: Record<string, unknown>) => string = (key) => key,
|
|
43
|
-
): FunctionNodeDefinition {
|
|
44
|
-
return {
|
|
45
|
-
type: "FunctionCall",
|
|
46
|
-
functionInfo: fn,
|
|
47
|
-
label: fn.name,
|
|
48
|
-
category: NodeCategory.Function,
|
|
49
|
-
description: t("builder.functionCallDesc", { name: fn.name }),
|
|
50
|
-
parameters: [
|
|
51
|
-
...fn.arguments.map((param) => ({
|
|
52
|
-
id: paramKey(param),
|
|
53
|
-
label: param.name,
|
|
54
|
-
description: t("builder.functionParamDesc", { name: param.name }),
|
|
55
|
-
type: "expression" as const,
|
|
56
|
-
expressionType: param.dataType as DataType,
|
|
57
|
-
default: { expression: "", references: [], dataType: param.dataType as DataType },
|
|
58
|
-
activationRules: [{ type: "isControlFlow" as const }],
|
|
59
|
-
})),
|
|
60
|
-
{
|
|
61
|
-
id: "toolDescription",
|
|
62
|
-
label: "Tool Description",
|
|
63
|
-
description: "Description shown to the agent when this function is wired as a tool",
|
|
64
|
-
type: "string" as const,
|
|
65
|
-
multiline: true,
|
|
66
|
-
activationRules: [{ type: "isToolInput" as const }],
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
outputs: fn.returns.map((ret) => ({
|
|
70
|
-
id: paramKey(ret),
|
|
71
|
-
label: ret.name,
|
|
72
|
-
type: "static" as const,
|
|
73
|
-
dataType: ret.dataType as DataType,
|
|
74
|
-
})),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
1
|
+
import { NodeBase } from "./Node";
|
|
2
|
+
import type { Expression } from "../api";
|
|
3
|
+
import type { FunctionInfo } from "../function";
|
|
4
|
+
import type { DataType } from "../api";
|
|
5
|
+
import { OutputBinding } from "../parameter";
|
|
6
|
+
import { NodeDefinition } from "./NodeDefinition";
|
|
7
|
+
import { NodeCategory } from "./constants";
|
|
8
|
+
import { paramKey } from "../variable";
|
|
9
|
+
|
|
10
|
+
// Function Call Node - invokes a user-defined function.
|
|
11
|
+
// Arguments are flat — keyed by Variable uid. Input argument uids map to Expression,
|
|
12
|
+
// return uids map to OutputBinding. Same shape as every other node, so the rest of
|
|
13
|
+
// the system (parameter editors, output bindings, merge/update) treats FunctionCall
|
|
14
|
+
// uniformly. Outputs are derived on-the-fly via buildFunctionNodeDef from
|
|
15
|
+
// functionInfo.returns — there is no registered NodeDefinition.
|
|
16
|
+
export interface FunctionCallNode extends NodeBase {
|
|
17
|
+
type: "FunctionCall";
|
|
18
|
+
functionInfo: FunctionInfo; // Snapshot at creation; may be stale vs registry
|
|
19
|
+
// Flat bag keyed by Variable uid (Expression for args, OutputBinding for returns),
|
|
20
|
+
// plus the reserved `toolDescription` key (string) for the tool-mode parameter.
|
|
21
|
+
arguments: Record<string, Expression | OutputBinding | string>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type FunctionCallNodeType = "FunctionCall";
|
|
25
|
+
|
|
26
|
+
// FunctionNodeDefinition extends NodeDefinition with function-specific fields
|
|
27
|
+
// Used by NodeLibrary to create new FunctionCall nodes
|
|
28
|
+
export interface FunctionNodeDefinition extends NodeDefinition {
|
|
29
|
+
type: "FunctionCall";
|
|
30
|
+
functionInfo: FunctionInfo; // Metadata about the function being called
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Build a FunctionCall NodeDefinition from FunctionInfo. Pure — takes an
|
|
35
|
+
* optional translator function so the headless validator can call it without
|
|
36
|
+
* an i18n runtime; workflow-builder passes `i18n.t.bind(i18n)` to get
|
|
37
|
+
* translated descriptions. Defaults to identity (returns the key) when no
|
|
38
|
+
* translator is supplied; validation logic ignores description strings.
|
|
39
|
+
*/
|
|
40
|
+
export function buildFunctionNodeDef(
|
|
41
|
+
fn: FunctionInfo,
|
|
42
|
+
t: (key: string, params?: Record<string, unknown>) => string = (key) => key,
|
|
43
|
+
): FunctionNodeDefinition {
|
|
44
|
+
return {
|
|
45
|
+
type: "FunctionCall",
|
|
46
|
+
functionInfo: fn,
|
|
47
|
+
label: fn.name,
|
|
48
|
+
category: NodeCategory.Function,
|
|
49
|
+
description: t("builder.functionCallDesc", { name: fn.name }),
|
|
50
|
+
parameters: [
|
|
51
|
+
...fn.arguments.map((param) => ({
|
|
52
|
+
id: paramKey(param),
|
|
53
|
+
label: param.name,
|
|
54
|
+
description: t("builder.functionParamDesc", { name: param.name }),
|
|
55
|
+
type: "expression" as const,
|
|
56
|
+
expressionType: param.dataType as DataType,
|
|
57
|
+
default: { expression: "", references: [], dataType: param.dataType as DataType },
|
|
58
|
+
activationRules: [{ type: "isControlFlow" as const }],
|
|
59
|
+
})),
|
|
60
|
+
{
|
|
61
|
+
id: "toolDescription",
|
|
62
|
+
label: "Tool Description",
|
|
63
|
+
description: "Description shown to the agent when this function is wired as a tool",
|
|
64
|
+
type: "string" as const,
|
|
65
|
+
multiline: true,
|
|
66
|
+
activationRules: [{ type: "isToolInput" as const }],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
outputs: fn.returns.map((ret) => ({
|
|
70
|
+
id: paramKey(ret),
|
|
71
|
+
label: ret.name,
|
|
72
|
+
type: "static" as const,
|
|
73
|
+
dataType: ret.dataType as DataType,
|
|
74
|
+
})),
|
|
75
|
+
};
|
|
76
|
+
}
|