@wingman-ai/gateway 0.2.5 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +9 -0
  2. package/dist/agent/config/agentConfig.cjs +12 -0
  3. package/dist/agent/config/agentConfig.d.ts +26 -0
  4. package/dist/agent/config/agentConfig.js +10 -1
  5. package/dist/agent/config/agentLoader.cjs +9 -0
  6. package/dist/agent/config/agentLoader.js +9 -0
  7. package/dist/agent/config/mcpClientManager.cjs +44 -10
  8. package/dist/agent/config/mcpClientManager.d.ts +6 -2
  9. package/dist/agent/config/mcpClientManager.js +44 -10
  10. package/dist/agent/config/toolRegistry.cjs +20 -1
  11. package/dist/agent/config/toolRegistry.d.ts +15 -0
  12. package/dist/agent/config/toolRegistry.js +20 -1
  13. package/dist/agent/tests/agentConfig.test.cjs +6 -1
  14. package/dist/agent/tests/agentConfig.test.js +6 -1
  15. package/dist/agent/tests/browserControlHelpers.test.cjs +35 -0
  16. package/dist/agent/tests/browserControlHelpers.test.d.ts +1 -0
  17. package/dist/agent/tests/browserControlHelpers.test.js +29 -0
  18. package/dist/agent/tests/browserControlTool.test.cjs +2117 -0
  19. package/dist/agent/tests/browserControlTool.test.d.ts +1 -0
  20. package/dist/agent/tests/browserControlTool.test.js +2111 -0
  21. package/dist/agent/tests/mcpClientManager.test.cjs +124 -0
  22. package/dist/agent/tests/mcpClientManager.test.d.ts +1 -0
  23. package/dist/agent/tests/mcpClientManager.test.js +118 -0
  24. package/dist/agent/tests/toolRegistry.test.cjs +6 -0
  25. package/dist/agent/tests/toolRegistry.test.js +6 -0
  26. package/dist/agent/tools/browser_control.cjs +1282 -0
  27. package/dist/agent/tools/browser_control.d.ts +478 -0
  28. package/dist/agent/tools/browser_control.js +1242 -0
  29. package/dist/agent/tools/command_execute.cjs +1 -1
  30. package/dist/agent/tools/command_execute.js +1 -1
  31. package/dist/cli/commands/agent.cjs +16 -2
  32. package/dist/cli/commands/agent.js +16 -2
  33. package/dist/cli/commands/browser.cjs +603 -0
  34. package/dist/cli/commands/browser.d.ts +13 -0
  35. package/dist/cli/commands/browser.js +566 -0
  36. package/dist/cli/commands/gateway.cjs +18 -7
  37. package/dist/cli/commands/gateway.d.ts +5 -1
  38. package/dist/cli/commands/gateway.js +18 -7
  39. package/dist/cli/commands/init.cjs +134 -45
  40. package/dist/cli/commands/init.js +134 -45
  41. package/dist/cli/commands/skill.cjs +3 -2
  42. package/dist/cli/commands/skill.js +3 -2
  43. package/dist/cli/config/loader.cjs +15 -0
  44. package/dist/cli/config/loader.js +15 -0
  45. package/dist/cli/config/schema.cjs +51 -2
  46. package/dist/cli/config/schema.d.ts +51 -0
  47. package/dist/cli/config/schema.js +44 -1
  48. package/dist/cli/core/agentInvoker.cjs +55 -66
  49. package/dist/cli/core/agentInvoker.d.ts +10 -13
  50. package/dist/cli/core/agentInvoker.js +42 -62
  51. package/dist/cli/core/imagePersistence.cjs +125 -0
  52. package/dist/cli/core/imagePersistence.d.ts +24 -0
  53. package/dist/cli/core/imagePersistence.js +85 -0
  54. package/dist/cli/core/sessionManager.cjs +297 -40
  55. package/dist/cli/core/sessionManager.d.ts +9 -0
  56. package/dist/cli/core/sessionManager.js +297 -40
  57. package/dist/cli/core/workspace.cjs +89 -0
  58. package/dist/cli/core/workspace.d.ts +1 -0
  59. package/dist/cli/core/workspace.js +55 -0
  60. package/dist/cli/index.cjs +53 -5
  61. package/dist/cli/index.js +53 -5
  62. package/dist/cli/types/browser.cjs +18 -0
  63. package/dist/cli/types/browser.d.ts +9 -0
  64. package/dist/cli/types/browser.js +0 -0
  65. package/dist/debug/terminalProbe.cjs +57 -0
  66. package/dist/debug/terminalProbe.d.ts +10 -0
  67. package/dist/debug/terminalProbe.js +20 -0
  68. package/dist/debug/terminalProbeAuth.cjs +140 -0
  69. package/dist/debug/terminalProbeAuth.d.ts +20 -0
  70. package/dist/debug/terminalProbeAuth.js +97 -0
  71. package/dist/gateway/browserRelayServer.cjs +338 -0
  72. package/dist/gateway/browserRelayServer.d.ts +38 -0
  73. package/dist/gateway/browserRelayServer.js +301 -0
  74. package/dist/gateway/http/agents.cjs +22 -0
  75. package/dist/gateway/http/agents.js +22 -0
  76. package/dist/gateway/http/fs.cjs +76 -0
  77. package/dist/gateway/http/fs.js +77 -1
  78. package/dist/gateway/http/sessions.cjs +25 -5
  79. package/dist/gateway/http/sessions.js +25 -5
  80. package/dist/gateway/server.cjs +155 -17
  81. package/dist/gateway/server.d.ts +6 -1
  82. package/dist/gateway/server.js +148 -16
  83. package/dist/gateway/transport/websocket.cjs +45 -10
  84. package/dist/gateway/transport/websocket.d.ts +1 -0
  85. package/dist/gateway/transport/websocket.js +41 -9
  86. package/dist/gateway/types.d.ts +4 -0
  87. package/dist/tests/agentInvokerSummarization.test.cjs +56 -37
  88. package/dist/tests/agentInvokerSummarization.test.js +58 -39
  89. package/dist/tests/agentInvokerWorkdir.test.cjs +50 -0
  90. package/dist/tests/agentInvokerWorkdir.test.js +52 -2
  91. package/dist/tests/agents-api.test.cjs +52 -0
  92. package/dist/tests/agents-api.test.js +53 -1
  93. package/dist/tests/browser-command.test.cjs +264 -0
  94. package/dist/tests/browser-command.test.d.ts +1 -0
  95. package/dist/tests/browser-command.test.js +258 -0
  96. package/dist/tests/browser-relay-server.test.cjs +20 -0
  97. package/dist/tests/browser-relay-server.test.d.ts +1 -0
  98. package/dist/tests/browser-relay-server.test.js +14 -0
  99. package/dist/tests/cli-config-loader.test.cjs +43 -0
  100. package/dist/tests/cli-config-loader.test.js +43 -0
  101. package/dist/tests/cli-init.test.cjs +61 -2
  102. package/dist/tests/cli-init.test.js +61 -2
  103. package/dist/tests/cli-workspace-root.test.cjs +114 -0
  104. package/dist/tests/cli-workspace-root.test.d.ts +1 -0
  105. package/dist/tests/cli-workspace-root.test.js +108 -0
  106. package/dist/tests/falRuntime.test.cjs +78 -0
  107. package/dist/tests/falRuntime.test.d.ts +1 -0
  108. package/dist/tests/falRuntime.test.js +72 -0
  109. package/dist/tests/falSummary.test.cjs +51 -0
  110. package/dist/tests/falSummary.test.d.ts +1 -0
  111. package/dist/tests/falSummary.test.js +45 -0
  112. package/dist/tests/fs-api.test.cjs +138 -0
  113. package/dist/tests/fs-api.test.d.ts +1 -0
  114. package/dist/tests/fs-api.test.js +132 -0
  115. package/dist/tests/gateway-command-workspace.test.cjs +150 -0
  116. package/dist/tests/gateway-command-workspace.test.d.ts +1 -0
  117. package/dist/tests/gateway-command-workspace.test.js +144 -0
  118. package/dist/tests/gateway-request-execution-overrides.test.cjs +42 -0
  119. package/dist/tests/gateway-request-execution-overrides.test.d.ts +1 -0
  120. package/dist/tests/gateway-request-execution-overrides.test.js +36 -0
  121. package/dist/tests/gateway.test.cjs +140 -1
  122. package/dist/tests/gateway.test.js +140 -1
  123. package/dist/tests/imagePersistence.test.cjs +143 -0
  124. package/dist/tests/imagePersistence.test.d.ts +1 -0
  125. package/dist/tests/imagePersistence.test.js +137 -0
  126. package/dist/tests/sessionMessageAttachments.test.cjs +30 -0
  127. package/dist/tests/sessionMessageAttachments.test.js +30 -0
  128. package/dist/tests/sessionStateMessages.test.cjs +126 -0
  129. package/dist/tests/sessionStateMessages.test.js +126 -0
  130. package/dist/tests/sessions-api.test.cjs +117 -3
  131. package/dist/tests/sessions-api.test.js +118 -4
  132. package/dist/tests/terminalProbe.test.cjs +45 -0
  133. package/dist/tests/terminalProbe.test.d.ts +1 -0
  134. package/dist/tests/terminalProbe.test.js +39 -0
  135. package/dist/tests/terminalProbeAuth.test.cjs +85 -0
  136. package/dist/tests/terminalProbeAuth.test.d.ts +1 -0
  137. package/dist/tests/terminalProbeAuth.test.js +79 -0
  138. package/dist/tests/websocket-transport.test.cjs +31 -0
  139. package/dist/tests/websocket-transport.test.d.ts +1 -0
  140. package/dist/tests/websocket-transport.test.js +25 -0
  141. package/dist/tools/fal/runtime.cjs +103 -0
  142. package/dist/tools/fal/runtime.d.ts +10 -0
  143. package/dist/tools/fal/runtime.js +60 -0
  144. package/dist/tools/fal/summary.cjs +78 -0
  145. package/dist/tools/fal/summary.d.ts +22 -0
  146. package/dist/tools/fal/summary.js +41 -0
  147. package/dist/tools/mcp-fal-ai.cjs +1041 -0
  148. package/dist/tools/mcp-fal-ai.d.ts +1 -0
  149. package/dist/tools/mcp-fal-ai.js +1025 -0
  150. package/dist/types/mcp.cjs +2 -0
  151. package/dist/types/mcp.d.ts +8 -0
  152. package/dist/types/mcp.js +3 -1
  153. package/dist/webui/assets/index-BW9nM0J2.css +11 -0
  154. package/dist/webui/assets/index-C8-oboEC.js +278 -0
  155. package/dist/webui/index.html +2 -2
  156. package/extensions/wingman-browser-extension/README.md +27 -0
  157. package/extensions/wingman-browser-extension/background.js +416 -0
  158. package/extensions/wingman-browser-extension/manifest.json +19 -0
  159. package/extensions/wingman-browser-extension/options.html +156 -0
  160. package/extensions/wingman-browser-extension/options.js +106 -0
  161. package/package.json +18 -13
  162. package/{.wingman → templates}/agents/README.md +2 -1
  163. package/{.wingman → templates}/agents/coding/agent.md +5 -1
  164. package/{.wingman → templates}/agents/coding-v2/agent.md +58 -1
  165. package/templates/agents/game-dev/agent.md +101 -0
  166. package/templates/agents/game-dev/art-generation.md +38 -0
  167. package/templates/agents/game-dev/asset-refinement.md +17 -0
  168. package/templates/agents/game-dev/planning-idea.md +17 -0
  169. package/templates/agents/game-dev/ui-specialist.md +17 -0
  170. package/templates/agents/main/agent.md +29 -0
  171. package/{.wingman → templates}/agents/researcher/agent.md +9 -0
  172. package/{.wingman → templates}/agents/stock-trader/agent.md +1 -0
  173. package/.wingman/agents/main/agent.md +0 -22
  174. package/dist/webui/assets/index-C7EuTbnE.js +0 -270
  175. package/dist/webui/assets/index-DVWQluit.css +0 -11
  176. /package/{.wingman → templates}/agents/coding-v2/implementor.md +0 -0
  177. /package/{.wingman → templates}/agents/stock-trader/chain-curator.md +0 -0
  178. /package/{.wingman → templates}/agents/stock-trader/goal-translator.md +0 -0
  179. /package/{.wingman → templates}/agents/stock-trader/guardrails-veto.md +0 -0
  180. /package/{.wingman → templates}/agents/stock-trader/path-planner.md +0 -0
  181. /package/{.wingman → templates}/agents/stock-trader/regime-analyst.md +0 -0
  182. /package/{.wingman → templates}/agents/stock-trader/risk.md +0 -0
  183. /package/{.wingman → templates}/agents/stock-trader/selection.md +0 -0
  184. /package/{.wingman → templates}/agents/stock-trader/strategy-composer.md +0 -0
