@elizaos/autonomous 2.0.0-alpha.10

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 (241) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +270 -0
  3. package/src/actions/emote.ts +101 -0
  4. package/src/actions/restart.ts +101 -0
  5. package/src/actions/send-message.ts +168 -0
  6. package/src/actions/stream-control.ts +439 -0
  7. package/src/actions/switch-stream-source.ts +126 -0
  8. package/src/actions/terminal.ts +186 -0
  9. package/src/api/agent-admin-routes.ts +178 -0
  10. package/src/api/agent-lifecycle-routes.ts +129 -0
  11. package/src/api/agent-model.ts +143 -0
  12. package/src/api/agent-transfer-routes.ts +211 -0
  13. package/src/api/apps-routes.ts +210 -0
  14. package/src/api/auth-routes.ts +90 -0
  15. package/src/api/bsc-trade.ts +736 -0
  16. package/src/api/bug-report-routes.ts +161 -0
  17. package/src/api/character-routes.ts +421 -0
  18. package/src/api/cloud-billing-routes.ts +598 -0
  19. package/src/api/cloud-compat-routes.ts +192 -0
  20. package/src/api/cloud-routes.ts +529 -0
  21. package/src/api/cloud-status-routes.ts +234 -0
  22. package/src/api/compat-utils.ts +154 -0
  23. package/src/api/connector-health.ts +135 -0
  24. package/src/api/coordinator-wiring.ts +179 -0
  25. package/src/api/credit-detection.ts +47 -0
  26. package/src/api/database.ts +1357 -0
  27. package/src/api/diagnostics-routes.ts +389 -0
  28. package/src/api/drop-service.ts +205 -0
  29. package/src/api/early-logs.ts +111 -0
  30. package/src/api/http-helpers.ts +252 -0
  31. package/src/api/index.ts +85 -0
  32. package/src/api/knowledge-routes.ts +1189 -0
  33. package/src/api/knowledge-service-loader.ts +92 -0
  34. package/src/api/memory-bounds.ts +121 -0
  35. package/src/api/memory-routes.ts +349 -0
  36. package/src/api/merkle-tree.ts +239 -0
  37. package/src/api/models-routes.ts +72 -0
  38. package/src/api/nfa-routes.ts +169 -0
  39. package/src/api/nft-verify.ts +188 -0
  40. package/src/api/og-tracker.ts +72 -0
  41. package/src/api/parse-action-block.ts +145 -0
  42. package/src/api/permissions-routes.ts +222 -0
  43. package/src/api/plugin-validation.ts +355 -0
  44. package/src/api/provider-switch-config.ts +455 -0
  45. package/src/api/registry-routes.ts +165 -0
  46. package/src/api/registry-service.ts +292 -0
  47. package/src/api/route-helpers.ts +21 -0
  48. package/src/api/sandbox-routes.ts +1480 -0
  49. package/src/api/server.ts +17674 -0
  50. package/src/api/signal-routes.ts +265 -0
  51. package/src/api/stream-persistence.ts +297 -0
  52. package/src/api/stream-route-state.ts +48 -0
  53. package/src/api/stream-routes.ts +1046 -0
  54. package/src/api/stream-voice-routes.ts +208 -0
  55. package/src/api/streaming-text.ts +129 -0
  56. package/src/api/streaming-types.ts +23 -0
  57. package/src/api/subscription-routes.ts +283 -0
  58. package/src/api/terminal-run-limits.ts +31 -0
  59. package/src/api/training-backend-check.ts +40 -0
  60. package/src/api/training-routes.ts +314 -0
  61. package/src/api/training-service-like.ts +46 -0
  62. package/src/api/trajectory-routes.ts +714 -0
  63. package/src/api/trigger-routes.ts +438 -0
  64. package/src/api/twitter-verify.ts +226 -0
  65. package/src/api/tx-service.ts +193 -0
  66. package/src/api/wallet-dex-prices.ts +206 -0
  67. package/src/api/wallet-evm-balance.ts +989 -0
  68. package/src/api/wallet-routes.ts +505 -0
  69. package/src/api/wallet-rpc.ts +523 -0
  70. package/src/api/wallet-trading-profile.ts +694 -0
  71. package/src/api/wallet.ts +745 -0
  72. package/src/api/whatsapp-routes.ts +282 -0
  73. package/src/api/zip-utils.ts +130 -0
  74. package/src/auth/anthropic.ts +63 -0
  75. package/src/auth/apply-stealth.ts +38 -0
  76. package/src/auth/claude-code-stealth.ts +141 -0
  77. package/src/auth/credentials.ts +226 -0
  78. package/src/auth/index.ts +18 -0
  79. package/src/auth/openai-codex.ts +94 -0
  80. package/src/auth/types.ts +24 -0
  81. package/src/awareness/registry.ts +220 -0
  82. package/src/bin.ts +10 -0
  83. package/src/cli/index.ts +36 -0
  84. package/src/cli/parse-duration.ts +43 -0
  85. package/src/cloud/auth.test.ts +370 -0
  86. package/src/cloud/auth.ts +176 -0
  87. package/src/cloud/backup.test.ts +150 -0
  88. package/src/cloud/backup.ts +50 -0
  89. package/src/cloud/base-url.ts +45 -0
  90. package/src/cloud/bridge-client.test.ts +481 -0
  91. package/src/cloud/bridge-client.ts +307 -0
  92. package/src/cloud/cloud-manager.test.ts +223 -0
  93. package/src/cloud/cloud-manager.ts +151 -0
  94. package/src/cloud/cloud-proxy.test.ts +122 -0
  95. package/src/cloud/cloud-proxy.ts +52 -0
  96. package/src/cloud/index.ts +23 -0
  97. package/src/cloud/reconnect.test.ts +178 -0
  98. package/src/cloud/reconnect.ts +108 -0
  99. package/src/cloud/validate-url.test.ts +147 -0
  100. package/src/cloud/validate-url.ts +176 -0
  101. package/src/config/character-schema.ts +44 -0
  102. package/src/config/config.ts +149 -0
  103. package/src/config/env-vars.ts +86 -0
  104. package/src/config/includes.ts +196 -0
  105. package/src/config/index.ts +15 -0
  106. package/src/config/object-utils.ts +10 -0
  107. package/src/config/paths.ts +92 -0
  108. package/src/config/plugin-auto-enable.ts +520 -0
  109. package/src/config/schema.ts +1342 -0
  110. package/src/config/telegram-custom-commands.ts +99 -0
  111. package/src/config/types.agent-defaults.ts +342 -0
  112. package/src/config/types.agents.ts +112 -0
  113. package/src/config/types.gateway.ts +243 -0
  114. package/src/config/types.hooks.ts +124 -0
  115. package/src/config/types.messages.ts +201 -0
  116. package/src/config/types.milady.ts +791 -0
  117. package/src/config/types.tools.ts +416 -0
  118. package/src/config/types.ts +7 -0
  119. package/src/config/zod-schema.agent-runtime.ts +777 -0
  120. package/src/config/zod-schema.core.ts +778 -0
  121. package/src/config/zod-schema.hooks.ts +139 -0
  122. package/src/config/zod-schema.providers-core.ts +1126 -0
  123. package/src/config/zod-schema.session.ts +98 -0
  124. package/src/config/zod-schema.ts +865 -0
  125. package/src/contracts/apps.ts +46 -0
  126. package/src/contracts/awareness.ts +56 -0
  127. package/src/contracts/config.ts +172 -0
  128. package/src/contracts/drop.ts +21 -0
  129. package/src/contracts/index.ts +8 -0
  130. package/src/contracts/onboarding.ts +592 -0
  131. package/src/contracts/permissions.ts +52 -0
  132. package/src/contracts/verification.ts +9 -0
  133. package/src/contracts/wallet.ts +503 -0
  134. package/src/diagnostics/integration-observability.ts +132 -0
  135. package/src/emotes/catalog.ts +655 -0
  136. package/src/external-modules.d.ts +7 -0
  137. package/src/hooks/discovery.test.ts +357 -0
  138. package/src/hooks/discovery.ts +231 -0
  139. package/src/hooks/eligibility.ts +146 -0
  140. package/src/hooks/hooks.test.ts +320 -0
  141. package/src/hooks/index.ts +8 -0
  142. package/src/hooks/loader.test.ts +418 -0
  143. package/src/hooks/loader.ts +256 -0
  144. package/src/hooks/registry.test.ts +168 -0
  145. package/src/hooks/registry.ts +74 -0
  146. package/src/hooks/types.ts +121 -0
  147. package/src/index.ts +19 -0
  148. package/src/onboarding-presets.ts +828 -0
  149. package/src/plugins/custom-rtmp/index.ts +40 -0
  150. package/src/providers/admin-trust.ts +76 -0
  151. package/src/providers/session-bridge.ts +143 -0
  152. package/src/providers/session-utils.ts +42 -0
  153. package/src/providers/simple-mode.ts +113 -0
  154. package/src/providers/ui-catalog.ts +135 -0
  155. package/src/providers/workspace-provider.ts +213 -0
  156. package/src/providers/workspace.ts +497 -0
  157. package/src/runtime/agent-event-service.ts +57 -0
  158. package/src/runtime/cloud-onboarding.test.ts +489 -0
  159. package/src/runtime/cloud-onboarding.ts +408 -0
  160. package/src/runtime/core-plugins.ts +53 -0
  161. package/src/runtime/custom-actions.ts +605 -0
  162. package/src/runtime/eliza.ts +4941 -0
  163. package/src/runtime/embedding-presets.ts +73 -0
  164. package/src/runtime/index.ts +8 -0
  165. package/src/runtime/milady-plugin.ts +180 -0
  166. package/src/runtime/onboarding-names.ts +76 -0
  167. package/src/runtime/release-plugin-policy.ts +119 -0
  168. package/src/runtime/restart.ts +59 -0
  169. package/src/runtime/trajectory-persistence.ts +2584 -0
  170. package/src/runtime/version.ts +6 -0
  171. package/src/security/audit-log.ts +222 -0
  172. package/src/security/network-policy.ts +91 -0
  173. package/src/server/index.ts +6 -0
  174. package/src/services/agent-export.ts +976 -0
  175. package/src/services/app-manager.ts +755 -0
  176. package/src/services/browser-capture.ts +215 -0
  177. package/src/services/coding-agent-context.ts +355 -0
  178. package/src/services/fallback-training-service.ts +196 -0
  179. package/src/services/index.ts +17 -0
  180. package/src/services/mcp-marketplace.ts +327 -0
  181. package/src/services/plugin-manager-types.ts +185 -0
  182. package/src/services/privy-wallets.ts +352 -0
  183. package/src/services/registry-client-app-meta.ts +201 -0
  184. package/src/services/registry-client-endpoints.ts +253 -0
  185. package/src/services/registry-client-local.ts +485 -0
  186. package/src/services/registry-client-network.ts +173 -0
  187. package/src/services/registry-client-queries.ts +176 -0
  188. package/src/services/registry-client-types.ts +104 -0
  189. package/src/services/registry-client.ts +366 -0
  190. package/src/services/remote-signing-service.ts +261 -0
  191. package/src/services/sandbox-engine.ts +753 -0
  192. package/src/services/sandbox-manager.ts +503 -0
  193. package/src/services/self-updater.ts +213 -0
  194. package/src/services/signal-pairing.ts +189 -0
  195. package/src/services/signing-policy.ts +230 -0
  196. package/src/services/skill-catalog-client.ts +195 -0
  197. package/src/services/skill-marketplace.ts +909 -0
  198. package/src/services/stream-manager.ts +707 -0
  199. package/src/services/tts-stream-bridge.ts +465 -0
  200. package/src/services/update-checker.ts +163 -0
  201. package/src/services/version-compat.ts +367 -0
  202. package/src/services/whatsapp-pairing.ts +279 -0
  203. package/src/shared/ui-catalog-prompt.ts +1158 -0
  204. package/src/test-support/process-helpers.ts +35 -0
  205. package/src/test-support/route-test-helpers.ts +113 -0
  206. package/src/test-support/test-helpers.ts +304 -0
  207. package/src/testing/index.ts +3 -0
  208. package/src/triggers/action.ts +342 -0
  209. package/src/triggers/runtime.ts +432 -0
  210. package/src/triggers/scheduling.ts +472 -0
  211. package/src/triggers/types.ts +133 -0
  212. package/src/types/app-hyperscape-routes-shim.d.ts +29 -0
  213. package/src/types/external-modules.d.ts +7 -0
  214. package/src/utils/exec-safety.ts +23 -0
  215. package/src/utils/number-parsing.ts +112 -0
  216. package/src/utils/spoken-text.ts +65 -0
  217. package/src/version-resolver.ts +60 -0
  218. package/test/api/agent-admin-routes.test.ts +160 -0
  219. package/test/api/agent-lifecycle-routes.test.ts +164 -0
  220. package/test/api/agent-transfer-routes.test.ts +136 -0
  221. package/test/api/apps-routes.test.ts +140 -0
  222. package/test/api/auth-routes.test.ts +160 -0
  223. package/test/api/bug-report-routes.test.ts +88 -0
  224. package/test/api/knowledge-routes.test.ts +73 -0
  225. package/test/api/lifecycle.test.ts +342 -0
  226. package/test/api/memory-routes.test.ts +74 -0
  227. package/test/api/models-routes.test.ts +112 -0
  228. package/test/api/nfa-routes.test.ts +78 -0
  229. package/test/api/permissions-routes.test.ts +185 -0
  230. package/test/api/registry-routes.test.ts +157 -0
  231. package/test/api/signal-routes.test.ts +113 -0
  232. package/test/api/subscription-routes.test.ts +90 -0
  233. package/test/api/trigger-routes.test.ts +87 -0
  234. package/test/api/wallet-routes.observability.test.ts +191 -0
  235. package/test/api/wallet-routes.test.ts +502 -0
  236. package/test/diagnostics/integration-observability.test.ts +135 -0
  237. package/test/security/audit-log.test.ts +229 -0
  238. package/test/security/network-policy.test.ts +143 -0
  239. package/test/services/version-compat.test.ts +127 -0
  240. package/tsconfig.build.json +21 -0
  241. package/tsconfig.json +19 -0
