miladyai 2.0.0-alpha.27

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/dist/_virtual/_rolldown/runtime.js +7 -0
  2. package/dist/actions/emote.js +64 -0
  3. package/dist/actions/restart.js +81 -0
  4. package/dist/actions/send-message.js +152 -0
  5. package/dist/agent-admin-routes.js +82 -0
  6. package/dist/agent-lifecycle-routes.js +79 -0
  7. package/dist/agent-transfer-routes.js +102 -0
  8. package/dist/api/agent-admin-routes.js +82 -0
  9. package/dist/api/agent-lifecycle-routes.js +79 -0
  10. package/dist/api/agent-transfer-routes.js +102 -0
  11. package/dist/api/apps-hyperscape-routes.js +58 -0
  12. package/dist/api/apps-routes.js +114 -0
  13. package/dist/api/auth-routes.js +56 -0
  14. package/dist/api/autonomy-routes.js +44 -0
  15. package/dist/api/bug-report-routes.js +111 -0
  16. package/dist/api/character-routes.js +195 -0
  17. package/dist/api/cloud-routes.js +330 -0
  18. package/dist/api/cloud-status-routes.js +155 -0
  19. package/dist/api/compat-utils.js +111 -0
  20. package/dist/api/database.js +735 -0
  21. package/dist/api/diagnostics-routes.js +205 -0
  22. package/dist/api/drop-service.js +134 -0
  23. package/dist/api/early-logs.js +86 -0
  24. package/dist/api/http-helpers.js +131 -0
  25. package/dist/api/knowledge-routes.js +534 -0
  26. package/dist/api/memory-bounds.js +71 -0
  27. package/dist/api/models-routes.js +28 -0
  28. package/dist/api/og-tracker.js +36 -0
  29. package/dist/api/permissions-routes.js +109 -0
  30. package/dist/api/plugin-validation.js +198 -0
  31. package/dist/api/provider-switch-config.js +41 -0
  32. package/dist/api/registry-routes.js +86 -0
  33. package/dist/api/registry-service.js +164 -0
  34. package/dist/api/sandbox-routes.js +1112 -0
  35. package/dist/api/server.js +7949 -0
  36. package/dist/api/subscription-routes.js +172 -0
  37. package/dist/api/terminal-run-limits.js +24 -0
  38. package/dist/api/training-routes.js +158 -0
  39. package/dist/api/trajectory-routes.js +300 -0
  40. package/dist/api/trigger-routes.js +246 -0
  41. package/dist/api/twitter-verify.js +134 -0
  42. package/dist/api/tx-service.js +108 -0
  43. package/dist/api/wallet-routes.js +266 -0
  44. package/dist/api/wallet.js +568 -0
  45. package/dist/api/whatsapp-routes.js +182 -0
  46. package/dist/api/zip-utils.js +109 -0
  47. package/dist/apps-hyperscape-routes.js +58 -0
  48. package/dist/apps-routes.js +114 -0
  49. package/dist/ascii.js +20 -0
  50. package/dist/auth/anthropic.js +44 -0
  51. package/dist/auth/apply-stealth.js +41 -0
  52. package/dist/auth/claude-code-stealth.js +78 -0
  53. package/dist/auth/credentials.js +156 -0
  54. package/dist/auth/index.js +5 -0
  55. package/dist/auth/openai-codex.js +66 -0
  56. package/dist/auth/types.js +9 -0
  57. package/dist/auth-routes.js +56 -0
  58. package/dist/autonomy-routes.js +44 -0
  59. package/dist/bug-report-routes.js +111 -0
  60. package/dist/build-info.json +6 -0
  61. package/dist/character-routes.js +195 -0
  62. package/dist/cli/argv.js +63 -0
  63. package/dist/cli/banner.js +34 -0
  64. package/dist/cli/cli-name.js +21 -0
  65. package/dist/cli/cli-utils.js +16 -0
  66. package/dist/cli/git-commit.js +78 -0
  67. package/dist/cli/parse-duration.js +15 -0
  68. package/dist/cli/plugins-cli.js +590 -0
  69. package/dist/cli/profile-utils.js +9 -0
  70. package/dist/cli/profile.js +95 -0
  71. package/dist/cli/program/build-program.js +17 -0
  72. package/dist/cli/program/command-registry.js +23 -0
  73. package/dist/cli/program/help.js +47 -0
  74. package/dist/cli/program/preaction.js +33 -0
  75. package/dist/cli/program/register.config.js +106 -0
  76. package/dist/cli/program/register.configure.js +20 -0
  77. package/dist/cli/program/register.dashboard.js +124 -0
  78. package/dist/cli/program/register.models.js +23 -0
  79. package/dist/cli/program/register.setup.js +36 -0
  80. package/dist/cli/program/register.start.js +22 -0
  81. package/dist/cli/program/register.subclis.js +70 -0
  82. package/dist/cli/program/register.tui.js +163 -0
  83. package/dist/cli/program/register.update.js +154 -0
  84. package/dist/cli/program.js +3 -0
  85. package/dist/cli/run-main.js +37 -0
  86. package/dist/cli/version.js +7 -0
  87. package/dist/cloud/validate-url.js +93 -0
  88. package/dist/cloud-routes.js +330 -0
  89. package/dist/cloud-status-routes.js +155 -0
  90. package/dist/compat-utils.js +111 -0
  91. package/dist/config/config.js +69 -0
  92. package/dist/config/env-vars.js +19 -0
  93. package/dist/config/includes.js +121 -0
  94. package/dist/config/object-utils.js +7 -0
  95. package/dist/config/paths.js +38 -0
  96. package/dist/config/plugin-auto-enable.js +231 -0
  97. package/dist/config/schema.js +864 -0
  98. package/dist/config/telegram-custom-commands.js +76 -0
  99. package/dist/config/zod-schema.agent-runtime.js +519 -0
  100. package/dist/config/zod-schema.core.js +538 -0
  101. package/dist/config/zod-schema.hooks.js +103 -0
  102. package/dist/config/zod-schema.js +488 -0
  103. package/dist/config/zod-schema.providers-core.js +785 -0
  104. package/dist/config/zod-schema.session.js +73 -0
  105. package/dist/core-plugins.js +37 -0
  106. package/dist/custom-actions.js +250 -0
  107. package/dist/database.js +735 -0
  108. package/dist/diagnostics/integration-observability.js +57 -0
  109. package/dist/diagnostics-routes.js +205 -0
  110. package/dist/drop-service.js +134 -0
  111. package/dist/early-logs.js +24 -0
  112. package/dist/eliza.js +2061 -0
  113. package/dist/emotes/catalog.js +271 -0
  114. package/dist/entry.js +40 -0
  115. package/dist/hooks/discovery.js +167 -0
  116. package/dist/hooks/eligibility.js +64 -0
  117. package/dist/hooks/index.js +4 -0
  118. package/dist/hooks/loader.js +147 -0
  119. package/dist/hooks/registry.js +55 -0
  120. package/dist/http-helpers.js +131 -0
  121. package/dist/index.js +49 -0
  122. package/dist/knowledge-routes.js +534 -0
  123. package/dist/memory-bounds.js +71 -0
  124. package/dist/milady-plugin.js +90 -0
  125. package/dist/models-routes.js +28 -0
  126. package/dist/onboarding-names.js +78 -0
  127. package/dist/onboarding-presets.js +922 -0
  128. package/dist/package.json +1 -0
  129. package/dist/permissions-routes.js +109 -0
  130. package/dist/plugin-validation.js +107 -0
  131. package/dist/plugins/whatsapp/actions.js +91 -0
  132. package/dist/plugins/whatsapp/index.js +16 -0
  133. package/dist/plugins/whatsapp/service.js +270 -0
  134. package/dist/provider-switch-config.js +41 -0
  135. package/dist/providers/admin-trust.js +46 -0
  136. package/dist/providers/autonomous-state.js +101 -0
  137. package/dist/providers/session-bridge.js +86 -0
  138. package/dist/providers/session-utils.js +36 -0
  139. package/dist/providers/simple-mode.js +50 -0
  140. package/dist/providers/ui-catalog.js +15 -0
  141. package/dist/providers/workspace-provider.js +93 -0
  142. package/dist/providers/workspace.js +348 -0
  143. package/dist/registry-routes.js +86 -0
  144. package/dist/registry-service.js +164 -0
  145. package/dist/restart.js +40 -0
  146. package/dist/runtime/core-plugins.js +37 -0
  147. package/dist/runtime/custom-actions.js +250 -0
  148. package/dist/runtime/eliza.js +2061 -0
  149. package/dist/runtime/embedding-manager-support.js +185 -0
  150. package/dist/runtime/embedding-manager.js +193 -0
  151. package/dist/runtime/embedding-presets.js +54 -0
  152. package/dist/runtime/embedding-state.js +8 -0
  153. package/dist/runtime/milady-plugin.js +90 -0
  154. package/dist/runtime/onboarding-names.js +78 -0
  155. package/dist/runtime/restart.js +40 -0
  156. package/dist/runtime/version.js +7 -0
  157. package/dist/sandbox-routes.js +1112 -0
  158. package/dist/security/audit-log.js +149 -0
  159. package/dist/security/network-policy.js +70 -0
  160. package/dist/server.js +7949 -0
  161. package/dist/services/agent-export.js +559 -0
  162. package/dist/services/app-manager.js +389 -0
  163. package/dist/services/browser-capture.js +86 -0
  164. package/dist/services/fallback-training-service.js +128 -0
  165. package/dist/services/mcp-marketplace.js +134 -0
  166. package/dist/services/plugin-installer.js +396 -0
  167. package/dist/services/plugin-manager-types.js +15 -0
  168. package/dist/services/registry-client-app-meta.js +144 -0
  169. package/dist/services/registry-client-endpoints.js +166 -0
  170. package/dist/services/registry-client-local.js +271 -0
  171. package/dist/services/registry-client-network.js +93 -0
  172. package/dist/services/registry-client-queries.js +70 -0
  173. package/dist/services/registry-client.js +157 -0
  174. package/dist/services/sandbox-engine.js +511 -0
  175. package/dist/services/sandbox-manager.js +297 -0
  176. package/dist/services/self-updater.js +175 -0
  177. package/dist/services/skill-catalog-client.js +119 -0
  178. package/dist/services/skill-marketplace.js +521 -0
  179. package/dist/services/stream-manager.js +236 -0
  180. package/dist/services/update-checker.js +121 -0
  181. package/dist/services/update-notifier.js +29 -0
  182. package/dist/services/version-compat.js +78 -0
  183. package/dist/services/whatsapp-pairing.js +196 -0
  184. package/dist/shared/ui-catalog-prompt.js +728 -0
  185. package/dist/subscription-routes.js +172 -0
  186. package/dist/terminal/links.js +19 -0
  187. package/dist/terminal/palette.js +14 -0
  188. package/dist/terminal/theme.js +25 -0
  189. package/dist/terminal-run-limits.js +24 -0
  190. package/dist/training-routes.js +158 -0
  191. package/dist/trajectory-routes.js +300 -0
  192. package/dist/trigger-routes.js +246 -0
  193. package/dist/triggers/action.js +218 -0
  194. package/dist/triggers/runtime.js +281 -0
  195. package/dist/triggers/scheduling.js +295 -0
  196. package/dist/triggers/types.js +5 -0
  197. package/dist/tui/components/assistant-message.js +76 -0
  198. package/dist/tui/components/chat-editor.js +34 -0
  199. package/dist/tui/components/embeddings-overlay.js +46 -0
  200. package/dist/tui/components/footer.js +60 -0
  201. package/dist/tui/components/index.js +15 -0
  202. package/dist/tui/components/modal-frame.js +45 -0
  203. package/dist/tui/components/modal-style.js +15 -0
  204. package/dist/tui/components/model-selector.js +70 -0
  205. package/dist/tui/components/pinned-chat-layout.js +46 -0
  206. package/dist/tui/components/plugins-endpoints-tab.js +196 -0
  207. package/dist/tui/components/plugins-installed-tab-view.js +69 -0
  208. package/dist/tui/components/plugins-installed-tab.js +319 -0
  209. package/dist/tui/components/plugins-overlay-catalog.js +81 -0
  210. package/dist/tui/components/plugins-overlay-data-api.js +21 -0
  211. package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
  212. package/dist/tui/components/plugins-overlay-data.js +323 -0
  213. package/dist/tui/components/plugins-overlay.js +117 -0
  214. package/dist/tui/components/plugins-store-tab.js +148 -0
  215. package/dist/tui/components/settings-overlay.js +61 -0
  216. package/dist/tui/components/status-bar.js +64 -0
  217. package/dist/tui/components/tool-execution.js +68 -0
  218. package/dist/tui/components/user-message.js +22 -0
  219. package/dist/tui/eliza-tui-bridge.js +606 -0
  220. package/dist/tui/index.js +370 -0
  221. package/dist/tui/modal-presets.js +33 -0
  222. package/dist/tui/model-spec.js +46 -0
  223. package/dist/tui/sse-parser.js +78 -0
  224. package/dist/tui/theme.js +110 -0
  225. package/dist/tui/titlebar-spinner.js +62 -0
  226. package/dist/tui/tui-app.js +311 -0
  227. package/dist/tui/ws-client.js +215 -0
  228. package/dist/twitter-verify.js +134 -0
  229. package/dist/tx-service.js +108 -0
  230. package/dist/utils/exec-safety.js +17 -0
  231. package/dist/utils/globals.js +20 -0
  232. package/dist/utils/milady-root.js +61 -0
  233. package/dist/utils/number-parsing.js +37 -0
  234. package/dist/version-resolver.js +37 -0
  235. package/dist/version.js +7 -0
  236. package/dist/wallet-routes.js +266 -0
  237. package/dist/wallet.js +568 -0
  238. package/dist/whatsapp-routes.js +182 -0
  239. package/dist/zip-utils.js +109 -0
  240. package/milady.mjs +14 -0
  241. package/package.json +111 -0
