@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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +28 -26
  3. package/dist/actions/eval-code.d.ts +12 -0
  4. package/dist/actions/eval-code.d.ts.map +1 -0
  5. package/dist/actions/eval-code.js +59 -0
  6. package/dist/actions/eval-code.js.map +1 -0
  7. package/dist/actions/index.d.ts +1 -0
  8. package/dist/actions/index.d.ts.map +1 -1
  9. package/dist/actions/index.js +1 -0
  10. package/dist/actions/index.js.map +1 -1
  11. package/dist/actions/workflow.d.ts +7 -0
  12. package/dist/actions/workflow.d.ts.map +1 -1
  13. package/dist/actions/workflow.js +462 -10
  14. package/dist/actions/workflow.js.map +1 -1
  15. package/dist/db/schema.d.ts +196 -0
  16. package/dist/db/schema.d.ts.map +1 -1
  17. package/dist/db/schema.js +23 -0
  18. package/dist/db/schema.js.map +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +9 -64
  21. package/dist/index.js.map +1 -1
  22. package/dist/lib/automations-builder.d.ts.map +1 -1
  23. package/dist/lib/automations-builder.js +10 -35
  24. package/dist/lib/automations-builder.js.map +1 -1
  25. package/dist/lib/automations-types.d.ts +2 -2
  26. package/dist/lib/automations-types.d.ts.map +1 -1
  27. package/dist/lib/automations-types.js.map +1 -1
  28. package/dist/lib/index.d.ts +0 -2
  29. package/dist/lib/index.d.ts.map +1 -1
  30. package/dist/lib/index.js +1 -2
  31. package/dist/lib/index.js.map +1 -1
  32. package/dist/lib/workflow-clarification.d.ts +2 -2
  33. package/dist/lib/workflow-clarification.d.ts.map +1 -1
  34. package/dist/lib/workflow-clarification.js +15 -11
  35. package/dist/lib/workflow-clarification.js.map +1 -1
  36. package/dist/plugin-routes.d.ts.map +1 -1
  37. package/dist/plugin-routes.js +6 -0
  38. package/dist/plugin-routes.js.map +1 -1
  39. package/dist/providers/activeWorkflows.js +2 -2
  40. package/dist/providers/activeWorkflows.js.map +1 -1
  41. package/dist/providers/workflowStatus.js +1 -1
  42. package/dist/providers/workflowStatus.js.map +1 -1
  43. package/dist/routes/workflow-routes.d.ts.map +1 -1
  44. package/dist/routes/workflow-routes.js +68 -2
  45. package/dist/routes/workflow-routes.js.map +1 -1
  46. package/dist/routes/workflows.d.ts.map +1 -1
  47. package/dist/routes/workflows.js +5 -1
  48. package/dist/routes/workflows.js.map +1 -1
  49. package/dist/services/embedded-workflow-service.d.ts +74 -17
  50. package/dist/services/embedded-workflow-service.d.ts.map +1 -1
  51. package/dist/services/embedded-workflow-service.js +343 -149
  52. package/dist/services/embedded-workflow-service.js.map +1 -1
  53. package/dist/services/smithers-runtime.d.ts +47 -0
  54. package/dist/services/smithers-runtime.d.ts.map +1 -0
  55. package/dist/services/smithers-runtime.js +444 -0
  56. package/dist/services/smithers-runtime.js.map +1 -0
  57. package/dist/services/workflow-credential-store.js +1 -1
  58. package/dist/services/workflow-credential-store.js.map +1 -1
  59. package/dist/services/workflow-dispatch.d.ts +31 -1
  60. package/dist/services/workflow-dispatch.d.ts.map +1 -1
  61. package/dist/services/workflow-dispatch.js +75 -10
  62. package/dist/services/workflow-dispatch.js.map +1 -1
  63. package/dist/services/workflow-service.d.ts +27 -1
  64. package/dist/services/workflow-service.d.ts.map +1 -1
  65. package/dist/services/workflow-service.js +133 -11
  66. package/dist/services/workflow-service.js.map +1 -1
  67. package/dist/trigger-routes.d.ts +2 -18
  68. package/dist/trigger-routes.d.ts.map +1 -1
  69. package/dist/trigger-routes.js +11 -39
  70. package/dist/trigger-routes.js.map +1 -1
  71. package/dist/types/index.d.ts +82 -2
  72. package/dist/types/index.d.ts.map +1 -1
  73. package/dist/types/index.js.map +1 -1
  74. package/dist/types/workflow-contracts.d.ts +118 -0
  75. package/dist/types/workflow-contracts.d.ts.map +1 -0
  76. package/dist/types/workflow-contracts.js +2 -0
  77. package/dist/types/workflow-contracts.js.map +1 -0
  78. package/dist/utils/catalog.js +2 -2
  79. package/dist/utils/catalog.js.map +1 -1
  80. package/dist/utils/clarification.d.ts +1 -1
  81. package/dist/utils/clarification.d.ts.map +1 -1
  82. package/dist/utils/clarification.js +15 -4
  83. package/dist/utils/clarification.js.map +1 -1
  84. package/dist/utils/context.js +1 -1
  85. package/dist/utils/context.js.map +1 -1
  86. package/dist/utils/evaluation-samples.d.ts +6 -0
  87. package/dist/utils/evaluation-samples.d.ts.map +1 -0
  88. package/dist/utils/evaluation-samples.js +216 -0
  89. package/dist/utils/evaluation-samples.js.map +1 -0
  90. package/dist/utils/execution-diagnostics.d.ts +26 -0
  91. package/dist/utils/execution-diagnostics.d.ts.map +1 -0
  92. package/dist/utils/execution-diagnostics.js +159 -0
  93. package/dist/utils/execution-diagnostics.js.map +1 -0
  94. package/dist/utils/generation.d.ts.map +1 -1
  95. package/dist/utils/generation.js +134 -19
  96. package/dist/utils/generation.js.map +1 -1
  97. package/dist/utils/host-capabilities.d.ts.map +1 -1
  98. package/dist/utils/host-capabilities.js +20 -5
  99. package/dist/utils/host-capabilities.js.map +1 -1
  100. package/dist/utils/inferSyntheticOutputSchema.js +3 -3
  101. package/dist/utils/inferSyntheticOutputSchema.js.map +1 -1
  102. package/dist/utils/outputSchema.js +1 -1
  103. package/dist/utils/outputSchema.js.map +1 -1
  104. package/dist/utils/validateAndRepair.js +10 -10
  105. package/dist/utils/validateAndRepair.js.map +1 -1
  106. package/dist/utils/workflow-prompts/draftIntent.d.ts +1 -1
  107. package/dist/utils/workflow-prompts/draftIntent.d.ts.map +1 -1
  108. package/dist/utils/workflow-prompts/draftIntent.js +1 -1
  109. package/dist/utils/workflow-prompts/keywordExtraction.d.ts +1 -1
  110. package/dist/utils/workflow-prompts/keywordExtraction.d.ts.map +1 -1
  111. package/dist/utils/workflow-prompts/keywordExtraction.js +1 -1
  112. package/dist/utils/workflow-prompts/workflowGeneration.d.ts +1 -1
  113. package/dist/utils/workflow-prompts/workflowGeneration.d.ts.map +1 -1
  114. package/dist/utils/workflow-prompts/workflowGeneration.js +4 -4
  115. package/dist/utils/workflow-prompts/workflowMatching.d.ts +1 -1
  116. package/dist/utils/workflow-prompts/workflowMatching.d.ts.map +1 -1
  117. package/dist/utils/workflow-prompts/workflowMatching.js +1 -1
  118. package/dist/utils/workflow.d.ts +1 -0
  119. package/dist/utils/workflow.d.ts.map +1 -1
  120. package/dist/utils/workflow.js +44 -8
  121. package/dist/utils/workflow.js.map +1 -1
  122. package/package.json +27 -8
  123. package/registry-entry.json +25 -0
  124. package/src/actions/eval-code.ts +81 -0
  125. package/src/actions/index.ts +1 -0
  126. package/src/actions/workflow.ts +518 -10
  127. package/src/db/schema.ts +31 -0
  128. package/src/index.ts +9 -82
  129. package/src/lib/automations-builder.ts +11 -35
  130. package/src/lib/automations-types.ts +1 -2
  131. package/src/lib/index.ts +0 -8
  132. package/src/lib/workflow-clarification.ts +18 -13
  133. package/src/plugin-routes.ts +6 -0
  134. package/src/providers/activeWorkflows.ts +2 -2
  135. package/src/providers/workflowStatus.ts +1 -1
  136. package/src/routes/workflow-routes.ts +100 -2
  137. package/src/routes/workflows.ts +5 -1
  138. package/src/services/embedded-workflow-service.ts +447 -172
  139. package/src/services/smithers-runtime.ts +526 -0
  140. package/src/services/workflow-credential-store.ts +1 -1
  141. package/src/services/workflow-dispatch.ts +116 -13
  142. package/src/services/workflow-service.ts +186 -10
  143. package/src/trigger-routes.ts +12 -70
  144. package/src/types/index.ts +94 -2
  145. package/src/types/workflow-contracts.ts +166 -0
  146. package/src/utils/catalog.ts +2 -2
  147. package/src/utils/clarification.ts +19 -5
  148. package/src/utils/context.ts +1 -1
  149. package/src/utils/evaluation-samples.ts +239 -0
  150. package/src/utils/execution-diagnostics.ts +192 -0
  151. package/src/utils/generation.ts +224 -32
  152. package/src/utils/host-capabilities.ts +21 -5
  153. package/src/utils/inferSyntheticOutputSchema.ts +3 -3
  154. package/src/utils/outputSchema.ts +1 -1
  155. package/src/utils/validateAndRepair.ts +10 -10
  156. package/src/utils/workflow-prompts/draftIntent.ts +1 -1
  157. package/src/utils/workflow-prompts/keywordExtraction.ts +1 -1
  158. package/src/utils/workflow-prompts/workflowGeneration.ts +4 -4
  159. package/src/utils/workflow-prompts/workflowMatching.ts +1 -1
  160. package/src/utils/workflow.ts +56 -8
  161. package/dist/lib/legacy-task-migration.d.ts +0 -20
  162. package/dist/lib/legacy-task-migration.d.ts.map +0 -1
  163. package/dist/lib/legacy-task-migration.js +0 -110
  164. package/dist/lib/legacy-task-migration.js.map +0 -1
  165. package/dist/lib/legacy-text-trigger-migration.d.ts +0 -18
  166. package/dist/lib/legacy-text-trigger-migration.d.ts.map +0 -1
  167. package/dist/lib/legacy-text-trigger-migration.js +0 -131
  168. package/dist/lib/legacy-text-trigger-migration.js.map +0 -1
  169. package/src/lib/legacy-task-migration.ts +0 -143
  170. package/src/lib/legacy-text-trigger-migration.ts +0 -178
@@ -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
- const WORKFLOW_CONTEXTS = ['automation', 'tasks', 'agent_internal'];
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 ?? runtime.character?.id ?? '00000000-0000-0000-0000-000000000000';
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 ?? resolveAgentId(runtime)),
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 = (deployed.missingCredentials ?? []).map((c) => c.credType).join(', ');
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: 'manage workflows; action-based dispatch (create modify activate deactivate toggle_active delete executions)',
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 for action=executions (default 10).',
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