@wingman-ai/gateway 0.5.3 → 0.6.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 (327) hide show
  1. package/dist/agent/backend/filtered-backend.cjs +130 -0
  2. package/dist/agent/backend/filtered-backend.d.ts +10 -0
  3. package/dist/agent/backend/filtered-backend.js +87 -0
  4. package/dist/agent/config/agentConfig.cjs +4 -0
  5. package/dist/agent/config/agentConfig.d.ts +12 -0
  6. package/dist/agent/config/agentConfig.js +4 -0
  7. package/dist/agent/config/toolRegistry.cjs +75 -1
  8. package/dist/agent/config/toolRegistry.d.ts +3 -0
  9. package/dist/agent/config/toolRegistry.js +75 -1
  10. package/dist/agent/middleware/additional-messages.cjs +4 -1
  11. package/dist/agent/middleware/additional-messages.js +4 -1
  12. package/dist/agent/middleware/large-tool-results.cjs +207 -0
  13. package/dist/agent/middleware/large-tool-results.d.ts +16 -0
  14. package/dist/agent/middleware/large-tool-results.js +173 -0
  15. package/dist/agent/tools/browser_control.cjs +9 -1231
  16. package/dist/agent/tools/browser_control.d.ts +126 -234
  17. package/dist/agent/tools/browser_control.js +7 -1226
  18. package/dist/agent/tools/browser_runtime.cjs +1358 -0
  19. package/dist/agent/tools/browser_runtime.d.ts +617 -0
  20. package/dist/agent/tools/browser_runtime.js +1288 -0
  21. package/dist/agent/tools/browser_session.cjs +189 -0
  22. package/dist/agent/tools/browser_session.d.ts +686 -0
  23. package/dist/agent/tools/browser_session.js +146 -0
  24. package/dist/agent/tools/browser_session_manager.cjs +213 -0
  25. package/dist/agent/tools/browser_session_manager.d.ts +70 -0
  26. package/dist/agent/tools/browser_session_manager.js +176 -0
  27. package/dist/cli/commands/init.cjs +80 -98
  28. package/dist/cli/commands/init.js +80 -98
  29. package/dist/cli/config/loader.cjs +0 -5
  30. package/dist/cli/config/loader.js +0 -5
  31. package/dist/cli/config/schema.cjs +3 -7
  32. package/dist/cli/config/schema.d.ts +6 -6
  33. package/dist/cli/config/schema.js +3 -7
  34. package/dist/cli/core/agentInvoker.cjs +88 -22
  35. package/dist/cli/core/agentInvoker.d.ts +10 -3
  36. package/dist/cli/core/agentInvoker.js +88 -25
  37. package/dist/cli/core/outputManager.cjs +7 -2
  38. package/dist/cli/core/outputManager.d.ts +2 -2
  39. package/dist/cli/core/outputManager.js +7 -2
  40. package/dist/cli/core/sessionManager.cjs +208 -41
  41. package/dist/cli/core/sessionManager.d.ts +20 -0
  42. package/dist/cli/core/sessionManager.js +208 -41
  43. package/dist/cli/index.cjs +16 -1
  44. package/dist/cli/index.js +16 -1
  45. package/dist/cli/services/updateCheck.cjs +212 -0
  46. package/dist/cli/services/updateCheck.d.ts +26 -0
  47. package/dist/cli/services/updateCheck.js +166 -0
  48. package/dist/cli/types.d.ts +2 -1
  49. package/dist/gateway/server.cjs +7 -0
  50. package/dist/gateway/server.js +7 -0
  51. package/dist/webui/assets/index-D3x3G75t.css +11 -0
  52. package/dist/webui/assets/index-UpMmcU1f.js +215 -0
  53. package/dist/webui/index.html +2 -2
  54. package/package.json +12 -12
  55. package/templates/agents/README.md +3 -1
  56. package/templates/agents/coding/agent.md +6 -13
  57. package/templates/agents/coding-v2/agent.md +6 -1
  58. package/templates/agents/game-dev/agent.md +9 -2
  59. package/templates/agents/game-dev/game-designer.md +4 -0
  60. package/templates/agents/game-dev/scene-engineer.md +4 -0
  61. package/templates/agents/main/agent.md +7 -2
  62. package/templates/agents/researcher/agent.md +14 -3
  63. package/templates/agents/stock-trader/agent.md +4 -0
  64. package/dist/agent/tests/agentConfig.test.cjs +0 -224
  65. package/dist/agent/tests/agentConfig.test.d.ts +0 -1
  66. package/dist/agent/tests/agentConfig.test.js +0 -218
  67. package/dist/agent/tests/agentLoader.test.cjs +0 -335
  68. package/dist/agent/tests/agentLoader.test.d.ts +0 -1
  69. package/dist/agent/tests/agentLoader.test.js +0 -329
  70. package/dist/agent/tests/backgroundTerminal.test.cjs +0 -70
  71. package/dist/agent/tests/backgroundTerminal.test.d.ts +0 -1
  72. package/dist/agent/tests/backgroundTerminal.test.js +0 -64
  73. package/dist/agent/tests/browserControlHelpers.test.cjs +0 -35
  74. package/dist/agent/tests/browserControlHelpers.test.d.ts +0 -1
  75. package/dist/agent/tests/browserControlHelpers.test.js +0 -29
  76. package/dist/agent/tests/browserControlTool.test.cjs +0 -2117
  77. package/dist/agent/tests/browserControlTool.test.d.ts +0 -1
  78. package/dist/agent/tests/browserControlTool.test.js +0 -2111
  79. package/dist/agent/tests/commandExecuteTool.test.cjs +0 -29
  80. package/dist/agent/tests/commandExecuteTool.test.d.ts +0 -1
  81. package/dist/agent/tests/commandExecuteTool.test.js +0 -23
  82. package/dist/agent/tests/internet_search.test.cjs +0 -107
  83. package/dist/agent/tests/internet_search.test.d.ts +0 -1
  84. package/dist/agent/tests/internet_search.test.js +0 -101
  85. package/dist/agent/tests/mcpClientManager.test.cjs +0 -290
  86. package/dist/agent/tests/mcpClientManager.test.d.ts +0 -1
  87. package/dist/agent/tests/mcpClientManager.test.js +0 -284
  88. package/dist/agent/tests/mcpResourceTools.test.cjs +0 -101
  89. package/dist/agent/tests/mcpResourceTools.test.d.ts +0 -1
  90. package/dist/agent/tests/mcpResourceTools.test.js +0 -95
  91. package/dist/agent/tests/modelFactory.test.cjs +0 -190
  92. package/dist/agent/tests/modelFactory.test.d.ts +0 -1
  93. package/dist/agent/tests/modelFactory.test.js +0 -184
  94. package/dist/agent/tests/terminalSessionManager.test.cjs +0 -121
  95. package/dist/agent/tests/terminalSessionManager.test.d.ts +0 -1
  96. package/dist/agent/tests/terminalSessionManager.test.js +0 -115
  97. package/dist/agent/tests/test-agent-loader.cjs +0 -33
  98. package/dist/agent/tests/test-agent-loader.d.ts +0 -1
  99. package/dist/agent/tests/test-agent-loader.js +0 -27
  100. package/dist/agent/tests/test-subagent-loading.cjs +0 -99
  101. package/dist/agent/tests/test-subagent-loading.d.ts +0 -1
  102. package/dist/agent/tests/test-subagent-loading.js +0 -93
  103. package/dist/agent/tests/toolRegistry.test.cjs +0 -147
  104. package/dist/agent/tests/toolRegistry.test.d.ts +0 -1
  105. package/dist/agent/tests/toolRegistry.test.js +0 -141
  106. package/dist/agent/tests/uiRegistryTools.test.cjs +0 -114
  107. package/dist/agent/tests/uiRegistryTools.test.d.ts +0 -1
  108. package/dist/agent/tests/uiRegistryTools.test.js +0 -105
  109. package/dist/agent/tests/xaiImageModel.test.cjs +0 -194
  110. package/dist/agent/tests/xaiImageModel.test.d.ts +0 -1
  111. package/dist/agent/tests/xaiImageModel.test.js +0 -188
  112. package/dist/tests/additionalMessageMiddleware.test.cjs +0 -216
  113. package/dist/tests/additionalMessageMiddleware.test.d.ts +0 -1
  114. package/dist/tests/additionalMessageMiddleware.test.js +0 -188
  115. package/dist/tests/agent-config-voice.test.cjs +0 -25
  116. package/dist/tests/agent-config-voice.test.d.ts +0 -1
  117. package/dist/tests/agent-config-voice.test.js +0 -19
  118. package/dist/tests/agentInvokerAttachments.test.cjs +0 -190
  119. package/dist/tests/agentInvokerAttachments.test.d.ts +0 -1
  120. package/dist/tests/agentInvokerAttachments.test.js +0 -184
  121. package/dist/tests/agentInvokerSummarization.test.cjs +0 -613
  122. package/dist/tests/agentInvokerSummarization.test.d.ts +0 -1
  123. package/dist/tests/agentInvokerSummarization.test.js +0 -607
  124. package/dist/tests/agentInvokerTokenUsage.test.cjs +0 -124
  125. package/dist/tests/agentInvokerTokenUsage.test.d.ts +0 -1
  126. package/dist/tests/agentInvokerTokenUsage.test.js +0 -118
  127. package/dist/tests/agentInvokerWorkdir.test.cjs +0 -150
  128. package/dist/tests/agentInvokerWorkdir.test.d.ts +0 -1
  129. package/dist/tests/agentInvokerWorkdir.test.js +0 -122
  130. package/dist/tests/agents-api.test.cjs +0 -324
  131. package/dist/tests/agents-api.test.d.ts +0 -1
  132. package/dist/tests/agents-api.test.js +0 -318
  133. package/dist/tests/attachments-utils.test.cjs +0 -46
  134. package/dist/tests/attachments-utils.test.d.ts +0 -1
  135. package/dist/tests/attachments-utils.test.js +0 -40
  136. package/dist/tests/browser-command.test.cjs +0 -264
  137. package/dist/tests/browser-command.test.d.ts +0 -1
  138. package/dist/tests/browser-command.test.js +0 -258
  139. package/dist/tests/browser-relay-server.test.cjs +0 -20
  140. package/dist/tests/browser-relay-server.test.d.ts +0 -1
  141. package/dist/tests/browser-relay-server.test.js +0 -14
  142. package/dist/tests/bunSqliteAdapter.test.cjs +0 -265
  143. package/dist/tests/bunSqliteAdapter.test.d.ts +0 -1
  144. package/dist/tests/bunSqliteAdapter.test.js +0 -259
  145. package/dist/tests/candleRange.test.cjs +0 -48
  146. package/dist/tests/candleRange.test.d.ts +0 -1
  147. package/dist/tests/candleRange.test.js +0 -42
  148. package/dist/tests/cli-config-loader.test.cjs +0 -532
  149. package/dist/tests/cli-config-loader.test.d.ts +0 -1
  150. package/dist/tests/cli-config-loader.test.js +0 -526
  151. package/dist/tests/cli-config-warnings.test.cjs +0 -94
  152. package/dist/tests/cli-config-warnings.test.d.ts +0 -1
  153. package/dist/tests/cli-config-warnings.test.js +0 -88
  154. package/dist/tests/cli-init.test.cjs +0 -225
  155. package/dist/tests/cli-init.test.d.ts +0 -1
  156. package/dist/tests/cli-init.test.js +0 -219
  157. package/dist/tests/cli-workspace-root.test.cjs +0 -114
  158. package/dist/tests/cli-workspace-root.test.d.ts +0 -1
  159. package/dist/tests/cli-workspace-root.test.js +0 -108
  160. package/dist/tests/codex-credentials-precedence.test.cjs +0 -94
  161. package/dist/tests/codex-credentials-precedence.test.d.ts +0 -1
  162. package/dist/tests/codex-credentials-precedence.test.js +0 -88
  163. package/dist/tests/codex-provider.test.cjs +0 -383
  164. package/dist/tests/codex-provider.test.d.ts +0 -1
  165. package/dist/tests/codex-provider.test.js +0 -377
  166. package/dist/tests/config-json-schema.test.cjs +0 -37
  167. package/dist/tests/config-json-schema.test.d.ts +0 -1
  168. package/dist/tests/config-json-schema.test.js +0 -31
  169. package/dist/tests/discord-adapter.test.cjs +0 -89
  170. package/dist/tests/discord-adapter.test.d.ts +0 -1
  171. package/dist/tests/discord-adapter.test.js +0 -83
  172. package/dist/tests/falRuntime.test.cjs +0 -78
  173. package/dist/tests/falRuntime.test.d.ts +0 -1
  174. package/dist/tests/falRuntime.test.js +0 -72
  175. package/dist/tests/falSummary.test.cjs +0 -51
  176. package/dist/tests/falSummary.test.d.ts +0 -1
  177. package/dist/tests/falSummary.test.js +0 -45
  178. package/dist/tests/fs-api.test.cjs +0 -138
  179. package/dist/tests/fs-api.test.d.ts +0 -1
  180. package/dist/tests/fs-api.test.js +0 -132
  181. package/dist/tests/gateway-command-workspace.test.cjs +0 -150
  182. package/dist/tests/gateway-command-workspace.test.d.ts +0 -1
  183. package/dist/tests/gateway-command-workspace.test.js +0 -144
  184. package/dist/tests/gateway-http-security.test.cjs +0 -318
  185. package/dist/tests/gateway-http-security.test.d.ts +0 -1
  186. package/dist/tests/gateway-http-security.test.js +0 -312
  187. package/dist/tests/gateway-node-mode.test.cjs +0 -174
  188. package/dist/tests/gateway-node-mode.test.d.ts +0 -1
  189. package/dist/tests/gateway-node-mode.test.js +0 -168
  190. package/dist/tests/gateway-origin-policy.test.cjs +0 -82
  191. package/dist/tests/gateway-origin-policy.test.d.ts +0 -1
  192. package/dist/tests/gateway-origin-policy.test.js +0 -76
  193. package/dist/tests/gateway-request-execution-overrides.test.cjs +0 -42
  194. package/dist/tests/gateway-request-execution-overrides.test.d.ts +0 -1
  195. package/dist/tests/gateway-request-execution-overrides.test.js +0 -36
  196. package/dist/tests/gateway.test.cjs +0 -700
  197. package/dist/tests/gateway.test.d.ts +0 -1
  198. package/dist/tests/gateway.test.js +0 -694
  199. package/dist/tests/hooks-matcher.test.cjs +0 -309
  200. package/dist/tests/hooks-matcher.test.d.ts +0 -1
  201. package/dist/tests/hooks-matcher.test.js +0 -303
  202. package/dist/tests/hooks-merger.test.cjs +0 -528
  203. package/dist/tests/hooks-merger.test.d.ts +0 -1
  204. package/dist/tests/hooks-merger.test.js +0 -522
  205. package/dist/tests/imagePersistence.test.cjs +0 -169
  206. package/dist/tests/imagePersistence.test.d.ts +0 -1
  207. package/dist/tests/imagePersistence.test.js +0 -163
  208. package/dist/tests/integration/agent-invocation.integration.test.cjs +0 -264
  209. package/dist/tests/integration/agent-invocation.integration.test.d.ts +0 -1
  210. package/dist/tests/integration/agent-invocation.integration.test.js +0 -258
  211. package/dist/tests/integration/finnhub-candles.integration.test.cjs +0 -98
  212. package/dist/tests/integration/finnhub-candles.integration.test.d.ts +0 -1
  213. package/dist/tests/integration/finnhub-candles.integration.test.js +0 -92
  214. package/dist/tests/integration/summarization-e2e.integration.test.cjs +0 -127
  215. package/dist/tests/integration/summarization-e2e.integration.test.d.ts +0 -1
  216. package/dist/tests/integration/summarization-e2e.integration.test.js +0 -121
  217. package/dist/tests/logger.test.cjs +0 -353
  218. package/dist/tests/logger.test.d.ts +0 -1
  219. package/dist/tests/logger.test.js +0 -347
  220. package/dist/tests/mediaCompatibilityMiddleware.test.cjs +0 -106
  221. package/dist/tests/mediaCompatibilityMiddleware.test.d.ts +0 -1
  222. package/dist/tests/mediaCompatibilityMiddleware.test.js +0 -100
  223. package/dist/tests/node-tools.test.cjs +0 -77
  224. package/dist/tests/node-tools.test.d.ts +0 -1
  225. package/dist/tests/node-tools.test.js +0 -71
  226. package/dist/tests/nodes-api.test.cjs +0 -86
  227. package/dist/tests/nodes-api.test.d.ts +0 -1
  228. package/dist/tests/nodes-api.test.js +0 -80
  229. package/dist/tests/outputManagerContextSummarized.test.cjs +0 -43
  230. package/dist/tests/outputManagerContextSummarized.test.d.ts +0 -1
  231. package/dist/tests/outputManagerContextSummarized.test.js +0 -37
  232. package/dist/tests/provider-command-codex.test.cjs +0 -57
  233. package/dist/tests/provider-command-codex.test.d.ts +0 -1
  234. package/dist/tests/provider-command-codex.test.js +0 -51
  235. package/dist/tests/routines-api.test.cjs +0 -107
  236. package/dist/tests/routines-api.test.d.ts +0 -1
  237. package/dist/tests/routines-api.test.js +0 -101
  238. package/dist/tests/run-terminal-bench-official-script.test.cjs +0 -61
  239. package/dist/tests/run-terminal-bench-official-script.test.d.ts +0 -1
  240. package/dist/tests/run-terminal-bench-official-script.test.js +0 -55
  241. package/dist/tests/sessionManager-uionly.test.cjs +0 -50
  242. package/dist/tests/sessionManager-uionly.test.d.ts +0 -1
  243. package/dist/tests/sessionManager-uionly.test.js +0 -44
  244. package/dist/tests/sessionMessageAttachments.test.cjs +0 -197
  245. package/dist/tests/sessionMessageAttachments.test.d.ts +0 -1
  246. package/dist/tests/sessionMessageAttachments.test.js +0 -191
  247. package/dist/tests/sessionMessageRole.test.cjs +0 -44
  248. package/dist/tests/sessionMessageRole.test.d.ts +0 -1
  249. package/dist/tests/sessionMessageRole.test.js +0 -38
  250. package/dist/tests/sessionStateMessages.test.cjs +0 -236
  251. package/dist/tests/sessionStateMessages.test.d.ts +0 -1
  252. package/dist/tests/sessionStateMessages.test.js +0 -230
  253. package/dist/tests/sessions-api.test.cjs +0 -250
  254. package/dist/tests/sessions-api.test.d.ts +0 -1
  255. package/dist/tests/sessions-api.test.js +0 -244
  256. package/dist/tests/skill-activation.test.cjs +0 -86
  257. package/dist/tests/skill-activation.test.d.ts +0 -1
  258. package/dist/tests/skill-activation.test.js +0 -80
  259. package/dist/tests/skill-metadata.test.cjs +0 -119
  260. package/dist/tests/skill-metadata.test.d.ts +0 -1
  261. package/dist/tests/skill-metadata.test.js +0 -113
  262. package/dist/tests/skill-repository.test.cjs +0 -469
  263. package/dist/tests/skill-repository.test.d.ts +0 -1
  264. package/dist/tests/skill-repository.test.js +0 -463
  265. package/dist/tests/skill-security-scanner.test.cjs +0 -126
  266. package/dist/tests/skill-security-scanner.test.d.ts +0 -1
  267. package/dist/tests/skill-security-scanner.test.js +0 -120
  268. package/dist/tests/sms-api.test.cjs +0 -183
  269. package/dist/tests/sms-api.test.d.ts +0 -1
  270. package/dist/tests/sms-api.test.js +0 -177
  271. package/dist/tests/sms-commands.test.cjs +0 -90
  272. package/dist/tests/sms-commands.test.d.ts +0 -1
  273. package/dist/tests/sms-commands.test.js +0 -84
  274. package/dist/tests/sms-policy-store.test.cjs +0 -69
  275. package/dist/tests/sms-policy-store.test.d.ts +0 -1
  276. package/dist/tests/sms-policy-store.test.js +0 -63
  277. package/dist/tests/teams-adapter.test.cjs +0 -58
  278. package/dist/tests/teams-adapter.test.d.ts +0 -1
  279. package/dist/tests/teams-adapter.test.js +0 -52
  280. package/dist/tests/technicalIndicators.test.cjs +0 -82
  281. package/dist/tests/technicalIndicators.test.d.ts +0 -1
  282. package/dist/tests/technicalIndicators.test.js +0 -76
  283. package/dist/tests/terminal-bench-adapters-helpers.test.cjs +0 -64
  284. package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +0 -1
  285. package/dist/tests/terminal-bench-adapters-helpers.test.js +0 -58
  286. package/dist/tests/terminal-bench-cleanup.test.cjs +0 -93
  287. package/dist/tests/terminal-bench-cleanup.test.d.ts +0 -1
  288. package/dist/tests/terminal-bench-cleanup.test.js +0 -87
  289. package/dist/tests/terminal-bench-config.test.cjs +0 -62
  290. package/dist/tests/terminal-bench-config.test.d.ts +0 -1
  291. package/dist/tests/terminal-bench-config.test.js +0 -56
  292. package/dist/tests/terminal-bench-official.test.cjs +0 -194
  293. package/dist/tests/terminal-bench-official.test.d.ts +0 -1
  294. package/dist/tests/terminal-bench-official.test.js +0 -188
  295. package/dist/tests/terminal-bench-runner.test.cjs +0 -82
  296. package/dist/tests/terminal-bench-runner.test.d.ts +0 -1
  297. package/dist/tests/terminal-bench-runner.test.js +0 -76
  298. package/dist/tests/terminal-bench-scoring.test.cjs +0 -128
  299. package/dist/tests/terminal-bench-scoring.test.d.ts +0 -1
  300. package/dist/tests/terminal-bench-scoring.test.js +0 -122
  301. package/dist/tests/terminalProbe.test.cjs +0 -45
  302. package/dist/tests/terminalProbe.test.d.ts +0 -1
  303. package/dist/tests/terminalProbe.test.js +0 -39
  304. package/dist/tests/terminalProbeAuth.test.cjs +0 -85
  305. package/dist/tests/terminalProbeAuth.test.d.ts +0 -1
  306. package/dist/tests/terminalProbeAuth.test.js +0 -79
  307. package/dist/tests/toolDisplayHelpers.test.cjs +0 -46
  308. package/dist/tests/toolDisplayHelpers.test.d.ts +0 -1
  309. package/dist/tests/toolDisplayHelpers.test.js +0 -40
  310. package/dist/tests/uv.test.cjs +0 -47
  311. package/dist/tests/uv.test.d.ts +0 -1
  312. package/dist/tests/uv.test.js +0 -41
  313. package/dist/tests/voice-config.test.cjs +0 -35
  314. package/dist/tests/voice-config.test.d.ts +0 -1
  315. package/dist/tests/voice-config.test.js +0 -29
  316. package/dist/tests/websocket-transport.test.cjs +0 -31
  317. package/dist/tests/websocket-transport.test.d.ts +0 -1
  318. package/dist/tests/websocket-transport.test.js +0 -25
  319. package/dist/tests/yahooCandles.test.cjs +0 -111
  320. package/dist/tests/yahooCandles.test.d.ts +0 -1
  321. package/dist/tests/yahooCandles.test.js +0 -105
  322. package/dist/tools/finance/optionsAnalytics.test.cjs +0 -128
  323. package/dist/tools/finance/optionsAnalytics.test.d.ts +0 -1
  324. package/dist/tools/finance/optionsAnalytics.test.js +0 -122
  325. package/dist/webui/assets/index-BMf95nv5.js +0 -215
  326. package/dist/webui/assets/index-DhJQ8Mbn.css +0 -11
  327. package/dist/webui/assets/wingman_logo-Cogyt3qm.webp +0 -0
