@amodalai/runtime 0.1.0

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 (277) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.last_build +0 -0
  3. package/dist/src/agent/agent-runner.d.ts +13 -0
  4. package/dist/src/agent/agent-runner.js +827 -0
  5. package/dist/src/agent/agent-runner.js.map +1 -0
  6. package/dist/src/agent/agent-runner.test.d.ts +6 -0
  7. package/dist/src/agent/agent-runner.test.js +552 -0
  8. package/dist/src/agent/agent-runner.test.js.map +1 -0
  9. package/dist/src/agent/agent-types.d.ts +57 -0
  10. package/dist/src/agent/agent-types.js +17 -0
  11. package/dist/src/agent/agent-types.js.map +1 -0
  12. package/dist/src/agent/agent-types.test.d.ts +6 -0
  13. package/dist/src/agent/agent-types.test.js +44 -0
  14. package/dist/src/agent/agent-types.test.js.map +1 -0
  15. package/dist/src/agent/automation-bridge.d.ts +24 -0
  16. package/dist/src/agent/automation-bridge.js +24 -0
  17. package/dist/src/agent/automation-bridge.js.map +1 -0
  18. package/dist/src/agent/automation-bridge.test.d.ts +6 -0
  19. package/dist/src/agent/automation-bridge.test.js +67 -0
  20. package/dist/src/agent/automation-bridge.test.js.map +1 -0
  21. package/dist/src/agent/config-watcher.d.ts +20 -0
  22. package/dist/src/agent/config-watcher.js +68 -0
  23. package/dist/src/agent/config-watcher.js.map +1 -0
  24. package/dist/src/agent/config-watcher.test.d.ts +6 -0
  25. package/dist/src/agent/config-watcher.test.js +83 -0
  26. package/dist/src/agent/config-watcher.test.js.map +1 -0
  27. package/dist/src/agent/custom-tools-e2e.test.d.ts +6 -0
  28. package/dist/src/agent/custom-tools-e2e.test.js +566 -0
  29. package/dist/src/agent/custom-tools-e2e.test.js.map +1 -0
  30. package/dist/src/agent/local-server.d.ts +15 -0
  31. package/dist/src/agent/local-server.js +158 -0
  32. package/dist/src/agent/local-server.js.map +1 -0
  33. package/dist/src/agent/local-server.test.d.ts +6 -0
  34. package/dist/src/agent/local-server.test.js +126 -0
  35. package/dist/src/agent/local-server.test.js.map +1 -0
  36. package/dist/src/agent/proactive/delivery.d.ts +21 -0
  37. package/dist/src/agent/proactive/delivery.js +68 -0
  38. package/dist/src/agent/proactive/delivery.js.map +1 -0
  39. package/dist/src/agent/proactive/delivery.test.d.ts +6 -0
  40. package/dist/src/agent/proactive/delivery.test.js +65 -0
  41. package/dist/src/agent/proactive/delivery.test.js.map +1 -0
  42. package/dist/src/agent/proactive/proactive-runner.d.ts +76 -0
  43. package/dist/src/agent/proactive/proactive-runner.js +201 -0
  44. package/dist/src/agent/proactive/proactive-runner.js.map +1 -0
  45. package/dist/src/agent/proactive/proactive-runner.test.d.ts +6 -0
  46. package/dist/src/agent/proactive/proactive-runner.test.js +265 -0
  47. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -0
  48. package/dist/src/agent/request-helper.d.ts +16 -0
  49. package/dist/src/agent/request-helper.js +87 -0
  50. package/dist/src/agent/request-helper.js.map +1 -0
  51. package/dist/src/agent/routes/automations.d.ts +19 -0
  52. package/dist/src/agent/routes/automations.js +58 -0
  53. package/dist/src/agent/routes/automations.js.map +1 -0
  54. package/dist/src/agent/routes/automations.test.d.ts +6 -0
  55. package/dist/src/agent/routes/automations.test.js +117 -0
  56. package/dist/src/agent/routes/automations.test.js.map +1 -0
  57. package/dist/src/agent/routes/chat.d.ts +35 -0
  58. package/dist/src/agent/routes/chat.js +88 -0
  59. package/dist/src/agent/routes/chat.js.map +1 -0
  60. package/dist/src/agent/routes/chat.test.d.ts +6 -0
  61. package/dist/src/agent/routes/chat.test.js +115 -0
  62. package/dist/src/agent/routes/chat.test.js.map +1 -0
  63. package/dist/src/agent/routes/inspect.d.ts +12 -0
  64. package/dist/src/agent/routes/inspect.js +40 -0
  65. package/dist/src/agent/routes/inspect.js.map +1 -0
  66. package/dist/src/agent/routes/inspect.test.d.ts +6 -0
  67. package/dist/src/agent/routes/inspect.test.js +80 -0
  68. package/dist/src/agent/routes/inspect.test.js.map +1 -0
  69. package/dist/src/agent/routes/stores.d.ts +20 -0
  70. package/dist/src/agent/routes/stores.js +137 -0
  71. package/dist/src/agent/routes/stores.js.map +1 -0
  72. package/dist/src/agent/routes/stores.test.d.ts +6 -0
  73. package/dist/src/agent/routes/stores.test.js +191 -0
  74. package/dist/src/agent/routes/stores.test.js.map +1 -0
  75. package/dist/src/agent/routes/task.d.ts +11 -0
  76. package/dist/src/agent/routes/task.js +116 -0
  77. package/dist/src/agent/routes/task.js.map +1 -0
  78. package/dist/src/agent/routes/task.test.d.ts +6 -0
  79. package/dist/src/agent/routes/task.test.js +91 -0
  80. package/dist/src/agent/routes/task.test.js.map +1 -0
  81. package/dist/src/agent/routes/webhooks.d.ts +17 -0
  82. package/dist/src/agent/routes/webhooks.js +53 -0
  83. package/dist/src/agent/routes/webhooks.js.map +1 -0
  84. package/dist/src/agent/routes/webhooks.test.d.ts +6 -0
  85. package/dist/src/agent/routes/webhooks.test.js +100 -0
  86. package/dist/src/agent/routes/webhooks.test.js.map +1 -0
  87. package/dist/src/agent/session-manager.d.ts +72 -0
  88. package/dist/src/agent/session-manager.js +214 -0
  89. package/dist/src/agent/session-manager.js.map +1 -0
  90. package/dist/src/agent/session-manager.test.d.ts +6 -0
  91. package/dist/src/agent/session-manager.test.js +145 -0
  92. package/dist/src/agent/session-manager.test.js.map +1 -0
  93. package/dist/src/agent/shell-executor-local.d.ts +16 -0
  94. package/dist/src/agent/shell-executor-local.js +51 -0
  95. package/dist/src/agent/shell-executor-local.js.map +1 -0
  96. package/dist/src/agent/shell-executor-local.test.d.ts +6 -0
  97. package/dist/src/agent/shell-executor-local.test.js +46 -0
  98. package/dist/src/agent/shell-executor-local.test.js.map +1 -0
  99. package/dist/src/agent/snapshot-server.d.ts +38 -0
  100. package/dist/src/agent/snapshot-server.js +114 -0
  101. package/dist/src/agent/snapshot-server.js.map +1 -0
  102. package/dist/src/agent/stores-e2e.test.d.ts +6 -0
  103. package/dist/src/agent/stores-e2e.test.js +433 -0
  104. package/dist/src/agent/stores-e2e.test.js.map +1 -0
  105. package/dist/src/agent/tool-context-builder.d.ts +11 -0
  106. package/dist/src/agent/tool-context-builder.js +84 -0
  107. package/dist/src/agent/tool-context-builder.js.map +1 -0
  108. package/dist/src/agent/tool-context-builder.test.d.ts +6 -0
  109. package/dist/src/agent/tool-context-builder.test.js +152 -0
  110. package/dist/src/agent/tool-context-builder.test.js.map +1 -0
  111. package/dist/src/agent/tool-executor-local.d.ts +15 -0
  112. package/dist/src/agent/tool-executor-local.js +74 -0
  113. package/dist/src/agent/tool-executor-local.js.map +1 -0
  114. package/dist/src/agent/tool-executor-local.test.d.ts +6 -0
  115. package/dist/src/agent/tool-executor-local.test.js +116 -0
  116. package/dist/src/agent/tool-executor-local.test.js.map +1 -0
  117. package/dist/src/agent/tool-harness-template.d.ts +23 -0
  118. package/dist/src/agent/tool-harness-template.js +94 -0
  119. package/dist/src/agent/tool-harness-template.js.map +1 -0
  120. package/dist/src/agent/user-context-fetcher.d.ts +25 -0
  121. package/dist/src/agent/user-context-fetcher.js +79 -0
  122. package/dist/src/agent/user-context-fetcher.js.map +1 -0
  123. package/dist/src/agent/user-context-fetcher.test.d.ts +6 -0
  124. package/dist/src/agent/user-context-fetcher.test.js +121 -0
  125. package/dist/src/agent/user-context-fetcher.test.js.map +1 -0
  126. package/dist/src/audit/audit-client.d.ts +46 -0
  127. package/dist/src/audit/audit-client.js +83 -0
  128. package/dist/src/audit/audit-client.js.map +1 -0
  129. package/dist/src/cron/heartbeat-runner.d.ts +24 -0
  130. package/dist/src/cron/heartbeat-runner.js +87 -0
  131. package/dist/src/cron/heartbeat-runner.js.map +1 -0
  132. package/dist/src/cron/heartbeat-runner.test.d.ts +6 -0
  133. package/dist/src/cron/heartbeat-runner.test.js +120 -0
  134. package/dist/src/cron/heartbeat-runner.test.js.map +1 -0
  135. package/dist/src/cron/heartbeat-scheduler.d.ts +26 -0
  136. package/dist/src/cron/heartbeat-scheduler.js +54 -0
  137. package/dist/src/cron/heartbeat-scheduler.js.map +1 -0
  138. package/dist/src/cron/heartbeat-scheduler.test.d.ts +6 -0
  139. package/dist/src/cron/heartbeat-scheduler.test.js +61 -0
  140. package/dist/src/cron/heartbeat-scheduler.test.js.map +1 -0
  141. package/dist/src/index.d.ts +24 -0
  142. package/dist/src/index.js +118 -0
  143. package/dist/src/index.js.map +1 -0
  144. package/dist/src/middleware/auth.d.ts +40 -0
  145. package/dist/src/middleware/auth.js +135 -0
  146. package/dist/src/middleware/auth.js.map +1 -0
  147. package/dist/src/middleware/auth.test.d.ts +6 -0
  148. package/dist/src/middleware/auth.test.js +268 -0
  149. package/dist/src/middleware/auth.test.js.map +1 -0
  150. package/dist/src/middleware/error-handler.d.ts +20 -0
  151. package/dist/src/middleware/error-handler.js +48 -0
  152. package/dist/src/middleware/error-handler.js.map +1 -0
  153. package/dist/src/middleware/error-handler.test.d.ts +6 -0
  154. package/dist/src/middleware/error-handler.test.js +68 -0
  155. package/dist/src/middleware/error-handler.test.js.map +1 -0
  156. package/dist/src/middleware/request-validation.d.ts +13 -0
  157. package/dist/src/middleware/request-validation.js +26 -0
  158. package/dist/src/middleware/request-validation.js.map +1 -0
  159. package/dist/src/middleware/request-validation.test.d.ts +6 -0
  160. package/dist/src/middleware/request-validation.test.js +57 -0
  161. package/dist/src/middleware/request-validation.test.js.map +1 -0
  162. package/dist/src/output/email-output.d.ts +10 -0
  163. package/dist/src/output/email-output.js +12 -0
  164. package/dist/src/output/email-output.js.map +1 -0
  165. package/dist/src/output/output-router.d.ts +12 -0
  166. package/dist/src/output/output-router.js +36 -0
  167. package/dist/src/output/output-router.js.map +1 -0
  168. package/dist/src/output/output-router.test.d.ts +6 -0
  169. package/dist/src/output/output-router.test.js +132 -0
  170. package/dist/src/output/output-router.test.js.map +1 -0
  171. package/dist/src/output/slack-output.d.ts +10 -0
  172. package/dist/src/output/slack-output.js +54 -0
  173. package/dist/src/output/slack-output.js.map +1 -0
  174. package/dist/src/output/webhook-output.d.ts +10 -0
  175. package/dist/src/output/webhook-output.js +25 -0
  176. package/dist/src/output/webhook-output.js.map +1 -0
  177. package/dist/src/routes/ai-stream.d.ts +159 -0
  178. package/dist/src/routes/ai-stream.js +309 -0
  179. package/dist/src/routes/ai-stream.js.map +1 -0
  180. package/dist/src/routes/ai-stream.test.d.ts +6 -0
  181. package/dist/src/routes/ai-stream.test.js +586 -0
  182. package/dist/src/routes/ai-stream.test.js.map +1 -0
  183. package/dist/src/routes/ask-user-response.d.ts +30 -0
  184. package/dist/src/routes/ask-user-response.js +61 -0
  185. package/dist/src/routes/ask-user-response.js.map +1 -0
  186. package/dist/src/routes/ask-user-response.test.d.ts +6 -0
  187. package/dist/src/routes/ask-user-response.test.js +88 -0
  188. package/dist/src/routes/ask-user-response.test.js.map +1 -0
  189. package/dist/src/routes/chat-stream.d.ts +14 -0
  190. package/dist/src/routes/chat-stream.js +84 -0
  191. package/dist/src/routes/chat-stream.js.map +1 -0
  192. package/dist/src/routes/chat-stream.test.d.ts +6 -0
  193. package/dist/src/routes/chat-stream.test.js +155 -0
  194. package/dist/src/routes/chat-stream.test.js.map +1 -0
  195. package/dist/src/routes/chat.d.ts +13 -0
  196. package/dist/src/routes/chat.js +55 -0
  197. package/dist/src/routes/chat.js.map +1 -0
  198. package/dist/src/routes/chat.test.d.ts +6 -0
  199. package/dist/src/routes/chat.test.js +99 -0
  200. package/dist/src/routes/chat.test.js.map +1 -0
  201. package/dist/src/routes/health.d.ts +13 -0
  202. package/dist/src/routes/health.js +23 -0
  203. package/dist/src/routes/health.js.map +1 -0
  204. package/dist/src/routes/health.test.d.ts +6 -0
  205. package/dist/src/routes/health.test.js +45 -0
  206. package/dist/src/routes/health.test.js.map +1 -0
  207. package/dist/src/routes/sessions.d.ts +14 -0
  208. package/dist/src/routes/sessions.js +82 -0
  209. package/dist/src/routes/sessions.js.map +1 -0
  210. package/dist/src/routes/webhooks.d.ts +13 -0
  211. package/dist/src/routes/webhooks.js +43 -0
  212. package/dist/src/routes/webhooks.js.map +1 -0
  213. package/dist/src/routes/webhooks.test.d.ts +6 -0
  214. package/dist/src/routes/webhooks.test.js +80 -0
  215. package/dist/src/routes/webhooks.test.js.map +1 -0
  216. package/dist/src/routes/widget-actions.d.ts +49 -0
  217. package/dist/src/routes/widget-actions.js +78 -0
  218. package/dist/src/routes/widget-actions.js.map +1 -0
  219. package/dist/src/server.d.ts +31 -0
  220. package/dist/src/server.js +129 -0
  221. package/dist/src/server.js.map +1 -0
  222. package/dist/src/server.test.d.ts +6 -0
  223. package/dist/src/server.test.js +153 -0
  224. package/dist/src/server.test.js.map +1 -0
  225. package/dist/src/session/history-converter.d.ts +21 -0
  226. package/dist/src/session/history-converter.js +59 -0
  227. package/dist/src/session/history-converter.js.map +1 -0
  228. package/dist/src/session/history-converter.test.d.ts +6 -0
  229. package/dist/src/session/history-converter.test.js +130 -0
  230. package/dist/src/session/history-converter.test.js.map +1 -0
  231. package/dist/src/session/session-manager.d.ts +117 -0
  232. package/dist/src/session/session-manager.js +480 -0
  233. package/dist/src/session/session-manager.js.map +1 -0
  234. package/dist/src/session/session-manager.test.d.ts +6 -0
  235. package/dist/src/session/session-manager.test.js +586 -0
  236. package/dist/src/session/session-manager.test.js.map +1 -0
  237. package/dist/src/session/session-runner.d.ts +30 -0
  238. package/dist/src/session/session-runner.js +771 -0
  239. package/dist/src/session/session-runner.js.map +1 -0
  240. package/dist/src/session/session-runner.test.d.ts +6 -0
  241. package/dist/src/session/session-runner.test.js +842 -0
  242. package/dist/src/session/session-runner.test.js.map +1 -0
  243. package/dist/src/stores/index.d.ts +8 -0
  244. package/dist/src/stores/index.js +9 -0
  245. package/dist/src/stores/index.js.map +1 -0
  246. package/dist/src/stores/key-resolver.d.ts +21 -0
  247. package/dist/src/stores/key-resolver.js +30 -0
  248. package/dist/src/stores/key-resolver.js.map +1 -0
  249. package/dist/src/stores/key-resolver.test.d.ts +6 -0
  250. package/dist/src/stores/key-resolver.test.js +31 -0
  251. package/dist/src/stores/key-resolver.test.js.map +1 -0
  252. package/dist/src/stores/pglite-store-backend.d.ts +36 -0
  253. package/dist/src/stores/pglite-store-backend.js +227 -0
  254. package/dist/src/stores/pglite-store-backend.js.map +1 -0
  255. package/dist/src/stores/pglite-store-backend.test.d.ts +6 -0
  256. package/dist/src/stores/pglite-store-backend.test.js +150 -0
  257. package/dist/src/stores/pglite-store-backend.test.js.map +1 -0
  258. package/dist/src/stores/ttl-resolver.d.ts +24 -0
  259. package/dist/src/stores/ttl-resolver.js +64 -0
  260. package/dist/src/stores/ttl-resolver.js.map +1 -0
  261. package/dist/src/stores/ttl-resolver.test.d.ts +6 -0
  262. package/dist/src/stores/ttl-resolver.test.js +68 -0
  263. package/dist/src/stores/ttl-resolver.test.js.map +1 -0
  264. package/dist/src/types.d.ts +227 -0
  265. package/dist/src/types.js +50 -0
  266. package/dist/src/types.js.map +1 -0
  267. package/dist/src/types.test.d.ts +6 -0
  268. package/dist/src/types.test.js +68 -0
  269. package/dist/src/types.test.js.map +1 -0
  270. package/dist/src/utils/jwt-verify.d.ts +20 -0
  271. package/dist/src/utils/jwt-verify.js +34 -0
  272. package/dist/src/utils/jwt-verify.js.map +1 -0
  273. package/dist/src/utils/jwt-verify.test.d.ts +6 -0
  274. package/dist/src/utils/jwt-verify.test.js +156 -0
  275. package/dist/src/utils/jwt-verify.test.js.map +1 -0
  276. package/dist/tsconfig.tsbuildinfo +1 -0
  277. package/package.json +51 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
