@elizaos/plugin-workflow 2.0.0-beta.1

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 (294) hide show
  1. package/README.md +71 -0
  2. package/auto-enable.ts +18 -0
  3. package/dist/actions/index.d.ts +2 -0
  4. package/dist/actions/index.d.ts.map +1 -0
  5. package/dist/actions/index.js +2 -0
  6. package/dist/actions/index.js.map +1 -0
  7. package/dist/actions/workflow.d.ts +23 -0
  8. package/dist/actions/workflow.d.ts.map +1 -0
  9. package/dist/actions/workflow.js +425 -0
  10. package/dist/actions/workflow.js.map +1 -0
  11. package/dist/data/defaultNodes.json +9887 -0
  12. package/dist/data/schemaIndex.json +1 -0
  13. package/dist/data/triggerSchemaIndex.json +1 -0
  14. package/dist/db/index.d.ts +2 -0
  15. package/dist/db/index.d.ts.map +1 -0
  16. package/dist/db/index.js +2 -0
  17. package/dist/db/index.js.map +1 -0
  18. package/dist/db/schema.d.ts +588 -0
  19. package/dist/db/schema.d.ts.map +1 -0
  20. package/dist/db/schema.js +59 -0
  21. package/dist/db/schema.js.map +1 -0
  22. package/dist/index.d.ts +34 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +126 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lib/automations-builder.d.ts +21 -0
  27. package/dist/lib/automations-builder.d.ts.map +1 -0
  28. package/dist/lib/automations-builder.js +557 -0
  29. package/dist/lib/automations-builder.js.map +1 -0
  30. package/dist/lib/automations-types.d.ts +153 -0
  31. package/dist/lib/automations-types.d.ts.map +1 -0
  32. package/dist/lib/automations-types.js +191 -0
  33. package/dist/lib/automations-types.js.map +1 -0
  34. package/dist/lib/index.d.ts +3 -0
  35. package/dist/lib/index.d.ts.map +1 -0
  36. package/dist/lib/index.js +3 -0
  37. package/dist/lib/index.js.map +1 -0
  38. package/dist/lib/legacy-task-migration.d.ts +20 -0
  39. package/dist/lib/legacy-task-migration.d.ts.map +1 -0
  40. package/dist/lib/legacy-task-migration.js +110 -0
  41. package/dist/lib/legacy-task-migration.js.map +1 -0
  42. package/dist/lib/legacy-text-trigger-migration.d.ts +18 -0
  43. package/dist/lib/legacy-text-trigger-migration.d.ts.map +1 -0
  44. package/dist/lib/legacy-text-trigger-migration.js +131 -0
  45. package/dist/lib/legacy-text-trigger-migration.js.map +1 -0
  46. package/dist/lib/workflow-clarification.d.ts +113 -0
  47. package/dist/lib/workflow-clarification.d.ts.map +1 -0
  48. package/dist/lib/workflow-clarification.js +425 -0
  49. package/dist/lib/workflow-clarification.js.map +1 -0
  50. package/dist/plugin-routes.d.ts +9 -0
  51. package/dist/plugin-routes.d.ts.map +1 -0
  52. package/dist/plugin-routes.js +147 -0
  53. package/dist/plugin-routes.js.map +1 -0
  54. package/dist/providers/activeWorkflows.d.ts +11 -0
  55. package/dist/providers/activeWorkflows.d.ts.map +1 -0
  56. package/dist/providers/activeWorkflows.js +72 -0
  57. package/dist/providers/activeWorkflows.js.map +1 -0
  58. package/dist/providers/index.d.ts +4 -0
  59. package/dist/providers/index.d.ts.map +1 -0
  60. package/dist/providers/index.js +4 -0
  61. package/dist/providers/index.js.map +1 -0
  62. package/dist/providers/pendingDraft.d.ts +9 -0
  63. package/dist/providers/pendingDraft.d.ts.map +1 -0
  64. package/dist/providers/pendingDraft.js +48 -0
  65. package/dist/providers/pendingDraft.js.map +1 -0
  66. package/dist/providers/workflowStatus.d.ts +3 -0
  67. package/dist/providers/workflowStatus.d.ts.map +1 -0
  68. package/dist/providers/workflowStatus.js +69 -0
  69. package/dist/providers/workflowStatus.js.map +1 -0
  70. package/dist/register-routes.d.ts +2 -0
  71. package/dist/register-routes.d.ts.map +1 -0
  72. package/dist/register-routes.js +6 -0
  73. package/dist/register-routes.js.map +1 -0
  74. package/dist/routes/_helpers.d.ts +11 -0
  75. package/dist/routes/_helpers.d.ts.map +1 -0
  76. package/dist/routes/_helpers.js +22 -0
  77. package/dist/routes/_helpers.js.map +1 -0
  78. package/dist/routes/automations.d.ts +19 -0
  79. package/dist/routes/automations.d.ts.map +1 -0
  80. package/dist/routes/automations.js +32 -0
  81. package/dist/routes/automations.js.map +1 -0
  82. package/dist/routes/embedded-webhooks.d.ts +3 -0
  83. package/dist/routes/embedded-webhooks.d.ts.map +1 -0
  84. package/dist/routes/embedded-webhooks.js +47 -0
  85. package/dist/routes/embedded-webhooks.js.map +1 -0
  86. package/dist/routes/executions.d.ts +3 -0
  87. package/dist/routes/executions.d.ts.map +1 -0
  88. package/dist/routes/executions.js +58 -0
  89. package/dist/routes/executions.js.map +1 -0
  90. package/dist/routes/index.d.ts +4 -0
  91. package/dist/routes/index.d.ts.map +1 -0
  92. package/dist/routes/index.js +14 -0
  93. package/dist/routes/index.js.map +1 -0
  94. package/dist/routes/nodes.d.ts +3 -0
  95. package/dist/routes/nodes.d.ts.map +1 -0
  96. package/dist/routes/nodes.js +168 -0
  97. package/dist/routes/nodes.js.map +1 -0
  98. package/dist/routes/validation.d.ts +3 -0
  99. package/dist/routes/validation.d.ts.map +1 -0
  100. package/dist/routes/validation.js +41 -0
  101. package/dist/routes/validation.js.map +1 -0
  102. package/dist/routes/workflow-routes.d.ts +27 -0
  103. package/dist/routes/workflow-routes.d.ts.map +1 -0
  104. package/dist/routes/workflow-routes.js +326 -0
  105. package/dist/routes/workflow-routes.js.map +1 -0
  106. package/dist/routes/workflows.d.ts +3 -0
  107. package/dist/routes/workflows.d.ts.map +1 -0
  108. package/dist/routes/workflows.js +252 -0
  109. package/dist/routes/workflows.js.map +1 -0
  110. package/dist/schemas/draftIntent.d.ts +22 -0
  111. package/dist/schemas/draftIntent.d.ts.map +1 -0
  112. package/dist/schemas/draftIntent.js +22 -0
  113. package/dist/schemas/draftIntent.js.map +1 -0
  114. package/dist/schemas/feasibility.d.ts +13 -0
  115. package/dist/schemas/feasibility.d.ts.map +1 -0
  116. package/dist/schemas/feasibility.js +9 -0
  117. package/dist/schemas/feasibility.js.map +1 -0
  118. package/dist/schemas/index.d.ts +5 -0
  119. package/dist/schemas/index.d.ts.map +1 -0
  120. package/dist/schemas/index.js +5 -0
  121. package/dist/schemas/index.js.map +1 -0
  122. package/dist/schemas/keywordExtraction.d.ts +14 -0
  123. package/dist/schemas/keywordExtraction.d.ts.map +1 -0
  124. package/dist/schemas/keywordExtraction.js +12 -0
  125. package/dist/schemas/keywordExtraction.js.map +1 -0
  126. package/dist/schemas/workflowMatching.d.ts +36 -0
  127. package/dist/schemas/workflowMatching.d.ts.map +1 -0
  128. package/dist/schemas/workflowMatching.js +30 -0
  129. package/dist/schemas/workflowMatching.js.map +1 -0
  130. package/dist/services/embedded-workflow-service.d.ts +106 -0
  131. package/dist/services/embedded-workflow-service.d.ts.map +1 -0
  132. package/dist/services/embedded-workflow-service.js +1900 -0
  133. package/dist/services/embedded-workflow-service.js.map +1 -0
  134. package/dist/services/index.d.ts +5 -0
  135. package/dist/services/index.d.ts.map +1 -0
  136. package/dist/services/index.js +5 -0
  137. package/dist/services/index.js.map +1 -0
  138. package/dist/services/workflow-credential-store.d.ts +27 -0
  139. package/dist/services/workflow-credential-store.d.ts.map +1 -0
  140. package/dist/services/workflow-credential-store.js +92 -0
  141. package/dist/services/workflow-credential-store.js.map +1 -0
  142. package/dist/services/workflow-dispatch.d.ts +41 -0
  143. package/dist/services/workflow-dispatch.d.ts.map +1 -0
  144. package/dist/services/workflow-dispatch.js +86 -0
  145. package/dist/services/workflow-dispatch.js.map +1 -0
  146. package/dist/services/workflow-service.d.ts +63 -0
  147. package/dist/services/workflow-service.d.ts.map +1 -0
  148. package/dist/services/workflow-service.js +492 -0
  149. package/dist/services/workflow-service.js.map +1 -0
  150. package/dist/trigger-routes.d.ts +153 -0
  151. package/dist/trigger-routes.d.ts.map +1 -0
  152. package/dist/trigger-routes.js +424 -0
  153. package/dist/trigger-routes.js.map +1 -0
  154. package/dist/types/index.d.ts +457 -0
  155. package/dist/types/index.d.ts.map +1 -0
  156. package/dist/types/index.js +59 -0
  157. package/dist/types/index.js.map +1 -0
  158. package/dist/utils/catalog.d.ts +16 -0
  159. package/dist/utils/catalog.d.ts.map +1 -0
  160. package/dist/utils/catalog.js +211 -0
  161. package/dist/utils/catalog.js.map +1 -0
  162. package/dist/utils/clarification.d.ts +17 -0
  163. package/dist/utils/clarification.d.ts.map +1 -0
  164. package/dist/utils/clarification.js +46 -0
  165. package/dist/utils/clarification.js.map +1 -0
  166. package/dist/utils/context.d.ts +4 -0
  167. package/dist/utils/context.d.ts.map +1 -0
  168. package/dist/utils/context.js +18 -0
  169. package/dist/utils/context.js.map +1 -0
  170. package/dist/utils/credentialResolver.d.ts +22 -0
  171. package/dist/utils/credentialResolver.d.ts.map +1 -0
  172. package/dist/utils/credentialResolver.js +146 -0
  173. package/dist/utils/credentialResolver.js.map +1 -0
  174. package/dist/utils/generation.d.ts +36 -0
  175. package/dist/utils/generation.d.ts.map +1 -0
  176. package/dist/utils/generation.js +701 -0
  177. package/dist/utils/generation.js.map +1 -0
  178. package/dist/utils/host-capabilities.d.ts +27 -0
  179. package/dist/utils/host-capabilities.d.ts.map +1 -0
  180. package/dist/utils/host-capabilities.js +59 -0
  181. package/dist/utils/host-capabilities.js.map +1 -0
  182. package/dist/utils/inferSyntheticOutputSchema.d.ts +20 -0
  183. package/dist/utils/inferSyntheticOutputSchema.d.ts.map +1 -0
  184. package/dist/utils/inferSyntheticOutputSchema.js +151 -0
  185. package/dist/utils/inferSyntheticOutputSchema.js.map +1 -0
  186. package/dist/utils/outputSchema.d.ts +26 -0
  187. package/dist/utils/outputSchema.d.ts.map +1 -0
  188. package/dist/utils/outputSchema.js +297 -0
  189. package/dist/utils/outputSchema.js.map +1 -0
  190. package/dist/utils/validateAndRepair.d.ts +41 -0
  191. package/dist/utils/validateAndRepair.d.ts.map +1 -0
  192. package/dist/utils/validateAndRepair.js +483 -0
  193. package/dist/utils/validateAndRepair.js.map +1 -0
  194. package/dist/utils/workflow-prompts/actionResponse.d.ts +2 -0
  195. package/dist/utils/workflow-prompts/actionResponse.d.ts.map +1 -0
  196. package/dist/utils/workflow-prompts/actionResponse.js +17 -0
  197. package/dist/utils/workflow-prompts/actionResponse.js.map +1 -0
  198. package/dist/utils/workflow-prompts/draftIntent.d.ts +2 -0
  199. package/dist/utils/workflow-prompts/draftIntent.d.ts.map +1 -0
  200. package/dist/utils/workflow-prompts/draftIntent.js +23 -0
  201. package/dist/utils/workflow-prompts/draftIntent.js.map +1 -0
  202. package/dist/utils/workflow-prompts/feasibilityCheck.d.ts +2 -0
  203. package/dist/utils/workflow-prompts/feasibilityCheck.d.ts.map +1 -0
  204. package/dist/utils/workflow-prompts/feasibilityCheck.js +21 -0
  205. package/dist/utils/workflow-prompts/feasibilityCheck.js.map +1 -0
  206. package/dist/utils/workflow-prompts/fieldCorrection.d.ts +3 -0
  207. package/dist/utils/workflow-prompts/fieldCorrection.d.ts.map +1 -0
  208. package/dist/utils/workflow-prompts/fieldCorrection.js +20 -0
  209. package/dist/utils/workflow-prompts/fieldCorrection.js.map +1 -0
  210. package/dist/utils/workflow-prompts/index.d.ts +8 -0
  211. package/dist/utils/workflow-prompts/index.d.ts.map +1 -0
  212. package/dist/utils/workflow-prompts/index.js +8 -0
  213. package/dist/utils/workflow-prompts/index.js.map +1 -0
  214. package/dist/utils/workflow-prompts/keywordExtraction.d.ts +2 -0
  215. package/dist/utils/workflow-prompts/keywordExtraction.d.ts.map +1 -0
  216. package/dist/utils/workflow-prompts/keywordExtraction.js +21 -0
  217. package/dist/utils/workflow-prompts/keywordExtraction.js.map +1 -0
  218. package/dist/utils/workflow-prompts/parameterCorrection.d.ts +3 -0
  219. package/dist/utils/workflow-prompts/parameterCorrection.d.ts.map +1 -0
  220. package/dist/utils/workflow-prompts/parameterCorrection.js +29 -0
  221. package/dist/utils/workflow-prompts/parameterCorrection.js.map +1 -0
  222. package/dist/utils/workflow-prompts/workflowGeneration.d.ts +2 -0
  223. package/dist/utils/workflow-prompts/workflowGeneration.d.ts.map +1 -0
  224. package/dist/utils/workflow-prompts/workflowGeneration.js +529 -0
  225. package/dist/utils/workflow-prompts/workflowGeneration.js.map +1 -0
  226. package/dist/utils/workflow-prompts/workflowMatching.d.ts +2 -0
  227. package/dist/utils/workflow-prompts/workflowMatching.d.ts.map +1 -0
  228. package/dist/utils/workflow-prompts/workflowMatching.js +23 -0
  229. package/dist/utils/workflow-prompts/workflowMatching.js.map +1 -0
  230. package/dist/utils/workflow.d.ts +62 -0
  231. package/dist/utils/workflow.d.ts.map +1 -0
  232. package/dist/utils/workflow.js +712 -0
  233. package/dist/utils/workflow.js.map +1 -0
  234. package/package.json +87 -0
  235. package/src/actions/index.ts +1 -0
  236. package/src/actions/workflow.ts +494 -0
  237. package/src/data/defaultNodes.json +9887 -0
  238. package/src/data/schemaIndex.json +1 -0
  239. package/src/data/triggerSchemaIndex.json +1 -0
  240. package/src/db/index.ts +8 -0
  241. package/src/db/schema.ts +94 -0
  242. package/src/index.ts +179 -0
  243. package/src/lib/automations-builder.ts +679 -0
  244. package/src/lib/automations-types.ts +391 -0
  245. package/src/lib/index.ts +8 -0
  246. package/src/lib/legacy-task-migration.ts +143 -0
  247. package/src/lib/legacy-text-trigger-migration.ts +178 -0
  248. package/src/lib/workflow-clarification.ts +497 -0
  249. package/src/plugin-routes.ts +164 -0
  250. package/src/providers/activeWorkflows.ts +81 -0
  251. package/src/providers/index.ts +3 -0
  252. package/src/providers/pendingDraft.ts +55 -0
  253. package/src/providers/workflowStatus.ts +88 -0
  254. package/src/register-routes.ts +6 -0
  255. package/src/routes/_helpers.ts +27 -0
  256. package/src/routes/automations.ts +46 -0
  257. package/src/routes/embedded-webhooks.ts +64 -0
  258. package/src/routes/executions.ts +75 -0
  259. package/src/routes/index.ts +16 -0
  260. package/src/routes/nodes.ts +211 -0
  261. package/src/routes/validation.ts +51 -0
  262. package/src/routes/workflow-routes.ts +469 -0
  263. package/src/routes/workflows.ts +310 -0
  264. package/src/schemas/draftIntent.ts +21 -0
  265. package/src/schemas/feasibility.ts +8 -0
  266. package/src/schemas/index.ts +4 -0
  267. package/src/schemas/keywordExtraction.ts +11 -0
  268. package/src/schemas/workflowMatching.ts +29 -0
  269. package/src/services/embedded-workflow-service.ts +2224 -0
  270. package/src/services/index.ts +17 -0
  271. package/src/services/workflow-credential-store.ts +132 -0
  272. package/src/services/workflow-dispatch.ts +121 -0
  273. package/src/services/workflow-service.ts +839 -0
  274. package/src/trigger-routes.ts +714 -0
  275. package/src/types/index.ts +562 -0
  276. package/src/utils/catalog.ts +260 -0
  277. package/src/utils/clarification.ts +52 -0
  278. package/src/utils/context.ts +22 -0
  279. package/src/utils/credentialResolver.ts +234 -0
  280. package/src/utils/generation.ts +987 -0
  281. package/src/utils/host-capabilities.ts +81 -0
  282. package/src/utils/inferSyntheticOutputSchema.ts +163 -0
  283. package/src/utils/outputSchema.ts +372 -0
  284. package/src/utils/validateAndRepair.ts +610 -0
  285. package/src/utils/workflow-prompts/actionResponse.ts +16 -0
  286. package/src/utils/workflow-prompts/draftIntent.ts +22 -0
  287. package/src/utils/workflow-prompts/feasibilityCheck.ts +20 -0
  288. package/src/utils/workflow-prompts/fieldCorrection.ts +20 -0
  289. package/src/utils/workflow-prompts/index.ts +10 -0
  290. package/src/utils/workflow-prompts/keywordExtraction.ts +20 -0
  291. package/src/utils/workflow-prompts/parameterCorrection.ts +29 -0
  292. package/src/utils/workflow-prompts/workflowGeneration.ts +528 -0
  293. package/src/utils/workflow-prompts/workflowMatching.ts +22 -0
  294. package/src/utils/workflow.ts +895 -0