@@ -0,0 +1,432 @@
1
+ import crypto from "node:crypto";
2
+ import type { IAgentRuntime, Task, UUID } from "@elizaos/core";
3
+ import { stringToUuid } from "@elizaos/core";
4
+ import {
5
+ buildTriggerMetadata,
6
+ DISABLED_TRIGGER_INTERVAL_MS,
7
+ MAX_TRIGGER_RUN_HISTORY,
8
+ } from "./scheduling";
9
+ import type {
10
+ TriggerConfig,
11
+ TriggerHealthSnapshot,
12
+ TriggerRunRecord,
13
+ TriggerSummary,
14
+ TriggerTaskMetadata,
15
+ } from "./types";
16
+
17
+ export const TRIGGER_TASK_NAME = "TRIGGER_DISPATCH" as const;
18
+ export const TRIGGER_TASK_TAGS = ["queue", "repeat", "trigger"] as const;
19
+
20
+ const DEFAULT_MAX_ACTIVE_TRIGGERS = 100;
21
+
22
+ interface TriggerMetricsState {
23
+ totalExecutions: number;
24
+ totalFailures: number;
25
+ totalSkipped: number;
26
+ lastExecutionAt?: number;
27
+ }
28
+
29
+ export interface TriggerExecutionOptions {
30
+ source: "scheduler" | "manual";
31
+ force?: boolean;
32
+ }
33
+
34
+ export interface TriggerExecutionResult {
35
+ status: "success" | "error" | "skipped";
36
+ error?: string;
37
+ taskDeleted: boolean;
38
+ runRecord?: TriggerRunRecord;
39
+ }
40
+
41
+ const metricsByAgent = new Map<UUID, TriggerMetricsState>();
42
+
43
+ function getMetrics(agentId: UUID): TriggerMetricsState {
44
+ const current = metricsByAgent.get(agentId);
45
+ if (current) return current;
46
+ const created: TriggerMetricsState = {
47
+ totalExecutions: 0,
48
+ totalFailures: 0,
49
+ totalSkipped: 0,
50
+ };
51
+ metricsByAgent.set(agentId, created);
52
+ return created;
53
+ }
54
+
55
+ function recordExecutionMetric(
56
+ agentId: UUID,
57
+ status: TriggerExecutionResult["status"],
58
+ ts: number,
59
+ ): void {
60
+ const metrics = getMetrics(agentId);
61
+ if (status === "success" || status === "error") {
62
+ metrics.totalExecutions += 1;
63
+ metrics.lastExecutionAt = ts;
64
+ }
65
+ if (status === "error") {
66
+ metrics.totalFailures += 1;
67
+ }
68
+ if (status === "skipped") {
69
+ metrics.totalSkipped += 1;
70
+ }
71
+ }
72
+
73
+ function appendRunRecord(
74
+ existing: TriggerRunRecord[] | undefined,
75
+ record: TriggerRunRecord,
76
+ ): TriggerRunRecord[] {
77
+ const runs = [...(existing ?? []), record];
78
+ return runs.length <= MAX_TRIGGER_RUN_HISTORY
79
+ ? runs
80
+ : runs.slice(runs.length - MAX_TRIGGER_RUN_HISTORY);
81
+ }
82
+
83
+ function taskMetadata(task: Task): TriggerTaskMetadata {
84
+ return (task.metadata ?? {}) as TriggerTaskMetadata;
85
+ }
86
+
87
+ export function readTriggerConfig(task: Task): TriggerConfig | null {
88
+ const trigger = taskMetadata(task).trigger;
89
+ if (!trigger || typeof trigger !== "object" || Array.isArray(trigger))
90
+ return null;
91
+ return (trigger as TriggerConfig).triggerId
92
+ ? (trigger as TriggerConfig)
93
+ : null;
94
+ }
95
+
96
+ export function readTriggerRuns(task: Task): TriggerRunRecord[] {
97
+ const runs = taskMetadata(task).triggerRuns;
98
+ return Array.isArray(runs) ? (runs as TriggerRunRecord[]) : [];
99
+ }
100
+
101
+ export function triggersFeatureEnabled(runtime?: IAgentRuntime): boolean {
102
+ const runtimeSetting = runtime?.getSetting("MILADY_TRIGGERS_ENABLED");
103
+ if (
104
+ runtimeSetting === false ||
105
+ runtimeSetting === "false" ||
106
+ runtimeSetting === "0"
107
+ ) {
108
+ return false;
109
+ }
110
+ const env = process.env.MILADY_TRIGGERS_ENABLED;
111
+ if (!env) return true;
112
+ const normalized = env.trim().toLowerCase();
113
+ return normalized !== "0" && normalized !== "false";
114
+ }
115
+
116
+ export function getTriggerLimit(runtime?: IAgentRuntime): number {
117
+ const runtimeSetting = runtime?.getSetting("MILADY_TRIGGERS_MAX_ACTIVE");
118
+ if (typeof runtimeSetting === "number" && Number.isFinite(runtimeSetting)) {
119
+ return Math.max(1, Math.floor(runtimeSetting));
120
+ }
121
+ if (typeof runtimeSetting === "string" && /^\d+$/.test(runtimeSetting)) {
122
+ return Math.max(1, Number(runtimeSetting));
123
+ }
124
+ const env = process.env.MILADY_TRIGGERS_MAX_ACTIVE;
125
+ if (env && /^\d+$/.test(env)) {
126
+ return Math.max(1, Number(env));
127
+ }
128
+ return DEFAULT_MAX_ACTIVE_TRIGGERS;
129
+ }
130
+
131
+ function isAutonomyServiceAvailable(runtime: IAgentRuntime): boolean {
132
+ const svc =
133
+ (runtime.getService("autonomy") as Record<string, unknown> | null) ??
134
+ (runtime.getService("AUTONOMY") as Record<string, unknown> | null);
135
+ return typeof svc?.injectAutonomousInstruction === "function";
136
+ }
137
+
138
+ async function dispatchInstruction(
139
+ runtime: IAgentRuntime,
140
+ taskId: UUID,
141
+ trigger: TriggerConfig,
142
+ ): Promise<void> {
143
+ type TriggerAutonomyService = {
144
+ getAutonomousRoomId?: () => UUID;
145
+ injectAutonomousInstruction?: (payload: {
146
+ instructions: string;
147
+ source: string;
148
+ wakeMode: TriggerConfig["wakeMode"];
149
+ triggerId: UUID;
150
+ triggerTaskId: UUID;
151
+ taskId?: UUID;
152
+ roomId?: UUID;
153
+ }) => Promise<void> | void;
154
+ };
155
+ const autonomyService =
156
+ (runtime.getService("autonomy") as TriggerAutonomyService | null) ??
157
+ (runtime.getService("AUTONOMY") as TriggerAutonomyService | null);
158
+
159
+ if (!autonomyService?.injectAutonomousInstruction) {
160
+ runtime.logger.warn?.(
161
+ `Autonomy service missing injectAutonomousInstruction (taskId=${taskId}, triggerId=${trigger.triggerId})`,
162
+ );
163
+ throw new Error("Autonomy service unavailable for trigger dispatch");
164
+ }
165
+
166
+ const roomId =
167
+ typeof autonomyService.getAutonomousRoomId === "function"
168
+ ? autonomyService.getAutonomousRoomId()
169
+ : undefined;
170
+
171
+ await autonomyService.injectAutonomousInstruction({
172
+ instructions: trigger.instructions,
173
+ source: "trigger-runtime",
174
+ wakeMode: trigger.wakeMode,
175
+ triggerId: trigger.triggerId,
176
+ triggerTaskId: taskId,
177
+ taskId,
178
+ roomId,
179
+ });
180
+ }
181
+
182
+ export async function executeTriggerTask(
183
+ runtime: IAgentRuntime,
184
+ task: Task,
185
+ options: TriggerExecutionOptions,
186
+ ): Promise<TriggerExecutionResult> {
187
+ if (!task.id) {
188
+ return { status: "skipped", taskDeleted: false };
189
+ }
190
+
191
+ const trigger = readTriggerConfig(task);
192
+ if (!trigger) {
193
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
194
+ return { status: "skipped", taskDeleted: false };
195
+ }
196
+
197
+ if (!trigger.enabled && !options.force) {
198
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
199
+ return { status: "skipped", taskDeleted: false };
200
+ }
201
+
202
+ if (
203
+ typeof trigger.maxRuns === "number" &&
204
+ trigger.maxRuns > 0 &&
205
+ trigger.runCount >= trigger.maxRuns
206
+ ) {
207
+ await runtime.deleteTask(task.id);
208
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
209
+ return { status: "skipped", taskDeleted: true };
210
+ }
211
+
212
+ if (!isAutonomyServiceAvailable(runtime) && options.source !== "manual") {
213
+ runtime.logger.warn?.(
214
+ {
215
+ src: "trigger-runtime",
216
+ taskId: task.id,
217
+ triggerId: trigger.triggerId,
218
+ },
219
+ "Autonomy service unavailable — skipping trigger (will retry next cycle)",
220
+ );
221
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
222
+ return { status: "skipped", taskDeleted: false };
223
+ }
224
+
225
+ const startedAt = Date.now();
226
+ let status: TriggerExecutionResult["status"] = "success";
227
+ let errorMessage = "";
228
+
229
+ try {
230
+ await dispatchInstruction(runtime, task.id, trigger);
231
+ } catch (error) {
232
+ status = "error";
233
+ errorMessage = error instanceof Error ? error.message : String(error);
234
+ runtime.logger.error(
235
+ {
236
+ src: "trigger-runtime",
237
+ agentId: runtime.agentId,
238
+ taskId: task.id,
239
+ triggerId: trigger.triggerId,
240
+ error: errorMessage,
241
+ },
242
+ "Trigger execution failed",
243
+ );
244
+ }
245
+
246
+ if (status === "success") {
247
+ runtime.logger.info(
248
+ {
249
+ src: "trigger-runtime",
250
+ triggerId: trigger.triggerId,
251
+ triggerName: trigger.displayName,
252
+ triggerType: trigger.triggerType,
253
+ source: options.source,
254
+ latencyMs: Date.now() - startedAt,
255
+ },
256
+ `Trigger "${trigger.displayName}" executed successfully`,
257
+ );
258
+ }
259
+
260
+ const finishedAt = Date.now();
261
+ const runRecord: TriggerRunRecord = {
262
+ triggerRunId: stringToUuid(crypto.randomUUID()),
263
+ triggerId: trigger.triggerId,
264
+ taskId: task.id,
265
+ startedAt,
266
+ finishedAt,
267
+ status,
268
+ error: errorMessage || undefined,
269
+ latencyMs: finishedAt - startedAt,
270
+ source: options.source,
271
+ };
272
+
273
+ const updatedTrigger: TriggerConfig = {
274
+ ...trigger,
275
+ runCount: trigger.runCount + 1,
276
+ lastRunAtIso: new Date(finishedAt).toISOString(),
277
+ lastStatus: status,
278
+ lastError: errorMessage || undefined,
279
+ };
280
+
281
+ if (
282
+ updatedTrigger.triggerType === "once" ||
283
+ (typeof updatedTrigger.maxRuns === "number" &&
284
+ updatedTrigger.maxRuns > 0 &&
285
+ updatedTrigger.runCount >= updatedTrigger.maxRuns)
286
+ ) {
287
+ await runtime.deleteTask(task.id);
288
+ recordExecutionMetric(runtime.agentId, status, finishedAt);
289
+ return {
290
+ status,
291
+ error: errorMessage || undefined,
292
+ runRecord,
293
+ taskDeleted: true,
294
+ };
295
+ }
296
+
297
+ const existingMetadata = taskMetadata(task);
298
+ const nextMetadata = buildTriggerMetadata({
299
+ existingMetadata,
300
+ trigger: updatedTrigger,
301
+ nowMs: finishedAt,
302
+ });
303
+
304
+ let metadataToPersist: TriggerTaskMetadata;
305
+ if (!nextMetadata) {
306
+ metadataToPersist = {
307
+ ...existingMetadata,
308
+ updatedAt: finishedAt,
309
+ updateInterval: DISABLED_TRIGGER_INTERVAL_MS,
310
+ trigger: {
311
+ ...updatedTrigger,
312
+ enabled: false,
313
+ nextRunAtMs: finishedAt + DISABLED_TRIGGER_INTERVAL_MS,
314
+ lastError:
315
+ updatedTrigger.lastError ?? "Failed to compute next trigger schedule",
316
+ },
317
+ triggerRuns: appendRunRecord(existingMetadata.triggerRuns, runRecord),
318
+ };
319
+ } else {
320
+ metadataToPersist = {
321
+ ...nextMetadata,
322
+ triggerRuns: appendRunRecord(existingMetadata.triggerRuns, runRecord),
323
+ };
324
+ }
325
+
326
+ await runtime.updateTask(task.id, {
327
+ description: metadataToPersist.trigger?.displayName ?? task.description,
328
+ metadata: metadataToPersist,
329
+ });
330
+
331
+ recordExecutionMetric(runtime.agentId, status, finishedAt);
332
+ return {
333
+ status,
334
+ error: errorMessage || undefined,
335
+ runRecord,
336
+ taskDeleted: false,
337
+ };
338
+ }
339
+
340
+ export function registerTriggerTaskWorker(runtime: IAgentRuntime): void {
341
+ if (runtime.getTaskWorker(TRIGGER_TASK_NAME)) return;
342
+
343
+ runtime.registerTaskWorker({
344
+ name: TRIGGER_TASK_NAME,
345
+ validate: async () => true,
346
+ execute: async (rt, options, task) => {
347
+ await executeTriggerTask(rt, task, {
348
+ source: options.source === "manual" ? "manual" : "scheduler",
349
+ force: options.force === true,
350
+ });
351
+ },
352
+ });
353
+ }
354
+
355
+ export async function listTriggerTasks(
356
+ runtime: IAgentRuntime,
357
+ ): Promise<Task[]> {
358
+ if (!triggersFeatureEnabled(runtime)) return [];
359
+ return runtime.getTasks({
360
+ tags: [...TRIGGER_TASK_TAGS],
361
+ });
362
+ }
363
+
364
+ export function taskToTriggerSummary(task: Task): TriggerSummary | null {
365
+ const trigger = readTriggerConfig(task);
366
+ if (!trigger || !task.id) return null;
367
+ const metadata = taskMetadata(task);
368
+ return {
369
+ id: trigger.triggerId,
370
+ taskId: task.id,
371
+ displayName: trigger.displayName,
372
+ instructions: trigger.instructions,
373
+ triggerType: trigger.triggerType,
374
+ enabled: trigger.enabled,
375
+ wakeMode: trigger.wakeMode,
376
+ createdBy: trigger.createdBy,
377
+ timezone: trigger.timezone,
378
+ intervalMs: trigger.intervalMs,
379
+ scheduledAtIso: trigger.scheduledAtIso,
380
+ cronExpression: trigger.cronExpression,
381
+ maxRuns: trigger.maxRuns,
382
+ runCount: trigger.runCount,
383
+ nextRunAtMs: trigger.nextRunAtMs,
384
+ lastRunAtIso: trigger.lastRunAtIso,
385
+ lastStatus: trigger.lastStatus,
386
+ lastError: trigger.lastError,
387
+ updatedAt: metadata.updatedAt,
388
+ updateInterval: metadata.updateInterval,
389
+ };
390
+ }
391
+
392
+ export async function getTriggerHealthSnapshot(
393
+ runtime: IAgentRuntime,
394
+ ): Promise<TriggerHealthSnapshot> {
395
+ const tasks = await listTriggerTasks(runtime);
396
+ let activeTriggers = 0;
397
+ let disabledTriggers = 0;
398
+
399
+ let durableExecutions = 0;
400
+ let durableFailures = 0;
401
+ let durableLastExecAt: number | undefined;
402
+
403
+ for (const task of tasks) {
404
+ const trigger = readTriggerConfig(task);
405
+ if (!trigger) continue;
406
+ if (trigger.enabled) {
407
+ activeTriggers += 1;
408
+ } else {
409
+ disabledTriggers += 1;
410
+ }
411
+
412
+ const runs = readTriggerRuns(task);
413
+ for (const run of runs) {
414
+ durableExecutions += 1;
415
+ if (run.status === "error") durableFailures += 1;
416
+ if (!durableLastExecAt || run.finishedAt > durableLastExecAt) {
417
+ durableLastExecAt = run.finishedAt;
418
+ }
419
+ }
420
+ }
421
+
422
+ const inMemory = getMetrics(runtime.agentId);
423
+ return {
424
+ triggersEnabled: triggersFeatureEnabled(runtime),
425
+ activeTriggers,
426
+ disabledTriggers,
427
+ totalExecutions: Math.max(inMemory.totalExecutions, durableExecutions),
428
+ totalFailures: Math.max(inMemory.totalFailures, durableFailures),
429
+ totalSkipped: inMemory.totalSkipped,
430
+ lastExecutionAt: inMemory.lastExecutionAt ?? durableLastExecAt,
431
+ };
432
+ }