@elizaos/plugin-workflow 2.0.0-beta.1 → 2.0.3-beta.5
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 +21 -0
- package/README.md +28 -26
- package/dist/actions/eval-code.d.ts +12 -0
- package/dist/actions/eval-code.d.ts.map +1 -0
- package/dist/actions/eval-code.js +59 -0
- package/dist/actions/eval-code.js.map +1 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +1 -0
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/workflow.d.ts +7 -0
- package/dist/actions/workflow.d.ts.map +1 -1
- package/dist/actions/workflow.js +462 -10
- package/dist/actions/workflow.js.map +1 -1
- package/dist/db/schema.d.ts +196 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +23 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -64
- package/dist/index.js.map +1 -1
- package/dist/lib/automations-builder.d.ts.map +1 -1
- package/dist/lib/automations-builder.js +10 -35
- package/dist/lib/automations-builder.js.map +1 -1
- package/dist/lib/automations-types.d.ts +2 -2
- package/dist/lib/automations-types.d.ts.map +1 -1
- package/dist/lib/automations-types.js.map +1 -1
- package/dist/lib/index.d.ts +0 -2
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/workflow-clarification.d.ts +2 -2
- package/dist/lib/workflow-clarification.d.ts.map +1 -1
- package/dist/lib/workflow-clarification.js +15 -11
- package/dist/lib/workflow-clarification.js.map +1 -1
- package/dist/plugin-routes.d.ts.map +1 -1
- package/dist/plugin-routes.js +6 -0
- package/dist/plugin-routes.js.map +1 -1
- package/dist/providers/activeWorkflows.js +2 -2
- package/dist/providers/activeWorkflows.js.map +1 -1
- package/dist/providers/workflowStatus.js +1 -1
- package/dist/providers/workflowStatus.js.map +1 -1
- package/dist/routes/workflow-routes.d.ts.map +1 -1
- package/dist/routes/workflow-routes.js +68 -2
- package/dist/routes/workflow-routes.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +5 -1
- package/dist/routes/workflows.js.map +1 -1
- package/dist/services/embedded-workflow-service.d.ts +74 -17
- package/dist/services/embedded-workflow-service.d.ts.map +1 -1
- package/dist/services/embedded-workflow-service.js +343 -149
- package/dist/services/embedded-workflow-service.js.map +1 -1
- package/dist/services/smithers-runtime.d.ts +47 -0
- package/dist/services/smithers-runtime.d.ts.map +1 -0
- package/dist/services/smithers-runtime.js +444 -0
- package/dist/services/smithers-runtime.js.map +1 -0
- package/dist/services/workflow-credential-store.js +1 -1
- package/dist/services/workflow-credential-store.js.map +1 -1
- package/dist/services/workflow-dispatch.d.ts +31 -1
- package/dist/services/workflow-dispatch.d.ts.map +1 -1
- package/dist/services/workflow-dispatch.js +75 -10
- package/dist/services/workflow-dispatch.js.map +1 -1
- package/dist/services/workflow-service.d.ts +27 -1
- package/dist/services/workflow-service.d.ts.map +1 -1
- package/dist/services/workflow-service.js +133 -11
- package/dist/services/workflow-service.js.map +1 -1
- package/dist/trigger-routes.d.ts +2 -18
- package/dist/trigger-routes.d.ts.map +1 -1
- package/dist/trigger-routes.js +11 -39
- package/dist/trigger-routes.js.map +1 -1
- package/dist/types/index.d.ts +82 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/workflow-contracts.d.ts +118 -0
- package/dist/types/workflow-contracts.d.ts.map +1 -0
- package/dist/types/workflow-contracts.js +2 -0
- package/dist/types/workflow-contracts.js.map +1 -0
- package/dist/utils/catalog.js +2 -2
- package/dist/utils/catalog.js.map +1 -1
- package/dist/utils/clarification.d.ts +1 -1
- package/dist/utils/clarification.d.ts.map +1 -1
- package/dist/utils/clarification.js +15 -4
- package/dist/utils/clarification.js.map +1 -1
- package/dist/utils/context.js +1 -1
- package/dist/utils/context.js.map +1 -1
- package/dist/utils/evaluation-samples.d.ts +6 -0
- package/dist/utils/evaluation-samples.d.ts.map +1 -0
- package/dist/utils/evaluation-samples.js +216 -0
- package/dist/utils/evaluation-samples.js.map +1 -0
- package/dist/utils/execution-diagnostics.d.ts +26 -0
- package/dist/utils/execution-diagnostics.d.ts.map +1 -0
- package/dist/utils/execution-diagnostics.js +159 -0
- package/dist/utils/execution-diagnostics.js.map +1 -0
- package/dist/utils/generation.d.ts.map +1 -1
- package/dist/utils/generation.js +134 -19
- package/dist/utils/generation.js.map +1 -1
- package/dist/utils/host-capabilities.d.ts.map +1 -1
- package/dist/utils/host-capabilities.js +20 -5
- package/dist/utils/host-capabilities.js.map +1 -1
- package/dist/utils/inferSyntheticOutputSchema.js +3 -3
- package/dist/utils/inferSyntheticOutputSchema.js.map +1 -1
- package/dist/utils/outputSchema.js +1 -1
- package/dist/utils/outputSchema.js.map +1 -1
- package/dist/utils/validateAndRepair.js +10 -10
- package/dist/utils/validateAndRepair.js.map +1 -1
- package/dist/utils/workflow-prompts/draftIntent.d.ts +1 -1
- package/dist/utils/workflow-prompts/draftIntent.d.ts.map +1 -1
- package/dist/utils/workflow-prompts/draftIntent.js +1 -1
- package/dist/utils/workflow-prompts/keywordExtraction.d.ts +1 -1
- package/dist/utils/workflow-prompts/keywordExtraction.d.ts.map +1 -1
- package/dist/utils/workflow-prompts/keywordExtraction.js +1 -1
- package/dist/utils/workflow-prompts/workflowGeneration.d.ts +1 -1
- package/dist/utils/workflow-prompts/workflowGeneration.d.ts.map +1 -1
- package/dist/utils/workflow-prompts/workflowGeneration.js +4 -4
- package/dist/utils/workflow-prompts/workflowMatching.d.ts +1 -1
- package/dist/utils/workflow-prompts/workflowMatching.d.ts.map +1 -1
- package/dist/utils/workflow-prompts/workflowMatching.js +1 -1
- package/dist/utils/workflow.d.ts +1 -0
- package/dist/utils/workflow.d.ts.map +1 -1
- package/dist/utils/workflow.js +44 -8
- package/dist/utils/workflow.js.map +1 -1
- package/package.json +27 -8
- package/registry-entry.json +25 -0
- package/src/actions/eval-code.ts +81 -0
- package/src/actions/index.ts +1 -0
- package/src/actions/workflow.ts +518 -10
- package/src/db/schema.ts +31 -0
- package/src/index.ts +9 -82
- package/src/lib/automations-builder.ts +11 -35
- package/src/lib/automations-types.ts +1 -2
- package/src/lib/index.ts +0 -8
- package/src/lib/workflow-clarification.ts +18 -13
- package/src/plugin-routes.ts +6 -0
- package/src/providers/activeWorkflows.ts +2 -2
- package/src/providers/workflowStatus.ts +1 -1
- package/src/routes/workflow-routes.ts +100 -2
- package/src/routes/workflows.ts +5 -1
- package/src/services/embedded-workflow-service.ts +447 -172
- package/src/services/smithers-runtime.ts +526 -0
- package/src/services/workflow-credential-store.ts +1 -1
- package/src/services/workflow-dispatch.ts +116 -13
- package/src/services/workflow-service.ts +186 -10
- package/src/trigger-routes.ts +12 -70
- package/src/types/index.ts +94 -2
- package/src/types/workflow-contracts.ts +166 -0
- package/src/utils/catalog.ts +2 -2
- package/src/utils/clarification.ts +19 -5
- package/src/utils/context.ts +1 -1
- package/src/utils/evaluation-samples.ts +239 -0
- package/src/utils/execution-diagnostics.ts +192 -0
- package/src/utils/generation.ts +224 -32
- package/src/utils/host-capabilities.ts +21 -5
- package/src/utils/inferSyntheticOutputSchema.ts +3 -3
- package/src/utils/outputSchema.ts +1 -1
- package/src/utils/validateAndRepair.ts +10 -10
- package/src/utils/workflow-prompts/draftIntent.ts +1 -1
- package/src/utils/workflow-prompts/keywordExtraction.ts +1 -1
- package/src/utils/workflow-prompts/workflowGeneration.ts +4 -4
- package/src/utils/workflow-prompts/workflowMatching.ts +1 -1
- package/src/utils/workflow.ts +56 -8
- package/dist/lib/legacy-task-migration.d.ts +0 -20
- package/dist/lib/legacy-task-migration.d.ts.map +0 -1
- package/dist/lib/legacy-task-migration.js +0 -110
- package/dist/lib/legacy-task-migration.js.map +0 -1
- package/dist/lib/legacy-text-trigger-migration.d.ts +0 -18
- package/dist/lib/legacy-text-trigger-migration.d.ts.map +0 -1
- package/dist/lib/legacy-text-trigger-migration.js +0 -131
- package/dist/lib/legacy-text-trigger-migration.js.map +0 -1
- package/src/lib/legacy-task-migration.ts +0 -143
- package/src/lib/legacy-text-trigger-migration.ts +0 -178
package/src/types/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
INodeProperties,
|
|
6
6
|
INodeTypeDescription,
|
|
7
7
|
IWorkflowSettings,
|
|
8
|
-
} from '
|
|
8
|
+
} from './workflow-contracts';
|
|
9
9
|
|
|
10
10
|
// Core workflow types
|
|
11
11
|
|
|
@@ -111,6 +111,27 @@ export interface WorkflowDefinitionResponse extends WorkflowDefinition {
|
|
|
111
111
|
versionId: string;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
export type WorkflowRevisionOperation =
|
|
115
|
+
| 'update'
|
|
116
|
+
| 'activate'
|
|
117
|
+
| 'deactivate'
|
|
118
|
+
| 'tags'
|
|
119
|
+
| 'restore'
|
|
120
|
+
| 'delete';
|
|
121
|
+
|
|
122
|
+
export interface WorkflowRevision {
|
|
123
|
+
id: string;
|
|
124
|
+
workflowId: string;
|
|
125
|
+
versionId: string;
|
|
126
|
+
name: string;
|
|
127
|
+
active: boolean;
|
|
128
|
+
workflow: WorkflowDefinition;
|
|
129
|
+
createdAt: string;
|
|
130
|
+
updatedAt: string;
|
|
131
|
+
capturedAt: string;
|
|
132
|
+
operation: WorkflowRevisionOperation;
|
|
133
|
+
}
|
|
134
|
+
|
|
114
135
|
export interface WorkflowCredential {
|
|
115
136
|
id: string;
|
|
116
137
|
name: string;
|
|
@@ -121,6 +142,18 @@ export interface WorkflowCredential {
|
|
|
121
142
|
updatedAt: string;
|
|
122
143
|
}
|
|
123
144
|
|
|
145
|
+
export interface WorkflowExecutionEngineMetrics {
|
|
146
|
+
provider: 'smithers';
|
|
147
|
+
nodes: number;
|
|
148
|
+
levels: number;
|
|
149
|
+
maxConcurrency: number;
|
|
150
|
+
started: number;
|
|
151
|
+
finished: number;
|
|
152
|
+
failed: number;
|
|
153
|
+
skipped: number;
|
|
154
|
+
retries: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
124
157
|
export interface WorkflowExecution {
|
|
125
158
|
id: string;
|
|
126
159
|
finished: boolean;
|
|
@@ -147,6 +180,7 @@ export interface WorkflowExecution {
|
|
|
147
180
|
resultData?: {
|
|
148
181
|
runData?: Record<string, unknown[]>;
|
|
149
182
|
lastNodeExecuted?: string;
|
|
183
|
+
engine?: WorkflowExecutionEngineMetrics;
|
|
150
184
|
error?: {
|
|
151
185
|
message: string;
|
|
152
186
|
stack?: string;
|
|
@@ -160,6 +194,64 @@ export interface WorkflowExecution {
|
|
|
160
194
|
};
|
|
161
195
|
}
|
|
162
196
|
|
|
197
|
+
export interface WorkflowEvaluationSampleNode {
|
|
198
|
+
name: string;
|
|
199
|
+
status: 'success' | 'error' | 'unknown';
|
|
200
|
+
itemCount: number;
|
|
201
|
+
executionTimeMs?: number;
|
|
202
|
+
error?: string;
|
|
203
|
+
preview?: string;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface WorkflowEvaluationSample {
|
|
207
|
+
id: string;
|
|
208
|
+
workflowId: string;
|
|
209
|
+
workflowName: string;
|
|
210
|
+
workflowVersionId?: string;
|
|
211
|
+
executionId: string;
|
|
212
|
+
createdAt: string;
|
|
213
|
+
input: {
|
|
214
|
+
mode: WorkflowExecution['mode'];
|
|
215
|
+
triggerData?: Record<string, unknown>;
|
|
216
|
+
};
|
|
217
|
+
expected: {
|
|
218
|
+
status: WorkflowExecution['status'];
|
|
219
|
+
passed: boolean;
|
|
220
|
+
lastNodeExecuted?: string;
|
|
221
|
+
engine?: WorkflowExecutionEngineMetrics;
|
|
222
|
+
error?: string;
|
|
223
|
+
nodes: WorkflowEvaluationSampleNode[];
|
|
224
|
+
};
|
|
225
|
+
score: {
|
|
226
|
+
pass: boolean;
|
|
227
|
+
value: number;
|
|
228
|
+
reason: string;
|
|
229
|
+
};
|
|
230
|
+
tags: string[];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface WorkflowEvaluationSuite {
|
|
234
|
+
workflowId: string;
|
|
235
|
+
workflowName: string;
|
|
236
|
+
workflowVersionId?: string;
|
|
237
|
+
generatedAt: string;
|
|
238
|
+
sampleCount: number;
|
|
239
|
+
samples: WorkflowEvaluationSample[];
|
|
240
|
+
jsonl: string;
|
|
241
|
+
optimizer: {
|
|
242
|
+
engine: 'smithers-gepa';
|
|
243
|
+
target: 'workflow-generation';
|
|
244
|
+
suiteName: string;
|
|
245
|
+
caseFile: string;
|
|
246
|
+
recommendedCommand: string;
|
|
247
|
+
recommendedEvalCommand: string;
|
|
248
|
+
recommendedOptimizeCommand: string;
|
|
249
|
+
recommendedObservabilityCommand: string;
|
|
250
|
+
recommendedMetricsCommand: string;
|
|
251
|
+
notes: string[];
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
163
255
|
export interface WorkflowTag {
|
|
164
256
|
id: string;
|
|
165
257
|
name: string;
|
|
@@ -426,7 +518,7 @@ export interface ConnectorDisconnectedPayload extends EventPayload {
|
|
|
426
518
|
userId: string;
|
|
427
519
|
/**
|
|
428
520
|
* Workflow credential type ids tied to the disconnected connector
|
|
429
|
-
* (e.g. `['gmailOAuth2', 'gmailOAuth2Api']`). Empty list
|
|
521
|
+
* (e.g. `['gmailOAuth2', 'gmailOAuth2Api']`). Empty list skips deletion.
|
|
430
522
|
*/
|
|
431
523
|
credTypes: readonly string[];
|
|
432
524
|
/** Connector name (e.g. `'gmail'`). Informational. */
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
export type GenericValue = string | object | number | boolean | undefined | null;
|
|
2
|
+
|
|
3
|
+
export type NodeParameterValue = string | number | boolean | undefined | null;
|
|
4
|
+
|
|
5
|
+
export type NodeParameterValueType =
|
|
6
|
+
| NodeParameterValue
|
|
7
|
+
| INodeParameters
|
|
8
|
+
| NodeParameterValue[]
|
|
9
|
+
| INodeParameters[]
|
|
10
|
+
| Record<string, unknown>
|
|
11
|
+
| Array<Record<string, unknown>>;
|
|
12
|
+
|
|
13
|
+
export interface INodeParameters {
|
|
14
|
+
[key: string]: NodeParameterValueType;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type NodePropertyTypes =
|
|
18
|
+
| 'boolean'
|
|
19
|
+
| 'button'
|
|
20
|
+
| 'collection'
|
|
21
|
+
| 'color'
|
|
22
|
+
| 'dateTime'
|
|
23
|
+
| 'fixedCollection'
|
|
24
|
+
| 'hidden'
|
|
25
|
+
| 'json'
|
|
26
|
+
| 'notice'
|
|
27
|
+
| 'multiOptions'
|
|
28
|
+
| 'number'
|
|
29
|
+
| 'options'
|
|
30
|
+
| 'string'
|
|
31
|
+
| 'credentialsSelect'
|
|
32
|
+
| 'resourceLocator'
|
|
33
|
+
| 'curlImport'
|
|
34
|
+
| 'resourceMapper'
|
|
35
|
+
| 'filter'
|
|
36
|
+
| 'assignmentCollection'
|
|
37
|
+
| 'credentials'
|
|
38
|
+
| 'workflowSelector';
|
|
39
|
+
|
|
40
|
+
export interface INodePropertyOptions {
|
|
41
|
+
name: string;
|
|
42
|
+
value?: string | number | boolean;
|
|
43
|
+
action?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
displayName?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface INodePropertyCollection {
|
|
49
|
+
displayName?: string;
|
|
50
|
+
name: string;
|
|
51
|
+
values: INodeProperties[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface INodeProperties {
|
|
55
|
+
displayName: string;
|
|
56
|
+
name: string;
|
|
57
|
+
type: NodePropertyTypes;
|
|
58
|
+
default: NodeParameterValueType;
|
|
59
|
+
description?: string;
|
|
60
|
+
hint?: string;
|
|
61
|
+
options?: Array<INodePropertyOptions | INodeProperties | INodePropertyCollection>;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
required?: boolean;
|
|
64
|
+
typeOptions?: Record<string, unknown>;
|
|
65
|
+
displayOptions?: unknown;
|
|
66
|
+
routing?: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface INodeCredentialsDetails {
|
|
70
|
+
id: string | null;
|
|
71
|
+
name: string;
|
|
72
|
+
__aiGatewayManaged?: boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface INodeCredentials {
|
|
76
|
+
[key: string]: INodeCredentialsDetails;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type OnError = 'continueErrorOutput' | 'continueRegularOutput' | 'stopWorkflow';
|
|
80
|
+
|
|
81
|
+
export interface INode {
|
|
82
|
+
id: string;
|
|
83
|
+
name: string;
|
|
84
|
+
typeVersion: number;
|
|
85
|
+
type: string;
|
|
86
|
+
position: [number, number];
|
|
87
|
+
disabled?: boolean;
|
|
88
|
+
notes?: string;
|
|
89
|
+
notesInFlow?: boolean;
|
|
90
|
+
retryOnFail?: boolean;
|
|
91
|
+
maxTries?: number;
|
|
92
|
+
waitBetweenTries?: number;
|
|
93
|
+
alwaysOutputData?: boolean;
|
|
94
|
+
executeOnce?: boolean;
|
|
95
|
+
onError?: OnError;
|
|
96
|
+
continueOnFail?: boolean;
|
|
97
|
+
parameters: INodeParameters;
|
|
98
|
+
credentials?: INodeCredentials;
|
|
99
|
+
webhookId?: string;
|
|
100
|
+
extendsCredential?: string;
|
|
101
|
+
rewireOutputLogTo?: string;
|
|
102
|
+
forceCustomOperation?: {
|
|
103
|
+
resource: string;
|
|
104
|
+
operation: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export type NodeGroupType =
|
|
109
|
+
| 'input'
|
|
110
|
+
| 'output'
|
|
111
|
+
| 'organization'
|
|
112
|
+
| 'schedule'
|
|
113
|
+
| 'transform'
|
|
114
|
+
| 'trigger';
|
|
115
|
+
|
|
116
|
+
export interface INodeTypeDescription {
|
|
117
|
+
displayName: string;
|
|
118
|
+
name: string;
|
|
119
|
+
group: NodeGroupType[];
|
|
120
|
+
version: number | number[];
|
|
121
|
+
description: string;
|
|
122
|
+
defaults: {
|
|
123
|
+
name: string;
|
|
124
|
+
color?: string;
|
|
125
|
+
};
|
|
126
|
+
inputs: unknown[] | string[] | string;
|
|
127
|
+
outputs: unknown[] | string[] | string;
|
|
128
|
+
credentials?: Array<{
|
|
129
|
+
name: string;
|
|
130
|
+
required?: boolean;
|
|
131
|
+
displayOptions?: unknown;
|
|
132
|
+
}>;
|
|
133
|
+
properties: INodeProperties[];
|
|
134
|
+
icon?: string;
|
|
135
|
+
iconUrl?: string;
|
|
136
|
+
polling?: boolean;
|
|
137
|
+
triggerPanel?: unknown;
|
|
138
|
+
webhooks?: Array<Record<string, unknown>>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export namespace WorkflowSettings {
|
|
142
|
+
export type CallerPolicy = 'workflowsFromSameOwner' | 'workflowsFromAList' | 'any';
|
|
143
|
+
export type SaveDataExecution = 'DEFAULT' | 'all' | 'none';
|
|
144
|
+
export type RedactionPolicy = 'none' | 'mask';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export type WorkflowSettingsBinaryMode = 'separate' | 'combined';
|
|
148
|
+
|
|
149
|
+
export interface IWorkflowSettings {
|
|
150
|
+
timezone?: 'DEFAULT' | string;
|
|
151
|
+
errorWorkflow?: 'DEFAULT' | string;
|
|
152
|
+
callerIds?: string;
|
|
153
|
+
callerPolicy?: WorkflowSettings.CallerPolicy;
|
|
154
|
+
saveDataErrorExecution?: WorkflowSettings.SaveDataExecution;
|
|
155
|
+
saveDataSuccessExecution?: WorkflowSettings.SaveDataExecution;
|
|
156
|
+
saveManualExecutions?: 'DEFAULT' | boolean;
|
|
157
|
+
saveExecutionProgress?: 'DEFAULT' | boolean;
|
|
158
|
+
executionTimeout?: number;
|
|
159
|
+
executionOrder?: 'v0' | 'v1';
|
|
160
|
+
binaryMode?: WorkflowSettingsBinaryMode;
|
|
161
|
+
timeSavedPerExecution?: number;
|
|
162
|
+
timeSavedMode?: 'fixed' | 'dynamic';
|
|
163
|
+
availableInMCP?: boolean;
|
|
164
|
+
credentialResolverId?: string;
|
|
165
|
+
redactionPolicy?: WorkflowSettings.RedactionPolicy;
|
|
166
|
+
}
|
package/src/utils/catalog.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
/**
|
|
10
10
|
* workflows node catalog with keyword-based search
|
|
11
11
|
* @note Uses embedded catalog (457 nodes as of April 2025)
|
|
12
|
-
* @
|
|
12
|
+
* @note Dynamic refresh via GET /node-types belongs in a catalog-refresh pass.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
const NODE_CATALOG = defaultNodesData as NodeDefinition[];
|
|
@@ -64,7 +64,7 @@ export function searchNodes(keywords: string[], limit = 15): NodeSearchResult[]
|
|
|
64
64
|
|
|
65
65
|
const nodeName = node.name.toLowerCase();
|
|
66
66
|
const nodeDisplayName = node.displayName.toLowerCase();
|
|
67
|
-
const nodeDescription = node.description
|
|
67
|
+
const nodeDescription = node.description.toLowerCase() || '';
|
|
68
68
|
const nameTokens = tokenize(node.name);
|
|
69
69
|
const displayTokens = tokenize(node.displayName);
|
|
70
70
|
|
|
@@ -18,6 +18,10 @@ export function isCatalogClarification(item: string | ClarificationRequest): boo
|
|
|
18
18
|
: isCatalogClarificationString(item.question);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
/**
|
|
22
26
|
* Normalize a mixed-shape clarifications array into structured
|
|
23
27
|
* `ClarificationRequest` objects. Legacy strings become `kind: 'free_text'`
|
|
@@ -25,7 +29,7 @@ export function isCatalogClarification(item: string | ClarificationRequest): boo
|
|
|
25
29
|
* picker). Structured items pass through unchanged.
|
|
26
30
|
*/
|
|
27
31
|
export function coerceClarificationRequests(
|
|
28
|
-
items: ReadonlyArray<
|
|
32
|
+
items: ReadonlyArray<unknown> | undefined | null
|
|
29
33
|
): ClarificationRequest[] {
|
|
30
34
|
if (!items || items.length === 0) {
|
|
31
35
|
return [];
|
|
@@ -38,11 +42,21 @@ export function coerceClarificationRequests(
|
|
|
38
42
|
continue;
|
|
39
43
|
}
|
|
40
44
|
out.push({ kind: 'free_text', question: trimmed, paramPath: '' });
|
|
41
|
-
} else if (item && typeof item
|
|
45
|
+
} else if (isRecord(item) && typeof item.question === 'string') {
|
|
42
46
|
out.push({
|
|
43
|
-
kind:
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
kind:
|
|
48
|
+
item.kind === 'target_channel' ||
|
|
49
|
+
item.kind === 'target_server' ||
|
|
50
|
+
item.kind === 'recipient' ||
|
|
51
|
+
item.kind === 'value' ||
|
|
52
|
+
item.kind === 'free_text'
|
|
53
|
+
? item.kind
|
|
54
|
+
: 'free_text',
|
|
55
|
+
platform: typeof item.platform === 'string' ? item.platform : undefined,
|
|
56
|
+
scope:
|
|
57
|
+
isRecord(item.scope) && typeof item.scope.guildId === 'string'
|
|
58
|
+
? { guildId: item.scope.guildId }
|
|
59
|
+
: undefined,
|
|
46
60
|
question: item.question,
|
|
47
61
|
paramPath: typeof item.paramPath === 'string' ? item.paramPath : '',
|
|
48
62
|
});
|
package/src/utils/context.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { IAgentRuntime, Memory, State, UUID } from '@elizaos/core';
|
|
|
3
3
|
export function buildConversationContext(message: Memory, state: State | undefined): string {
|
|
4
4
|
const raw = state?.values?.recentMessages;
|
|
5
5
|
const recentMessages = typeof raw === 'string' ? raw : '';
|
|
6
|
-
const currentText = message.content
|
|
6
|
+
const currentText = message.content.text ?? '';
|
|
7
7
|
|
|
8
8
|
if (!recentMessages) {
|
|
9
9
|
return currentText;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
WorkflowDefinitionResponse,
|
|
3
|
+
WorkflowEvaluationSample,
|
|
4
|
+
WorkflowEvaluationSampleNode,
|
|
5
|
+
WorkflowEvaluationSuite,
|
|
6
|
+
WorkflowExecution,
|
|
7
|
+
} from '../types/index';
|
|
8
|
+
|
|
9
|
+
const DEFAULT_LIMIT = 10;
|
|
10
|
+
const MAX_LIMIT = 50;
|
|
11
|
+
const MAX_PREVIEW_LENGTH = 240;
|
|
12
|
+
const MAX_SAMPLE_VALUE_DEPTH = 4;
|
|
13
|
+
const MAX_SAMPLE_OBJECT_KEYS = 20;
|
|
14
|
+
const MAX_SAMPLE_ARRAY_ITEMS = 10;
|
|
15
|
+
|
|
16
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
17
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readString(value: unknown): string | undefined {
|
|
21
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readNumber(value: unknown): number | undefined {
|
|
25
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function clampLimit(limit?: number): number {
|
|
29
|
+
if (typeof limit !== 'number' || !Number.isFinite(limit)) return DEFAULT_LIMIT;
|
|
30
|
+
return Math.min(Math.max(1, Math.floor(limit)), MAX_LIMIT);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function truncate(value: string, maxLength = MAX_PREVIEW_LENGTH): string {
|
|
34
|
+
return value.length > maxLength ? `${value.slice(0, maxLength - 3)}...` : value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function compactValue(value: unknown, depth = 0): unknown {
|
|
38
|
+
if (
|
|
39
|
+
value === null ||
|
|
40
|
+
typeof value === 'boolean' ||
|
|
41
|
+
typeof value === 'number' ||
|
|
42
|
+
typeof value === 'undefined'
|
|
43
|
+
) {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === 'string') {
|
|
47
|
+
return truncate(value, MAX_PREVIEW_LENGTH);
|
|
48
|
+
}
|
|
49
|
+
if (depth >= MAX_SAMPLE_VALUE_DEPTH) {
|
|
50
|
+
return '[truncated]';
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
return value.slice(0, MAX_SAMPLE_ARRAY_ITEMS).map((item) => compactValue(item, depth + 1));
|
|
54
|
+
}
|
|
55
|
+
if (!isRecord(value)) {
|
|
56
|
+
return String(value);
|
|
57
|
+
}
|
|
58
|
+
return Object.fromEntries(
|
|
59
|
+
Object.entries(value)
|
|
60
|
+
.slice(0, MAX_SAMPLE_OBJECT_KEYS)
|
|
61
|
+
.map(([key, item]) => [key, compactValue(item, depth + 1)])
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function compactRecord(value: unknown): Record<string, unknown> | undefined {
|
|
66
|
+
if (!isRecord(value)) return undefined;
|
|
67
|
+
const compacted = compactValue(value);
|
|
68
|
+
return isRecord(compacted) ? compacted : undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function countMainItems(data: unknown): number {
|
|
72
|
+
if (!isRecord(data) || !Array.isArray(data.main)) return 0;
|
|
73
|
+
return data.main.reduce((total, output) => {
|
|
74
|
+
if (!Array.isArray(output)) return total;
|
|
75
|
+
return total + output.length;
|
|
76
|
+
}, 0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function previewMainData(data: unknown): string | undefined {
|
|
80
|
+
if (!isRecord(data) || !Array.isArray(data.main)) return undefined;
|
|
81
|
+
for (const output of data.main) {
|
|
82
|
+
if (!Array.isArray(output)) continue;
|
|
83
|
+
const first = output.find(isRecord);
|
|
84
|
+
if (!first) continue;
|
|
85
|
+
const json = isRecord(first.json) ? first.json : first;
|
|
86
|
+
try {
|
|
87
|
+
return truncate(JSON.stringify(compactValue(json)));
|
|
88
|
+
} catch {
|
|
89
|
+
return 'Output could not be previewed';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function readRunError(run: unknown): string | undefined {
|
|
96
|
+
if (!isRecord(run)) return undefined;
|
|
97
|
+
const error = run.error;
|
|
98
|
+
if (isRecord(error)) {
|
|
99
|
+
return readString(error.message) ?? readString(error.description);
|
|
100
|
+
}
|
|
101
|
+
return readString(error);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function readExecutionError(execution: WorkflowExecution): string | undefined {
|
|
105
|
+
const error = execution.data?.resultData?.error;
|
|
106
|
+
if (error?.message) return error.message;
|
|
107
|
+
for (const node of collectNodeSamples(execution)) {
|
|
108
|
+
if (node.error) return node.error;
|
|
109
|
+
}
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function collectNodeSamples(execution: WorkflowExecution): WorkflowEvaluationSampleNode[] {
|
|
114
|
+
const runData = execution.data?.resultData?.runData;
|
|
115
|
+
if (!runData) return [];
|
|
116
|
+
|
|
117
|
+
return Object.entries(runData).flatMap(([name, runs]) => {
|
|
118
|
+
if (!Array.isArray(runs)) return [];
|
|
119
|
+
return runs.map((run): WorkflowEvaluationSampleNode => {
|
|
120
|
+
const record = isRecord(run) ? run : {};
|
|
121
|
+
const error = readRunError(record);
|
|
122
|
+
const preview = previewMainData(record.data);
|
|
123
|
+
return {
|
|
124
|
+
name,
|
|
125
|
+
status: error ? 'error' : execution.status === 'success' ? 'success' : 'unknown',
|
|
126
|
+
itemCount: countMainItems(record.data),
|
|
127
|
+
...(readNumber(record.executionTime) !== undefined
|
|
128
|
+
? { executionTimeMs: readNumber(record.executionTime) }
|
|
129
|
+
: {}),
|
|
130
|
+
...(error ? { error } : {}),
|
|
131
|
+
...(preview ? { preview } : {}),
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function slugify(value: string): string {
|
|
138
|
+
return value
|
|
139
|
+
.toLowerCase()
|
|
140
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
141
|
+
.replace(/^-+|-+$/g, '')
|
|
142
|
+
.slice(0, 48);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function buildSample(
|
|
146
|
+
workflow: WorkflowDefinitionResponse,
|
|
147
|
+
execution: WorkflowExecution
|
|
148
|
+
): WorkflowEvaluationSample {
|
|
149
|
+
const passed = execution.status === 'success';
|
|
150
|
+
const workflowId = workflow.id;
|
|
151
|
+
const triggerData = compactRecord(execution.customData?.triggerData);
|
|
152
|
+
const error = readExecutionError(execution);
|
|
153
|
+
const nodes = collectNodeSamples(execution);
|
|
154
|
+
const scoreReason = passed
|
|
155
|
+
? 'Execution completed successfully.'
|
|
156
|
+
: error
|
|
157
|
+
? `Execution failed: ${error}`
|
|
158
|
+
: `Execution finished with status ${execution.status}.`;
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
id: `${workflowId}:${execution.id}`,
|
|
162
|
+
workflowId,
|
|
163
|
+
workflowName: workflow.name,
|
|
164
|
+
workflowVersionId: workflow.versionId,
|
|
165
|
+
executionId: execution.id,
|
|
166
|
+
createdAt: execution.stoppedAt ?? execution.startedAt,
|
|
167
|
+
input: {
|
|
168
|
+
mode: execution.mode,
|
|
169
|
+
...(triggerData ? { triggerData } : {}),
|
|
170
|
+
},
|
|
171
|
+
expected: {
|
|
172
|
+
status: execution.status,
|
|
173
|
+
passed,
|
|
174
|
+
...(execution.data?.resultData?.lastNodeExecuted
|
|
175
|
+
? { lastNodeExecuted: execution.data.resultData.lastNodeExecuted }
|
|
176
|
+
: {}),
|
|
177
|
+
...(execution.data?.resultData?.engine ? { engine: execution.data.resultData.engine } : {}),
|
|
178
|
+
...(error ? { error } : {}),
|
|
179
|
+
nodes,
|
|
180
|
+
},
|
|
181
|
+
score: {
|
|
182
|
+
pass: passed,
|
|
183
|
+
value: passed ? 1 : 0,
|
|
184
|
+
reason: scoreReason,
|
|
185
|
+
},
|
|
186
|
+
tags: [
|
|
187
|
+
'smithers',
|
|
188
|
+
'workflow-eval',
|
|
189
|
+
`workflow:${workflowId}`,
|
|
190
|
+
`status:${execution.status}`,
|
|
191
|
+
`mode:${execution.mode}`,
|
|
192
|
+
],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function buildWorkflowEvaluationSuite(
|
|
197
|
+
workflow: WorkflowDefinitionResponse,
|
|
198
|
+
executions: WorkflowExecution[],
|
|
199
|
+
options?: { limit?: number; generatedAt?: string }
|
|
200
|
+
): WorkflowEvaluationSuite {
|
|
201
|
+
const limit = clampLimit(options?.limit);
|
|
202
|
+
const samples = executions.slice(0, limit).map((execution) => buildSample(workflow, execution));
|
|
203
|
+
const safeName = slugify(workflow.name) || slugify(workflow.id) || 'workflow';
|
|
204
|
+
const suiteName = safeName;
|
|
205
|
+
const caseFile = `evals/${suiteName}.jsonl`;
|
|
206
|
+
const recommendedEvalCommand = `bunx smithers-orchestrator eval <workflow.tsx> --cases ${caseFile} --suite ${suiteName}`;
|
|
207
|
+
const recommendedOptimizeCommand = 'bunx smithers-orchestrator optimize';
|
|
208
|
+
const recommendedObservabilityCommand = 'bunx smithers-orchestrator observability --detach';
|
|
209
|
+
const recommendedMetricsCommand =
|
|
210
|
+
'bunx smithers-orchestrator up <workflow.tsx> --serve --metrics';
|
|
211
|
+
const jsonl = samples.map((sample) => JSON.stringify(sample)).join('\n');
|
|
212
|
+
return {
|
|
213
|
+
workflowId: workflow.id,
|
|
214
|
+
workflowName: workflow.name,
|
|
215
|
+
workflowVersionId: workflow.versionId,
|
|
216
|
+
generatedAt: options?.generatedAt ?? new Date().toISOString(),
|
|
217
|
+
sampleCount: samples.length,
|
|
218
|
+
samples,
|
|
219
|
+
jsonl,
|
|
220
|
+
optimizer: {
|
|
221
|
+
engine: 'smithers-gepa',
|
|
222
|
+
target: 'workflow-generation',
|
|
223
|
+
suiteName,
|
|
224
|
+
caseFile,
|
|
225
|
+
recommendedCommand: recommendedEvalCommand,
|
|
226
|
+
recommendedEvalCommand,
|
|
227
|
+
recommendedOptimizeCommand,
|
|
228
|
+
recommendedObservabilityCommand,
|
|
229
|
+
recommendedMetricsCommand,
|
|
230
|
+
notes: [
|
|
231
|
+
`Copy jsonl to ${caseFile} before running eval.`,
|
|
232
|
+
'Run GEPA optimization after the eval suite is configured; Smithers writes an optimized prompt artifact only when score improves.',
|
|
233
|
+
'Use the observability and metrics commands when inspecting long-running or flaky workflows.',
|
|
234
|
+
'Successful executions are positive examples; failed executions remain useful regression cases.',
|
|
235
|
+
'Samples are generated from persisted workflow executions and compact large payloads.',
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|