@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 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.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 {};
@@ -0,0 +1,153 @@
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 request from 'supertest';
8
+ import { SSEEventType } from './types.js';
9
+ // Mock core module
10
+ const mockInitialize = vi.fn().mockResolvedValue(undefined);
11
+ const mockShutdownAudit = vi.fn().mockResolvedValue(undefined);
12
+ const mockGetGeminiClient = vi.fn();
13
+ const mockGetMessageBus = vi.fn().mockReturnValue({
14
+ on: vi.fn(),
15
+ removeListener: vi.fn(),
16
+ });
17
+ const mockGetModel = vi.fn().mockReturnValue('test-model');
18
+ vi.mock('@amodalai/core', () => ({
19
+ AmodalConfig: vi.fn(function () {
20
+ this['initialize'] = mockInitialize;
21
+ this['shutdownAudit'] = mockShutdownAudit;
22
+ this['getGeminiClient'] = mockGetGeminiClient;
23
+ this['getMessageBus'] = mockGetMessageBus;
24
+ this['getModel'] = mockGetModel;
25
+ this['getConnections'] = vi.fn().mockReturnValue({});
26
+ this['getUpstreamConfig'] = vi.fn().mockReturnValue({});
27
+ this['initializeAuth'] = vi.fn().mockResolvedValue(undefined);
28
+ this['getModelConfig'] = vi.fn().mockReturnValue(undefined);
29
+ this['setModelConfig'] = vi.fn();
30
+ this['getBasePrompt'] = vi.fn().mockReturnValue(undefined);
31
+ this['getAgentName'] = vi.fn().mockReturnValue('Test Agent');
32
+ this['getAgentDescription'] = vi.fn().mockReturnValue(undefined);
33
+ this['getAgentContext'] = vi.fn().mockReturnValue(undefined);
34
+ this['getStores'] = vi.fn().mockReturnValue([]);
35
+ this['getStoreBackend'] = vi.fn().mockReturnValue(undefined);
36
+ this['setStoreBackend'] = vi.fn();
37
+ }),
38
+ Scheduler: vi.fn(function () {
39
+ this['schedule'] = vi.fn().mockResolvedValue([]);
40
+ }),
41
+ ROOT_SCHEDULER_ID: 'root',
42
+ ApprovalMode: { YOLO: 'yolo' },
43
+ PolicyDecision: { ALLOW: 'allow', ASK_USER: 'ask_user', DENY: 'deny' },
44
+ GeminiEventType: {
45
+ Content: 'content',
46
+ ToolCallRequest: 'tool_call_request',
47
+ Error: 'error',
48
+ AgentExecutionStopped: 'agent_execution_stopped',
49
+ },
50
+ ToolErrorType: {
51
+ STOP_EXECUTION: 'stop_execution',
52
+ },
53
+ PRESENT_TOOL_NAME: 'present',
54
+ ACTIVATE_SKILL_TOOL_NAME: 'activate_skill',
55
+ buildDefaultPrompt: vi.fn().mockReturnValue('Default system prompt'),
56
+ }));
57
+ const { createServer } = await import('./server.js');
58
+ // Helper to create an async generator from events
59
+ async function* makeStream(events) {
60
+ for (const event of events) {
61
+ yield event;
62
+ }
63
+ }
64
+ describe('createServer', () => {
65
+ let serverInstance;
66
+ beforeEach(() => {
67
+ vi.clearAllMocks();
68
+ mockInitialize.mockResolvedValue(undefined);
69
+ mockShutdownAudit.mockResolvedValue(undefined);
70
+ mockGetMessageBus.mockReturnValue({
71
+ on: vi.fn(),
72
+ removeListener: vi.fn(),
73
+ });
74
+ const mockChat = {
75
+ recordCompletedToolCalls: vi.fn(),
76
+ };
77
+ mockGetGeminiClient.mockReturnValue({
78
+ sendMessageStream: vi.fn().mockReturnValue(makeStream([{ type: 'content', value: 'Hello from server!' }])),
79
+ getCurrentSequenceModel: vi.fn().mockReturnValue('test-model'),
80
+ getChat: vi.fn().mockReturnValue(mockChat),
81
+ });
82
+ vi.spyOn(process.stderr, 'write').mockReturnValue(true);
83
+ serverInstance = createServer({
84
+ baseParams: {
85
+ sessionId: 'server-test',
86
+ model: 'test-model',
87
+ cwd: '/tmp',
88
+ targetDir: '/tmp',
89
+ debugMode: false,
90
+ },
91
+ config: {
92
+ port: 0, // Random port
93
+ host: '127.0.0.1',
94
+ sessionTtlMs: 30_000,
95
+ automations: [],
96
+ },
97
+ version: '1.0.0-test',
98
+ });
99
+ });
100
+ afterEach(async () => {
101
+ await serverInstance.stop();
102
+ });
103
+ it('responds to GET /health', async () => {
104
+ const res = await request(serverInstance.app).get('/health');
105
+ expect(res.status).toBe(200);
106
+ expect(res.body.status).toBe('ok');
107
+ });
108
+ it('responds to GET /version', async () => {
109
+ const res = await request(serverInstance.app).get('/version');
110
+ expect(res.status).toBe(200);
111
+ expect(res.body.version).toBe('1.0.0-test');
112
+ });
113
+ it('responds to POST /chat with valid message', async () => {
114
+ const res = await request(serverInstance.app)
115
+ .post('/chat')
116
+ .send({ message: 'hello' });
117
+ expect(res.status).toBe(200);
118
+ expect(res.body.session_id).toBeDefined();
119
+ expect(res.body.response).toBe('Hello from server!');
120
+ });
121
+ it('responds to POST /chat/stream with SSE', async () => {
122
+ const res = await request(serverInstance.app)
123
+ .post('/chat/stream')
124
+ .send({ message: 'hello' });
125
+ expect(res.headers['content-type']).toContain('text/event-stream');
126
+ expect(res.text).toContain('data: ');
127
+ // Parse the SSE events
128
+ const lines = res.text.split('\n\n').filter(Boolean);
129
+ const events = lines.map((line) => JSON.parse(line.replace('data: ', '')));
130
+ // Should have init, text_delta, done events
131
+ const types = events.map((e) => e['type']);
132
+ expect(types).toContain(SSEEventType.Init);
133
+ expect(types).toContain(SSEEventType.Done);
134
+ });
135
+ it('rejects invalid POST /chat request', async () => {
136
+ const res = await request(serverInstance.app)
137
+ .post('/chat')
138
+ .send({});
139
+ expect(res.status).toBe(400);
140
+ expect(res.body.error.code).toBe('VALIDATION_ERROR');
141
+ });
142
+ it('returns 404 for unknown webhook', async () => {
143
+ const res = await request(serverInstance.app)
144
+ .post('/webhooks/nonexistent')
145
+ .send({});
146
+ expect(res.status).toBe(404);
147
+ });
148
+ it('returns 404 for non-existent routes', async () => {
149
+ const res = await request(serverInstance.app).get('/nonexistent');
150
+ expect(res.status).toBe(404);
151
+ });
152
+ });
153
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/server.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { Content } from '@amodalai/core';
7
+ import type { SessionMessage } from './session-manager.js';
8
+ /**
9
+ * Convert stored SessionMessage[] to Gemini Content[] history.
10
+ *
11
+ * Text-only approach — tool call structures are NOT reconstructed.
12
+ * The assistant's text already summarizes tool results, which avoids
13
+ * fragile reconstruction of functionCall/functionResponse pairs.
14
+ *
15
+ * Guarantees:
16
+ * - Error messages and empty-text messages are skipped
17
+ * - Adjacent same-role entries are merged (can happen after filtering)
18
+ * - History starts with 'user' role
19
+ * - Roles alternate (user ↔ model) as required by the Gemini API
20
+ */
21
+ export declare function convertSessionMessagesToHistory(messages: SessionMessage[]): Content[];
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Convert stored SessionMessage[] to Gemini Content[] history.
8
+ *
9
+ * Text-only approach — tool call structures are NOT reconstructed.
10
+ * The assistant's text already summarizes tool results, which avoids
11
+ * fragile reconstruction of functionCall/functionResponse pairs.
12
+ *
13
+ * Guarantees:
14
+ * - Error messages and empty-text messages are skipped
15
+ * - Adjacent same-role entries are merged (can happen after filtering)
16
+ * - History starts with 'user' role
17
+ * - Roles alternate (user ↔ model) as required by the Gemini API
18
+ */
19
+ export function convertSessionMessagesToHistory(messages) {
20
+ const history = [];
21
+ for (const msg of messages) {
22
+ // Skip errors and empty text
23
+ if (msg.type === 'error')
24
+ continue;
25
+ if (!msg.text || msg.text.trim() === '')
26
+ continue;
27
+ const role = msg.type === 'user' ? 'user' : 'model';
28
+ // Merge adjacent same-role entries
29
+ const last = history[history.length - 1];
30
+ if (last && last.role === role) {
31
+ const existingText = last.parts?.[0]?.text ?? '';
32
+ last.parts = [{ text: `${existingText}\n\n${msg.text}` }];
33
+ }
34
+ else {
35
+ history.push({ role, parts: [{ text: msg.text }] });
36
+ }
37
+ }
38
+ // Ensure history starts with 'user' role
39
+ while (history.length > 0 && history[0]?.role !== 'user') {
40
+ history.shift();
41
+ }
42
+ // Ensure alternating roles by dropping consecutive duplicates
43
+ // (a second pass in case the start-trim exposed new adjacencies)
44
+ const alternating = [];
45
+ for (const entry of history) {
46
+ const prev = alternating[alternating.length - 1];
47
+ if (prev && prev.role === entry.role) {
48
+ // Merge into previous
49
+ const existingText = prev.parts?.[0]?.text ?? '';
50
+ const newText = entry.parts?.[0]?.text ?? '';
51
+ prev.parts = [{ text: `${existingText}\n\n${newText}` }];
52
+ }
53
+ else {
54
+ alternating.push(entry);
55
+ }
56
+ }
57
+ return alternating;
58
+ }
59
+ //# sourceMappingURL=history-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-converter.js","sourceRoot":"","sources":["../../../src/session/history-converter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAA0B;IAE1B,MAAM,OAAO,GAAc,EAAE,CAAC;IAE9B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,6BAA6B;QAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QACnC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAElD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAEpD,mCAAmC;QACnC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;YACjD,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,YAAY,OAAO,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACzD,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,8DAA8D;IAC9D,iEAAiE;IACjE,MAAM,WAAW,GAAc,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YACrC,sBAAsB;YACtB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,YAAY,OAAO,OAAO,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ export {};
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { describe, it, expect } from 'vitest';
7
+ import { convertSessionMessagesToHistory } from './history-converter.js';
8
+ function makeMsg(overrides) {
9
+ return {
10
+ id: `msg-${Math.random().toString(36).slice(2)}`,
11
+ timestamp: new Date().toISOString(),
12
+ ...overrides,
13
+ };
14
+ }
15
+ describe('convertSessionMessagesToHistory', () => {
16
+ it('converts user and assistant messages to Content[]', () => {
17
+ const messages = [
18
+ makeMsg({ type: 'user', text: 'Hello' }),
19
+ makeMsg({ type: 'assistant_text', text: 'Hi there!' }),
20
+ makeMsg({ type: 'user', text: 'How are you?' }),
21
+ makeMsg({ type: 'assistant_text', text: 'I am well.' }),
22
+ ];
23
+ const history = convertSessionMessagesToHistory(messages);
24
+ expect(history).toHaveLength(4);
25
+ expect(history[0]).toEqual({ role: 'user', parts: [{ text: 'Hello' }] });
26
+ expect(history[1]).toEqual({ role: 'model', parts: [{ text: 'Hi there!' }] });
27
+ expect(history[2]).toEqual({ role: 'user', parts: [{ text: 'How are you?' }] });
28
+ expect(history[3]).toEqual({ role: 'model', parts: [{ text: 'I am well.' }] });
29
+ });
30
+ it('skips error messages', () => {
31
+ const messages = [
32
+ makeMsg({ type: 'user', text: 'Hello' }),
33
+ makeMsg({ type: 'error', text: 'Something went wrong' }),
34
+ makeMsg({ type: 'assistant_text', text: 'Hi!' }),
35
+ ];
36
+ const history = convertSessionMessagesToHistory(messages);
37
+ expect(history).toHaveLength(2);
38
+ expect(history[0]?.role).toBe('user');
39
+ expect(history[1]?.role).toBe('model');
40
+ });
41
+ it('skips empty text messages', () => {
42
+ const messages = [
43
+ makeMsg({ type: 'user', text: 'Hello' }),
44
+ makeMsg({ type: 'assistant_text', text: '' }),
45
+ makeMsg({ type: 'assistant_text', text: ' ' }),
46
+ makeMsg({ type: 'assistant_text', text: 'Real response' }),
47
+ ];
48
+ const history = convertSessionMessagesToHistory(messages);
49
+ expect(history).toHaveLength(2);
50
+ expect(history[1]?.parts?.[0]?.text).toBe('Real response');
51
+ });
52
+ it('merges adjacent same-role entries', () => {
53
+ const messages = [
54
+ makeMsg({ type: 'user', text: 'Part 1' }),
55
+ makeMsg({ type: 'user', text: 'Part 2' }),
56
+ makeMsg({ type: 'assistant_text', text: 'Response' }),
57
+ ];
58
+ const history = convertSessionMessagesToHistory(messages);
59
+ expect(history).toHaveLength(2);
60
+ expect(history[0]?.parts?.[0]?.text).toBe('Part 1\n\nPart 2');
61
+ expect(history[1]?.parts?.[0]?.text).toBe('Response');
62
+ });
63
+ it('merges after filtering errors leaves adjacent same-role', () => {
64
+ const messages = [
65
+ makeMsg({ type: 'user', text: 'Hello' }),
66
+ makeMsg({ type: 'assistant_text', text: 'Part A' }),
67
+ makeMsg({ type: 'error', text: 'oops' }),
68
+ makeMsg({ type: 'assistant_text', text: 'Part B' }),
69
+ makeMsg({ type: 'user', text: 'Next' }),
70
+ ];
71
+ const history = convertSessionMessagesToHistory(messages);
72
+ expect(history).toHaveLength(3);
73
+ expect(history[0]?.role).toBe('user');
74
+ expect(history[1]?.role).toBe('model');
75
+ expect(history[1]?.parts?.[0]?.text).toBe('Part A\n\nPart B');
76
+ expect(history[2]?.role).toBe('user');
77
+ });
78
+ it('ensures history starts with user role', () => {
79
+ const messages = [
80
+ makeMsg({ type: 'assistant_text', text: 'I start first' }),
81
+ makeMsg({ type: 'user', text: 'Hello' }),
82
+ makeMsg({ type: 'assistant_text', text: 'Hi!' }),
83
+ ];
84
+ const history = convertSessionMessagesToHistory(messages);
85
+ expect(history).toHaveLength(2);
86
+ expect(history[0]?.role).toBe('user');
87
+ expect(history[0]?.parts?.[0]?.text).toBe('Hello');
88
+ });
89
+ it('returns empty array for empty input', () => {
90
+ expect(convertSessionMessagesToHistory([])).toEqual([]);
91
+ });
92
+ it('returns empty array when all messages are errors', () => {
93
+ const messages = [
94
+ makeMsg({ type: 'error', text: 'fail 1' }),
95
+ makeMsg({ type: 'error', text: 'fail 2' }),
96
+ ];
97
+ expect(convertSessionMessagesToHistory(messages)).toEqual([]);
98
+ });
99
+ it('handles single user message', () => {
100
+ const messages = [
101
+ makeMsg({ type: 'user', text: 'Solo' }),
102
+ ];
103
+ const history = convertSessionMessagesToHistory(messages);
104
+ expect(history).toHaveLength(1);
105
+ expect(history[0]).toEqual({ role: 'user', parts: [{ text: 'Solo' }] });
106
+ });
107
+ it('handles single assistant message (dropped — must start with user)', () => {
108
+ const messages = [
109
+ makeMsg({ type: 'assistant_text', text: 'Orphan response' }),
110
+ ];
111
+ const history = convertSessionMessagesToHistory(messages);
112
+ expect(history).toEqual([]);
113
+ });
114
+ it('ensures alternating roles after start-trim exposes adjacency', () => {
115
+ // After removing the leading model messages, two user messages become adjacent
116
+ const messages = [
117
+ makeMsg({ type: 'assistant_text', text: 'pre-1' }),
118
+ makeMsg({ type: 'assistant_text', text: 'pre-2' }),
119
+ makeMsg({ type: 'user', text: 'Hello' }),
120
+ makeMsg({ type: 'user', text: 'World' }),
121
+ makeMsg({ type: 'assistant_text', text: 'Response' }),
122
+ ];
123
+ const history = convertSessionMessagesToHistory(messages);
124
+ expect(history).toHaveLength(2);
125
+ expect(history[0]?.role).toBe('user');
126
+ expect(history[0]?.parts?.[0]?.text).toBe('Hello\n\nWorld');
127
+ expect(history[1]?.role).toBe('model');
128
+ });
129
+ });
130
+ //# sourceMappingURL=history-converter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-converter.test.js","sourceRoot":"","sources":["../../../src/session/history-converter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { AmodalConfig, type AmodalConfigParameters, Scheduler, type GeminiClient } from '@amodalai/core';
7
+ import type { AuthContext } from '../middleware/auth.js';
8
+ export interface PendingAskUser {
9
+ resolve: (answers: Record<string, string>) => void;
10
+ reject: (reason: Error) => void;
11
+ }
12
+ export interface SessionMessage {
13
+ type: 'user' | 'assistant_text' | 'error';
14
+ id: string;
15
+ text: string;
16
+ timestamp: string;
17
+ toolCalls?: Array<Record<string, unknown>>;
18
+ skillActivations?: string[];
19
+ widgets?: Array<Record<string, unknown>>;
20
+ contentBlocks?: Array<Record<string, unknown>>;
21
+ }
22
+ export interface ManagedSession {
23
+ id: string;
24
+ config: AmodalConfig;
25
+ geminiClient: GeminiClient;
26
+ scheduler: Scheduler;
27
+ createdAt: number;
28
+ lastAccessedAt: number;
29
+ /** The org this session belongs to */
30
+ orgId?: string;
31
+ /** Session type — controls which skills, tools, KB docs load */
32
+ sessionType?: string;
33
+ /** Pending ask_user responses awaiting user input */
34
+ pendingAskUser: Map<string, PendingAskUser>;
35
+ /** Accumulated messages for session history persistence */
36
+ accumulatedMessages: SessionMessage[];
37
+ /** Model used for this session (pinned at creation, survives hydration) */
38
+ model?: string;
39
+ /** Provider used for this session (pinned at creation, survives hydration) */
40
+ provider?: string;
41
+ /** Store backend for cleanup on session destroy */
42
+ storeBackend?: import('@amodalai/core').StoreBackend;
43
+ }
44
+ export interface SessionManagerOptions {
45
+ /** Base config parameters to clone for each session */
46
+ baseParams: AmodalConfigParameters;
47
+ /** Session TTL in milliseconds (default 30 minutes) */
48
+ ttlMs?: number;
49
+ /** Cleanup interval in milliseconds (default 5 minutes) */
50
+ cleanupIntervalMs?: number;
51
+ /** Platform API URL (for loading org-specific config per session) */
52
+ platformApiUrl?: string;
53
+ }
54
+ export declare class SessionManager {
55
+ private readonly sessions;
56
+ private readonly baseParams;
57
+ private readonly ttlMs;
58
+ private readonly platformApiUrl?;
59
+ private cleanupTimer;
60
+ /** Deduplicates concurrent hydration requests for the same conversation */
61
+ private readonly pendingHydrations;
62
+ constructor(options: SessionManagerOptions);
63
+ /**
64
+ * Create a new session with optional role override and auth context.
65
+ * When auth context is provided, the session is configured with
66
+ * the caller's API key and org/app/tenant context.
67
+ */
68
+ create(role?: string, auth?: AuthContext, sessionType?: string, pinnedModel?: {
69
+ provider: string;
70
+ model: string;
71
+ }, deployId?: string): Promise<ManagedSession>;
72
+ /**
73
+ * Get an existing session by ID, updating its last-accessed timestamp.
74
+ * Returns undefined if the session doesn't exist.
75
+ */
76
+ get(id: string): ManagedSession | undefined;
77
+ /**
78
+ * Hydrate a session from stored conversation history in the platform API.
79
+ *
80
+ * When a user sends a message to a session that expired from the in-memory
81
+ * cache, this method fetches the conversation from the DB, creates a fresh
82
+ * runtime session (new config, tools, KB, secrets), seeds its LLM history
83
+ * with the stored messages, and registers it under the original conversation ID.
84
+ *
85
+ * Returns null if hydration cannot proceed (no platform API, missing auth,
86
+ * fetch failure, or no stored messages).
87
+ */
88
+ hydrate(conversationId: string, role?: string, auth?: AuthContext, sessionType?: string): Promise<ManagedSession | null>;
89
+ private doHydrate;
90
+ /**
91
+ * Destroy a session, flushing its audit log.
92
+ */
93
+ destroy(id: string): Promise<void>;
94
+ /**
95
+ * Remove sessions that have been idle longer than the TTL.
96
+ */
97
+ cleanup(): Promise<number>;
98
+ /**
99
+ * Shutdown all sessions and stop the cleanup timer.
100
+ */
101
+ shutdown(): Promise<void>;
102
+ /**
103
+ * Wait for a user's response to an ask_user prompt.
104
+ * Resolves when the user submits answers via the HTTP endpoint.
105
+ * Rejects on timeout or if the signal is aborted.
106
+ */
107
+ waitForAskUserResponse(session: ManagedSession, askId: string, signal: AbortSignal): Promise<Record<string, string>>;
108
+ /**
109
+ * Resolve a pending ask_user with user-provided answers.
110
+ * Returns true if the ask_id was found and resolved, false otherwise.
111
+ */
112
+ resolveAskUser(session: ManagedSession, askId: string, answers: Record<string, string>): boolean;
113
+ /**
114
+ * Number of active sessions.
115
+ */
116
+ get size(): number;
117
+ }