@amodalai/runtime 0.2.0 → 0.2.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 (209) hide show
  1. package/dist/src/__fixtures__/README.md +4 -0
  2. package/dist/src/__fixtures__/e2e.test.d.ts +6 -0
  3. package/dist/src/__fixtures__/e2e.test.js +211 -0
  4. package/dist/src/__fixtures__/e2e.test.js.map +1 -0
  5. package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
  6. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +1 -1
  7. package/dist/src/__fixtures__/smoke.test.js +715 -29
  8. package/dist/src/__fixtures__/smoke.test.js.map +1 -1
  9. package/dist/src/__fixtures__/test-env.d.ts +27 -0
  10. package/dist/src/__fixtures__/test-env.js +64 -0
  11. package/dist/src/__fixtures__/test-env.js.map +1 -0
  12. package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
  13. package/dist/src/__fixtures__/test-helpers.js +120 -0
  14. package/dist/src/__fixtures__/test-helpers.js.map +1 -0
  15. package/dist/src/agent/agent-types.d.ts +22 -0
  16. package/dist/src/agent/agent-types.js.map +1 -1
  17. package/dist/src/agent/automation-bridge.d.ts +9 -0
  18. package/dist/src/agent/automation-bridge.js +26 -0
  19. package/dist/src/agent/automation-bridge.js.map +1 -1
  20. package/dist/src/agent/automation-bridge.test.js +63 -0
  21. package/dist/src/agent/automation-bridge.test.js.map +1 -1
  22. package/dist/src/agent/local-server.d.ts +0 -7
  23. package/dist/src/agent/local-server.js +230 -86
  24. package/dist/src/agent/local-server.js.map +1 -1
  25. package/dist/src/agent/local-server.test.js +14 -8
  26. package/dist/src/agent/local-server.test.js.map +1 -1
  27. package/dist/src/agent/loop-types.d.ts +81 -2
  28. package/dist/src/agent/loop-types.js +4 -0
  29. package/dist/src/agent/loop-types.js.map +1 -1
  30. package/dist/src/agent/loop.js +16 -3
  31. package/dist/src/agent/loop.js.map +1 -1
  32. package/dist/src/agent/loop.test.js +572 -8
  33. package/dist/src/agent/loop.test.js.map +1 -1
  34. package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
  35. package/dist/src/agent/proactive/delivery-router.js +337 -0
  36. package/dist/src/agent/proactive/delivery-router.js.map +1 -0
  37. package/dist/src/agent/proactive/delivery-router.test.d.ts +6 -0
  38. package/dist/src/agent/proactive/delivery-router.test.js +455 -0
  39. package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
  40. package/dist/src/agent/proactive/proactive-runner.d.ts +23 -1
  41. package/dist/src/agent/proactive/proactive-runner.js +42 -10
  42. package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
  43. package/dist/src/agent/proactive/proactive-runner.test.js +0 -2
  44. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
  45. package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
  46. package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
  47. package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
  48. package/dist/src/agent/routes/admin-chat.js +0 -2
  49. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  50. package/dist/src/agent/routes/task.test.js +0 -2
  51. package/dist/src/agent/routes/task.test.js.map +1 -1
  52. package/dist/src/agent/snapshot-server.js +0 -2
  53. package/dist/src/agent/snapshot-server.js.map +1 -1
  54. package/dist/src/agent/states/compacting.js +5 -3
  55. package/dist/src/agent/states/compacting.js.map +1 -1
  56. package/dist/src/agent/states/confirming.js +3 -0
  57. package/dist/src/agent/states/confirming.js.map +1 -1
  58. package/dist/src/agent/states/dispatching.js +45 -1
  59. package/dist/src/agent/states/dispatching.js.map +1 -1
  60. package/dist/src/agent/states/executing.js +225 -81
  61. package/dist/src/agent/states/executing.js.map +1 -1
  62. package/dist/src/agent/states/streaming.js +14 -0
  63. package/dist/src/agent/states/streaming.js.map +1 -1
  64. package/dist/src/agent/states/thinking.d.ts +1 -1
  65. package/dist/src/agent/states/thinking.js +246 -29
  66. package/dist/src/agent/states/thinking.js.map +1 -1
  67. package/dist/src/agent/token-estimate.d.ts +20 -6
  68. package/dist/src/agent/token-estimate.js +24 -3
  69. package/dist/src/agent/token-estimate.js.map +1 -1
  70. package/dist/src/agent/token-estimate.test.d.ts +6 -0
  71. package/dist/src/agent/token-estimate.test.js +44 -0
  72. package/dist/src/agent/token-estimate.test.js.map +1 -0
  73. package/dist/src/api/create-agent.js +0 -3
  74. package/dist/src/api/create-agent.js.map +1 -1
  75. package/dist/src/api/types.d.ts +0 -2
  76. package/dist/src/env-ref.d.ts +13 -0
  77. package/dist/src/env-ref.js +31 -0
  78. package/dist/src/env-ref.js.map +1 -0
  79. package/dist/src/env-ref.test.d.ts +6 -0
  80. package/dist/src/env-ref.test.js +34 -0
  81. package/dist/src/env-ref.test.js.map +1 -0
  82. package/dist/src/errors.d.ts +15 -0
  83. package/dist/src/errors.js +22 -0
  84. package/dist/src/errors.js.map +1 -1
  85. package/dist/src/errors.test.js +2 -2
  86. package/dist/src/errors.test.js.map +1 -1
  87. package/dist/src/events/event-bus.d.ts +54 -0
  88. package/dist/src/events/event-bus.js +84 -0
  89. package/dist/src/events/event-bus.js.map +1 -0
  90. package/dist/src/events/event-bus.test.d.ts +6 -0
  91. package/dist/src/events/event-bus.test.js +112 -0
  92. package/dist/src/events/event-bus.test.js.map +1 -0
  93. package/dist/src/events/events-route.d.ts +36 -0
  94. package/dist/src/events/events-route.js +80 -0
  95. package/dist/src/events/events-route.js.map +1 -0
  96. package/dist/src/events/events-route.test.d.ts +6 -0
  97. package/dist/src/events/events-route.test.js +134 -0
  98. package/dist/src/events/events-route.test.js.map +1 -0
  99. package/dist/src/events/store-event-wrapper.d.ts +19 -0
  100. package/dist/src/events/store-event-wrapper.js +57 -0
  101. package/dist/src/events/store-event-wrapper.js.map +1 -0
  102. package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
  103. package/dist/src/events/store-event-wrapper.test.js +91 -0
  104. package/dist/src/events/store-event-wrapper.test.js.map +1 -0
  105. package/dist/src/middleware/auth.d.ts +0 -2
  106. package/dist/src/middleware/auth.js.map +1 -1
  107. package/dist/src/providers/search-provider.d.ts +64 -0
  108. package/dist/src/providers/search-provider.js +174 -0
  109. package/dist/src/providers/search-provider.js.map +1 -0
  110. package/dist/src/providers/types.d.ts +8 -0
  111. package/dist/src/routes/ai-stream.d.ts +15 -0
  112. package/dist/src/routes/ai-stream.js +9 -0
  113. package/dist/src/routes/ai-stream.js.map +1 -1
  114. package/dist/src/routes/chat-stream.d.ts +6 -0
  115. package/dist/src/routes/chat-stream.js +2 -0
  116. package/dist/src/routes/chat-stream.js.map +1 -1
  117. package/dist/src/routes/chat.d.ts +6 -0
  118. package/dist/src/routes/chat.js +2 -0
  119. package/dist/src/routes/chat.js.map +1 -1
  120. package/dist/src/routes/session-resolver.d.ts +5 -0
  121. package/dist/src/routes/session-resolver.js +1 -15
  122. package/dist/src/routes/session-resolver.js.map +1 -1
  123. package/dist/src/routes/session-resolver.test.js +7 -6
  124. package/dist/src/routes/session-resolver.test.js.map +1 -1
  125. package/dist/src/server.d.ts +6 -0
  126. package/dist/src/server.js +2 -0
  127. package/dist/src/server.js.map +1 -1
  128. package/dist/src/session/drizzle-session-store.d.ts +56 -0
  129. package/dist/src/session/drizzle-session-store.js +203 -0
  130. package/dist/src/session/drizzle-session-store.js.map +1 -0
  131. package/dist/src/session/manager.d.ts +6 -3
  132. package/dist/src/session/manager.js +46 -16
  133. package/dist/src/session/manager.js.map +1 -1
  134. package/dist/src/session/manager.test.js +12 -18
  135. package/dist/src/session/manager.test.js.map +1 -1
  136. package/dist/src/session/pglite-session-store.d.ts +23 -0
  137. package/dist/src/session/pglite-session-store.js +70 -0
  138. package/dist/src/session/pglite-session-store.js.map +1 -0
  139. package/dist/src/session/postgres-session-store.d.ts +44 -0
  140. package/dist/src/session/postgres-session-store.js +138 -0
  141. package/dist/src/session/postgres-session-store.js.map +1 -0
  142. package/dist/src/session/session-builder.d.ts +0 -2
  143. package/dist/src/session/session-builder.js +22 -2
  144. package/dist/src/session/session-builder.js.map +1 -1
  145. package/dist/src/session/session-builder.test.js +0 -2
  146. package/dist/src/session/session-builder.test.js.map +1 -1
  147. package/dist/src/session/session-store-selector.d.ts +49 -0
  148. package/dist/src/session/session-store-selector.js +60 -0
  149. package/dist/src/session/session-store-selector.js.map +1 -0
  150. package/dist/src/session/session-store-selector.test.d.ts +6 -0
  151. package/dist/src/session/session-store-selector.test.js +79 -0
  152. package/dist/src/session/session-store-selector.test.js.map +1 -0
  153. package/dist/src/session/store.d.ts +146 -32
  154. package/dist/src/session/store.js +126 -138
  155. package/dist/src/session/store.js.map +1 -1
  156. package/dist/src/session/store.test.js +385 -107
  157. package/dist/src/session/store.test.js.map +1 -1
  158. package/dist/src/session/tool-context-factory.d.ts +3 -2
  159. package/dist/src/session/tool-context-factory.js +1 -2
  160. package/dist/src/session/tool-context-factory.js.map +1 -1
  161. package/dist/src/session/tool-context-factory.test.js +1 -4
  162. package/dist/src/session/tool-context-factory.test.js.map +1 -1
  163. package/dist/src/session/types.d.ts +13 -6
  164. package/dist/src/stores/schema.d.ts +0 -34
  165. package/dist/src/stores/schema.js +6 -4
  166. package/dist/src/stores/schema.js.map +1 -1
  167. package/dist/src/tools/admin-file-tools.d.ts +29 -0
  168. package/dist/src/tools/admin-file-tools.js +525 -11
  169. package/dist/src/tools/admin-file-tools.js.map +1 -1
  170. package/dist/src/tools/admin-file-tools.test.js +373 -4
  171. package/dist/src/tools/admin-file-tools.test.js.map +1 -1
  172. package/dist/src/tools/custom-tool-adapter.test.js +0 -1
  173. package/dist/src/tools/custom-tool-adapter.test.js.map +1 -1
  174. package/dist/src/tools/dispatch-tool.d.ts +4 -4
  175. package/dist/src/tools/fetch-url-tool.d.ts +23 -0
  176. package/dist/src/tools/fetch-url-tool.js +333 -0
  177. package/dist/src/tools/fetch-url-tool.js.map +1 -0
  178. package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
  179. package/dist/src/tools/fetch-url-tool.test.js +228 -0
  180. package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
  181. package/dist/src/tools/mcp-tool-adapter.test.js +0 -1
  182. package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -1
  183. package/dist/src/tools/registry.test.js +0 -1
  184. package/dist/src/tools/registry.test.js.map +1 -1
  185. package/dist/src/tools/request-tool.test.js +0 -1
  186. package/dist/src/tools/request-tool.test.js.map +1 -1
  187. package/dist/src/tools/store-tools.test.js +0 -1
  188. package/dist/src/tools/store-tools.test.js.map +1 -1
  189. package/dist/src/tools/types.d.ts +20 -2
  190. package/dist/src/tools/web-search-tool.d.ts +31 -0
  191. package/dist/src/tools/web-search-tool.js +170 -0
  192. package/dist/src/tools/web-search-tool.js.map +1 -0
  193. package/dist/src/tools/web-search-tool.test.d.ts +6 -0
  194. package/dist/src/tools/web-search-tool.test.js +153 -0
  195. package/dist/src/tools/web-search-tool.test.js.map +1 -0
  196. package/dist/src/tools/web-tools-shared.d.ts +21 -0
  197. package/dist/src/tools/web-tools-shared.js +32 -0
  198. package/dist/src/tools/web-tools-shared.js.map +1 -0
  199. package/dist/src/types.d.ts +20 -0
  200. package/dist/src/types.js +13 -0
  201. package/dist/src/types.js.map +1 -1
  202. package/dist/tsconfig.tsbuildinfo +1 -1
  203. package/package.json +17 -3
  204. package/dist/src/agent/session-store.d.ts +0 -71
  205. package/dist/src/agent/session-store.js +0 -151
  206. package/dist/src/agent/session-store.js.map +0 -1
  207. package/dist/src/session/admin-file-tools.d.ts +0 -136
  208. package/dist/src/session/admin-file-tools.js +0 -240
  209. package/dist/src/session/admin-file-tools.js.map +0 -1
