@elizaos/plugin-workflow 2.0.0-beta.1 → 2.0.3-beta.6
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/dist/actions/workflow.js
CHANGED
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
* WORKFLOW — single umbrella action for workflow lifecycle ops.
|
|
3
3
|
*
|
|
4
4
|
* Action-based dispatch (provide `action` parameter):
|
|
5
|
+
* list — list deployed workflows for the current user
|
|
6
|
+
* get — fetch one deployed workflow definition by id
|
|
5
7
|
* create — generate + deploy a new workflow from a seed prompt
|
|
6
8
|
* modify — load a deployed workflow into the draft editor by id
|
|
7
9
|
* activate — activate a workflow by id
|
|
8
10
|
* deactivate — deactivate a workflow by id
|
|
9
11
|
* toggle_active — explicit active=true|false (preferred when scripting)
|
|
10
12
|
* delete — permanently delete a workflow by id
|
|
13
|
+
* run — run a workflow immediately
|
|
11
14
|
* executions — fetch recent executions for a workflow id
|
|
15
|
+
* revisions — fetch restorable workflow versions
|
|
16
|
+
* restore — restore a workflow by version id
|
|
17
|
+
* diagnose — inspect a failed/recent workflow execution
|
|
18
|
+
* eval_samples — generate JSONL evaluation samples from recent executions
|
|
12
19
|
*
|
|
13
20
|
* All actions talk to the in-process `WorkflowService` via
|
|
14
21
|
* `runtime.getService(WORKFLOW_SERVICE_TYPE)`. There is no HTTP boundary.
|
|
@@ -20,17 +27,31 @@
|
|
|
20
27
|
*/
|
|
21
28
|
import { logger, } from '@elizaos/core';
|
|
22
29
|
import { WORKFLOW_SERVICE_TYPE } from '../services/workflow-service';
|
|
30
|
+
import { buildWorkflowExecutionDiagnostics, getWorkflowExecutionError, summarizeWorkflowExecution, } from '../utils/execution-diagnostics';
|
|
23
31
|
const WORKFLOW_ACTION = 'WORKFLOW';
|
|
24
32
|
const WORKFLOW_OPS = [
|
|
33
|
+
'list',
|
|
34
|
+
'search',
|
|
35
|
+
'get',
|
|
25
36
|
'create',
|
|
26
37
|
'modify',
|
|
27
38
|
'activate',
|
|
28
39
|
'deactivate',
|
|
29
40
|
'toggle_active',
|
|
30
41
|
'delete',
|
|
42
|
+
'run',
|
|
31
43
|
'executions',
|
|
44
|
+
'revisions',
|
|
45
|
+
'restore',
|
|
46
|
+
'diagnose',
|
|
47
|
+
'eval_samples',
|
|
32
48
|
];
|
|
33
|
-
|
|
49
|
+
// `general` (the active context a plain chat/Telegram turn actually seeds) is
|
|
50
|
+
// included so a message like "find my Slack workflow" routes to WORKFLOW search,
|
|
51
|
+
// not just automation/agent-internal turns (#8913). The gate matches active
|
|
52
|
+
// contexts literally; `chat` is only an alias of the `general` *definition* and is
|
|
53
|
+
// NOT expanded by normalizeContextList, so listing `chat` here would be inert.
|
|
54
|
+
const WORKFLOW_CONTEXTS = ['general', 'automation', 'tasks', 'agent_internal'];
|
|
34
55
|
function readString(value) {
|
|
35
56
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
36
57
|
}
|
|
@@ -68,15 +89,118 @@ function getWorkflowService(runtime) {
|
|
|
68
89
|
return runtime.getService(WORKFLOW_SERVICE_TYPE) ?? null;
|
|
69
90
|
}
|
|
70
91
|
function resolveAgentId(runtime) {
|
|
71
|
-
return runtime.agentId
|
|
92
|
+
return runtime.agentId;
|
|
72
93
|
}
|
|
73
94
|
function summarizeWorkflow(workflow) {
|
|
95
|
+
const nodes = workflow.nodes;
|
|
96
|
+
const nodeCount = typeof workflow.nodeCount === 'number'
|
|
97
|
+
? workflow.nodeCount
|
|
98
|
+
: Array.isArray(nodes)
|
|
99
|
+
? nodes.length
|
|
100
|
+
: undefined;
|
|
74
101
|
return {
|
|
75
102
|
id: String(workflow.id ?? ''),
|
|
76
|
-
name: String(workflow.name
|
|
103
|
+
name: String(workflow.name),
|
|
77
104
|
active: Boolean(workflow.active),
|
|
105
|
+
...(typeof nodeCount === 'number' ? { nodeCount } : {}),
|
|
78
106
|
};
|
|
79
107
|
}
|
|
108
|
+
async function handleListWorkflows(service, params, message, callback) {
|
|
109
|
+
const limit = Math.min(Math.max(1, readNumber(params.limit) ?? 20), 50);
|
|
110
|
+
try {
|
|
111
|
+
const workflows = await service.listWorkflows(String(message.entityId));
|
|
112
|
+
const summaries = workflows.slice(0, limit).map(summarizeWorkflow);
|
|
113
|
+
const text = summaries.length === 0
|
|
114
|
+
? 'No workflows found.'
|
|
115
|
+
: `Found ${summaries.length} workflow${summaries.length === 1 ? '' : 's'}.`;
|
|
116
|
+
if (callback) {
|
|
117
|
+
await callback({
|
|
118
|
+
text,
|
|
119
|
+
action: WORKFLOW_ACTION,
|
|
120
|
+
metadata: { count: summaries.length },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
text,
|
|
126
|
+
values: { count: summaries.length },
|
|
127
|
+
data: { workflows: summaries, total: workflows.length },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
132
|
+
logger.warn({ src: 'plugin:workflow:action:list' }, message);
|
|
133
|
+
return { success: false, text: message };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function handleSearchWorkflows(service, params, message, callback) {
|
|
137
|
+
const query = readString(params.query) ?? readString(params.q);
|
|
138
|
+
if (!query) {
|
|
139
|
+
return {
|
|
140
|
+
success: false,
|
|
141
|
+
text: 'A search `query` is required (free text to match workflow name / node type / description).',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const limit = Math.min(Math.max(1, readNumber(params.limit) ?? 20), 50);
|
|
145
|
+
try {
|
|
146
|
+
const matches = await service.searchWorkflows(query, String(message.entityId));
|
|
147
|
+
const summaries = matches.slice(0, limit).map(summarizeWorkflow);
|
|
148
|
+
const text = summaries.length === 0
|
|
149
|
+
? `No workflows match "${query}".`
|
|
150
|
+
: `Found ${summaries.length} workflow${summaries.length === 1 ? '' : 's'} matching "${query}".`;
|
|
151
|
+
if (callback) {
|
|
152
|
+
await callback({
|
|
153
|
+
text,
|
|
154
|
+
action: WORKFLOW_ACTION,
|
|
155
|
+
metadata: { count: summaries.length, query },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
success: true,
|
|
160
|
+
text,
|
|
161
|
+
values: { count: summaries.length },
|
|
162
|
+
data: { workflows: summaries, total: matches.length, query },
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const errMessage = err instanceof Error ? err.message : String(err);
|
|
167
|
+
logger.warn({ src: 'plugin:workflow:action:search' }, errMessage);
|
|
168
|
+
return { success: false, text: errMessage };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function handleGetWorkflow(service, params, callback) {
|
|
172
|
+
const workflowId = readString(params.workflowId);
|
|
173
|
+
if (!workflowId) {
|
|
174
|
+
return { success: false, text: 'workflowId is required to review a workflow.' };
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const workflow = await service.getWorkflow(workflowId);
|
|
178
|
+
const text = `Fetched workflow "${workflow.name}" for review.`;
|
|
179
|
+
if (callback) {
|
|
180
|
+
await callback({
|
|
181
|
+
text,
|
|
182
|
+
action: WORKFLOW_ACTION,
|
|
183
|
+
metadata: { workflowId, workflowName: workflow.name },
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
success: true,
|
|
188
|
+
text,
|
|
189
|
+
values: {
|
|
190
|
+
workflowId,
|
|
191
|
+
workflowName: workflow.name,
|
|
192
|
+
active: Boolean(workflow.active),
|
|
193
|
+
nodeCount: workflow.nodes.length,
|
|
194
|
+
},
|
|
195
|
+
data: { workflow },
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
200
|
+
logger.warn({ src: 'plugin:workflow:action:get' }, message);
|
|
201
|
+
return { success: false, text: message };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
80
204
|
async function handleCreate(runtime, service, params, message, callback) {
|
|
81
205
|
const seedPrompt = readString(params.seedPrompt);
|
|
82
206
|
const name = readString(params.name);
|
|
@@ -88,14 +212,14 @@ async function handleCreate(runtime, service, params, message, callback) {
|
|
|
88
212
|
}
|
|
89
213
|
try {
|
|
90
214
|
const draft = await service.generateWorkflowDraft(seedPrompt, {
|
|
91
|
-
userId: String(message.entityId
|
|
215
|
+
userId: String(message.entityId),
|
|
92
216
|
});
|
|
93
217
|
if (name) {
|
|
94
218
|
draft.name = name;
|
|
95
219
|
}
|
|
96
220
|
const deployed = await service.deployWorkflow(draft, resolveAgentId(runtime));
|
|
97
221
|
if (!deployed.id) {
|
|
98
|
-
const missing =
|
|
222
|
+
const missing = deployed.missingCredentials.map((c) => c.credType).join(', ');
|
|
99
223
|
const text = missing
|
|
100
224
|
? `Workflow generated but missing credentials: ${missing}.`
|
|
101
225
|
: 'Workflow generation produced no deployable result.';
|
|
@@ -240,7 +364,7 @@ async function handleExecutions(service, params, callback) {
|
|
|
240
364
|
const limit = readNumber(params.limit) ?? 10;
|
|
241
365
|
try {
|
|
242
366
|
const response = await service.listExecutions({ workflowId, limit });
|
|
243
|
-
const executions = response.data
|
|
367
|
+
const executions = response.data;
|
|
244
368
|
const text = executions.length === 0
|
|
245
369
|
? `No executions found for workflow ${workflowId}.`
|
|
246
370
|
: `Fetched ${executions.length} executions for workflow ${workflowId}.`;
|
|
@@ -264,14 +388,235 @@ async function handleExecutions(service, params, callback) {
|
|
|
264
388
|
return { success: false, text: msg };
|
|
265
389
|
}
|
|
266
390
|
}
|
|
391
|
+
async function handleRunWorkflow(service, params, callback) {
|
|
392
|
+
const workflowId = readString(params.workflowId);
|
|
393
|
+
if (!workflowId) {
|
|
394
|
+
return { success: false, text: 'workflowId is required to run a workflow.' };
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
const execution = await service.runWorkflow(workflowId, { throwOnError: false });
|
|
398
|
+
const text = `Ran workflow ${workflowId}: ${execution.status}.`;
|
|
399
|
+
if (callback) {
|
|
400
|
+
await callback({
|
|
401
|
+
text,
|
|
402
|
+
action: WORKFLOW_ACTION,
|
|
403
|
+
metadata: { workflowId, executionId: execution.id, status: execution.status },
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
success: execution.status !== 'error' && execution.status !== 'crashed',
|
|
408
|
+
text,
|
|
409
|
+
values: { workflowId, executionId: execution.id, status: execution.status },
|
|
410
|
+
data: { execution },
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
catch (err) {
|
|
414
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
415
|
+
logger.warn({ src: 'plugin:workflow:action:run' }, msg);
|
|
416
|
+
return { success: false, text: msg };
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async function handleRevisions(service, params, callback) {
|
|
420
|
+
const workflowId = readString(params.workflowId);
|
|
421
|
+
if (!workflowId) {
|
|
422
|
+
return { success: false, text: 'workflowId is required to fetch workflow revisions.' };
|
|
423
|
+
}
|
|
424
|
+
const limit = readNumber(params.limit) ?? 10;
|
|
425
|
+
try {
|
|
426
|
+
const revisions = await service.listWorkflowRevisions(workflowId, limit);
|
|
427
|
+
const text = revisions.length === 0
|
|
428
|
+
? `No revisions found for workflow ${workflowId}.`
|
|
429
|
+
: `Fetched ${revisions.length} revisions for workflow ${workflowId}.`;
|
|
430
|
+
if (callback) {
|
|
431
|
+
await callback({
|
|
432
|
+
text,
|
|
433
|
+
action: WORKFLOW_ACTION,
|
|
434
|
+
metadata: { workflowId, count: revisions.length },
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
success: true,
|
|
439
|
+
text,
|
|
440
|
+
values: { workflowId, count: revisions.length },
|
|
441
|
+
data: { revisions },
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
446
|
+
logger.warn({ src: 'plugin:workflow:action:revisions' }, msg);
|
|
447
|
+
return { success: false, text: msg };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
async function handleRestoreRevision(service, params, callback) {
|
|
451
|
+
const workflowId = readString(params.workflowId);
|
|
452
|
+
const versionId = readString(params.versionId);
|
|
453
|
+
if (!workflowId) {
|
|
454
|
+
return { success: false, text: 'workflowId is required to restore a workflow revision.' };
|
|
455
|
+
}
|
|
456
|
+
if (!versionId) {
|
|
457
|
+
return { success: false, text: 'versionId is required to restore a workflow revision.' };
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
const workflow = await service.restoreWorkflowRevision(workflowId, versionId);
|
|
461
|
+
const text = `Restored workflow "${workflow.name}".`;
|
|
462
|
+
if (callback) {
|
|
463
|
+
await callback({
|
|
464
|
+
text,
|
|
465
|
+
action: WORKFLOW_ACTION,
|
|
466
|
+
metadata: { workflowId, versionId, workflowName: workflow.name },
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
return {
|
|
470
|
+
success: true,
|
|
471
|
+
text,
|
|
472
|
+
values: { workflowId, workflowName: workflow.name, versionId },
|
|
473
|
+
data: { workflow: summarizeWorkflow(workflow) },
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
catch (err) {
|
|
477
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
478
|
+
logger.warn({ src: 'plugin:workflow:action:restore' }, msg);
|
|
479
|
+
return { success: false, text: msg };
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function isProblemExecution(execution) {
|
|
483
|
+
return (execution.status === 'error' ||
|
|
484
|
+
execution.status === 'crashed' ||
|
|
485
|
+
execution.status === 'canceled' ||
|
|
486
|
+
Boolean(getWorkflowExecutionError(execution)));
|
|
487
|
+
}
|
|
488
|
+
async function handleDiagnoseExecution(service, params, callback) {
|
|
489
|
+
const workflowId = readString(params.workflowId);
|
|
490
|
+
const executionId = readString(params.executionId);
|
|
491
|
+
const limit = Math.min(Math.max(1, readNumber(params.limit) ?? 10), 50);
|
|
492
|
+
if (!executionId && !workflowId) {
|
|
493
|
+
return {
|
|
494
|
+
success: false,
|
|
495
|
+
text: 'workflowId or executionId is required to diagnose a workflow run.',
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
try {
|
|
499
|
+
let execution;
|
|
500
|
+
if (executionId) {
|
|
501
|
+
execution = await service.getExecutionDetail(executionId);
|
|
502
|
+
if (workflowId && execution.workflowId !== workflowId) {
|
|
503
|
+
return {
|
|
504
|
+
success: false,
|
|
505
|
+
text: `Execution ${executionId} belongs to workflow ${execution.workflowId}, not ${workflowId}.`,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
else if (workflowId) {
|
|
510
|
+
const response = await service.listExecutions({ workflowId, limit });
|
|
511
|
+
execution = response.data.find(isProblemExecution) ?? response.data[0];
|
|
512
|
+
if (!execution) {
|
|
513
|
+
return {
|
|
514
|
+
success: false,
|
|
515
|
+
text: `No executions found for workflow ${workflowId}. Run it before diagnosing.`,
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
if (!execution) {
|
|
520
|
+
return { success: false, text: 'No workflow execution was available to diagnose.' };
|
|
521
|
+
}
|
|
522
|
+
const summary = summarizeWorkflowExecution(execution);
|
|
523
|
+
const diagnostics = buildWorkflowExecutionDiagnostics(execution);
|
|
524
|
+
const text = summary.error
|
|
525
|
+
? `Diagnosed workflow ${execution.workflowId} execution ${execution.id}: ${summary.statusLabel} - ${summary.error}`
|
|
526
|
+
: `Diagnosed workflow ${execution.workflowId} execution ${execution.id}: ${summary.statusLabel}.`;
|
|
527
|
+
if (callback) {
|
|
528
|
+
await callback({
|
|
529
|
+
text,
|
|
530
|
+
action: WORKFLOW_ACTION,
|
|
531
|
+
metadata: {
|
|
532
|
+
workflowId: execution.workflowId,
|
|
533
|
+
executionId: execution.id,
|
|
534
|
+
status: execution.status,
|
|
535
|
+
...(summary.error ? { error: summary.error } : {}),
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
return {
|
|
540
|
+
success: true,
|
|
541
|
+
text,
|
|
542
|
+
values: {
|
|
543
|
+
workflowId: execution.workflowId,
|
|
544
|
+
executionId: execution.id,
|
|
545
|
+
status: execution.status,
|
|
546
|
+
...(summary.error ? { error: summary.error } : {}),
|
|
547
|
+
},
|
|
548
|
+
data: { execution, summary, diagnostics },
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
catch (err) {
|
|
552
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
553
|
+
logger.warn({ src: 'plugin:workflow:action:diagnose' }, msg);
|
|
554
|
+
return { success: false, text: msg };
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
async function handleEvaluationSamples(service, params, callback) {
|
|
558
|
+
const workflowId = readString(params.workflowId);
|
|
559
|
+
if (!workflowId) {
|
|
560
|
+
return {
|
|
561
|
+
success: false,
|
|
562
|
+
text: 'workflowId is required to generate workflow evaluation samples.',
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
const limit = readNumber(params.limit) ?? 10;
|
|
566
|
+
try {
|
|
567
|
+
const suite = await service.getWorkflowEvaluationSuite(workflowId, limit);
|
|
568
|
+
const text = suite.sampleCount === 0
|
|
569
|
+
? `No executions found for workflow ${workflowId}; run it before generating eval samples.`
|
|
570
|
+
: [
|
|
571
|
+
`Generated ${suite.sampleCount} workflow eval sample${suite.sampleCount === 1 ? '' : 's'} for ${workflowId}.`,
|
|
572
|
+
`Save cases to ${suite.optimizer.caseFile}.`,
|
|
573
|
+
`Eval: ${suite.optimizer.recommendedEvalCommand}`,
|
|
574
|
+
`Optimize: ${suite.optimizer.recommendedOptimizeCommand}`,
|
|
575
|
+
].join('\n');
|
|
576
|
+
if (callback) {
|
|
577
|
+
await callback({
|
|
578
|
+
text,
|
|
579
|
+
action: WORKFLOW_ACTION,
|
|
580
|
+
metadata: {
|
|
581
|
+
workflowId,
|
|
582
|
+
count: suite.sampleCount,
|
|
583
|
+
caseFile: suite.optimizer.caseFile,
|
|
584
|
+
suiteName: suite.optimizer.suiteName,
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return {
|
|
589
|
+
success: true,
|
|
590
|
+
text,
|
|
591
|
+
values: {
|
|
592
|
+
workflowId,
|
|
593
|
+
count: suite.sampleCount,
|
|
594
|
+
caseFile: suite.optimizer.caseFile,
|
|
595
|
+
suiteName: suite.optimizer.suiteName,
|
|
596
|
+
},
|
|
597
|
+
data: { suite },
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
catch (err) {
|
|
601
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
602
|
+
logger.warn({ src: 'plugin:workflow:action:eval_samples' }, msg);
|
|
603
|
+
return { success: false, text: msg };
|
|
604
|
+
}
|
|
605
|
+
}
|
|
267
606
|
export const workflowAction = {
|
|
268
607
|
name: WORKFLOW_ACTION,
|
|
269
608
|
contexts: [...WORKFLOW_CONTEXTS],
|
|
270
609
|
contextGate: { anyOf: [...WORKFLOW_CONTEXTS] },
|
|
271
610
|
roleGate: { minRole: 'OWNER' },
|
|
272
611
|
similes: [
|
|
612
|
+
'LIST_WORKFLOWS',
|
|
613
|
+
'SHOW_WORKFLOWS',
|
|
614
|
+
'GET_WORKFLOW',
|
|
615
|
+
'REVIEW_WORKFLOW',
|
|
273
616
|
'CREATE_WORKFLOW',
|
|
274
617
|
'DELETE_WORKFLOW',
|
|
618
|
+
'RUN_WORKFLOW',
|
|
619
|
+
'RUN_WORKFLOW_NOW',
|
|
275
620
|
'TOGGLE_WORKFLOW_ACTIVE',
|
|
276
621
|
'ACTIVATE_WORKFLOW',
|
|
277
622
|
'DEACTIVATE_WORKFLOW',
|
|
@@ -292,24 +637,50 @@ export const workflowAction = {
|
|
|
292
637
|
'EXECUTION_HISTORY',
|
|
293
638
|
'WORKFLOW_RUNS',
|
|
294
639
|
'WORKFLOW_EXECUTIONS',
|
|
640
|
+
'WORKFLOW_REVISIONS',
|
|
641
|
+
'RESTORE_WORKFLOW',
|
|
642
|
+
'ROLL_BACK_WORKFLOW',
|
|
643
|
+
'ROLLBACK_WORKFLOW',
|
|
644
|
+
'DIAGNOSE_WORKFLOW',
|
|
645
|
+
'TROUBLESHOOT_WORKFLOW',
|
|
646
|
+
'EXPLAIN_WORKFLOW_FAILURE',
|
|
647
|
+
'GET_WORKFLOW_DIAGNOSTICS',
|
|
648
|
+
'WORKFLOW_RUN_DIAGNOSTICS',
|
|
649
|
+
'WORKFLOW_EVAL_SAMPLES',
|
|
650
|
+
'GENERATE_WORKFLOW_TRAINING_SAMPLES',
|
|
651
|
+
'GENERATE_WORKFLOW_EVAL_CASES',
|
|
652
|
+
'GEPA_WORKFLOW_SAMPLES',
|
|
653
|
+
'OPTIMIZE_WORKFLOW_SAMPLES',
|
|
295
654
|
],
|
|
296
655
|
description: 'Manage workflows. Action-based dispatch - provide an `action` parameter:\n' +
|
|
297
|
-
' create, modify, activate, deactivate, toggle_active, delete, executions.\n' +
|
|
656
|
+
' list, get, create, modify, activate, deactivate, toggle_active, delete, run, executions, revisions, restore, diagnose, eval_samples.\n' +
|
|
298
657
|
'For creating/updating scheduled triggers (including promoting a task to a workflow), use the TRIGGER action.',
|
|
299
|
-
descriptionCompressed: '
|
|
658
|
+
descriptionCompressed: 'workflow list|get|create|modify|activate|deactivate|toggle_active|delete|run|executions|revisions|restore|diagnose|eval_samples',
|
|
300
659
|
parameters: [
|
|
301
660
|
{
|
|
302
661
|
name: 'action',
|
|
303
|
-
description: 'Operation: create, modify, activate, deactivate, toggle_active, delete, executions.',
|
|
662
|
+
description: 'Operation: list, get, search, create, modify, activate, deactivate, toggle_active, delete, run, executions, revisions, restore, diagnose, eval_samples.',
|
|
304
663
|
required: true,
|
|
305
664
|
schema: { type: 'string', enum: [...WORKFLOW_OPS] },
|
|
306
665
|
},
|
|
666
|
+
{
|
|
667
|
+
name: 'query',
|
|
668
|
+
description: 'Free text to match a workflow by name / node type for action=search.',
|
|
669
|
+
required: false,
|
|
670
|
+
schema: { type: 'string' },
|
|
671
|
+
},
|
|
307
672
|
{
|
|
308
673
|
name: 'workflowId',
|
|
309
674
|
description: 'Workflow id.',
|
|
310
675
|
required: false,
|
|
311
676
|
schema: { type: 'string' },
|
|
312
677
|
},
|
|
678
|
+
{
|
|
679
|
+
name: 'executionId',
|
|
680
|
+
description: 'Workflow execution id for action=diagnose.',
|
|
681
|
+
required: false,
|
|
682
|
+
schema: { type: 'string' },
|
|
683
|
+
},
|
|
313
684
|
{
|
|
314
685
|
name: 'workflowName',
|
|
315
686
|
description: 'Workflow name fragment for fuzzy matching.',
|
|
@@ -336,10 +707,16 @@ export const workflowAction = {
|
|
|
336
707
|
},
|
|
337
708
|
{
|
|
338
709
|
name: 'limit',
|
|
339
|
-
description: 'Max executions to return
|
|
710
|
+
description: 'Max executions/revisions/evaluation samples to return (default 10).',
|
|
340
711
|
required: false,
|
|
341
712
|
schema: { type: 'number' },
|
|
342
713
|
},
|
|
714
|
+
{
|
|
715
|
+
name: 'versionId',
|
|
716
|
+
description: 'Workflow version id for action=restore.',
|
|
717
|
+
required: false,
|
|
718
|
+
schema: { type: 'string' },
|
|
719
|
+
},
|
|
343
720
|
],
|
|
344
721
|
validate: async (runtime, _message, _state) => {
|
|
345
722
|
return getWorkflowService(runtime) !== null;
|
|
@@ -358,6 +735,12 @@ export const workflowAction = {
|
|
|
358
735
|
return { success: false, text: 'Workflow service is not registered.' };
|
|
359
736
|
}
|
|
360
737
|
switch (op) {
|
|
738
|
+
case 'list':
|
|
739
|
+
return handleListWorkflows(service, params, message, callback);
|
|
740
|
+
case 'search':
|
|
741
|
+
return handleSearchWorkflows(service, params, message, callback);
|
|
742
|
+
case 'get':
|
|
743
|
+
return handleGetWorkflow(service, params, callback);
|
|
361
744
|
case 'create':
|
|
362
745
|
return handleCreate(runtime, service, params, message, callback);
|
|
363
746
|
case 'modify':
|
|
@@ -370,11 +753,49 @@ export const workflowAction = {
|
|
|
370
753
|
return handleToggleActive(service, params, undefined, callback);
|
|
371
754
|
case 'delete':
|
|
372
755
|
return handleDeleteWorkflow(service, params, callback);
|
|
756
|
+
case 'run':
|
|
757
|
+
return handleRunWorkflow(service, params, callback);
|
|
373
758
|
case 'executions':
|
|
374
759
|
return handleExecutions(service, params, callback);
|
|
760
|
+
case 'revisions':
|
|
761
|
+
return handleRevisions(service, params, callback);
|
|
762
|
+
case 'restore':
|
|
763
|
+
return handleRestoreRevision(service, params, callback);
|
|
764
|
+
case 'diagnose':
|
|
765
|
+
return handleDiagnoseExecution(service, params, callback);
|
|
766
|
+
case 'eval_samples':
|
|
767
|
+
return handleEvaluationSamples(service, params, callback);
|
|
375
768
|
}
|
|
376
769
|
},
|
|
377
770
|
examples: [
|
|
771
|
+
[
|
|
772
|
+
{
|
|
773
|
+
name: '{{name1}}',
|
|
774
|
+
content: { text: 'Show my workflows.', source: 'chat' },
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
name: '{{agentName}}',
|
|
778
|
+
content: {
|
|
779
|
+
text: 'Fetching workflows.',
|
|
780
|
+
actions: ['WORKFLOW'],
|
|
781
|
+
thought: 'Workflow inventory maps to WORKFLOW op=list.',
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
],
|
|
785
|
+
[
|
|
786
|
+
{
|
|
787
|
+
name: '{{name1}}',
|
|
788
|
+
content: { text: 'Review workflow wf-123.', source: 'chat' },
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
name: '{{agentName}}',
|
|
792
|
+
content: {
|
|
793
|
+
text: 'Fetching the workflow definition.',
|
|
794
|
+
actions: ['WORKFLOW'],
|
|
795
|
+
thought: 'Workflow review maps to WORKFLOW op=get with workflowId=wf-123.',
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
],
|
|
378
799
|
[
|
|
379
800
|
{
|
|
380
801
|
name: '{{name1}}',
|
|
@@ -420,6 +841,37 @@ export const workflowAction = {
|
|
|
420
841
|
},
|
|
421
842
|
},
|
|
422
843
|
],
|
|
844
|
+
[
|
|
845
|
+
{
|
|
846
|
+
name: '{{name1}}',
|
|
847
|
+
content: { text: 'Roll back workflow wf-123 to version v-old.', source: 'chat' },
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
name: '{{agentName}}',
|
|
851
|
+
content: {
|
|
852
|
+
text: 'Restoring the workflow version.',
|
|
853
|
+
actions: ['WORKFLOW'],
|
|
854
|
+
thought: 'Rollback maps to WORKFLOW op=restore with workflowId=wf-123 and versionId=v-old.',
|
|
855
|
+
},
|
|
856
|
+
},
|
|
857
|
+
],
|
|
858
|
+
[
|
|
859
|
+
{
|
|
860
|
+
name: '{{name1}}',
|
|
861
|
+
content: {
|
|
862
|
+
text: 'Create eval samples from the last 10 runs of workflow wf-123.',
|
|
863
|
+
source: 'chat',
|
|
864
|
+
},
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
name: '{{agentName}}',
|
|
868
|
+
content: {
|
|
869
|
+
text: 'Generating workflow eval samples.',
|
|
870
|
+
actions: ['WORKFLOW'],
|
|
871
|
+
thought: 'Eval sample generation maps to WORKFLOW op=eval_samples with workflowId=wf-123 and limit=10.',
|
|
872
|
+
},
|
|
873
|
+
},
|
|
874
|
+
],
|
|
423
875
|
],
|
|
424
876
|
};
|
|
425
877
|
//# sourceMappingURL=workflow.js.map
|