@@ -1,694 +0,0 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
5
- import { GatewayClient, GatewayServer } from "../gateway/index.js";
6
- function _define_property(obj, key, value) {
7
- if (key in obj) Object.defineProperty(obj, key, {
8
- value: value,
9
- enumerable: true,
10
- configurable: true,
11
- writable: true
12
- });
13
- else obj[key] = value;
14
- return obj;
15
- }
16
- const isBun = void 0 !== globalThis.Bun;
17
- const describeIfBun = isBun ? describe : describe.skip;
18
- const invokerConstructOptions = [];
19
- vi.mock("@/cli/core/agentInvoker.js", ()=>({
20
- AgentInvoker: class {
21
- async invokeAgent(_agentId, content, _sessionId, _attachments, options) {
22
- if ("throw-no-event" === content) throw new Error("Synthetic invocation failure");
23
- if ("stream-model-failure-no-error" === content) {
24
- this.outputManager?.emitAgentStream?.({
25
- event: "on_chain_end",
26
- run_id: "model-failure-run-1",
27
- name: "ChannelWrite<branch:to:todoListMiddleware.after_model>",
28
- data: {
29
- output: [
30
- {
31
- lg_name: "Command",
32
- update: {
33
- messages: [
34
- {
35
- type: "constructor",
36
- id: [
37
- "langchain_core",
38
- "messages",
39
- "AIMessage"
40
- ],
41
- kwargs: {
42
- id: "model-failure-msg-1",
43
- content: "Model call failed after 3 attempts with Error: xAI image generation failed: Prompt len is larger than the maximum allowed length which is 8000"
44
- }
45
- }
46
- ]
47
- }
48
- }
49
- ],
50
- input: {}
51
- }
52
- });
53
- return {
54
- streaming: true
55
- };
56
- }
57
- const signal = options?.signal;
58
- await new Promise((resolve)=>{
59
- const timer = setTimeout(resolve, 75);
60
- if (signal) {
61
- const onAbort = ()=>{
62
- clearTimeout(timer);
63
- resolve();
64
- };
65
- if (signal.aborted) return void onAbort();
66
- signal.addEventListener("abort", onAbort, {
67
- once: true
68
- });
69
- }
70
- });
71
- if (signal?.aborted) {
72
- this.outputManager?.emitAgentError?.("Request cancelled");
73
- return {
74
- cancelled: true
75
- };
76
- }
77
- if ("return-no-event" === content) return {
78
- streaming: true
79
- };
80
- this.outputManager?.emitAgentComplete?.({
81
- streaming: true
82
- });
83
- return {
84
- streaming: true
85
- };
86
- }
87
- constructor(options){
88
- _define_property(this, "outputManager", void 0);
89
- this.outputManager = options?.outputManager;
90
- invokerConstructOptions.push(options || {});
91
- }
92
- }
93
- }));
94
- describeIfBun("Gateway", ()=>{
95
- let server;
96
- let port = 0;
97
- let testWorkspace;
98
- beforeAll(async ()=>{
99
- invokerConstructOptions.length = 0;
100
- testWorkspace = mkdtempSync(join(tmpdir(), "wingman-gateway-test-"));
101
- const instance = new GatewayServer({
102
- port: 0,
103
- host: "localhost",
104
- requireAuth: false,
105
- auth: {
106
- mode: "none"
107
- },
108
- logLevel: "silent",
109
- workspace: testWorkspace,
110
- configDir: ".wingman-test-config",
111
- stateDir: ".wingman-test-state"
112
- });
113
- await instance.start();
114
- server = instance;
115
- port = server.getPort();
116
- if (!port) throw new Error("Unable to determine gateway server port");
117
- await new Promise((resolve)=>setTimeout(resolve, 500));
118
- });
119
- afterAll(async ()=>{
120
- if (server) await server.stop();
121
- if (testWorkspace) rmSync(testWorkspace, {
122
- recursive: true,
123
- force: true
124
- });
125
- });
126
- const connectClient = (instanceId, clientType = "test")=>new Promise((resolve, reject)=>{
127
- const ws = new WebSocket(`ws://localhost:${port}/ws`);
128
- const connectId = `connect-${instanceId}-${Date.now()}`;
129
- const timeout = setTimeout(()=>reject(new Error("Connect timeout")), 5000);
130
- ws.addEventListener("open", ()=>{
131
- const message = {
132
- type: "connect",
133
- id: connectId,
134
- client: {
135
- instanceId,
136
- clientType
137
- },
138
- timestamp: Date.now()
139
- };
140
- ws.send(JSON.stringify(message));
141
- });
142
- ws.addEventListener("message", (event)=>{
143
- const msg = JSON.parse(event.data);
144
- if ("res" === msg.type && msg.id === connectId && msg.ok) {
145
- clearTimeout(timeout);
146
- resolve(ws);
147
- }
148
- });
149
- ws.addEventListener("error", ()=>{
150
- clearTimeout(timeout);
151
- reject(new Error("WebSocket error"));
152
- });
153
- });
154
- const waitForMessage = (ws, predicate, timeoutMs = 5000)=>new Promise((resolve, reject)=>{
155
- const timeout = setTimeout(()=>reject(new Error("Message timeout")), timeoutMs);
156
- const handler = (event)=>{
157
- let msg;
158
- try {
159
- msg = JSON.parse(event.data);
160
- } catch {
161
- return;
162
- }
163
- if (!predicate(msg)) return;
164
- clearTimeout(timeout);
165
- ws.removeEventListener("message", handler);
166
- resolve(msg);
167
- };
168
- ws.addEventListener("message", handler);
169
- });
170
- const collectMessages = (ws, predicate, durationMs = 600)=>new Promise((resolve)=>{
171
- const matches = [];
172
- const handler = (event)=>{
173
- let msg;
174
- try {
175
- msg = JSON.parse(event.data);
176
- } catch {
177
- return;
178
- }
179
- if (!predicate(msg)) return;
180
- matches.push(msg);
181
- };
182
- ws.addEventListener("message", handler);
183
- setTimeout(()=>{
184
- ws.removeEventListener("message", handler);
185
- resolve(matches);
186
- }, durationMs);
187
- });
188
- it("should start the gateway server", async ()=>{
189
- const response = await fetch(`http://localhost:${port}/health`);
190
- expect(response.ok).toBe(true);
191
- const health = await response.json();
192
- expect(health.status).toBe("healthy");
193
- });
194
- it("should connect a client", async ()=>new Promise((resolve, reject)=>{
195
- const client = new GatewayClient(`ws://localhost:${port}/ws`, "test-client", {
196
- events: {
197
- connected: ()=>{
198
- client.disconnect();
199
- resolve();
200
- },
201
- error: (error)=>{
202
- reject(new Error(error.message));
203
- }
204
- }
205
- });
206
- client.connect().catch(reject);
207
- setTimeout(()=>reject(new Error("Connection timeout")), 5000);
208
- }));
209
- it("should register a client and receive node ID", async ()=>new Promise((resolve, reject)=>{
210
- const client = new GatewayClient(`ws://localhost:${port}/ws`, "test-client-2", {
211
- events: {
212
- registered: (nodeId, name)=>{
213
- expect(nodeId).toBeTruthy();
214
- expect(name).toBe("test-client-2");
215
- client.disconnect();
216
- resolve();
217
- },
218
- error: (error)=>{
219
- reject(new Error(error.message));
220
- }
221
- }
222
- });
223
- client.connect().catch(reject);
224
- setTimeout(()=>reject(new Error("Registration timeout")), 5000);
225
- }));
226
- it("should join a broadcast group", async ()=>new Promise((resolve, reject)=>{
227
- const client = new GatewayClient(`ws://localhost:${port}/ws`, "test-client-3", {
228
- events: {
229
- registered: async ()=>{
230
- await client.joinGroup("test-group");
231
- },
232
- joinedGroup: (groupId, groupName)=>{
233
- expect(groupName).toBe("test-group");
234
- client.disconnect();
235
- resolve();
236
- },
237
- error: (error)=>{
238
- reject(new Error(error.message));
239
- }
240
- }
241
- });
242
- client.connect().catch(reject);
243
- setTimeout(()=>reject(new Error("Join group timeout")), 5000);
244
- }));
245
- it("should broadcast messages to group members", async ()=>new Promise((resolve, reject)=>{
246
- let client1NodeId = null;
247
- let broadcastGroupId = null;
248
- const client1 = new GatewayClient(`ws://localhost:${port}/ws`, "broadcaster", {
249
- events: {
250
- registered: async (nodeId)=>{
251
- client1NodeId = nodeId;
252
- await client1.joinGroup("broadcast-test");
253
- },
254
- joinedGroup: (groupId)=>{
255
- broadcastGroupId = groupId;
256
- client2.connect().catch(reject);
257
- }
258
- }
259
- });
260
- const client2 = new GatewayClient(`ws://localhost:${port}/ws`, "receiver", {
261
- events: {
262
- registered: async ()=>{
263
- await client2.joinGroup("broadcast-test");
264
- },
265
- joinedGroup: ()=>{
266
- client1.broadcast(broadcastGroupId || "broadcast-test", {
267
- message: "Hello from client 1"
268
- });
269
- },
270
- broadcast: (message, fromNodeId)=>{
271
- expect(fromNodeId).toBe(client1NodeId);
272
- expect(message.message).toBe("Hello from client 1");
273
- client1.disconnect();
274
- client2.disconnect();
275
- resolve();
276
- },
277
- error: (error)=>{
278
- reject(new Error(error.message));
279
- }
280
- }
281
- });
282
- client1.connect().catch(reject);
283
- setTimeout(()=>reject(new Error("Broadcast test timeout")), 10000);
284
- }));
285
- it("should handle ping/pong", async ()=>new Promise((resolve, reject)=>{
286
- const client = new GatewayClient(`ws://localhost:${port}/ws`, "ping-test", {
287
- events: {
288
- registered: ()=>{
289
- client.ping();
290
- },
291
- pong: ()=>{
292
- client.disconnect();
293
- resolve();
294
- },
295
- error: (error)=>{
296
- reject(new Error(error.message));
297
- }
298
- }
299
- });
300
- client.connect().catch(reject);
301
- setTimeout(()=>reject(new Error("Ping/pong timeout")), 5000);
302
- }));
303
- it("should stream agent events to session subscribers", async ()=>{
304
- const subscriber = await connectClient("session-subscriber");
305
- const sessionId = "session-test";
306
- subscriber.send(JSON.stringify({
307
- type: "session_subscribe",
308
- payload: {
309
- sessionId
310
- },
311
- timestamp: Date.now()
312
- }));
313
- await waitForMessage(subscriber, (msg)=>"ack" === msg.type && msg.payload?.action === "session_subscribe" && msg.payload?.sessionId === sessionId);
314
- const eventPromise = waitForMessage(subscriber, (msg)=>"event:agent" === msg.type && "req-session" === msg.id);
315
- const sent = server.broadcastSessionEvent(sessionId, {
316
- type: "event:agent",
317
- id: "req-session",
318
- payload: {
319
- type: "agent-stream",
320
- sessionId,
321
- agentId: "main",
322
- chunk: {
323
- content: "hello"
324
- }
325
- },
326
- timestamp: Date.now()
327
- });
328
- expect(sent).toBe(1);
329
- const eventMsg = await eventPromise;
330
- expect(eventMsg.payload?.sessionId).toBe(sessionId);
331
- subscriber.close();
332
- });
333
- it("should broadcast user messages to session subscribers", async ()=>{
334
- const subscriber = await connectClient("session-input-subscriber");
335
- const requester = await connectClient("session-input-requester");
336
- const sessionId = "session-input-test";
337
- subscriber.send(JSON.stringify({
338
- type: "session_subscribe",
339
- payload: {
340
- sessionId
341
- },
342
- timestamp: Date.now()
343
- }));
344
- await waitForMessage(subscriber, (msg)=>"ack" === msg.type && msg.payload?.action === "session_subscribe" && msg.payload?.sessionId === sessionId);
345
- const eventPromise = waitForMessage(subscriber, (msg)=>"event:agent" === msg.type && msg.payload?.type === "session-message" && msg.payload?.role === "user");
346
- requester.send(JSON.stringify({
347
- type: "req:agent",
348
- id: "req-session-input",
349
- payload: {
350
- agentId: "main",
351
- sessionKey: sessionId,
352
- content: "Hello from test"
353
- },
354
- timestamp: Date.now()
355
- }));
356
- const eventMsg = await eventPromise;
357
- expect(eventMsg.payload?.content).toBe("Hello from test");
358
- expect(eventMsg.payload?.sessionId).toBe(sessionId);
359
- expect(eventMsg.payload?.agentId).toBe("main");
360
- subscriber.close();
361
- requester.close();
362
- });
363
- it("should broadcast user messages to webui clients without session subscribe", async ()=>{
364
- const webuiClient = await connectClient("session-webui-listener", "webui");
365
- const requester = await connectClient("session-webui-requester");
366
- const sessionId = "session-webui-test";
367
- const eventPromise = waitForMessage(webuiClient, (msg)=>"event:agent" === msg.type && msg.payload?.type === "session-message" && msg.payload?.role === "user" && msg.payload?.sessionId === sessionId);
368
- requester.send(JSON.stringify({
369
- type: "req:agent",
370
- id: "req-session-webui",
371
- payload: {
372
- agentId: "main",
373
- sessionKey: sessionId,
374
- content: "Hello webui"
375
- },
376
- timestamp: Date.now()
377
- }));
378
- const eventMsg = await eventPromise;
379
- expect(eventMsg.payload?.content).toBe("Hello webui");
380
- expect(eventMsg.payload?.agentId).toBe("main");
381
- webuiClient.close();
382
- requester.close();
383
- });
384
- it("should broadcast user messages to desktop clients without session subscribe", async ()=>{
385
- const desktopClient = await connectClient("session-desktop-listener", "desktop");
386
- const requester = await connectClient("session-desktop-requester");
387
- const sessionId = "session-desktop-test";
388
- const eventPromise = waitForMessage(desktopClient, (msg)=>"event:agent" === msg.type && msg.payload?.type === "session-message" && msg.payload?.role === "user" && msg.payload?.sessionId === sessionId);
389
- requester.send(JSON.stringify({
390
- type: "req:agent",
391
- id: "req-session-desktop",
392
- payload: {
393
- agentId: "main",
394
- sessionKey: sessionId,
395
- content: "Hello desktop"
396
- },
397
- timestamp: Date.now()
398
- }));
399
- const eventMsg = await eventPromise;
400
- expect(eventMsg.payload?.content).toBe("Hello desktop");
401
- expect(eventMsg.payload?.agentId).toBe("main");
402
- desktopClient.close();
403
- requester.close();
404
- });
405
- it("should emit agent-error to requester when invocation throws without emitting", async ()=>{
406
- const requester = await connectClient("session-error-requester");
407
- const requestId = "req-invocation-error";
408
- const sessionId = "session-error-test";
409
- requester.send(JSON.stringify({
410
- type: "req:agent",
411
- id: requestId,
412
- payload: {
413
- agentId: "main",
414
- sessionKey: sessionId,
415
- content: "throw-no-event"
416
- },
417
- timestamp: Date.now()
418
- }));
419
- const errorMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error");
420
- expect(errorMsg.payload?.error).toContain("Synthetic invocation failure");
421
- expect(errorMsg.payload?.sessionId).toBe(sessionId);
422
- expect(errorMsg.payload?.agentId).toBe("main");
423
- requester.close();
424
- });
425
- it("should emit agent-complete when invocation returns without terminal output events", async ()=>{
426
- const requester = await connectClient("session-complete-fallback-requester");
427
- const requestId = "req-complete-fallback";
428
- const sessionId = "session-complete-fallback";
429
- requester.send(JSON.stringify({
430
- type: "req:agent",
431
- id: requestId,
432
- payload: {
433
- agentId: "main",
434
- sessionKey: sessionId,
435
- content: "return-no-event"
436
- },
437
- timestamp: Date.now()
438
- }));
439
- const completeMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete");
440
- expect(completeMsg.payload?.sessionId).toBe(sessionId);
441
- expect(completeMsg.payload?.agentId).toBe("main");
442
- expect(completeMsg.payload?.result).toEqual({
443
- streaming: true
444
- });
445
- requester.close();
446
- });
447
- it("does not auto-convert streamed model failure text into agent-error", async ()=>{
448
- const requester = await connectClient("session-streamed-failure-requester");
449
- const requestId = "req-streamed-failure-no-error";
450
- const sessionId = "session-streamed-failure-no-error";
451
- requester.send(JSON.stringify({
452
- type: "req:agent",
453
- id: requestId,
454
- payload: {
455
- agentId: "main",
456
- sessionKey: sessionId,
457
- content: "stream-model-failure-no-error"
458
- },
459
- timestamp: Date.now()
460
- }));
461
- const streamMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-stream" && msg.payload?.chunk?.event === "on_chain_end", 10000);
462
- expect(JSON.stringify(streamMsg.payload?.chunk?.data || {})).toContain("Model call failed after 3 attempts");
463
- const completeMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete", 10000);
464
- expect(completeMsg.payload?.sessionId).toBe(sessionId);
465
- expect(completeMsg.payload?.agentId).toBe("main");
466
- const terminalErrorEvents = await collectMessages(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error", 400);
467
- expect(terminalErrorEvents).toHaveLength(0);
468
- requester.close();
469
- });
470
- it("should emit a single agent-complete terminal event per request", async ()=>{
471
- const requester = await connectClient("session-single-complete-requester");
472
- const requestId = "req-single-complete";
473
- const sessionId = "session-single-complete";
474
- const completionEventsPromise = collectMessages(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete", 1000);
475
- requester.send(JSON.stringify({
476
- type: "req:agent",
477
- id: requestId,
478
- payload: {
479
- agentId: "main",
480
- sessionKey: sessionId,
481
- content: "single-complete"
482
- },
483
- timestamp: Date.now()
484
- }));
485
- const completionEvents = await completionEventsPromise;
486
- expect(completionEvents).toHaveLength(1);
487
- expect(completionEvents[0].payload?.sessionId).toBe(sessionId);
488
- expect(completionEvents[0].payload?.agentId).toBe("main");
489
- requester.close();
490
- });
491
- it("uses request execution workspace/configDir overrides for agent invocation", async ()=>{
492
- const requester = await connectClient("session-workspace-override-requester");
493
- const requestId = "req-workspace-override";
494
- const sessionId = "session-workspace-override";
495
- const workspaceOverride = "/tmp/wingman-override-workspace";
496
- const configDirOverride = ".wingman-custom";
497
- const beforeCount = invokerConstructOptions.length;
498
- requester.send(JSON.stringify({
499
- type: "req:agent",
500
- id: requestId,
501
- payload: {
502
- agentId: "main",
503
- sessionKey: sessionId,
504
- content: "workspace override test",
505
- execution: {
506
- workspace: workspaceOverride,
507
- configDir: configDirOverride
508
- }
509
- },
510
- timestamp: Date.now()
511
- }));
512
- await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete", 10000);
513
- expect(invokerConstructOptions.length).toBeGreaterThan(beforeCount);
514
- const lastOptions = invokerConstructOptions.at(-1) || {};
515
- expect(lastOptions.workspace).toBe(workspaceOverride);
516
- expect(lastOptions.configDir).toBe(configDirOverride);
517
- expect(typeof lastOptions.nodeInvoker).toBe("function");
518
- requester.close();
519
- });
520
- it("should cancel an in-flight agent request", async ()=>{
521
- const requester = await connectClient("session-cancel-requester");
522
- const requestId = "req-cancel-test";
523
- requester.send(JSON.stringify({
524
- type: "req:agent",
525
- id: requestId,
526
- payload: {
527
- agentId: "main",
528
- sessionKey: "session-cancel-test",
529
- content: "cancel me"
530
- },
531
- timestamp: Date.now()
532
- }));
533
- requester.send(JSON.stringify({
534
- type: "req:agent:cancel",
535
- id: "cancel-req-cancel-test",
536
- payload: {
537
- requestId
538
- },
539
- timestamp: Date.now()
540
- }));
541
- const ack = await waitForMessage(requester, (msg)=>"ack" === msg.type && msg.payload?.action === "req:agent:cancel" && msg.payload?.requestId === requestId);
542
- expect([
543
- "cancelled",
544
- "not_found"
545
- ]).toContain(ack.payload?.status);
546
- requester.close();
547
- });
548
- it("should queue and dequeue requests for the same session", async ()=>{
549
- const requester = await connectClient("session-queue-requester");
550
- const sessionId = `session-queue-${Date.now()}`;
551
- const firstRequestId = `req-queue-first-${Date.now()}`;
552
- const secondRequestId = `req-queue-second-${Date.now()}`;
553
- const firstCompletePromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === firstRequestId && msg.payload?.type === "agent-complete", 10000);
554
- const queuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "queued", 10000);
555
- const queuedEventPromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === secondRequestId && msg.payload?.type === "request-queued", 10000);
556
- const dequeuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "dequeued", 10000);
557
- const secondCompletePromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === secondRequestId && msg.payload?.type === "agent-complete", 10000);
558
- requester.send(JSON.stringify({
559
- type: "req:agent",
560
- id: firstRequestId,
561
- payload: {
562
- agentId: "main",
563
- sessionKey: sessionId,
564
- content: "First queued request"
565
- },
566
- timestamp: Date.now()
567
- }));
568
- requester.send(JSON.stringify({
569
- type: "req:agent",
570
- id: secondRequestId,
571
- payload: {
572
- agentId: "main",
573
- sessionKey: sessionId,
574
- content: "Second queued request"
575
- },
576
- timestamp: Date.now()
577
- }));
578
- const queuedAck = await queuedAckPromise;
579
- expect(queuedAck.payload?.position).toBe(1);
580
- const queuedEvent = await queuedEventPromise;
581
- expect(queuedEvent.payload?.position).toBe(1);
582
- expect(queuedEvent.payload?.sessionId).toBe(sessionId);
583
- await firstCompletePromise;
584
- const dequeuedAck = await dequeuedAckPromise;
585
- expect(dequeuedAck.payload?.remaining).toBe(0);
586
- await secondCompletePromise;
587
- requester.close();
588
- });
589
- it("should cancel a queued request", async ()=>{
590
- const requester = await connectClient("session-cancel-queued-requester");
591
- const sessionId = `session-cancel-queued-${Date.now()}`;
592
- const firstRequestId = `req-cancel-queued-first-${Date.now()}`;
593
- const secondRequestId = `req-cancel-queued-second-${Date.now()}`;
594
- const queuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "queued", 10000);
595
- requester.send(JSON.stringify({
596
- type: "req:agent",
597
- id: firstRequestId,
598
- payload: {
599
- agentId: "main",
600
- sessionKey: sessionId,
601
- content: "First request"
602
- },
603
- timestamp: Date.now()
604
- }));
605
- requester.send(JSON.stringify({
606
- type: "req:agent",
607
- id: secondRequestId,
608
- payload: {
609
- agentId: "main",
610
- sessionKey: sessionId,
611
- content: "Second request"
612
- },
613
- timestamp: Date.now()
614
- }));
615
- await queuedAckPromise;
616
- requester.send(JSON.stringify({
617
- type: "req:agent:cancel",
618
- id: `cancel-${secondRequestId}`,
619
- payload: {
620
- requestId: secondRequestId
621
- },
622
- timestamp: Date.now()
623
- }));
624
- const cancelAck = await waitForMessage(requester, (msg)=>"ack" === msg.type && msg.payload?.action === "req:agent:cancel" && msg.payload?.requestId === secondRequestId && msg.payload?.status === "cancelled_queued", 10000);
625
- expect(cancelAck.payload?.status).toBe("cancelled_queued");
626
- const cancelEvent = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === secondRequestId && msg.payload?.type === "agent-error" && /cancel/i.test(String(msg.payload?.error || "")), 10000);
627
- expect(cancelEvent.payload?.sessionId).toBe(sessionId);
628
- expect(cancelEvent.payload?.agentId).toBe("main");
629
- await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === firstRequestId && msg.payload?.type === "agent-complete", 10000);
630
- const queuedRequests = server.queuedSessionRequests;
631
- const isStillQueued = [
632
- ...queuedRequests.values()
633
- ].some((queue)=>queue.some((item)=>item.msg?.id === secondRequestId));
634
- expect(isStillQueued).toBe(false);
635
- requester.close();
636
- });
637
- it("should clear session messages via API", async ()=>{
638
- const createRes = await fetch(`http://localhost:${port}/api/sessions`, {
639
- method: "POST",
640
- headers: {
641
- "Content-Type": "application/json"
642
- },
643
- body: JSON.stringify({
644
- name: "Clear Test"
645
- })
646
- });
647
- expect(createRes.ok).toBe(true);
648
- const session = await createRes.json();
649
- const sessionAgentId = session.agentId || "main";
650
- const manager = await server.getSessionManager(sessionAgentId);
651
- manager.updateSession(session.id, {
652
- messageCount: 3,
653
- lastMessagePreview: "Hello"
654
- });
655
- const clearRes = await fetch(`http://localhost:${port}/api/sessions/${encodeURIComponent(session.id)}/messages?agentId=${encodeURIComponent(sessionAgentId)}`, {
656
- method: "DELETE"
657
- });
658
- expect(clearRes.ok).toBe(true);
659
- const cleared = await clearRes.json();
660
- expect(cleared.messageCount).toBe(0);
661
- const updated = manager.getSession(session.id);
662
- expect(updated?.messageCount).toBe(0);
663
- expect(updated?.lastMessagePreview).toBeNull();
664
- });
665
- it("persists failed first-turn messages so the thread survives reload", async ()=>{
666
- const requester = await connectClient("persist-failed-turn-requester");
667
- const sessionId = `session-persist-failed-${Date.now()}`;
668
- const requestId = `req-persist-failed-${Date.now()}`;
669
- requester.send(JSON.stringify({
670
- type: "req:agent",
671
- id: requestId,
672
- payload: {
673
- agentId: "main",
674
- sessionKey: sessionId,
675
- content: "throw-no-event"
676
- },
677
- timestamp: Date.now()
678
- }));
679
- await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error", 10000);
680
- const sessionsRes = await fetch(`http://localhost:${port}/api/sessions?limit=100`);
681
- expect(sessionsRes.ok).toBe(true);
682
- const sessions = await sessionsRes.json();
683
- const created = sessions.find((session)=>session.id === sessionId);
684
- expect(created).toBeTruthy();
685
- expect(created?.messageCount).toBe(1);
686
- const messagesRes = await fetch(`http://localhost:${port}/api/sessions/${encodeURIComponent(sessionId)}/messages?agentId=main`);
687
- expect(messagesRes.ok).toBe(true);
688
- const messages = await messagesRes.json();
689
- expect(messages.some((message)=>"user" === message.role)).toBe(true);
690
- expect(messages.some((message)=>"user" === message.role && message.content.includes("throw-no-event"))).toBe(true);
691
- expect(messages.some((message)=>"assistant" === message.role && message.content.includes("Synthetic invocation failure"))).toBe(true);
692
- requester.close();
693
- });
694
- });