@@ -27,7 +27,9 @@ var __webpack_require__ = {};
27
27
  var __webpack_exports__ = {};
28
28
  __webpack_require__.r(__webpack_exports__);
29
29
  __webpack_require__.d(__webpack_exports__, {
30
- GatewayServer: ()=>GatewayServer
30
+ resolveExecutionWorkspaceOverride: ()=>resolveExecutionWorkspaceOverride,
31
+ GatewayServer: ()=>GatewayServer,
32
+ resolveExecutionConfigDirOverride: ()=>resolveExecutionConfigDirOverride
31
33
  });
32
34
  const external_node_fs_namespaceObject = require("node:fs");
33
35
  const external_node_os_namespaceObject = require("node:os");
@@ -41,6 +43,7 @@ const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.c
41
43
  const external_logger_cjs_namespaceObject = require("../logger.cjs");
42
44
  const discord_cjs_namespaceObject = require("./adapters/discord.cjs");
43
45
  const external_auth_cjs_namespaceObject = require("./auth.cjs");
46
+ const external_browserRelayServer_cjs_namespaceObject = require("./browserRelayServer.cjs");
44
47
  const external_broadcast_cjs_namespaceObject = require("./broadcast.cjs");
45
48
  const index_cjs_namespaceObject = require("./discovery/index.cjs");