@@ -0,0 +1,337 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Delivery Router.
8
+ *
9
+ * Dispatches automation results to configured targets (webhooks and/or
10
+ * ISV callbacks). Also handles failure alerting with consecutive-failure
11
+ * tracking and cooldown windows.
12
+ *
13
+ * Each automation's `delivery` config fires on successful completion.
14
+ * Each automation's `failureAlert` config fires after N consecutive
15
+ * failures, respecting a cooldown so sustained outages don't flood the
16
+ * notification channel.
17
+ *
18
+ * **State is in-memory.** `consecutiveFailures` counters and `lastAlertAt`
19
+ * timestamps live on the DeliveryRouter instance. Process restart wipes
20
+ * them: a flapping service mid-cooldown gets re-alerted on restart, and
21
+ * a service failing for hours resets to 0 and needs `after` more failures
22
+ * before the next alert. For hosted runtimes that restart periodically,
23
+ * expect occasional alert repetition around deploy boundaries.
24
+ */
25
+ import { createHmac } from 'node:crypto';
26
+ const DEFAULT_FAILURE_THRESHOLD = 1;
27
+ const DEFAULT_COOLDOWN_MINUTES = 60;
28
+ const DELIVERY_TIMEOUT_MS = 10_000;
29
+ const DELIVERY_RETRY_DELAY_MS = 1_000;
30
+ /** Max characters kept in `result` field of delivery payload. */
31
+ const MAX_RESULT_CHARS = 16_384;
32
+ export class DeliveryRouter {
33
+ logger;
34
+ webhookSecret;
35
+ onResult;
36
+ eventBus;
37
+ failureState = new Map();
38
+ /** Templates we've already warned about (one log per template + missing-key combo). */
39
+ missingVarWarnings = new Set();
40
+ constructor(opts) {
41
+ this.logger = opts.logger;
42
+ this.webhookSecret = opts.webhookSecret;
43
+ this.onResult = opts.onResult;
44
+ this.eventBus = opts.eventBus;
45
+ }
46
+ /**
47
+ * Record a successful automation run and dispatch the configured
48
+ * delivery (if any). Resets the failure counter for this automation.
49
+ */
50
+ async onSuccess(automationName, rawOutput, delivery) {
51
+ this.failureState.delete(automationName);
52
+ if (!delivery)
53
+ return;
54
+ const parsed = tryParseJson(rawOutput);
55
+ const includeResult = delivery.includeResult ?? true;
56
+ const { text: truncatedResult, truncated } = truncateResult(rawOutput);
57
+ const payload = {
58
+ automation: automationName,
59
+ status: 'success',
60
+ timestamp: new Date().toISOString(),
61
+ ...(includeResult ? { result: truncatedResult } : {}),
62
+ ...(includeResult && truncated ? { truncated: true } : {}),
63
+ ...(parsed ? { data: parsed } : {}),
64
+ ...(delivery.template
65
+ ? { message: this.renderTemplateWithWarnings(delivery.template, {
66
+ automation: automationName,
67
+ timestamp: new Date().toISOString(),
68
+ result: rawOutput,
69
+ ...(parsed ?? {}),
70
+ }, automationName) }
71
+ : {}),
72
+ };
73
+ await this.dispatchTargets(delivery.targets, payload);
74
+ }
75
+ /**
76
+ * Record a failed automation run. Increments the consecutive-failure
77
+ * counter. If it meets the `after` threshold and no recent alert has
78
+ * fired within the cooldown window, dispatches the failure alert.
79
+ */
80
+ async onFailure(automationName, error, failureAlert) {
81
+ const state = this.failureState.get(automationName) ?? { consecutiveFailures: 0, lastAlertAt: null };
82
+ state.consecutiveFailures += 1;
83
+ this.failureState.set(automationName, state);
84
+ if (!failureAlert)
85
+ return;
86
+ const threshold = failureAlert.after ?? DEFAULT_FAILURE_THRESHOLD;
87
+ if (state.consecutiveFailures < threshold)
88
+ return;
89
+ const cooldownMs = (failureAlert.cooldownMinutes ?? DEFAULT_COOLDOWN_MINUTES) * 60_000;
90
+ const now = Date.now();
91
+ if (state.lastAlertAt !== null && now - state.lastAlertAt < cooldownMs) {
92
+ this.logger.debug('delivery_alert_cooldown_skip', {
93
+ automation: automationName,
94
+ consecutiveFailures: state.consecutiveFailures,
95
+ msSinceLastAlert: now - state.lastAlertAt,
96
+ });
97
+ return;
98
+ }
99
+ state.lastAlertAt = now;
100
+ const payload = {
101
+ automation: automationName,
102
+ status: 'failure',
103
+ timestamp: new Date().toISOString(),
104
+ error,
105
+ };
106
+ await this.dispatchTargets(failureAlert.targets, payload);
107
+ }
108
+ /** For tests / observability. */
109
+ getFailureCount(automationName) {
110
+ return this.failureState.get(automationName)?.consecutiveFailures ?? 0;
111
+ }
112
+ async dispatchTargets(targets, payload) {
113
+ await Promise.all(targets.map((target) => this.dispatchTarget(target, payload)));
114
+ }
115
+ async dispatchTarget(target, payload) {
116
+ const startedAt = Date.now();
117
+ try {
118
+ switch (target.type) {
119
+ case 'webhook': {
120
+ const httpStatus = await this.deliverWebhookWithRetry(target.url, payload);
121
+ this.emitDeliverySucceeded(payload.automation, 'webhook', target.url, httpStatus, Date.now() - startedAt);
122
+ break;
123
+ }
124
+ case 'callback': {
125
+ if (!this.onResult) {
126
+ this.logger.warn('delivery_callback_not_configured', {
127
+ automation: payload.automation,
128
+ hint: 'Pass onAutomationResult when creating the server to receive callback deliveries.',
129
+ });
130
+ return;
131
+ }
132
+ await this.onResult(payload, { name: target.name });
133
+ this.emitDeliverySucceeded(payload.automation, 'callback', undefined, undefined, Date.now() - startedAt);
134
+ break;
135
+ }
136
+ default: {
137
+ // Exhaustiveness guard: adding a new DeliveryTarget variant
138
+ // (e.g., 'email') will fail to compile here until a case is
139
+ // added, preventing silent "nothing delivered" regressions.
140
+ const _exhaustive = target;
141
+ throw new DeliveryConfigError(`Unhandled delivery target: ${String(_exhaustive.type)}`);
142
+ }
143
+ }
144
+ }
145
+ catch (err) {
146
+ // Delivery failures must not break the automation run. The
147
+ // automation's output text lives on the runner's runHistory entry
148
+ // and on session messages (via onSessionComplete); delivery
149
+ // correctness is decoupled from automation correctness.
150
+ const errorMessage = err instanceof Error ? err.message : String(err);
151
+ const targetUrl = target.type === 'webhook' ? target.url : undefined;
152
+ const httpStatus = err instanceof WebhookFailure ? err.httpStatus : undefined;
153
+ const attempts = err instanceof WebhookFailure ? err.attempts : 1;
154
+ this.logger.warn('delivery_failed', {
155
+ automation: payload.automation,
156
+ target: target.type,
157
+ targetUrl,
158
+ httpStatus,
159
+ attempts,
160
+ error: errorMessage,
161
+ });
162
+ this.eventBus?.emit({
163
+ type: 'delivery_failed',
164
+ automation: payload.automation,
165
+ targetType: target.type,
166
+ targetUrl,
167
+ httpStatus,
168
+ error: errorMessage,
169
+ attempts,
170
+ });
171
+ }
172
+ }
173
+ emitDeliverySucceeded(automation, targetType, targetUrl, httpStatus, durationMs) {
174
+ this.eventBus?.emit({
175
+ type: 'delivery_succeeded',
176
+ automation,
177
+ targetType,
178
+ targetUrl,
179
+ httpStatus,
180
+ durationMs,
181
+ });
182
+ }
183
+ /**
184
+ * Deliver with one retry on 5xx / network errors. 4xx errors are not
185
+ * retried — they're client-side config bugs that won't fix themselves.
186
+ * Throws a `WebhookFailure` carrying the final status + attempt count.
187
+ */
188
+ async deliverWebhookWithRetry(url, payload) {
189
+ for (let attempt = 1; attempt <= 2; attempt++) {
190
+ try {
191
+ return await this.deliverWebhook(url, payload);
192
+ }
193
+ catch (err) {
194
+ const isRetryable = isRetryableError(err);
195
+ if (attempt >= 2 || !isRetryable) {
196
+ throw new WebhookFailure(err instanceof Error ? err.message : String(err), attempt, err instanceof WebhookHttpError ? err.status : undefined);
197
+ }
198
+ this.logger.debug('delivery_retry', {
199
+ url,
200
+ attempt,
201
+ error: err instanceof Error ? err.message : String(err),
202
+ });
203
+ await sleep(DELIVERY_RETRY_DELAY_MS);
204
+ }
205
+ }
206
+ // Unreachable — loop either returns or throws.
207
+ throw new WebhookFailure('unreachable', 2);
208
+ }
209
+ async deliverWebhook(url, payload) {
210
+ const body = JSON.stringify(payload);
211
+ const headers = {
212
+ 'Content-Type': 'application/json',
213
+ };
214
+ if (this.webhookSecret) {
215
+ const signature = createHmac('sha256', this.webhookSecret).update(body).digest('hex');
216
+ headers['X-Amodal-Signature'] = `sha256=${signature}`;
217
+ }
218
+ const response = await fetch(url, {
219
+ method: 'POST',
220
+ headers,
221
+ body,
222
+ signal: AbortSignal.timeout(DELIVERY_TIMEOUT_MS),
223
+ });
224
+ if (!response.ok) {
225
+ throw new WebhookHttpError(url, response.status);
226
+ }
227
+ return response.status;
228
+ }
229
+ /**
230
+ * Render a template, warning once per (automation, template, missing-keys)
231
+ * combo. Helps diagnose agent-output drift (e.g. agent stopped producing
232
+ * `{{count}}` in its JSON output and now every alert reads
233
+ * "Found {{count}} new articles").
234
+ */
235
+ renderTemplateWithWarnings(template, vars, automationName) {
236
+ const missing = new Set();
237
+ const rendered = template.replace(/\{\{\s*([\w.]+)\s*\}\}/g, (_, key) => {
238
+ const value = vars[key];
239
+ if (value === undefined || value === null) {
240
+ missing.add(key);
241
+ return `{{${key}}}`;
242
+ }
243
+ if (typeof value === 'object')
244
+ return JSON.stringify(value);
245
+ return String(value);
246
+ });
247
+ if (missing.size > 0) {
248
+ const memoKey = `${automationName}\u0000${template}\u0000${[...missing].sort().join(',')}`;
249
+ if (!this.missingVarWarnings.has(memoKey)) {
250
+ this.missingVarWarnings.add(memoKey);
251
+ this.logger.warn('delivery_template_missing_var', {
252
+ automation: automationName,
253
+ missing: [...missing],
254
+ hint: 'Agent output may have drifted — verify the agent is producing these fields in its JSON result.',
255
+ });
256
+ }
257
+ }
258
+ return rendered;
259
+ }
260
+ }
261
+ class DeliveryConfigError extends Error {
262
+ constructor(message) {
263
+ super(message);
264
+ this.name = 'DeliveryConfigError';
265
+ }
266
+ }
267
+ class WebhookHttpError extends Error {
268
+ url;
269
+ status;
270
+ constructor(url, status) {
271
+ super(`webhook ${url} returned ${String(status)}`);
272
+ this.name = 'WebhookHttpError';
273
+ this.url = url;
274
+ this.status = status;
275
+ }
276
+ }
277
+ /** Error carrying the outcome of a webhook delivery attempt chain. */
278
+ class WebhookFailure extends Error {
279
+ attempts;
280
+ httpStatus;
281
+ constructor(message, attempts, httpStatus) {
282
+ super(message);
283
+ this.name = 'WebhookFailure';
284
+ this.attempts = attempts;
285
+ this.httpStatus = httpStatus;
286
+ }
287
+ }
288
+ /** Retryable: 5xx server errors, network errors, timeouts. Not: 4xx. */
289
+ function isRetryableError(err) {
290
+ if (err instanceof WebhookHttpError) {
291
+ return err.status >= 500;
292
+ }
293
+ // Network errors, aborts, DNS failures, TypeError from fetch, etc.
294
+ return err instanceof Error;
295
+ }
296
+ function sleep(ms) {
297
+ return new Promise((resolve) => setTimeout(resolve, ms));
298
+ }
299
+ /**
300
+ * Truncate the raw output at MAX_RESULT_CHARS, keeping a head + tail
301
+ * slice around an elision marker. Slack caps messages at ~4KB, GitHub
302
+ * at ~64KB, most receivers somewhere in between — 16KB is a reasonable
303
+ * ceiling that preserves most automation outputs intact.
304
+ */
305
+ function truncateResult(text) {
306
+ if (text.length <= MAX_RESULT_CHARS)
307
+ return { text, truncated: false };
308
+ const keepChars = MAX_RESULT_CHARS - 100;
309
+ const headChars = Math.floor(keepChars * 0.75);
310
+ const tailChars = keepChars - headChars;
311
+ const elision = `\n\n… [truncated ${String(text.length - keepChars)} chars] …\n\n`;
312
+ return {
313
+ text: text.slice(0, headChars) + elision + text.slice(-tailChars),
314
+ truncated: true,
315
+ };
316
+ }
317
+ /**
318
+ * Try to parse the automation's raw output as JSON. If the output looks
319
+ * like a fenced JSON code block, strip the fence first.
320
+ */
321
+ function tryParseJson(text) {
322
+ const trimmed = text.trim();
323
+ const fenced = /^```(?:json)?\s*\n([\s\S]+?)\n```\s*$/.exec(trimmed);
324
+ const candidate = fenced ? fenced[1] : trimmed;
325
+ if (!candidate)
326
+ return null;
327
+ try {
328
+ const parsed = JSON.parse(candidate);
329
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
330
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- verified object shape
331
+ return parsed;
332
+ }
333
+ }
334
+ catch { /* not JSON */ }
335
+ return null;
336
+ }
337
+ //# sourceMappingURL=delivery-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-router.js","sourceRoot":"","sources":["../../../../src/agent/proactive/delivery-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};