+ import { AutomationScheduler } from './heartbeat-scheduler.js';
8
+ function makeAutomation(name, triggerType = 'cron', schedule = '*/5 * * * *') {
9
+ return {
10
+ name,
11
+ trigger: triggerType === 'cron'
12
+ ? { type: 'cron', schedule }
13
+ : { type: 'webhook', source: name },
14
+ prompt: `Run ${name}`,
15
+ tools: ['tool1'],
16
+ skills: ['*'],
17
+ output: { channel: 'slack', target: 'https://hooks.slack.com/abc' },
18
+ allow_writes: false,
19
+ };
20
+ }
21
+ describe('AutomationScheduler', () => {
22
+ let scheduler;
23
+ beforeEach(() => {
24
+ scheduler = new AutomationScheduler();
25
+ vi.spyOn(process.stderr, 'write').mockReturnValue(true);
26
+ });
27
+ afterEach(() => {
28
+ scheduler.stop();
29
+ });
30
+ it('registers cron automations', () => {
31
+ const mockRunner = vi.fn().mockResolvedValue({});
32
+ scheduler.start([makeAutomation('a1'), makeAutomation('a2')], mockRunner);
33
+ expect(scheduler.size).toBe(2);
34
+ });
35
+ it('ignores webhook automations', () => {
36
+ const mockRunner = vi.fn().mockResolvedValue({});
37
+ scheduler.start([
38
+ makeAutomation('cron-a'),
39
+ makeAutomation('webhook-a', 'webhook'),
40
+ ], mockRunner);
41
+ expect(scheduler.size).toBe(1);
42
+ });
43
+ it('skips invalid cron schedules', () => {
44
+ const mockRunner = vi.fn().mockResolvedValue({});
45
+ scheduler.start([makeAutomation('bad-a', 'cron', 'not-a-cron')], mockRunner);
46
+ expect(scheduler.size).toBe(0);
47
+ });
48
+ it('stops all jobs on stop()', () => {
49
+ const mockRunner = vi.fn().mockResolvedValue({});
50
+ scheduler.start([makeAutomation('a1')], mockRunner);
51
+ expect(scheduler.size).toBe(1);
52
+ scheduler.stop();
53
+ expect(scheduler.size).toBe(0);
54
+ });
55
+ it('handles empty automation list', () => {
56
+ const mockRunner = vi.fn().mockResolvedValue({});
57
+ scheduler.start([], mockRunner);
58
+ expect(scheduler.size).toBe(0);
59
+ });
60
+ });
61
+ //# sourceMappingURL=heartbeat-scheduler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat-scheduler.test.js","sourceRoot":"","sources":["../../../src/cron/heartbeat-scheduler.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export declare const SERVER_VERSION = "0.1.0";
7
+ export { createServer } from './server.js';
8
+ export type { ServerInstance, CreateServerOptions } from './server.js';
9
+ export type { ServerConfig } from './types.js';
10
+ export { createAIStreamRouter, type AIStreamRouterOptions } from './routes/ai-stream.js';
11
+ export { createLocalServer } from './agent/local-server.js';
12
+ export type { LocalServerConfig, AgentChatRequest, AgentSession } from './agent/agent-types.js';
13
+ export { AgentSessionManager } from './agent/session-manager.js';
14
+ export { ProactiveRunner } from './agent/proactive/proactive-runner.js';
15
+ export type { AutomationInfo, ProactiveRunnerConfig } from './agent/proactive/proactive-runner.js';
16
+ export { createSnapshotServer } from './agent/snapshot-server.js';
17
+ export type { SnapshotServerConfig } from './agent/snapshot-server.js';
18
+ export { createChatRouter } from './agent/routes/chat.js';
19
+ export type { ChatRouterOptions, SessionCreator, SessionHydrator, TurnCompleteHandler } from './agent/routes/chat.js';
20
+ export { createTaskRouter } from './agent/routes/task.js';
21
+ export type { TaskRouterOptions } from './agent/routes/task.js';
22
+ export { getAuthContext, createAuthMiddleware } from './middleware/auth.js';
23
+ export type { AuthContext, AuthMiddlewareOptions } from './middleware/auth.js';
24
+ export { errorHandler } from './middleware/error-handler.js';
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { createServer } from './server.js';
7
+ export const SERVER_VERSION = '0.1.0';
8
+ // Re-export for consumers
9
+ export { createServer } from './server.js';
10
+ export { createAIStreamRouter } from './routes/ai-stream.js';
11
+ // Local mode
12
+ export { createLocalServer } from './agent/local-server.js';
13
+ export { AgentSessionManager } from './agent/session-manager.js';
14
+ export { ProactiveRunner } from './agent/proactive/proactive-runner.js';
15
+ // Snapshot mode
16
+ export { createSnapshotServer } from './agent/snapshot-server.js';
17
+ // Route creators (used by hosted-runtime to build its own server)
18
+ export { createChatRouter } from './agent/routes/chat.js';
19
+ export { createTaskRouter } from './agent/routes/task.js';
20
+ // Auth
21
+ export { getAuthContext, createAuthMiddleware } from './middleware/auth.js';
22
+ // Error handler
23
+ export { errorHandler } from './middleware/error-handler.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Environment variable parsing
26
+ // ---------------------------------------------------------------------------
27
+ function getEnvOrDefault(key, defaultValue) {
28
+ return process.env[key] ?? defaultValue;
29
+ }
30
+ function getEnvInt(key, defaultValue) {
31
+ const val = process.env[key];
32
+ if (!val)
33
+ return defaultValue;
34
+ const parsed = parseInt(val, 10);
35
+ return isNaN(parsed) ? defaultValue : parsed;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Main
39
+ // ---------------------------------------------------------------------------
40
+ async function main() {
41
+ // Parse env vars
42
+ const port = getEnvInt('PORT', 3000);
43
+ const host = getEnvOrDefault('HOST', '0.0.0.0');
44
+ const sessionTtlMs = getEnvInt('SESSION_TTL_MS', 30 * 60 * 1000);
45
+ // Platform API URL — used for auth (validating ak_ keys from requests)
46
+ // and for loading org-specific config per session.
47
+ // No API key needed at startup — keys come from request headers.
48
+ const platformApiUrl = process.env['PLATFORM_API_URL'];
49
+ // JWKS URL for JWT verification (defaults to platformApiUrl/.well-known/jwks.json)
50
+ const jwksUrl = process.env['JWT_JWKS_URL'] || undefined;
51
+ // LLM config comes from env. Default matches the platform API default.
52
+ const model = getEnvOrDefault('MODEL', 'claude-sonnet-4-20250514');
53
+ // WORKSPACE_DIR scopes file tools and shell_exec. In Docker, set to
54
+ // /workspace so the agent cannot read server source code. When unset,
55
+ // falls back to process.cwd() for local dev.
56
+ const workspaceDir = process.env['WORKSPACE_DIR'] || process.cwd();
57
+ // Base config params — minimal, org-agnostic defaults.
58
+ // Org-specific config (tools, skills, knowledge, base_prompt, agent_context)
59
+ // loaded per session using the API key from each request.
60
+ const baseParams = {
61
+ sessionId: 'server-init',
62
+ model,
63
+ cwd: workspaceDir,
64
+ targetDir: workspaceDir,
65
+ debugMode: process.env['DEBUG'] === 'true',
66
+ interactive: false,
67
+ noBrowser: true,
68
+ };
69
+ // Create and start server
70
+ let serverInstance;
71
+ try {
72
+ const corsOrigin = process.env['CORS_ORIGIN'] || undefined;
73
+ serverInstance = createServer({
74
+ baseParams,
75
+ config: {
76
+ port,
77
+ host,
78
+ sessionTtlMs,
79
+ automations: [],
80
+ corsOrigin,
81
+ },
82
+ version: SERVER_VERSION,
83
+ platformApiUrl,
84
+ jwksUrl,
85
+ });
86
+ await serverInstance.start();
87
+ }
88
+ catch (err) {
89
+ const message = err instanceof Error ? err.message : String(err);
90
+ process.stderr.write(`[FATAL] Failed to start server: ${message}\n`);
91
+ process.exit(1);
92
+ }
93
+ // Graceful shutdown
94
+ const shutdown = async (signal) => {
95
+ process.stderr.write(`[INFO] Received ${signal}, shutting down...\n`);
96
+ try {
97
+ await serverInstance.stop();
98
+ }
99
+ catch (err) {
100
+ const message = err instanceof Error ? err.message : String(err);
101
+ process.stderr.write(`[ERROR] Shutdown error: ${message}\n`);
102
+ }
103
+ process.exit(0);
104
+ };
105
+ process.on('SIGTERM', () => void shutdown('SIGTERM'));
106
+ process.on('SIGINT', () => void shutdown('SIGINT'));
107
+ }
108
+ // Only run main when this file is the entry point (the runtime package itself)
109
+ const isMainModule = process.argv[1] &&
110
+ (process.argv[1].includes('@amodalai/runtime') ||
111
+ process.argv[1].includes('packages/runtime/'));
112
+ if (isMainModule) {
113
+ main().catch((err) => {
114
+ process.stderr.write(`[FATAL] ${err}\n`);
115
+ process.exit(1);
116
+ });
117
+ }
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { Request, Response, NextFunction } from 'express';
7
+ /**
8
+ * Auth context attached to `res.locals.authContext` after successful auth.
9
+ * Contains the caller's API key and resolved platform context from /api/me.
10
+ */
11
+ export interface AuthContext {
12
+ apiKey?: string;
13
+ /** Raw Bearer token (JWT or ak_ key) for forwarding to platform API */
14
+ token?: string;
15
+ orgId: string;
16
+ applicationId: string;
17
+ tenantId: string;
18
+ authMethod: 'api_key' | 'platform_jwt';
19
+ actor?: string;
20
+ }
21
+ export interface AuthMiddlewareOptions {
22
+ /** Platform API base URL (e.g., "http://localhost:4000") */
23
+ platformApiUrl: string;
24
+ /** TTL in ms for cached key validations (default: 5 minutes) */
25
+ cacheTtlMs?: number;
26
+ /** JWKS URL for JWT verification (defaults to platformApiUrl/.well-known/jwks.json) */
27
+ jwksUrl?: string;
28
+ }
29
+ /**
30
+ * Get the auth context from response locals.
31
+ */
32
+ export declare function getAuthContext(res: Response): AuthContext | undefined;
33
+ /**
34
+ * Express middleware that validates Bearer tokens.
35
+ *
36
+ * Supports dual auth:
37
+ * - `ak_` prefixed keys: validated via `GET /api/me` on the platform API (cached)
38
+ * - JWTs: validated locally via JWKS (zero network overhead per request)
39
+ */
40
+ export declare function createAuthMiddleware(options: AuthMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { AppError } from './error-handler.js';
7
+ import { createJWTVerifier } from '../utils/jwt-verify.js';
8
+ const AUTH_CONTEXT_KEY = 'authContext';
9
+ /**
10
+ * Get the auth context from response locals.
11
+ */
12
+ export function getAuthContext(res) {
13
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
14
+ return res.locals[AUTH_CONTEXT_KEY];
15
+ }
16
+ /**
17
+ * Express middleware that validates Bearer tokens.
18
+ *
19
+ * Supports dual auth:
20
+ * - `ak_` prefixed keys: validated via `GET /api/me` on the platform API (cached)
21
+ * - JWTs: validated locally via JWKS (zero network overhead per request)
22
+ */
23
+ export function createAuthMiddleware(options) {
24
+ const { platformApiUrl, cacheTtlMs = 5 * 60 * 1000 } = options;
25
+ const cache = new Map();
26
+ // Set up JWT verifier if JWKS URL available
27
+ const jwksUrl = options.jwksUrl ?? `${platformApiUrl}/.well-known/jwks.json`;
28
+ let verifyJWT = null;
29
+ try {
30
+ verifyJWT = createJWTVerifier({ jwksUrl });
31
+ }
32
+ catch {
33
+ // JWKS URL invalid — JWT verification disabled
34
+ }
35
+ return (req, res, next) => {
36
+ const authHeader = req.headers['authorization'];
37
+ if (!authHeader) {
38
+ next(new AppError(401, 'UNAUTHORIZED', 'Missing Authorization header'));
39
+ return;
40
+ }
41
+ if (!authHeader.startsWith('Bearer ')) {
42
+ next(new AppError(401, 'UNAUTHORIZED', 'Authorization header must use Bearer scheme'));
43
+ return;
44
+ }
45
+ const token = authHeader.slice(7);
46
+ if (token.startsWith('ak_')) {
47
+ // API key flow — validate via /api/me (cached)
48
+ const cached = cache.get(token);
49
+ if (cached && cached.expiresAt > Date.now()) {
50
+ res.locals[AUTH_CONTEXT_KEY] = {
51
+ apiKey: token,
52
+ token,
53
+ orgId: cached.orgId,
54
+ applicationId: cached.applicationId,
55
+ tenantId: cached.tenantId,
56
+ authMethod: 'api_key',
57
+ };
58
+ next();
59
+ return;
60
+ }
61
+ void validateKey(platformApiUrl, token).then((result) => {
62
+ if (!result) {
63
+ next(new AppError(401, 'UNAUTHORIZED', 'Invalid API key'));
64
+ return;
65
+ }
66
+ cache.set(token, { ...result, expiresAt: Date.now() + cacheTtlMs });
67
+ res.locals[AUTH_CONTEXT_KEY] = {
68
+ apiKey: token,
69
+ token,
70
+ ...result,
71
+ authMethod: 'api_key',
72
+ };
73
+ next();
74
+ }, (err) => {
75
+ next(new AppError(502, 'AUTH_UPSTREAM_ERROR', `Failed to validate API key: ${err instanceof Error ? err.message : 'Unknown error'}`));
76
+ });
77
+ }
78
+ else if (verifyJWT) {
79
+ // JWT flow — validate locally via JWKS
80
+ void verifyJWT(token).then((claims) => {
81
+ if (!claims) {
82
+ next(new AppError(401, 'UNAUTHORIZED', 'Invalid or expired token'));
83
+ return;
84
+ }
85
+ res.locals[AUTH_CONTEXT_KEY] = {
86
+ token,
87
+ orgId: claims.org_id,
88
+ applicationId: claims.app_id,
89
+ tenantId: claims.tenant_id,
90
+ authMethod: 'platform_jwt',
91
+ ...(claims.actor ? { actor: claims.actor } : {}),
92
+ };
93
+ next();
94
+ }, () => {
95
+ next(new AppError(401, 'UNAUTHORIZED', 'Token verification failed'));
96
+ });
97
+ }
98
+ else {
99
+ next(new AppError(401, 'UNAUTHORIZED', 'Invalid API key format'));
100
+ }
101
+ };
102
+ }
103
+ /**
104
+ * Validate an API key by calling the platform API's /api/me endpoint.
105
+ * Returns org/app/tenant context if valid, null if invalid.
106
+ */
107
+ async function validateKey(platformApiUrl, apiKey) {
108
+ const controller = new AbortController();
109
+ const timer = setTimeout(() => controller.abort(), 10000);
110
+ try {
111
+ const response = await fetch(`${platformApiUrl}/api/me`, {
112
+ signal: controller.signal,
113
+ headers: {
114
+ Authorization: `Bearer ${apiKey}`,
115
+ Accept: 'application/json',
116
+ },
117
+ });
118
+ clearTimeout(timer);
119
+ if (!response.ok) {
120
+ return null;
121
+ }
122
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
123
+ const data = (await response.json());
124
+ // Prefer singular fields, fall back to arrays
125
+ const orgId = data.org?.id ?? '';
126
+ const applicationId = data.app?.id ?? data.apps?.[0]?.id ?? '';
127
+ const tenantId = data.tenant?.id ?? data.tenants?.[0]?.id ?? '';
128
+ return { orgId, applicationId, tenantId };
129
+ }
130
+ catch {
131
+ clearTimeout(timer);
132
+ throw new Error('Platform API unreachable');
133
+ }
134
+ }
135
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};