@@ -0,0 +1,218 @@
1
+ import { buildTriggerConfig, buildTriggerMetadata, normalizeTriggerDraft } from "./scheduling.js";
2
+ import { TRIGGER_TASK_NAME, TRIGGER_TASK_TAGS, getTriggerLimit, listTriggerTasks, readTriggerConfig, taskToTriggerSummary, triggersFeatureEnabled } from "./runtime.js";
3
+ import { parsePositiveInteger } from "../utils/number-parsing.js";
4
+ import { ModelType, stringToUuid } from "@elizaos/core";
5
+ import crypto from "node:crypto";
6
+
7
+ //#region src/triggers/action.ts
8
+ const CREATE_TRIGGER_TASK_ACTION = "CREATE_TRIGGER_TASK";
9
+ const CREATE_TRIGGER_KEYWORDS = [
10
+ "create trigger",
11
+ "create a trigger",
12
+ "create task",
13
+ "schedule trigger",
14
+ "schedule task",
15
+ "run every",
16
+ "run at",
17
+ "every hour",
18
+ "every day"
19
+ ];
20
+ function normalizeText(value) {
21
+ return value.trim().replace(/\s+/g, " ");
22
+ }
23
+ function parseTag(xml, tag) {
24
+ const match = new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`, "i").exec(xml);
25
+ if (!match?.[1]) return void 0;
26
+ const text = normalizeText(match[1]);
27
+ return text.length > 0 ? text : void 0;
28
+ }
29
+ function parseExtraction(xml) {
30
+ return {
31
+ triggerType: parseTag(xml, "triggerType"),
32
+ displayName: parseTag(xml, "displayName"),
33
+ instructions: parseTag(xml, "instructions"),
34
+ wakeMode: parseTag(xml, "wakeMode"),
35
+ intervalMs: parseTag(xml, "intervalMs"),
36
+ scheduledAtIso: parseTag(xml, "scheduledAtIso"),
37
+ cronExpression: parseTag(xml, "cronExpression"),
38
+ maxRuns: parseTag(xml, "maxRuns")
39
+ };
40
+ }
41
+ function deriveTriggerType(extracted) {
42
+ const type = extracted.triggerType?.toLowerCase();
43
+ if (type === "interval" || type === "once" || type === "cron") return type;
44
+ if (extracted.cronExpression) return "cron";
45
+ if (extracted.scheduledAtIso) return "once";
46
+ return "interval";
47
+ }
48
+ function extractionPrompt(userText) {
49
+ return [
50
+ "Extract trigger details from this request.",
51
+ "Return only XML with these keys:",
52
+ "triggerType, displayName, instructions, wakeMode, intervalMs, scheduledAtIso, cronExpression, maxRuns",
53
+ "Valid triggerType values: interval, once, cron",
54
+ "Valid wakeMode values: inject_now, next_autonomy_cycle",
55
+ "",
56
+ `Request: ${userText}`
57
+ ].join("\n");
58
+ }
59
+ function scheduleText(summary) {
60
+ if (!summary) return "scheduled";
61
+ if (summary.triggerType === "interval") return `every ${summary.intervalMs ?? 0} ms`;
62
+ if (summary.triggerType === "once") return `once at ${summary.scheduledAtIso ?? "unknown time"}`;
63
+ return `on cron ${summary.cronExpression ?? "* * * * *"}`;
64
+ }
65
+ const createTriggerTaskAction = {
66
+ name: CREATE_TRIGGER_TASK_ACTION,
67
+ similes: ["CREATE_TRIGGER", "SCHEDULE_TRIGGER"],
68
+ description: "Create an autonomous trigger task that executes interval, once, or cron schedules",
69
+ validate: async (runtime, message) => {
70
+ if (!runtime.enableAutonomy) return false;
71
+ if (!triggersFeatureEnabled(runtime)) return false;
72
+ const text = message.content.text?.toLowerCase() ?? "";
73
+ if (!text) return false;
74
+ return CREATE_TRIGGER_KEYWORDS.some((keyword) => text.includes(keyword));
75
+ },
76
+ handler: async (runtime, message, _state, _options, callback) => {
77
+ const text = normalizeText(message.content.text ?? "");
78
+ if (!text) return {
79
+ success: false,
80
+ text: "Cannot create a trigger from empty text."
81
+ };
82
+ if (!runtime.enableAutonomy) return {
83
+ success: false,
84
+ text: "Autonomy mode is disabled, so trigger creation is unavailable."
85
+ };
86
+ if (!triggersFeatureEnabled(runtime)) return {
87
+ success: false,
88
+ text: "Triggers are disabled by configuration."
89
+ };
90
+ try {
91
+ let extraction = {};
92
+ let extractionFailed = false;
93
+ try {
94
+ extraction = parseExtraction(await runtime.useModel(ModelType.TEXT_SMALL, {
95
+ prompt: extractionPrompt(text),
96
+ stopSequences: []
97
+ }));
98
+ } catch (extractionError) {
99
+ extractionFailed = true;
100
+ runtime.logger.warn({
101
+ src: "trigger-action",
102
+ error: extractionError instanceof Error ? extractionError.message : String(extractionError)
103
+ }, "LLM extraction failed, using fallback defaults from user text");
104
+ }
105
+ const creator = String(message.entityId ?? runtime.agentId);
106
+ const triggerType = deriveTriggerType(extraction);
107
+ const normalized = normalizeTriggerDraft({
108
+ input: {
109
+ displayName: extraction.displayName ?? `Trigger: ${text.slice(0, 64)}`,
110
+ instructions: extraction.instructions ?? text,
111
+ triggerType,
112
+ wakeMode: extraction.wakeMode === "next_autonomy_cycle" ? "next_autonomy_cycle" : "inject_now",
113
+ enabled: true,
114
+ createdBy: creator,
115
+ intervalMs: parsePositiveInteger(extraction.intervalMs),
116
+ scheduledAtIso: extraction.scheduledAtIso,
117
+ cronExpression: extraction.cronExpression,
118
+ maxRuns: parsePositiveInteger(extraction.maxRuns)
119
+ },
120
+ fallback: {
121
+ displayName: `Trigger: ${text.slice(0, 64)}`,
122
+ instructions: text,
123
+ triggerType: "interval",
124
+ wakeMode: "inject_now",
125
+ enabled: true,
126
+ createdBy: creator
127
+ }
128
+ });
129
+ if (!normalized.draft) return {
130
+ success: false,
131
+ text: normalized.error ?? "Invalid trigger request"
132
+ };
133
+ const existingTasks = await listTriggerTasks(runtime);
134
+ const limit = getTriggerLimit(runtime);
135
+ if (existingTasks.filter((task) => {
136
+ const trigger = readTriggerConfig(task);
137
+ return trigger?.enabled && trigger.createdBy === creator;
138
+ }).length >= limit) return {
139
+ success: false,
140
+ text: `Trigger limit reached (${limit} active triggers).`
141
+ };
142
+ const triggerId = stringToUuid(crypto.randomUUID());
143
+ const triggerConfig = buildTriggerConfig({
144
+ draft: normalized.draft,
145
+ triggerId
146
+ });
147
+ const duplicate = existingTasks.find((task) => {
148
+ const existingTrigger = readTriggerConfig(task);
149
+ if (!existingTrigger?.enabled) return false;
150
+ if (existingTrigger.dedupeKey && triggerConfig.dedupeKey) return existingTrigger.dedupeKey === triggerConfig.dedupeKey;
151
+ return normalizeText(existingTrigger.instructions).toLowerCase() === normalizeText(triggerConfig.instructions).toLowerCase() && existingTrigger.triggerType === triggerConfig.triggerType && (existingTrigger.intervalMs ?? 0) === (triggerConfig.intervalMs ?? 0) && (existingTrigger.scheduledAtIso ?? "") === (triggerConfig.scheduledAtIso ?? "") && (existingTrigger.cronExpression ?? "") === (triggerConfig.cronExpression ?? "");
152
+ });
153
+ if (duplicate?.id) {
154
+ const duplicateText = `Equivalent trigger already exists (${taskToTriggerSummary(duplicate)?.displayName ?? duplicate.id}).`;
155
+ if (callback) await callback({
156
+ text: duplicateText,
157
+ action: CREATE_TRIGGER_TASK_ACTION,
158
+ metadata: { duplicateTaskId: duplicate.id }
159
+ });
160
+ return {
161
+ success: true,
162
+ text: duplicateText,
163
+ data: { duplicateTaskId: duplicate.id }
164
+ };
165
+ }
166
+ const metadata = buildTriggerMetadata({
167
+ trigger: triggerConfig,
168
+ nowMs: Date.now()
169
+ });
170
+ if (!metadata) return {
171
+ success: false,
172
+ text: "Unable to compute trigger schedule."
173
+ };
174
+ const roomId = runtime.getService("AUTONOMY")?.getAutonomousRoomId?.() ?? message.roomId;
175
+ const createdTaskId = await runtime.createTask({
176
+ name: TRIGGER_TASK_NAME,
177
+ description: triggerConfig.displayName,
178
+ roomId,
179
+ tags: [...TRIGGER_TASK_TAGS],
180
+ metadata
181
+ });
182
+ const createdTask = await runtime.getTask(createdTaskId);
183
+ const createdSummary = createdTask ? taskToTriggerSummary(createdTask) : null;
184
+ const fallbackNote = extractionFailed ? " (Note: AI extraction failed; trigger was created from your raw text with default settings.)" : "";
185
+ const successText = `Created trigger "${triggerConfig.displayName}" ${scheduleText(createdSummary)}.${fallbackNote}`;
186
+ if (callback) await callback({
187
+ text: successText,
188
+ action: CREATE_TRIGGER_TASK_ACTION,
189
+ metadata: {
190
+ triggerId,
191
+ taskId: String(createdTaskId),
192
+ triggerType: triggerConfig.triggerType
193
+ }
194
+ });
195
+ return {
196
+ success: true,
197
+ text: successText,
198
+ values: {
199
+ triggerId,
200
+ taskId: String(createdTaskId)
201
+ },
202
+ data: {
203
+ triggerId,
204
+ taskId: String(createdTaskId),
205
+ triggerType: triggerConfig.triggerType
206
+ }
207
+ };
208
+ } catch (error) {
209
+ return {
210
+ success: false,
211
+ text: error instanceof Error ? error.message : "Failed to create trigger"
212
+ };
213
+ }
214
+ }
215
+ };
216
+
217
+ //#endregion
218
+ export { createTriggerTaskAction };
@@ -0,0 +1,281 @@
1
+ import { DISABLED_TRIGGER_INTERVAL_MS, MAX_TRIGGER_RUN_HISTORY, buildTriggerMetadata } from "./scheduling.js";
2
+ import { stringToUuid } from "@elizaos/core";
3
+ import crypto from "node:crypto";
4
+
5
+ //#region src/triggers/runtime.ts
6
+ const TRIGGER_TASK_NAME = "TRIGGER_DISPATCH";
7
+ const TRIGGER_TASK_TAGS = [
8
+ "queue",
9
+ "repeat",
10
+ "trigger"
11
+ ];
12
+ const DEFAULT_MAX_ACTIVE_TRIGGERS = 100;
13
+ /**
14
+ * In-memory trigger execution metrics per agent.
15
+ * These counters are approximations for the /api/triggers/health endpoint
16
+ * and reset on process restart. Durable execution history is stored in
17
+ * task.metadata.triggerRuns (persisted to database via the task system).
18
+ */
19
+ const metricsByAgent = /* @__PURE__ */ new Map();
20
+ function getMetrics(agentId) {
21
+ const current = metricsByAgent.get(agentId);
22
+ if (current) return current;
23
+ const created = {
24
+ totalExecutions: 0,
25
+ totalFailures: 0,
26
+ totalSkipped: 0
27
+ };
28
+ metricsByAgent.set(agentId, created);
29
+ return created;
30
+ }
31
+ function recordExecutionMetric(agentId, status, ts) {
32
+ const metrics = getMetrics(agentId);
33
+ if (status === "success" || status === "error") {
34
+ metrics.totalExecutions += 1;
35
+ metrics.lastExecutionAt = ts;
36
+ }
37
+ if (status === "error") metrics.totalFailures += 1;
38
+ if (status === "skipped") metrics.totalSkipped += 1;
39
+ }
40
+ function appendRunRecord(existing, record) {
41
+ const runs = [...existing ?? [], record];
42
+ return runs.length <= MAX_TRIGGER_RUN_HISTORY ? runs : runs.slice(runs.length - MAX_TRIGGER_RUN_HISTORY);
43
+ }
44
+ function taskMetadata(task) {
45
+ return task.metadata ?? {};
46
+ }
47
+ function readTriggerConfig(task) {
48
+ const trigger = taskMetadata(task).trigger;
49
+ if (!trigger || typeof trigger !== "object" || Array.isArray(trigger)) return null;
50
+ return trigger.triggerId ? trigger : null;
51
+ }
52
+ function readTriggerRuns(task) {
53
+ const runs = taskMetadata(task).triggerRuns;
54
+ return Array.isArray(runs) ? runs : [];
55
+ }
56
+ function triggersFeatureEnabled(runtime) {
57
+ const runtimeSetting = runtime?.getSetting("MILADY_TRIGGERS_ENABLED");
58
+ if (runtimeSetting === false || runtimeSetting === "false" || runtimeSetting === "0") return false;
59
+ const env = process.env.MILADY_TRIGGERS_ENABLED;
60
+ if (!env) return true;
61
+ const normalized = env.trim().toLowerCase();
62
+ return normalized !== "0" && normalized !== "false";
63
+ }
64
+ function getTriggerLimit(runtime) {
65
+ const runtimeSetting = runtime?.getSetting("MILADY_TRIGGERS_MAX_ACTIVE");
66
+ if (typeof runtimeSetting === "number" && Number.isFinite(runtimeSetting)) return Math.max(1, Math.floor(runtimeSetting));
67
+ if (typeof runtimeSetting === "string" && /^\d+$/.test(runtimeSetting)) return Math.max(1, Number(runtimeSetting));
68
+ const env = process.env.MILADY_TRIGGERS_MAX_ACTIVE;
69
+ if (env && /^\d+$/.test(env)) return Math.max(1, Number(env));
70
+ return DEFAULT_MAX_ACTIVE_TRIGGERS;
71
+ }
72
+ async function dispatchInstruction(runtime, taskId, trigger) {
73
+ const autonomyService = runtime.getService("autonomy") ?? runtime.getService("AUTONOMY");
74
+ if (!autonomyService?.injectAutonomousInstruction) {
75
+ runtime.logger.warn?.(`Autonomy service missing injectAutonomousInstruction (taskId=${taskId}, triggerId=${trigger.triggerId})`);
76
+ throw new Error("Autonomy service unavailable for trigger dispatch");
77
+ }
78
+ const roomId = typeof autonomyService.getAutonomousRoomId === "function" ? autonomyService.getAutonomousRoomId() : void 0;
79
+ await autonomyService.injectAutonomousInstruction({
80
+ instructions: trigger.instructions,
81
+ source: "trigger-runtime",
82
+ wakeMode: trigger.wakeMode,
83
+ triggerId: trigger.triggerId,
84
+ triggerTaskId: taskId,
85
+ taskId,
86
+ roomId
87
+ });
88
+ }
89
+ async function executeTriggerTask(runtime, task, options) {
90
+ if (!task.id) return {
91
+ status: "skipped",
92
+ taskDeleted: false
93
+ };
94
+ const trigger = readTriggerConfig(task);
95
+ if (!trigger) {
96
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
97
+ return {
98
+ status: "skipped",
99
+ taskDeleted: false
100
+ };
101
+ }
102
+ if (!trigger.enabled && !options.force) {
103
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
104
+ return {
105
+ status: "skipped",
106
+ taskDeleted: false
107
+ };
108
+ }
109
+ if (typeof trigger.maxRuns === "number" && trigger.maxRuns > 0 && trigger.runCount >= trigger.maxRuns) {
110
+ await runtime.deleteTask(task.id);
111
+ recordExecutionMetric(runtime.agentId, "skipped", Date.now());
112
+ return {
113
+ status: "skipped",
114
+ taskDeleted: true
115
+ };
116
+ }
117
+ const startedAt = Date.now();
118
+ let status = "success";
119
+ let errorMessage = "";
120
+ try {
121
+ await dispatchInstruction(runtime, task.id, trigger);
122
+ } catch (error) {
123
+ status = "error";
124
+ errorMessage = error instanceof Error ? error.message : String(error);
125
+ runtime.logger.error({
126
+ src: "trigger-runtime",
127
+ agentId: runtime.agentId,
128
+ taskId: task.id,
129
+ triggerId: trigger.triggerId,
130
+ error: errorMessage
131
+ }, "Trigger execution failed");
132
+ }
133
+ if (status === "success") runtime.logger.info({
134
+ src: "trigger-runtime",
135
+ triggerId: trigger.triggerId,
136
+ triggerName: trigger.displayName,
137
+ triggerType: trigger.triggerType,
138
+ source: options.source,
139
+ latencyMs: Date.now() - startedAt
140
+ }, `Trigger "${trigger.displayName}" executed successfully`);
141
+ const finishedAt = Date.now();
142
+ const runRecord = {
143
+ triggerRunId: stringToUuid(crypto.randomUUID()),
144
+ triggerId: trigger.triggerId,
145
+ taskId: task.id,
146
+ startedAt,
147
+ finishedAt,
148
+ status,
149
+ error: errorMessage || void 0,
150
+ latencyMs: finishedAt - startedAt,
151
+ source: options.source
152
+ };
153
+ const updatedTrigger = {
154
+ ...trigger,
155
+ runCount: trigger.runCount + 1,
156
+ lastRunAtIso: new Date(finishedAt).toISOString(),
157
+ lastStatus: status,
158
+ lastError: errorMessage || void 0
159
+ };
160
+ if (updatedTrigger.triggerType === "once" || typeof updatedTrigger.maxRuns === "number" && updatedTrigger.maxRuns > 0 && updatedTrigger.runCount >= updatedTrigger.maxRuns) {
161
+ await runtime.deleteTask(task.id);
162
+ recordExecutionMetric(runtime.agentId, status, finishedAt);
163
+ return {
164
+ status,
165
+ error: errorMessage || void 0,
166
+ runRecord,
167
+ taskDeleted: true
168
+ };
169
+ }
170
+ const existingMetadata = taskMetadata(task);
171
+ const nextMetadata = buildTriggerMetadata({
172
+ existingMetadata,
173
+ trigger: updatedTrigger,
174
+ nowMs: finishedAt
175
+ });
176
+ let metadataToPersist;
177
+ if (!nextMetadata) metadataToPersist = {
178
+ ...existingMetadata,
179
+ updatedAt: finishedAt,
180
+ updateInterval: DISABLED_TRIGGER_INTERVAL_MS,
181
+ trigger: {
182
+ ...updatedTrigger,
183
+ enabled: false,
184
+ nextRunAtMs: finishedAt + DISABLED_TRIGGER_INTERVAL_MS,
185
+ lastError: updatedTrigger.lastError ?? "Failed to compute next trigger schedule"
186
+ },
187
+ triggerRuns: appendRunRecord(existingMetadata.triggerRuns, runRecord)
188
+ };
189
+ else metadataToPersist = {
190
+ ...nextMetadata,
191
+ triggerRuns: appendRunRecord(existingMetadata.triggerRuns, runRecord)
192
+ };
193
+ await runtime.updateTask(task.id, {
194
+ description: metadataToPersist.trigger?.displayName ?? task.description,
195
+ metadata: metadataToPersist
196
+ });
197
+ recordExecutionMetric(runtime.agentId, status, finishedAt);
198
+ return {
199
+ status,
200
+ error: errorMessage || void 0,
201
+ runRecord,
202
+ taskDeleted: false
203
+ };
204
+ }
205
+ function registerTriggerTaskWorker(runtime) {
206
+ if (runtime.getTaskWorker(TRIGGER_TASK_NAME)) return;
207
+ runtime.registerTaskWorker({
208
+ name: TRIGGER_TASK_NAME,
209
+ validate: async () => true,
210
+ execute: async (rt, options, task) => {
211
+ await executeTriggerTask(rt, task, {
212
+ source: options.source === "manual" ? "manual" : "scheduler",
213
+ force: options.force === true
214
+ });
215
+ }
216
+ });
217
+ }
218
+ async function listTriggerTasks(runtime) {
219
+ if (!triggersFeatureEnabled(runtime)) return [];
220
+ return runtime.getTasks({ tags: [...TRIGGER_TASK_TAGS] });
221
+ }
222
+ function taskToTriggerSummary(task) {
223
+ const trigger = readTriggerConfig(task);
224
+ if (!trigger || !task.id) return null;
225
+ const metadata = taskMetadata(task);
226
+ return {
227
+ id: trigger.triggerId,
228
+ taskId: task.id,
229
+ displayName: trigger.displayName,
230
+ instructions: trigger.instructions,
231
+ triggerType: trigger.triggerType,
232
+ enabled: trigger.enabled,
233
+ wakeMode: trigger.wakeMode,
234
+ createdBy: trigger.createdBy,
235
+ timezone: trigger.timezone,
236
+ intervalMs: trigger.intervalMs,
237
+ scheduledAtIso: trigger.scheduledAtIso,
238
+ cronExpression: trigger.cronExpression,
239
+ maxRuns: trigger.maxRuns,
240
+ runCount: trigger.runCount,
241
+ nextRunAtMs: trigger.nextRunAtMs,
242
+ lastRunAtIso: trigger.lastRunAtIso,
243
+ lastStatus: trigger.lastStatus,
244
+ lastError: trigger.lastError,
245
+ updatedAt: metadata.updatedAt,
246
+ updateInterval: metadata.updateInterval
247
+ };
248
+ }
249
+ async function getTriggerHealthSnapshot(runtime) {
250
+ const tasks = await listTriggerTasks(runtime);
251
+ let activeTriggers = 0;
252
+ let disabledTriggers = 0;
253
+ let durableExecutions = 0;
254
+ let durableFailures = 0;
255
+ let durableLastExecAt;
256
+ for (const task of tasks) {
257
+ const trigger = readTriggerConfig(task);
258
+ if (!trigger) continue;
259
+ if (trigger.enabled) activeTriggers += 1;
260
+ else disabledTriggers += 1;
261
+ const runs = readTriggerRuns(task);
262
+ for (const run of runs) {
263
+ durableExecutions += 1;
264
+ if (run.status === "error") durableFailures += 1;
265
+ if (!durableLastExecAt || run.finishedAt > durableLastExecAt) durableLastExecAt = run.finishedAt;
266
+ }
267
+ }
268
+ const inMemory = getMetrics(runtime.agentId);
269
+ return {
270
+ triggersEnabled: triggersFeatureEnabled(runtime),
271
+ activeTriggers,
272
+ disabledTriggers,
273
+ totalExecutions: Math.max(inMemory.totalExecutions, durableExecutions),
274
+ totalFailures: Math.max(inMemory.totalFailures, durableFailures),
275
+ totalSkipped: inMemory.totalSkipped,
276
+ lastExecutionAt: inMemory.lastExecutionAt ?? durableLastExecAt
277
+ };
278
+ }
279
+
280
+ //#endregion
281
+ export { TRIGGER_TASK_NAME, TRIGGER_TASK_TAGS, executeTriggerTask, getTriggerHealthSnapshot, getTriggerLimit, listTriggerTasks, readTriggerConfig, readTriggerRuns, registerTriggerTaskWorker, taskToTriggerSummary, triggersFeatureEnabled };