@@ -0,0 +1,391 @@
1
+ /**
2
+ * Local types for the `/api/automations` response surface.
3
+ *
4
+ * These mirror the consumer-side shapes in @elizaos/ui's
5
+ * `client-types-config.ts`. We can't import @elizaos/ui from plugin-workflow
6
+ * (UI is a frontend package) and we can't import @elizaos/agent (would
7
+ * create a dependency cycle). The producer just needs to emit the right
8
+ * JSON; consumers retain their own view.
9
+ */
10
+
11
+ import type { Task } from '@elizaos/core';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Conversation metadata (mirrors @elizaos/agent server-types.ts)
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export type ConversationScope =
18
+ | 'general'
19
+ | 'automation-coordinator'
20
+ | 'automation-workflow'
21
+ | 'automation-workflow-draft'
22
+ | 'automation-draft'
23
+ | 'page-character'
24
+ | 'page-apps'
25
+ | 'page-connectors'
26
+ | 'page-phone'
27
+ | 'page-plugins'
28
+ | 'page-lifeops'
29
+ | 'page-settings'
30
+ | 'page-wallet'
31
+ | 'page-browser'
32
+ | 'page-automations';
33
+
34
+ export type ConversationAutomationType = 'coordinator_text' | 'workflow';
35
+
36
+ export interface ConversationMetadata {
37
+ scope?: ConversationScope;
38
+ automationType?: ConversationAutomationType;
39
+ taskId?: string;
40
+ triggerId?: string;
41
+ workflowId?: string;
42
+ workflowName?: string;
43
+ draftId?: string;
44
+ pageId?: string;
45
+ sourceConversationId?: string;
46
+ terminalBridgeConversationId?: string;
47
+ }
48
+
49
+ export function isAutomationConversationMetadata(
50
+ metadata: ConversationMetadata | null | undefined
51
+ ): boolean {
52
+ return (
53
+ metadata?.scope === 'automation-coordinator' ||
54
+ metadata?.scope === 'automation-workflow' ||
55
+ metadata?.scope === 'automation-workflow-draft' ||
56
+ metadata?.scope === 'automation-draft'
57
+ );
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Trigger (mirrors @elizaos/agent triggers/types.ts)
62
+ // ---------------------------------------------------------------------------
63
+
64
+ export type TriggerType = 'interval' | 'once' | 'cron' | 'event';
65
+ export type TriggerWakeMode = 'inject_now' | 'next_autonomy_cycle';
66
+ export type TriggerLastStatus = 'success' | 'error' | 'skipped';
67
+ export type TriggerKind = 'text' | 'workflow';
68
+
69
+ export interface TriggerSummary {
70
+ id: string;
71
+ taskId: string;
72
+ displayName: string;
73
+ instructions: string;
74
+ triggerType: TriggerType;
75
+ enabled: boolean;
76
+ wakeMode: TriggerWakeMode;
77
+ createdBy: string;
78
+ timezone?: string;
79
+ intervalMs?: number;
80
+ scheduledAtIso?: string;
81
+ cronExpression?: string;
82
+ eventKind?: string;
83
+ maxRuns?: number;
84
+ runCount: number;
85
+ nextRunAtMs?: number;
86
+ lastRunAtIso?: string;
87
+ lastStatus?: TriggerLastStatus;
88
+ lastError?: string;
89
+ updatedAt?: number;
90
+ updateInterval?: number;
91
+ kind?: TriggerKind;
92
+ workflowId?: string;
93
+ workflowName?: string;
94
+ }
95
+
96
+ interface TriggerConfigShape {
97
+ version?: number;
98
+ triggerId?: string;
99
+ displayName?: string;
100
+ instructions?: string;
101
+ triggerType?: TriggerType;
102
+ enabled?: boolean;
103
+ wakeMode?: TriggerWakeMode;
104
+ createdBy?: string;
105
+ timezone?: string;
106
+ intervalMs?: number;
107
+ scheduledAtIso?: string;
108
+ cronExpression?: string;
109
+ eventKind?: string;
110
+ maxRuns?: number;
111
+ runCount?: number;
112
+ nextRunAtMs?: number;
113
+ lastRunAtIso?: string;
114
+ lastStatus?: TriggerLastStatus;
115
+ lastError?: string;
116
+ kind?: TriggerKind;
117
+ workflowId?: string;
118
+ workflowName?: string;
119
+ }
120
+
121
+ interface TriggerTaskMetadataShape {
122
+ updatedAt?: number;
123
+ updateInterval?: number;
124
+ trigger?: TriggerConfigShape;
125
+ triggerRuns?: unknown[];
126
+ [key: string]: unknown;
127
+ }
128
+
129
+ const HEARTBEAT_TASK_TAGS = ['queue', 'repeat', 'heartbeat'] as const;
130
+
131
+ function taskMetadata(task: Task): TriggerTaskMetadataShape {
132
+ return (task.metadata ?? {}) as TriggerTaskMetadataShape;
133
+ }
134
+
135
+ /**
136
+ * Mirrors `readTriggerConfig` in @elizaos/agent triggers/runtime.ts.
137
+ */
138
+ export function readTriggerConfig(task: Task): TriggerConfigShape | null {
139
+ const trigger = taskMetadata(task).trigger;
140
+ if (!trigger || typeof trigger !== 'object' || Array.isArray(trigger)) return null;
141
+ return trigger.triggerId ? trigger : null;
142
+ }
143
+
144
+ function isExplicitHeartbeatTask(task: Task): boolean {
145
+ const tags = task.tags ?? [];
146
+ return HEARTBEAT_TASK_TAGS.every((tag) => tags.includes(tag));
147
+ }
148
+
149
+ function deriveSystemHeartbeatName(task: Task): string {
150
+ if (task.name && task.name.length > 0) {
151
+ return task.name
152
+ .replace(/_/g, ' ')
153
+ .toLowerCase()
154
+ .replace(/\b\w/g, (c) => c.toUpperCase());
155
+ }
156
+ const tag = (task.tags ?? []).find((t) => t !== 'queue' && t !== 'repeat' && t !== 'trigger');
157
+ if (tag) {
158
+ return `${tag.charAt(0).toUpperCase()}${tag.slice(1)} Heartbeat`;
159
+ }
160
+ return 'System Heartbeat';
161
+ }
162
+
163
+ function synthesizeSystemHeartbeatSummary(task: Task): TriggerSummary | null {
164
+ if (!task.id) return null;
165
+ const metadata = taskMetadata(task);
166
+ const intervalMs =
167
+ typeof metadata.updateInterval === 'number' ? metadata.updateInterval : undefined;
168
+ const tags = task.tags ?? [];
169
+ const createdBy =
170
+ tags.find((t) => t !== 'queue' && t !== 'repeat' && t !== 'trigger') ?? 'system';
171
+ return {
172
+ id: task.id,
173
+ taskId: task.id,
174
+ displayName: deriveSystemHeartbeatName(task),
175
+ instructions: task.description ?? '',
176
+ triggerType: 'interval',
177
+ enabled: true,
178
+ wakeMode: 'next_autonomy_cycle',
179
+ createdBy,
180
+ intervalMs,
181
+ runCount: 0,
182
+ updatedAt: typeof metadata.updatedAt === 'number' ? metadata.updatedAt : undefined,
183
+ updateInterval: intervalMs,
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Mirrors `taskToTriggerSummary` in @elizaos/agent triggers/runtime.ts.
189
+ */
190
+ export function taskToTriggerSummary(task: Task): TriggerSummary | null {
191
+ const trigger = readTriggerConfig(task);
192
+ if (
193
+ trigger &&
194
+ task.id &&
195
+ trigger.triggerId &&
196
+ trigger.displayName !== undefined &&
197
+ trigger.instructions !== undefined &&
198
+ trigger.triggerType &&
199
+ trigger.enabled !== undefined &&
200
+ trigger.wakeMode &&
201
+ trigger.createdBy
202
+ ) {
203
+ const metadata = taskMetadata(task);
204
+ return {
205
+ id: trigger.triggerId,
206
+ taskId: task.id,
207
+ displayName: trigger.displayName,
208
+ instructions: trigger.instructions,
209
+ triggerType: trigger.triggerType,
210
+ enabled: trigger.enabled,
211
+ wakeMode: trigger.wakeMode,
212
+ createdBy: trigger.createdBy,
213
+ ...(trigger.timezone !== undefined ? { timezone: trigger.timezone } : {}),
214
+ ...(trigger.intervalMs !== undefined ? { intervalMs: trigger.intervalMs } : {}),
215
+ ...(trigger.scheduledAtIso !== undefined ? { scheduledAtIso: trigger.scheduledAtIso } : {}),
216
+ ...(trigger.cronExpression !== undefined ? { cronExpression: trigger.cronExpression } : {}),
217
+ ...(trigger.eventKind !== undefined ? { eventKind: trigger.eventKind } : {}),
218
+ ...(trigger.maxRuns !== undefined ? { maxRuns: trigger.maxRuns } : {}),
219
+ runCount: typeof trigger.runCount === 'number' ? trigger.runCount : 0,
220
+ ...(trigger.nextRunAtMs !== undefined ? { nextRunAtMs: trigger.nextRunAtMs } : {}),
221
+ ...(trigger.lastRunAtIso !== undefined ? { lastRunAtIso: trigger.lastRunAtIso } : {}),
222
+ ...(trigger.lastStatus !== undefined ? { lastStatus: trigger.lastStatus } : {}),
223
+ ...(trigger.lastError !== undefined ? { lastError: trigger.lastError } : {}),
224
+ ...(metadata.updatedAt !== undefined ? { updatedAt: metadata.updatedAt } : {}),
225
+ ...(metadata.updateInterval !== undefined ? { updateInterval: metadata.updateInterval } : {}),
226
+ ...(trigger.kind !== undefined ? { kind: trigger.kind } : {}),
227
+ ...(trigger.workflowId !== undefined ? { workflowId: trigger.workflowId } : {}),
228
+ ...(trigger.workflowName !== undefined ? { workflowName: trigger.workflowName } : {}),
229
+ };
230
+ }
231
+
232
+ if (isExplicitHeartbeatTask(task)) {
233
+ return synthesizeSystemHeartbeatSummary(task);
234
+ }
235
+
236
+ return null;
237
+ }
238
+
239
+ // ---------------------------------------------------------------------------
240
+ // Workbench task (mirrors @elizaos/agent workbench-helpers.ts)
241
+ // ---------------------------------------------------------------------------
242
+
243
+ const WORKBENCH_TASK_TAG = 'workbench-task';
244
+ const WORKBENCH_TODO_TAG = 'workbench-todo';
245
+
246
+ export interface WorkbenchTaskView {
247
+ id: string;
248
+ name: string;
249
+ description: string;
250
+ tags: string[];
251
+ isCompleted: boolean;
252
+ updatedAt?: number;
253
+ }
254
+
255
+ function isObject(value: unknown): value is Record<string, unknown> {
256
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
257
+ }
258
+
259
+ function normalizeStringArray(value: unknown): string[] {
260
+ if (!Array.isArray(value)) return [];
261
+ return value
262
+ .filter((item): item is string => typeof item === 'string')
263
+ .map((item) => item.trim())
264
+ .filter((item) => item.length > 0);
265
+ }
266
+
267
+ function normalizeTimestamp(value: unknown): number | undefined {
268
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
269
+ if (value instanceof Date) return value.getTime();
270
+ if (typeof value === 'string') {
271
+ const asNumber = Number(value);
272
+ if (Number.isFinite(asNumber)) return asNumber;
273
+ const parsed = Date.parse(value);
274
+ if (Number.isFinite(parsed)) return parsed;
275
+ }
276
+ return undefined;
277
+ }
278
+
279
+ function readTaskMetadata(task: Task): Record<string, unknown> {
280
+ return isObject(task.metadata) ? task.metadata : {};
281
+ }
282
+
283
+ function readTaskCompleted(task: Task): boolean {
284
+ const metadata = readTaskMetadata(task);
285
+ if (typeof metadata.isCompleted === 'boolean') return metadata.isCompleted;
286
+ const todoMeta =
287
+ (isObject(metadata.workbenchTodo) ? metadata.workbenchTodo : null) ??
288
+ (isObject(metadata.todo) ? metadata.todo : null);
289
+ if (todoMeta && typeof todoMeta.isCompleted === 'boolean') {
290
+ return todoMeta.isCompleted;
291
+ }
292
+ return false;
293
+ }
294
+
295
+ function isWorkbenchTodoTask(task: Task): boolean {
296
+ if (readTriggerConfig(task)) return false;
297
+ const tags = new Set(normalizeStringArray(task.tags));
298
+ if (tags.has(WORKBENCH_TODO_TAG) || tags.has('todo')) return true;
299
+ const metadata = readTaskMetadata(task);
300
+ return isObject(metadata.workbenchTodo) || isObject(metadata.todo);
301
+ }
302
+
303
+ /**
304
+ * Mirrors `toWorkbenchTask` in @elizaos/agent workbench-helpers.ts.
305
+ */
306
+ export function toWorkbenchTaskView(task: Task): WorkbenchTaskView | null {
307
+ if (!task.tags?.includes(WORKBENCH_TASK_TAG)) return null;
308
+ if (readTriggerConfig(task) || isWorkbenchTodoTask(task)) return null;
309
+ const id = typeof task.id === 'string' && task.id.trim().length > 0 ? task.id : null;
310
+ if (!id) return null;
311
+ const metadata = readTaskMetadata(task);
312
+ const updatedAt = normalizeTimestamp(task.updatedAt) ?? normalizeTimestamp(metadata.updatedAt);
313
+ return {
314
+ id,
315
+ name: typeof task.name === 'string' && task.name.trim().length > 0 ? task.name : 'Task',
316
+ description: typeof task.description === 'string' ? task.description : '',
317
+ tags: normalizeStringArray(task.tags),
318
+ isCompleted: readTaskCompleted(task),
319
+ ...(updatedAt !== undefined ? { updatedAt } : {}),
320
+ };
321
+ }
322
+
323
+ // ---------------------------------------------------------------------------
324
+ // Automation response (mirrors @elizaos/ui client-types-config.ts)
325
+ // ---------------------------------------------------------------------------
326
+
327
+ export type AutomationType = 'coordinator_text' | 'workflow' | 'automation_draft';
328
+
329
+ export type AutomationSource =
330
+ | 'workbench_task'
331
+ | 'trigger'
332
+ | 'workflow'
333
+ | 'workflow_draft'
334
+ | 'workflow_shadow'
335
+ | 'automation_draft';
336
+
337
+ export type AutomationStatus = 'active' | 'paused' | 'completed' | 'draft' | 'system';
338
+
339
+ export interface AutomationRoomBinding {
340
+ conversationId: string | null;
341
+ roomId: string;
342
+ scope: ConversationScope;
343
+ sourceConversationId?: string;
344
+ terminalBridgeConversationId?: string;
345
+ }
346
+
347
+ export interface AutomationLastExecution {
348
+ status: 'success' | 'error' | 'running' | 'waiting' | 'unknown';
349
+ startedAt: string;
350
+ stoppedAt?: string | null;
351
+ errorMessage?: string;
352
+ }
353
+
354
+ export interface AutomationItem {
355
+ id: string;
356
+ type: AutomationType;
357
+ source: AutomationSource;
358
+ title: string;
359
+ description: string;
360
+ status: AutomationStatus;
361
+ enabled: boolean;
362
+ system: boolean;
363
+ isDraft: boolean;
364
+ hasBackingWorkflow: boolean;
365
+ updatedAt: string | null;
366
+ taskId?: string;
367
+ triggerId?: string;
368
+ workflowId?: string;
369
+ draftId?: string;
370
+ task?: WorkbenchTaskView;
371
+ trigger?: TriggerSummary;
372
+ workflow?: unknown;
373
+ schedules: TriggerSummary[];
374
+ room?: AutomationRoomBinding | null;
375
+ lastExecution?: AutomationLastExecution;
376
+ }
377
+
378
+ export interface AutomationSummary {
379
+ total: number;
380
+ coordinatorCount: number;
381
+ workflowCount: number;
382
+ scheduledCount: number;
383
+ draftCount: number;
384
+ }
385
+
386
+ export interface AutomationListResponse {
387
+ automations: AutomationItem[];
388
+ summary: AutomationSummary;
389
+ workflowStatus: unknown;
390
+ workflowFetchError: string | null;
391
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ type LegacyTaskMigrationSummary,
3
+ migrateLegacyWorkbenchTasks,
4
+ } from './legacy-task-migration';
5
+ export {
6
+ type LegacyTextTriggerMigrationSummary,
7
+ migrateLegacyTextTriggers,
8
+ } from './legacy-text-trigger-migration';
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Idempotent migration: legacy `workbench-task` Task records → workflows
3
+ *
4
+ * Walks every Task tagged `workbench-task` for the running agent and, for
5
+ * each task that has not already been converted, deploys a one-node workflow
6
+ * built around `workflows-nodes-base.respondToEvent`. The original task is
7
+ * mutated in place to record `metadata.migratedToWorkflowId` so subsequent
8
+ * boots skip it.
9
+ *
10
+ * Designed to run on every plugin init; per-task try/catch keeps a single
11
+ * failed conversion from aborting the loop. The function never throws.
12
+ */
13
+
14
+ import { type IAgentRuntime, logger, type Task } from '@elizaos/core';
15
+ import type { WorkflowService } from '../services/workflow-service';
16
+ import { WORKFLOW_SERVICE_TYPE } from '../services/workflow-service';
17
+ import type { WorkflowDefinition } from '../types/index';
18
+
19
+ const WORKBENCH_TASK_TAG = 'workbench-task';
20
+ const RESPOND_TO_EVENT_NODE_TYPE = 'workflows-nodes-base.respondToEvent';
21
+
22
+ export interface LegacyTaskMigrationSummary {
23
+ migrated: number;
24
+ skipped: number;
25
+ failed: number;
26
+ }
27
+
28
+ function readWorkflowService(runtime: IAgentRuntime): WorkflowService | null {
29
+ const svc = runtime.getService(WORKFLOW_SERVICE_TYPE) as WorkflowService | null;
30
+ return svc ?? null;
31
+ }
32
+
33
+ function buildRespondToEventWorkflow(task: Task): WorkflowDefinition {
34
+ const displayName = task.name?.trim().length ? task.name : 'Workbench Task';
35
+ const instructions = task.description?.trim().length ? task.description : displayName;
36
+
37
+ return {
38
+ name: displayName,
39
+ nodes: [
40
+ {
41
+ id: 'respond-to-event',
42
+ name: 'Respond To Event',
43
+ type: RESPOND_TO_EVENT_NODE_TYPE,
44
+ typeVersion: 1,
45
+ position: [0, 0],
46
+ parameters: {
47
+ instructions,
48
+ displayName,
49
+ wakeMode: 'inject_now',
50
+ },
51
+ },
52
+ ],
53
+ connections: {},
54
+ };
55
+ }
56
+
57
+ export async function migrateLegacyWorkbenchTasks(
58
+ runtime: IAgentRuntime
59
+ ): Promise<LegacyTaskMigrationSummary> {
60
+ const summary: LegacyTaskMigrationSummary = { migrated: 0, skipped: 0, failed: 0 };
61
+
62
+ const service = readWorkflowService(runtime);
63
+ if (!service) {
64
+ logger.debug(
65
+ { src: 'plugin:workflow:migration:workbench' },
66
+ 'WorkflowService not registered; skipping workbench-task migration'
67
+ );
68
+ return summary;
69
+ }
70
+
71
+ let tasks: Task[];
72
+ try {
73
+ tasks = await runtime.getTasks({
74
+ agentIds: [runtime.agentId],
75
+ tags: [WORKBENCH_TASK_TAG],
76
+ });
77
+ } catch (err) {
78
+ logger.warn(
79
+ {
80
+ src: 'plugin:workflow:migration:workbench',
81
+ err: err instanceof Error ? err.message : String(err),
82
+ },
83
+ 'Failed to list workbench-tagged tasks; aborting migration'
84
+ );
85
+ return summary;
86
+ }
87
+
88
+ for (const task of tasks) {
89
+ if (!task.id) {
90
+ summary.skipped += 1;
91
+ continue;
92
+ }
93
+
94
+ const metadata = (task.metadata ?? {}) as Record<string, unknown>;
95
+ if (typeof metadata.migratedToWorkflowId === 'string') {
96
+ summary.skipped += 1;
97
+ continue;
98
+ }
99
+
100
+ try {
101
+ const draft = buildRespondToEventWorkflow(task);
102
+ const deployed = await service.deployWorkflow(draft, runtime.agentId);
103
+
104
+ if (!deployed.id) {
105
+ // Deploy returned without a workflow id (typically: missing
106
+ // credentials). Treat as a failure rather than marking the task
107
+ // migrated — we want to retry on a future boot.
108
+ summary.failed += 1;
109
+ logger.warn(
110
+ {
111
+ src: 'plugin:workflow:migration:workbench',
112
+ taskId: task.id,
113
+ taskName: task.name,
114
+ },
115
+ 'deployWorkflow returned no id; will retry on next boot'
116
+ );
117
+ continue;
118
+ }
119
+
120
+ await runtime.updateTask(task.id, {
121
+ metadata: {
122
+ ...metadata,
123
+ migratedToWorkflowId: deployed.id,
124
+ migratedAt: Date.now(),
125
+ },
126
+ });
127
+ summary.migrated += 1;
128
+ } catch (err) {
129
+ summary.failed += 1;
130
+ logger.warn(
131
+ {
132
+ src: 'plugin:workflow:migration:workbench',
133
+ taskId: task.id,
134
+ taskName: task.name,
135
+ err: err instanceof Error ? err.message : String(err),
136
+ },
137
+ 'Failed to migrate workbench task to workflow'
138
+ );
139
+ }
140
+ }
141
+
142
+ return summary;
143
+ }