46
49
  const external_env_cjs_namespaceObject = require("./env.cjs");
@@ -80,6 +83,19 @@ function withApiCors(response) {
80
83
  headers
81
84
  });
82
85
  }
86
+ function resolveExecutionWorkspaceOverride(payload) {
87
+ const rawWorkspace = payload?.execution?.workspace;
88
+ if ("string" != typeof rawWorkspace) return null;
89
+ const trimmed = rawWorkspace.trim();
90
+ if (!trimmed || !(0, external_node_path_namespaceObject.isAbsolute)(trimmed)) return null;
91
+ return (0, external_node_path_namespaceObject.normalize)(trimmed);
92
+ }
93
+ function resolveExecutionConfigDirOverride(payload) {
94
+ const rawConfigDir = payload?.execution?.configDir;
95
+ if ("string" != typeof rawConfigDir) return null;
96
+ const trimmed = rawConfigDir.trim();
97
+ return trimmed || null;
98
+ }
83
99
  class GatewayServer {
84
100
  async start() {
85
101
  if (void 0 === globalThis.Bun) throw new Error("Gateway server requires Bun runtime. Start with `bun ./bin/wingman gateway start`.");
@@ -137,6 +153,7 @@ class GatewayServer {
137
153
  if (!this.uiDistDir) this.log("warn", "Control UI is enabled but build assets were not found. Run `bun run webui:build`.");
138
154
  this.log("info", `Control UI available on ${this.config.host}:${this.config.port}`);
139
155
  }
156
+ this.browserRelayServer?.start();
140
157
  if (this.config.discovery?.enabled) await this.startDiscovery();
141
158
  await this.startAdapters();
142
159
  this.log("info", `Gateway started on ${this.config.host}:${this.config.port}`);
@@ -165,6 +182,7 @@ class GatewayServer {
165
182
  this.uiServer.stop();
166
183
  this.uiServer = null;
167
184
  }
185
+ if (this.browserRelayServer) this.browserRelayServer.stop();
168
186
  this.terminalSessionManager.dispose();
169
187
  this.log("info", "Gateway stopped");
170
188
  }
@@ -357,6 +375,8 @@ class GatewayServer {
357
375
  const payload = msg.payload;
358
376
  const content = "string" == typeof payload?.content ? payload.content : "";
359
377
  const attachments = Array.isArray(payload?.attachments) ? payload.attachments : [];
378
+ const workspaceOverride = resolveExecutionWorkspaceOverride(payload);
379
+ const configDirOverride = resolveExecutionConfigDirOverride(payload);
360
380
  const hasContent = content.trim().length > 0;
361
381
  const hasAttachments = attachments.length > 0;
362
382
  if (!hasContent && !hasAttachments) return void this.sendAgentError(ws, msg.id, "Missing agent content");
@@ -367,12 +387,29 @@ class GatewayServer {
367
387
  const sessionManager = await this.getSessionManager(agentId);
368
388
  const existingSession = sessionManager.getSession(sessionKey);
369
389
  const session = existingSession || sessionManager.getOrCreateSession(sessionKey, agentId);
390
+ const requestId = msg.id || `req-${Date.now()}`;
370
391
  const workdir = session.metadata?.workdir ?? null;
371
392
  const defaultOutputDir = this.resolveDefaultOutputDir(agentId);
372
393
  const preview = hasContent ? content.trim() : buildAttachmentPreview(attachments);
373
394
  sessionManager.updateSession(session.id, {
395
+ messageCount: (session.messageCount ?? 0) + 1,
374
396
  lastMessagePreview: preview.substring(0, 200)
375
397
  });
398
+ try {
399
+ sessionManager.persistPendingMessage({
400
+ sessionId: sessionKey,
401
+ requestId,
402
+ message: {
403
+ id: `user-${requestId}`,
404
+ role: "user",
405
+ content,
406
+ attachments: attachments.length > 0 ? mapAttachmentsForPendingMessage(attachments) : void 0,
407
+ createdAt: Date.now()
408
+ }
409
+ });
410
+ } catch (error) {
411
+ this.logger.warn("Failed to persist pending user message", error);
412
+ }
376
413
  if (!existingSession) this.internalHooks?.emit({
377
414
  type: "session",
378
415
  action: "start",
@@ -425,7 +462,9 @@ class GatewayServer {
425
462
  attachments,
426
463
  sessionManager,
427
464
  workdir,
428
- defaultOutputDir
465
+ defaultOutputDir,
466
+ workspaceOverride,
467
+ configDirOverride
429
468
  };
430
469
  this.requestSessionKeys.set(msg.id, sessionQueueKey);
431
470
  const queueIfBusy = false !== payload.queueIfBusy;
@@ -471,13 +510,19 @@ class GatewayServer {
471
510
  this.executeAgentRequest(request);
472
511
  }
473
512
  async executeAgentRequest(request) {
474
- const { ws, msg, agentId, sessionKey, sessionQueueKey, content, attachments, sessionManager, workdir, defaultOutputDir } = request;
513
+ const { ws, msg, agentId, sessionKey, sessionQueueKey, content, attachments, sessionManager, workdir, defaultOutputDir, workspaceOverride, configDirOverride } = request;
475
514
  this.activeSessionRequests.set(sessionQueueKey, msg.id);
476
515
  const outputManager = new outputManager_cjs_namespaceObject.OutputManager("interactive");
477
516
  let emittedAgentError = false;
517
+ let streamedCompletionResult;
478
518
  const outputHandler = (event)=>{
479
519
  const payloadWithSession = this.attachSessionContext(event, sessionKey, agentId);
480
- if (payloadWithSession && "object" == typeof payloadWithSession && !Array.isArray(payloadWithSession) && "agent-error" === payloadWithSession.type) emittedAgentError = true;
520
+ const payloadType = payloadWithSession && "object" == typeof payloadWithSession && !Array.isArray(payloadWithSession) && "string" == typeof payloadWithSession.type ? payloadWithSession.type : "";
521
+ if ("agent-complete" === payloadType) {
522
+ if (payloadWithSession && "object" == typeof payloadWithSession && !Array.isArray(payloadWithSession)) streamedCompletionResult = payloadWithSession.result;
523
+ return;
524
+ }
525
+ if ("agent-error" === payloadType) emittedAgentError = true;
481
526
  const baseMessage = {
482
527
  type: "event:agent",
483
528
  id: msg.id,
@@ -491,10 +536,11 @@ class GatewayServer {
491
536
  this.broadcastSessionEvent(sessionKey, baseMessage, ws);
492
537
  };
493
538
  outputManager.on("output-event", outputHandler);
494
- const workspace = this.resolveAgentWorkspace(agentId);
539
+ const workspace = workspaceOverride || this.resolveAgentWorkspace(agentId);
540
+ const configDir = configDirOverride || this.configDir;
495
541
  const invoker = new agentInvoker_cjs_namespaceObject.AgentInvoker({
496
542
  workspace,
497
- configDir: this.configDir,
543
+ configDir,
498
544
  outputManager,
499
545
  logger: this.logger,
500
546
  sessionManager,
@@ -508,17 +554,43 @@ class GatewayServer {
508
554
  abortController
509
555
  });
510
556
  try {
511
- await invoker.invokeAgent(agentId, content, sessionKey, attachments, {
557
+ const invocationResult = await invoker.invokeAgent(agentId, content, sessionKey, attachments, {
512
558
  signal: abortController.signal
513
559
  });
514
- const updated = sessionManager.getSession(sessionKey);
515
- if (updated) sessionManager.updateSession(sessionKey, {
516
- messageCount: updated.messageCount + 1
560
+ if (msg.id) sessionManager.clearPendingMessagesForRequest(sessionKey, msg.id);
561
+ if (emittedAgentError) return;
562
+ const invocationCancelled = abortController.signal.aborted || "object" == typeof invocationResult && null !== invocationResult && !Array.isArray(invocationResult) && true === invocationResult.cancelled;
563
+ if (invocationCancelled) return void this.sendAgentError(ws, msg.id, "Request cancelled", {
564
+ sessionId: sessionKey,
565
+ agentId,
566
+ broadcastToSession: true,
567
+ exclude: ws
568
+ });
569
+ const completionResult = void 0 === streamedCompletionResult ? invocationResult : streamedCompletionResult;
570
+ this.sendAgentComplete(ws, msg.id, completionResult, {
571
+ sessionId: sessionKey,
572
+ agentId,
573
+ broadcastToSession: true,
574
+ exclude: ws
517
575
  });
518
576
  } catch (error) {
519
577
  this.logger.error("Agent invocation failed", error);
578
+ const message = error instanceof Error ? error.message : String(error);
579
+ if (msg.id) try {
580
+ sessionManager.persistPendingMessage({
581
+ sessionId: sessionKey,
582
+ requestId: msg.id,
583
+ message: {
584
+ id: msg.id,
585
+ role: "assistant",
586
+ content: message,
587
+ createdAt: Date.now()
588
+ }
589
+ });
590
+ } catch (persistError) {
591
+ this.logger.warn("Failed to persist pending assistant error message", persistError);
592
+ }
520
593
  if (!emittedAgentError) {
521
- const message = error instanceof Error ? error.message : String(error);
522
594
  const stack = error instanceof Error ? error.stack : void 0;
523
595
  this.sendAgentError(ws, msg.id, message, {
524
596
  sessionId: sessionKey,
@@ -594,6 +666,12 @@ class GatewayServer {
594
666
  },
595
667
  timestamp: Date.now()
596
668
  });
669
+ this.sendAgentError(ws, requestId, "Request cancelled", {
670
+ sessionId: queued.sessionKey,
671
+ agentId: queued.agentId,
672
+ broadcastToSession: true,
673
+ exclude: ws
674
+ });
597
675
  return;
598
676
  }
599
677
  this.sendMessage(ws, {
@@ -768,11 +846,25 @@ class GatewayServer {
768
846
  }
769
847
  sendMessage(ws, message) {
770
848
  try {
771
- ws.send(JSON.stringify(message));
849
+ const result = ws.send(JSON.stringify(message));
850
+ if ("number" == typeof result && result <= 0) return false;
851
+ return true;
772
852
  } catch (error) {
773
853
  this.log("error", "Failed to send message", error);
854
+ return false;
774
855
  }
775
856
  }
857
+ sendMessageWithRetry(ws, message, attempt = 0) {
858
+ if (this.sendMessage(ws, message)) return;
859
+ if (attempt >= 2) return void this.log("warn", "Dropping websocket message after retry attempts", {
860
+ type: message.type,
861
+ id: message.id
862
+ });
863
+ const delayMs = 25 * (attempt + 1);
864
+ setTimeout(()=>{
865
+ this.sendMessageWithRetry(ws, message, attempt + 1);
866
+ }, delayMs);
867
+ }
776
868
  sendError(ws, code, message) {
777
869
  const errorPayload = {
778
870
  code,
@@ -784,6 +876,25 @@ class GatewayServer {
784
876
  timestamp: Date.now()
785
877
  });
786
878
  }
879
+ sendAgentComplete(ws, requestId, result, options) {
880
+ let payload = {
881
+ type: "agent-complete",
882
+ result: result ?? null,
883
+ timestamp: new Date().toISOString()
884
+ };
885
+ if (options?.sessionId && options?.agentId) payload = this.attachSessionContext(payload, options.sessionId, options.agentId);
886
+ const baseMessage = {
887
+ type: "event:agent",
888
+ id: requestId,
889
+ payload,
890
+ timestamp: Date.now()
891
+ };
892
+ this.sendMessageWithRetry(ws, {
893
+ ...baseMessage,
894
+ clientId: ws.data.clientId
895
+ });
896
+ if (options?.broadcastToSession && options.sessionId) this.broadcastSessionEvent(options.sessionId, baseMessage, options.exclude, true);
897
+ }
787
898
  sendAgentError(ws, requestId, message, options) {
788
899
  let payload = {
789
900
  type: "agent-error",
@@ -798,11 +909,11 @@ class GatewayServer {
798
909
  payload,
799
910
  timestamp: Date.now()
800
911
  };
801
- this.sendMessage(ws, {
912
+ this.sendMessageWithRetry(ws, {
802
913
  ...baseMessage,
803
914
  clientId: ws.data.clientId
804
915
  });
805
- if (options?.broadcastToSession && options.sessionId) this.broadcastSessionEvent(options.sessionId, baseMessage, options.exclude);
916
+ if (options?.broadcastToSession && options.sessionId) this.broadcastSessionEvent(options.sessionId, baseMessage, options.exclude, true);
806
917
  }
807
918
  cancelSocketAgentRequests(ws) {
808
919
  for (const [requestId, active] of this.activeAgentRequests)if (active.socket === ws) {
@@ -831,12 +942,13 @@ class GatewayServer {
831
942
  agentId
832
943
  };
833
944
  }
834
- broadcastSessionEvent(sessionId, message, exclude) {
945
+ broadcastSessionEvent(sessionId, message, exclude, reliable = false) {
835
946
  const subscribers = this.sessionSubscriptions.get(sessionId);
836
947
  if (!subscribers || 0 === subscribers.size) return 0;
837
948
  let sent = 0;
838
949
  for (const ws of subscribers)if (!exclude || ws !== exclude) {
839
- this.sendMessage(ws, message);
950
+ if (reliable) this.sendMessageWithRetry(ws, message);
951
+ else this.sendMessage(ws, message);
840
952
  sent++;
841
953
  }
842
954
  return sent;
@@ -1325,6 +1437,7 @@ class GatewayServer {
1325
1437
  _define_property(this, "controlUiPort", 18790);
1326
1438
  _define_property(this, "controlUiSamePort", false);
1327
1439
  _define_property(this, "uiDistDir", null);
1440
+ _define_property(this, "browserRelayServer", null);
1328
1441
  _define_property(this, "webhookStore", void 0);
1329
1442
  _define_property(this, "routineStore", void 0);
1330
1443
  _define_property(this, "internalHooks", null);
@@ -1387,6 +1500,15 @@ class GatewayServer {
1387
1500
  this.controlUiPort = controlUi?.port || 18790;
1388
1501
  this.controlUiSamePort = this.controlUiEnabled && this.controlUiPort === this.config.port;
1389
1502
  this.uiDistDir = this.controlUiEnabled ? this.resolveControlUiDir() : null;
1503
+ const relayConfig = this.wingmanConfig.browser?.relay;
1504
+ if (relayConfig?.enabled) this.browserRelayServer = new external_browserRelayServer_cjs_namespaceObject.BrowserRelayServer({
1505
+ enabled: relayConfig.enabled,
1506
+ host: relayConfig.host || "127.0.0.1",
1507
+ port: relayConfig.port || 18792,
1508
+ requireAuth: relayConfig.requireAuth ?? true,
1509
+ authToken: relayConfig.authToken,
1510
+ maxMessageBytes: relayConfig.maxMessageBytes || 262144
1511
+ }, this.logger);
1390
1512
  this.terminalSessionManager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
1391
1513
  }
1392
1514
  }
@@ -1410,6 +1532,18 @@ function buildAttachmentPreview(attachments) {
1410
1532
  if (hasAudio) return count > 1 ? "Audio attachments" : "Audio attachment";
1411
1533
  return count > 1 ? "Image attachments" : "Image attachment";
1412
1534
  }
1535
+ function mapAttachmentsForPendingMessage(attachments) {
1536
+ return attachments.map((attachment)=>{
1537
+ const kind = isFileAttachment(attachment) ? "file" : isAudioAttachment(attachment) ? "audio" : "image";
1538
+ return {
1539
+ kind,
1540
+ dataUrl: attachment.dataUrl,
1541
+ name: attachment.name,
1542
+ mimeType: attachment.mimeType,
1543
+ size: attachment.size
1544
+ };
1545
+ });
1546
+ }
1413
1547
  function isAudioAttachment(attachment) {
1414
1548
  if ("audio" === attachment.kind) return true;
1415
1549
  if (attachment.mimeType?.startsWith("audio/")) return true;
@@ -1421,8 +1555,12 @@ function isFileAttachment(attachment) {
1421
1555
  return "string" == typeof attachment.textContent;
1422
1556
  }
1423
1557
  exports.GatewayServer = __webpack_exports__.GatewayServer;
1558
+ exports.resolveExecutionConfigDirOverride = __webpack_exports__.resolveExecutionConfigDirOverride;
1559
+ exports.resolveExecutionWorkspaceOverride = __webpack_exports__.resolveExecutionWorkspaceOverride;
1424
1560
  for(var __rspack_i in __webpack_exports__)if (-1 === [
1425
- "GatewayServer"
1561
+ "GatewayServer",
1562
+ "resolveExecutionConfigDirOverride",
1563
+ "resolveExecutionWorkspaceOverride"
1426
1564
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
1427
1565
  Object.defineProperty(exports, '__esModule', {
1428
1566
  value: true
@@ -1,5 +1,7 @@
1
1
  import { GatewayAuth } from "./auth.js";
2
- import type { GatewayConfig } from "./types.js";
2
+ import type { AgentRequestPayload, GatewayConfig } from "./types.js";
3
+ export declare function resolveExecutionWorkspaceOverride(payload: AgentRequestPayload | undefined): string | null;
4
+ export declare function resolveExecutionConfigDirOverride(payload: AgentRequestPayload | undefined): string | null;
3
5
  /**
4
6
  * Wingman Gateway Server
5
7
  * Manages WebSocket connections for AI agent swarming
@@ -26,6 +28,7 @@ export declare class GatewayServer {
26
28
  private controlUiPort;
27
29
  private controlUiSamePort;
28
30
  private uiDistDir;
31
+ private browserRelayServer;
29
32
  private webhookStore;
30
33
  private routineStore;
31
34
  private internalHooks;
@@ -129,10 +132,12 @@ export declare class GatewayServer {
129
132
  * Send a message to a WebSocket
130
133
  */
131
134
  private sendMessage;
135
+ private sendMessageWithRetry;
132
136
  /**
133
137
  * Send an error message
134
138
  */
135
139
  private sendError;
140
+ private sendAgentComplete;
136
141
  private sendAgentError;
137
142
  private cancelSocketAgentRequests;
138
143
  private attachSessionContext;