@truefoundry/trueforge-core 0.1.0-rc.0 → 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 (88) hide show
  1. package/dist/core/index.d.ts +9 -3
  2. package/dist/core/index.d.ts.map +1 -1
  3. package/dist/core/index.js +25 -0
  4. package/dist/core/index.js.map +1 -1
  5. package/dist/core/index.mjs +24 -2
  6. package/dist/core/index.mjs.map +1 -1
  7. package/dist/core/llm/VercelAILLM.d.ts +1 -0
  8. package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
  9. package/dist/core/llm/VercelAILLM.js +9 -14
  10. package/dist/core/llm/VercelAILLM.js.map +1 -1
  11. package/dist/core/llm/VercelAILLM.mjs +9 -15
  12. package/dist/core/llm/VercelAILLM.mjs.map +1 -1
  13. package/dist/core/runtime/AgentThread.d.ts.map +1 -1
  14. package/dist/core/runtime/AgentThread.js +3 -1
  15. package/dist/core/runtime/AgentThread.js.map +1 -1
  16. package/dist/core/runtime/AgentThread.mjs +3 -1
  17. package/dist/core/runtime/AgentThread.mjs.map +1 -1
  18. package/dist/core/sandbox/Sandbox.d.ts +7 -9
  19. package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
  20. package/dist/core/sandbox/Sandbox.js +45 -61
  21. package/dist/core/sandbox/Sandbox.js.map +1 -1
  22. package/dist/core/sandbox/Sandbox.mjs +46 -62
  23. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  24. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts +29 -0
  25. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -0
  26. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +128 -0
  27. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -0
  28. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +107 -0
  29. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -0
  30. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +21 -0
  31. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -0
  32. package/dist/core/sandbox/codeMode/CodeModeTransport.js +19 -0
  33. package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -0
  34. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs +1 -0
  35. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs.map +1 -0
  36. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +34 -0
  37. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -0
  38. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +187 -0
  39. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -0
  40. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +162 -0
  41. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -0
  42. package/dist/core/sandbox/codeMode/types.d.ts +34 -0
  43. package/dist/core/sandbox/codeMode/types.d.ts.map +1 -0
  44. package/dist/core/sandbox/codeMode/types.js +59 -0
  45. package/dist/core/sandbox/codeMode/types.js.map +1 -0
  46. package/dist/core/sandbox/codeMode/types.mjs +32 -0
  47. package/dist/core/sandbox/codeMode/types.mjs.map +1 -0
  48. package/dist/core/sandbox/provider/DaytonaProvider.d.ts +2 -1
  49. package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
  50. package/dist/core/sandbox/provider/DaytonaProvider.js +13 -6
  51. package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
  52. package/dist/core/sandbox/provider/DaytonaProvider.mjs +13 -6
  53. package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
  54. package/dist/core/sandbox/provider/Provider.d.ts +4 -3
  55. package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
  56. package/dist/core/sandbox/provider/Provider.js.map +1 -1
  57. package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
  58. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +2 -1
  59. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
  60. package/dist/core/sandbox/provider/TFYSandboxProvider.js +8 -2
  61. package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
  62. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +8 -2
  63. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
  64. package/dist/core/sandbox/sandboxImage.d.ts +1 -1
  65. package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
  66. package/dist/core/sandbox/sandboxImage.js +1 -1
  67. package/dist/core/sandbox/sandboxImage.js.map +1 -1
  68. package/dist/core/sandbox/sandboxImage.mjs +1 -1
  69. package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
  70. package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
  71. package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
  72. package/dist/core/sandbox/sandboxScripts.gen.js +8 -8
  73. package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
  74. package/dist/core/sandbox/sandboxScripts.gen.mjs +8 -8
  75. package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
  76. package/dist/core/util/errorLogFields.d.ts +5 -0
  77. package/dist/core/util/errorLogFields.d.ts.map +1 -1
  78. package/dist/core/util/errorLogFields.js +38 -2
  79. package/dist/core/util/errorLogFields.js.map +1 -1
  80. package/dist/core/util/errorLogFields.mjs +37 -2
  81. package/dist/core/util/errorLogFields.mjs.map +1 -1
  82. package/package.json +1 -1
  83. package/dist/core/sandbox/SandboxNatsBridge.d.ts +0 -33
  84. package/dist/core/sandbox/SandboxNatsBridge.d.ts.map +0 -1
  85. package/dist/core/sandbox/SandboxNatsBridge.js +0 -222
  86. package/dist/core/sandbox/SandboxNatsBridge.js.map +0 -1
  87. package/dist/core/sandbox/SandboxNatsBridge.mjs +0 -201
  88. package/dist/core/sandbox/SandboxNatsBridge.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeModeDispatcher.d.ts","sourceRoot":"","sources":["../../../../src/core/sandbox/codeMode/CodeModeDispatcher.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAuB,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEnF,4FAA4F;AAC5F,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAAC;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9C;AA2BD;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,MAAM,EAAE;QAAE,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAC;QAAC,MAAM,EAAE,cAAc,CAAA;KAAE,EAM5E;IAED,KAAK,IAAI,IAAI,CAEZ;IAEK,QAAQ,CAAC,MAAM,EAAE;QACrB,OAAO,EAAE,eAAe,CAAC;QACzB,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KAChD,GAAG,OAAO,CAAC,aAAa,CAAC,CAoBzB;IAED,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,UAAU;YAQJ,eAAe;YAUf,cAAc;CAoB7B"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/sandbox/codeMode/CodeModeDispatcher.ts
21
+ var CodeModeDispatcher_exports = {};
22
+ __export(CodeModeDispatcher_exports, {
23
+ CodeModeDispatcher: () => CodeModeDispatcher
24
+ });
25
+ module.exports = __toCommonJS(CodeModeDispatcher_exports);
26
+ var import_api = require("@opentelemetry/api");
27
+ var import_core = require("@opentelemetry/core");
28
+ var import_errors = require("../../errors.js");
29
+ var import_IMCPServer = require("../../mcp/IMCPServer.js");
30
+ var import_errorLogFields = require("../../util/errorLogFields.js");
31
+ var InvalidMCPUsageError = class extends Error {
32
+ name = "InvalidMCPUsageError";
33
+ };
34
+ function isHttpClientError(error) {
35
+ if (typeof error !== "object" || error === null || !("status" in error)) {
36
+ return false;
37
+ }
38
+ const { status } = error;
39
+ return typeof status === "number" && status >= 400 && status < 500;
40
+ }
41
+ function classifyErrorSource(e) {
42
+ if (e instanceof InvalidMCPUsageError) return "caller";
43
+ if (isHttpClientError(e)) return "caller";
44
+ if (e instanceof import_errors.McpConnectionError && e.statusCode >= 400 && e.statusCode < 500) return "caller";
45
+ return "internal";
46
+ }
47
+ var _w3cExtractor = new import_core.W3CTraceContextPropagator();
48
+ var CodeModeDispatcher = class {
49
+ toolSets;
50
+ logger;
51
+ closed = false;
52
+ constructor(params) {
53
+ this.toolSets = /* @__PURE__ */ new Map();
54
+ for (const server of params.toolSets) {
55
+ this.toolSets.set(server.name, server);
56
+ }
57
+ this.logger = params.logger.child({ module: "CodeModeDispatcher" });
58
+ }
59
+ close() {
60
+ this.closed = true;
61
+ }
62
+ async dispatch(params) {
63
+ if (this.closed) {
64
+ return { ok: false, error: "Code Mode dispatcher is closed", source: "transport" };
65
+ }
66
+ const ctx = _w3cExtractor.extract(
67
+ (0, import_core.unsuppressTracing)(import_api.context.active()),
68
+ { ...params.traceCarrier },
69
+ import_api.defaultTextMapGetter
70
+ );
71
+ try {
72
+ const result = await import_api.context.with(ctx, () => this.route(params.request));
73
+ return { ok: true, result };
74
+ } catch (e) {
75
+ const source = classifyErrorSource(e);
76
+ const errorMessage = e instanceof Error ? e.message : "Unknown Code Mode dispatch error";
77
+ this.logger.error(`Code Mode dispatch failed (source=${source})`, (0, import_errorLogFields.extractErrorLogFields)(e));
78
+ return { ok: false, error: errorMessage, source };
79
+ }
80
+ }
81
+ route(request) {
82
+ switch (request.op) {
83
+ case "list_tools":
84
+ return this.handleListTools(request);
85
+ case "call_tool":
86
+ return this.handleCallTool(request);
87
+ default:
88
+ throw new InvalidMCPUsageError(`Unknown Code Mode operation`);
89
+ }
90
+ }
91
+ getToolSet(serverName) {
92
+ const server = this.toolSets.get(serverName);
93
+ if (!server) {
94
+ throw new InvalidMCPUsageError(`MCP server '${serverName}' is not available for this agent`);
95
+ }
96
+ return server;
97
+ }
98
+ async handleListTools(req) {
99
+ const { server } = req;
100
+ const mcp = this.getToolSet(server);
101
+ const response = await mcp.listTools();
102
+ if ((0, import_IMCPServer.isAuthRequired)(response)) {
103
+ throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot list tools from sandbox`);
104
+ }
105
+ return response.result;
106
+ }
107
+ async handleCallTool(req) {
108
+ const { server, tool, arguments: args } = req;
109
+ const response = await this.getToolSet(server).callTool({ name: tool, arguments: args ?? {} });
110
+ if ((0, import_IMCPServer.isAuthRequired)(response)) {
111
+ throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot call tool from sandbox`);
112
+ }
113
+ if ((0, import_IMCPServer.isCallToolResponseCreateSubAgent)(response)) {
114
+ throw new InvalidMCPUsageError(`Tool '${server}/${tool}' creates a sub-agent and is not callable from sandbox`);
115
+ }
116
+ if (!(0, import_IMCPServer.isCallToolResponseResult)(response)) {
117
+ throw new InvalidMCPUsageError(
118
+ `Tool '${server}/${tool}' requires interactive handling and is not callable from sandbox`
119
+ );
120
+ }
121
+ return response.result;
122
+ }
123
+ };
124
+ // Annotate the CommonJS export names for ESM import in node:
125
+ 0 && (module.exports = {
126
+ CodeModeDispatcher
127
+ });
128
+ //# sourceMappingURL=CodeModeDispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/sandbox/codeMode/CodeModeDispatcher.ts"],"sourcesContent":["import { context, defaultTextMapGetter } from '@opentelemetry/api';\nimport { unsuppressTracing, W3CTraceContextPropagator } from '@opentelemetry/core';\nimport { McpConnectionError } from '../../errors';\nimport {\n isAuthRequired,\n isCallToolResponseCreateSubAgent,\n isCallToolResponseResult,\n type IToolSet,\n} from '../../mcp/IMCPServer';\nimport { extractErrorLogFields } from '../../util/errorLogFields';\nimport type { CodeModeErrorSource, CodeModeReply, CodeModeRequest } from './types';\n\n/** Minimal logger surface used by Code Mode (avoids a hard winston dep for PoC binders). */\nexport interface CodeModeLogger {\n child(bindings: Record<string, unknown>): CodeModeLogger;\n error(message: string, meta?: unknown): void;\n}\n\n// Caller-caused failure: retrying won't help.\nclass InvalidMCPUsageError extends Error {\n override readonly name = 'InvalidMCPUsageError';\n}\n\nfunction isHttpClientError(error: unknown): error is { status: number } {\n if (typeof error !== 'object' || error === null || !('status' in error)) {\n return false;\n }\n const { status } = error;\n return typeof status === 'number' && status >= 400 && status < 500;\n}\n\nfunction classifyErrorSource(e: unknown): CodeModeErrorSource {\n if (e instanceof InvalidMCPUsageError) return 'caller';\n if (isHttpClientError(e)) return 'caller';\n if (e instanceof McpConnectionError && e.statusCode >= 400 && e.statusCode < 500) return 'caller';\n return 'internal';\n}\n\n// Direct W3C extractor, NOT the global `propagation` API. The gateway-wide propagator\n// refuses to restore traceparent unless internal-secret headers are present. Code Mode\n// is intra-process trusted, so we bypass that gate and honor the sandbox carrier.\nconst _w3cExtractor = new W3CTraceContextPropagator();\n\n/**\n * Shared Code Mode policy leaf: tool routing, authz, error `source`. No NATS/UDS.\n */\nexport class CodeModeDispatcher {\n private readonly toolSets: Map<string, IToolSet>;\n private readonly logger: CodeModeLogger;\n private closed = false;\n\n constructor(params: { toolSets: readonly IToolSet[]; logger: CodeModeLogger }) {\n this.toolSets = new Map();\n for (const server of params.toolSets) {\n this.toolSets.set(server.name, server);\n }\n this.logger = params.logger.child({ module: 'CodeModeDispatcher' });\n }\n\n close(): void {\n this.closed = true;\n }\n\n async dispatch(params: {\n request: CodeModeRequest;\n traceCarrier: Readonly<Record<string, string>>;\n }): Promise<CodeModeReply> {\n if (this.closed) {\n return { ok: false, error: 'Code Mode dispatcher is closed', source: 'transport' };\n }\n\n const ctx = _w3cExtractor.extract(\n unsuppressTracing(context.active()),\n { ...params.traceCarrier },\n defaultTextMapGetter,\n );\n\n try {\n const result = await context.with(ctx, () => this.route(params.request));\n return { ok: true, result };\n } catch (e) {\n const source = classifyErrorSource(e);\n const errorMessage = e instanceof Error ? e.message : 'Unknown Code Mode dispatch error';\n this.logger.error(`Code Mode dispatch failed (source=${source})`, extractErrorLogFields(e));\n return { ok: false, error: errorMessage, source };\n }\n }\n\n private route(request: CodeModeRequest): Promise<unknown> {\n switch (request.op) {\n case 'list_tools':\n return this.handleListTools(request);\n case 'call_tool':\n return this.handleCallTool(request);\n default:\n throw new InvalidMCPUsageError(`Unknown Code Mode operation`);\n }\n }\n\n private getToolSet(serverName: string): IToolSet {\n const server = this.toolSets.get(serverName);\n if (!server) {\n throw new InvalidMCPUsageError(`MCP server '${serverName}' is not available for this agent`);\n }\n return server;\n }\n\n private async handleListTools(req: { server: string }): Promise<unknown> {\n const { server } = req;\n const mcp = this.getToolSet(server);\n const response = await mcp.listTools();\n if (isAuthRequired(response)) {\n throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot list tools from sandbox`);\n }\n return response.result;\n }\n\n private async handleCallTool(req: {\n server: string;\n tool: string;\n arguments?: Record<string, unknown> | undefined;\n }): Promise<unknown> {\n const { server, tool, arguments: args } = req;\n const response = await this.getToolSet(server).callTool({ name: tool, arguments: args ?? {} });\n if (isAuthRequired(response)) {\n throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot call tool from sandbox`);\n }\n if (isCallToolResponseCreateSubAgent(response)) {\n throw new InvalidMCPUsageError(`Tool '${server}/${tool}' creates a sub-agent and is not callable from sandbox`);\n }\n if (!isCallToolResponseResult(response)) {\n throw new InvalidMCPUsageError(\n `Tool '${server}/${tool}' requires interactive handling and is not callable from sandbox`,\n );\n }\n return response.result;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,107 @@
1
+ // src/core/sandbox/codeMode/CodeModeDispatcher.ts
2
+ import { context, defaultTextMapGetter } from "@opentelemetry/api";
3
+ import { unsuppressTracing, W3CTraceContextPropagator } from "@opentelemetry/core";
4
+ import { McpConnectionError } from "../../errors.mjs";
5
+ import {
6
+ isAuthRequired,
7
+ isCallToolResponseCreateSubAgent,
8
+ isCallToolResponseResult
9
+ } from "../../mcp/IMCPServer.mjs";
10
+ import { extractErrorLogFields } from "../../util/errorLogFields.mjs";
11
+ var InvalidMCPUsageError = class extends Error {
12
+ name = "InvalidMCPUsageError";
13
+ };
14
+ function isHttpClientError(error) {
15
+ if (typeof error !== "object" || error === null || !("status" in error)) {
16
+ return false;
17
+ }
18
+ const { status } = error;
19
+ return typeof status === "number" && status >= 400 && status < 500;
20
+ }
21
+ function classifyErrorSource(e) {
22
+ if (e instanceof InvalidMCPUsageError) return "caller";
23
+ if (isHttpClientError(e)) return "caller";
24
+ if (e instanceof McpConnectionError && e.statusCode >= 400 && e.statusCode < 500) return "caller";
25
+ return "internal";
26
+ }
27
+ var _w3cExtractor = new W3CTraceContextPropagator();
28
+ var CodeModeDispatcher = class {
29
+ toolSets;
30
+ logger;
31
+ closed = false;
32
+ constructor(params) {
33
+ this.toolSets = /* @__PURE__ */ new Map();
34
+ for (const server of params.toolSets) {
35
+ this.toolSets.set(server.name, server);
36
+ }
37
+ this.logger = params.logger.child({ module: "CodeModeDispatcher" });
38
+ }
39
+ close() {
40
+ this.closed = true;
41
+ }
42
+ async dispatch(params) {
43
+ if (this.closed) {
44
+ return { ok: false, error: "Code Mode dispatcher is closed", source: "transport" };
45
+ }
46
+ const ctx = _w3cExtractor.extract(
47
+ unsuppressTracing(context.active()),
48
+ { ...params.traceCarrier },
49
+ defaultTextMapGetter
50
+ );
51
+ try {
52
+ const result = await context.with(ctx, () => this.route(params.request));
53
+ return { ok: true, result };
54
+ } catch (e) {
55
+ const source = classifyErrorSource(e);
56
+ const errorMessage = e instanceof Error ? e.message : "Unknown Code Mode dispatch error";
57
+ this.logger.error(`Code Mode dispatch failed (source=${source})`, extractErrorLogFields(e));
58
+ return { ok: false, error: errorMessage, source };
59
+ }
60
+ }
61
+ route(request) {
62
+ switch (request.op) {
63
+ case "list_tools":
64
+ return this.handleListTools(request);
65
+ case "call_tool":
66
+ return this.handleCallTool(request);
67
+ default:
68
+ throw new InvalidMCPUsageError(`Unknown Code Mode operation`);
69
+ }
70
+ }
71
+ getToolSet(serverName) {
72
+ const server = this.toolSets.get(serverName);
73
+ if (!server) {
74
+ throw new InvalidMCPUsageError(`MCP server '${serverName}' is not available for this agent`);
75
+ }
76
+ return server;
77
+ }
78
+ async handleListTools(req) {
79
+ const { server } = req;
80
+ const mcp = this.getToolSet(server);
81
+ const response = await mcp.listTools();
82
+ if (isAuthRequired(response)) {
83
+ throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot list tools from sandbox`);
84
+ }
85
+ return response.result;
86
+ }
87
+ async handleCallTool(req) {
88
+ const { server, tool, arguments: args } = req;
89
+ const response = await this.getToolSet(server).callTool({ name: tool, arguments: args ?? {} });
90
+ if (isAuthRequired(response)) {
91
+ throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot call tool from sandbox`);
92
+ }
93
+ if (isCallToolResponseCreateSubAgent(response)) {
94
+ throw new InvalidMCPUsageError(`Tool '${server}/${tool}' creates a sub-agent and is not callable from sandbox`);
95
+ }
96
+ if (!isCallToolResponseResult(response)) {
97
+ throw new InvalidMCPUsageError(
98
+ `Tool '${server}/${tool}' requires interactive handling and is not callable from sandbox`
99
+ );
100
+ }
101
+ return response.result;
102
+ }
103
+ };
104
+ export {
105
+ CodeModeDispatcher
106
+ };
107
+ //# sourceMappingURL=CodeModeDispatcher.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/sandbox/codeMode/CodeModeDispatcher.ts"],"sourcesContent":["import { context, defaultTextMapGetter } from '@opentelemetry/api';\nimport { unsuppressTracing, W3CTraceContextPropagator } from '@opentelemetry/core';\nimport { McpConnectionError } from '../../errors';\nimport {\n isAuthRequired,\n isCallToolResponseCreateSubAgent,\n isCallToolResponseResult,\n type IToolSet,\n} from '../../mcp/IMCPServer';\nimport { extractErrorLogFields } from '../../util/errorLogFields';\nimport type { CodeModeErrorSource, CodeModeReply, CodeModeRequest } from './types';\n\n/** Minimal logger surface used by Code Mode (avoids a hard winston dep for PoC binders). */\nexport interface CodeModeLogger {\n child(bindings: Record<string, unknown>): CodeModeLogger;\n error(message: string, meta?: unknown): void;\n}\n\n// Caller-caused failure: retrying won't help.\nclass InvalidMCPUsageError extends Error {\n override readonly name = 'InvalidMCPUsageError';\n}\n\nfunction isHttpClientError(error: unknown): error is { status: number } {\n if (typeof error !== 'object' || error === null || !('status' in error)) {\n return false;\n }\n const { status } = error;\n return typeof status === 'number' && status >= 400 && status < 500;\n}\n\nfunction classifyErrorSource(e: unknown): CodeModeErrorSource {\n if (e instanceof InvalidMCPUsageError) return 'caller';\n if (isHttpClientError(e)) return 'caller';\n if (e instanceof McpConnectionError && e.statusCode >= 400 && e.statusCode < 500) return 'caller';\n return 'internal';\n}\n\n// Direct W3C extractor, NOT the global `propagation` API. The gateway-wide propagator\n// refuses to restore traceparent unless internal-secret headers are present. Code Mode\n// is intra-process trusted, so we bypass that gate and honor the sandbox carrier.\nconst _w3cExtractor = new W3CTraceContextPropagator();\n\n/**\n * Shared Code Mode policy leaf: tool routing, authz, error `source`. No NATS/UDS.\n */\nexport class CodeModeDispatcher {\n private readonly toolSets: Map<string, IToolSet>;\n private readonly logger: CodeModeLogger;\n private closed = false;\n\n constructor(params: { toolSets: readonly IToolSet[]; logger: CodeModeLogger }) {\n this.toolSets = new Map();\n for (const server of params.toolSets) {\n this.toolSets.set(server.name, server);\n }\n this.logger = params.logger.child({ module: 'CodeModeDispatcher' });\n }\n\n close(): void {\n this.closed = true;\n }\n\n async dispatch(params: {\n request: CodeModeRequest;\n traceCarrier: Readonly<Record<string, string>>;\n }): Promise<CodeModeReply> {\n if (this.closed) {\n return { ok: false, error: 'Code Mode dispatcher is closed', source: 'transport' };\n }\n\n const ctx = _w3cExtractor.extract(\n unsuppressTracing(context.active()),\n { ...params.traceCarrier },\n defaultTextMapGetter,\n );\n\n try {\n const result = await context.with(ctx, () => this.route(params.request));\n return { ok: true, result };\n } catch (e) {\n const source = classifyErrorSource(e);\n const errorMessage = e instanceof Error ? e.message : 'Unknown Code Mode dispatch error';\n this.logger.error(`Code Mode dispatch failed (source=${source})`, extractErrorLogFields(e));\n return { ok: false, error: errorMessage, source };\n }\n }\n\n private route(request: CodeModeRequest): Promise<unknown> {\n switch (request.op) {\n case 'list_tools':\n return this.handleListTools(request);\n case 'call_tool':\n return this.handleCallTool(request);\n default:\n throw new InvalidMCPUsageError(`Unknown Code Mode operation`);\n }\n }\n\n private getToolSet(serverName: string): IToolSet {\n const server = this.toolSets.get(serverName);\n if (!server) {\n throw new InvalidMCPUsageError(`MCP server '${serverName}' is not available for this agent`);\n }\n return server;\n }\n\n private async handleListTools(req: { server: string }): Promise<unknown> {\n const { server } = req;\n const mcp = this.getToolSet(server);\n const response = await mcp.listTools();\n if (isAuthRequired(response)) {\n throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot list tools from sandbox`);\n }\n return response.result;\n }\n\n private async handleCallTool(req: {\n server: string;\n tool: string;\n arguments?: Record<string, unknown> | undefined;\n }): Promise<unknown> {\n const { server, tool, arguments: args } = req;\n const response = await this.getToolSet(server).callTool({ name: tool, arguments: args ?? {} });\n if (isAuthRequired(response)) {\n throw new InvalidMCPUsageError(`MCP server '${server}' requires OAuth; cannot call tool from sandbox`);\n }\n if (isCallToolResponseCreateSubAgent(response)) {\n throw new InvalidMCPUsageError(`Tool '${server}/${tool}' creates a sub-agent and is not callable from sandbox`);\n }\n if (!isCallToolResponseResult(response)) {\n throw new InvalidMCPUsageError(\n `Tool '${server}/${tool}' requires interactive handling and is not callable from sandbox`,\n );\n }\n return response.result;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,21 @@
1
+ import type { CodeModeDispatcher } from './CodeModeDispatcher';
2
+ /**
3
+ * Code Mode channel. Construct eagerly with the dispatcher; connect/listen in `start`.
4
+ * `start` may be called again after failure; `stop` is always valid after construct.
5
+ */
6
+ export interface CodeModeTransport {
7
+ /**
8
+ * Lazy connect/listen; may be called again after a failed attempt (non-sticky).
9
+ * Idempotent once successfully started.
10
+ */
11
+ start(params: {
12
+ codeModeDispatcher: CodeModeDispatcher;
13
+ sandboxId: string;
14
+ requestTimeoutSeconds: number;
15
+ }): Promise<{
16
+ env: Record<string, string>;
17
+ }>;
18
+ /** Best-effort teardown whether start succeeded, failed, or never ran. */
19
+ stop(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=CodeModeTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeModeTransport.d.ts","sourceRoot":"","sources":["../../../../src/core/sandbox/codeMode/CodeModeTransport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE;QAAE,kBAAkB,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACnH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC7B,CAAC,CAAC;IACH,0EAA0E;IAC1E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/core/sandbox/codeMode/CodeModeTransport.ts
17
+ var CodeModeTransport_exports = {};
18
+ module.exports = __toCommonJS(CodeModeTransport_exports);
19
+ //# sourceMappingURL=CodeModeTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/sandbox/codeMode/CodeModeTransport.ts"],"sourcesContent":["import type { CodeModeDispatcher } from './CodeModeDispatcher';\n\n/**\n * Code Mode channel. Construct eagerly with the dispatcher; connect/listen in `start`.\n * `start` may be called again after failure; `stop` is always valid after construct.\n */\nexport interface CodeModeTransport {\n /**\n * Lazy connect/listen; may be called again after a failed attempt (non-sticky).\n * Idempotent once successfully started.\n */\n start(params: { codeModeDispatcher: CodeModeDispatcher; sandboxId: string; requestTimeoutSeconds: number }): Promise<{\n env: Record<string, string>;\n }>;\n /** Best-effort teardown whether start succeeded, failed, or never ran. */\n stop(): Promise<void>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=CodeModeTransport.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,34 @@
1
+ import type { Logger } from 'winston';
2
+ import type { CodeModeDispatcher } from '../CodeModeDispatcher';
3
+ import type { CodeModeTransport } from '../CodeModeTransport';
4
+ /**
5
+ * NATS Code Mode transport. Session cache + connection-drop invalidate live here
6
+ * (no `whenClosed` on the public interface).
7
+ */
8
+ export declare class CodeModeNatsTransport implements CodeModeTransport {
9
+ private readonly resolveHostUrl;
10
+ private readonly sandboxClientNatsUrl;
11
+ private readonly logger;
12
+ private sessionPromise;
13
+ private nc;
14
+ private dispatcher;
15
+ constructor(params: {
16
+ resolveHostUrl: (sandboxId: string) => Promise<string>;
17
+ sandboxClientNatsUrl?: string;
18
+ logger: Logger;
19
+ });
20
+ start(params: {
21
+ codeModeDispatcher: CodeModeDispatcher;
22
+ sandboxId: string;
23
+ requestTimeoutSeconds: number;
24
+ }): Promise<{
25
+ env: Record<string, string>;
26
+ }>;
27
+ stop(): Promise<void>;
28
+ private connectSession;
29
+ private subscribe;
30
+ private handleMessage;
31
+ private encode;
32
+ private decode;
33
+ }
34
+ //# sourceMappingURL=CodeModeNatsTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeModeNatsTransport.d.ts","sourceRoot":"","sources":["../../../../../src/core/sandbox/codeMode/nats/CodeModeNatsTransport.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAe9D;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyC;IACxE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,cAAc,CAAuD;IAC7E,OAAO,CAAC,EAAE,CAA6B;IACvC,OAAO,CAAC,UAAU,CAAiC;IAEnD,YAAY,MAAM,EAAE;QAClB,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,MAAM,EAAE,MAAM,CAAC;KAChB,EAIA;IAED,KAAK,CAAC,MAAM,EAAE;QACZ,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,qBAAqB,EAAE,MAAM,CAAC;KAC/B,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAO3C;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqB1B;YAEa,cAAc;IAkD5B,OAAO,CAAC,SAAS;YAQH,aAAa;IA+C3B,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,MAAM;CAIf"}
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/sandbox/codeMode/nats/CodeModeNatsTransport.ts
21
+ var CodeModeNatsTransport_exports = {};
22
+ __export(CodeModeNatsTransport_exports, {
23
+ CodeModeNatsTransport: () => CodeModeNatsTransport
24
+ });
25
+ module.exports = __toCommonJS(CodeModeNatsTransport_exports);
26
+ var import_nats_core = require("@nats-io/nats-core");
27
+ var import_api = require("@opentelemetry/api");
28
+ var import_core = require("@opentelemetry/core");
29
+ var import_node_crypto = require("crypto");
30
+ var import_ws = require("ws");
31
+ var import_errorLogFields = require("../../../util/errorLogFields.js");
32
+ var import_promiseUtils = require("../../../util/promiseUtils.js");
33
+ var import_constants = require("../../constants.js");
34
+ var import_types = require("../types.js");
35
+ Object.assign(global, { WebSocket: import_ws.WebSocket });
36
+ var NATS_CONNECT_TIMEOUT_MS = 1e4;
37
+ var NATS_CONNECT_RETRIES = 3;
38
+ var NATS_CONNECT_BACKOFF_MS = 250;
39
+ var NATS_DRAIN_TIMEOUT_MS = 5e3;
40
+ var SANDBOX_NATS_SUBJECT_ROOT = "sandbox.bridge";
41
+ var SANDBOX_NATS_MCP_LEAF = "mcp";
42
+ var CodeModeNatsTransport = class {
43
+ resolveHostUrl;
44
+ sandboxClientNatsUrl;
45
+ logger;
46
+ sessionPromise;
47
+ nc;
48
+ dispatcher;
49
+ constructor(params) {
50
+ this.resolveHostUrl = params.resolveHostUrl;
51
+ this.sandboxClientNatsUrl = params.sandboxClientNatsUrl ?? `ws://localhost:${String(import_constants.DEFAULT_SANDBOX_NATS_WS_PORT)}`;
52
+ this.logger = params.logger.child({ module: "CodeModeNatsTransport" });
53
+ }
54
+ start(params) {
55
+ this.dispatcher = params.codeModeDispatcher;
56
+ this.sessionPromise ??= this.connectSession(params).catch((e) => {
57
+ this.sessionPromise = void 0;
58
+ throw e;
59
+ });
60
+ return this.sessionPromise;
61
+ }
62
+ async stop() {
63
+ const pending = this.sessionPromise;
64
+ this.sessionPromise = void 0;
65
+ if (pending !== void 0) {
66
+ try {
67
+ await pending;
68
+ } catch {
69
+ }
70
+ }
71
+ const nc = this.nc;
72
+ this.nc = void 0;
73
+ if (nc === void 0) return;
74
+ try {
75
+ await (0, import_promiseUtils.withTimeout)(nc.drain(), NATS_DRAIN_TIMEOUT_MS);
76
+ } catch (e) {
77
+ this.logger.warn("Code Mode NATS drain failed/timed out; forcing close", (0, import_errorLogFields.extractErrorLogFields)(e));
78
+ await nc.close().catch(() => {
79
+ });
80
+ }
81
+ }
82
+ async connectSession(params) {
83
+ const url = await this.resolveHostUrl(params.sandboxId);
84
+ const subjectPrefix = `${SANDBOX_NATS_SUBJECT_ROOT}.${(0, import_node_crypto.randomUUID)()}`;
85
+ let lastErr;
86
+ let nc;
87
+ for (let attempt = 1; attempt <= NATS_CONNECT_RETRIES; attempt++) {
88
+ try {
89
+ nc = await import_api.context.with(
90
+ (0, import_core.suppressTracing)(import_api.context.active()),
91
+ () => (0, import_nats_core.wsconnect)({ servers: [url], timeout: NATS_CONNECT_TIMEOUT_MS })
92
+ );
93
+ this.logger.info(`Connected to sandbox NATS (attempt ${String(attempt)})`, { subjectPrefix });
94
+ break;
95
+ } catch (e) {
96
+ lastErr = e;
97
+ this.logger.warn(`Code Mode NATS connect attempt ${String(attempt)} failed`, (0, import_errorLogFields.extractErrorLogFields)(e));
98
+ if (attempt < NATS_CONNECT_RETRIES) {
99
+ await new Promise((resolve) => setTimeout(resolve, NATS_CONNECT_BACKOFF_MS));
100
+ }
101
+ }
102
+ }
103
+ if (nc === void 0) {
104
+ throw lastErr instanceof Error ? lastErr : new Error("Code Mode NATS connect failed");
105
+ }
106
+ this.nc = nc;
107
+ this.subscribe(nc, subjectPrefix);
108
+ const cachedPromise = this.sessionPromise;
109
+ void nc.closed().then(() => {
110
+ if (this.sessionPromise === cachedPromise) {
111
+ this.sessionPromise = void 0;
112
+ this.nc = void 0;
113
+ this.logger.info("Code Mode NATS connection closed; session invalidated", {
114
+ sandboxId: params.sandboxId
115
+ });
116
+ }
117
+ });
118
+ return {
119
+ env: {
120
+ TFY_NATS_URL: this.sandboxClientNatsUrl,
121
+ TFY_NATS_SUBJECT_PREFIX: subjectPrefix,
122
+ TFY_CM_REQUEST_TIMEOUT_SECONDS: String(params.requestTimeoutSeconds)
123
+ }
124
+ };
125
+ }
126
+ subscribe(nc, subjectPrefix) {
127
+ nc.subscribe(`${subjectPrefix}.${SANDBOX_NATS_MCP_LEAF}`, {
128
+ callback: (err, msg) => {
129
+ void this.handleMessage(err, msg);
130
+ }
131
+ });
132
+ }
133
+ async handleMessage(err, msg) {
134
+ if (err) {
135
+ this.logger.error("Code Mode NATS subscription error", (0, import_errorLogFields.extractErrorLogFields)(err));
136
+ return;
137
+ }
138
+ if (!msg.reply) {
139
+ this.logger.warn(`Code Mode NATS request on '${msg.subject}' has no reply subject; dropping`);
140
+ return;
141
+ }
142
+ const dispatcher = this.dispatcher;
143
+ if (dispatcher === void 0) {
144
+ try {
145
+ msg.respond(this.encode({ ok: false, error: "Code Mode dispatcher is not configured", source: "internal" }));
146
+ } catch (e) {
147
+ this.logger.warn(`Failed to send dispatcher-missing reply on '${msg.subject}'`, (0, import_errorLogFields.extractErrorLogFields)(e));
148
+ }
149
+ return;
150
+ }
151
+ const carrier = {};
152
+ const traceparent = msg.headers?.get("traceparent");
153
+ const tracestate = msg.headers?.get("tracestate");
154
+ if (traceparent) carrier["traceparent"] = traceparent;
155
+ if (tracestate) carrier["tracestate"] = tracestate;
156
+ let request;
157
+ try {
158
+ request = this.decode(msg);
159
+ } catch (e) {
160
+ this.logger.error(`Failed to decode Code Mode NATS request on '${msg.subject}'`, (0, import_errorLogFields.extractErrorLogFields)(e));
161
+ try {
162
+ msg.respond(this.encode({ ok: false, error: "Malformed Code Mode request", source: "caller" }));
163
+ } catch (respondErr) {
164
+ this.logger.warn(`Failed to send decode-error reply on '${msg.subject}'`, (0, import_errorLogFields.extractErrorLogFields)(respondErr));
165
+ }
166
+ return;
167
+ }
168
+ const reply = await dispatcher.dispatch({ request, traceCarrier: carrier });
169
+ try {
170
+ msg.respond(this.encode(reply));
171
+ } catch (e) {
172
+ this.logger.error("Failed to publish Code Mode NATS reply", (0, import_errorLogFields.extractErrorLogFields)(e));
173
+ }
174
+ }
175
+ encode(reply) {
176
+ return new TextEncoder().encode(JSON.stringify(reply));
177
+ }
178
+ decode(msg) {
179
+ const raw = JSON.parse(new TextDecoder().decode(msg.data));
180
+ return import_types.CodeModeRequestSchema.parse(raw);
181
+ }
182
+ };
183
+ // Annotate the CommonJS export names for ESM import in node:
184
+ 0 && (module.exports = {
185
+ CodeModeNatsTransport
186
+ });
187
+ //# sourceMappingURL=CodeModeNatsTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/core/sandbox/codeMode/nats/CodeModeNatsTransport.ts"],"sourcesContent":["import { wsconnect, type Msg, type NatsConnection } from '@nats-io/nats-core';\nimport { context } from '@opentelemetry/api';\nimport { suppressTracing } from '@opentelemetry/core';\nimport { randomUUID } from 'node:crypto';\nimport type { Logger } from 'winston';\nimport { WebSocket } from 'ws';\nimport { extractErrorLogFields } from '../../../util/errorLogFields';\nimport { withTimeout } from '../../../util/promiseUtils';\nimport { DEFAULT_SANDBOX_NATS_WS_PORT } from '../../constants';\nimport type { CodeModeDispatcher } from '../CodeModeDispatcher';\nimport type { CodeModeTransport } from '../CodeModeTransport';\nimport { CodeModeRequestSchema, type CodeModeReply, type CodeModeRequest } from '../types';\n\n// `wsconnect` from @nats-io/nats-core relies on a global WebSocket constructor; in Node we\n// provide it from `ws`. Same pattern as `src/services/NatsService.ts`.\nObject.assign(global, { WebSocket });\n\nconst NATS_CONNECT_TIMEOUT_MS = 10_000;\nconst NATS_CONNECT_RETRIES = 3;\nconst NATS_CONNECT_BACKOFF_MS = 250;\nconst NATS_DRAIN_TIMEOUT_MS = 5_000;\n\nconst SANDBOX_NATS_SUBJECT_ROOT = 'sandbox.bridge';\nconst SANDBOX_NATS_MCP_LEAF = 'mcp';\n\n/**\n * NATS Code Mode transport. Session cache + connection-drop invalidate live here\n * (no `whenClosed` on the public interface).\n */\nexport class CodeModeNatsTransport implements CodeModeTransport {\n private readonly resolveHostUrl: (sandboxId: string) => Promise<string>;\n private readonly sandboxClientNatsUrl: string;\n private readonly logger: Logger;\n\n private sessionPromise: Promise<{ env: Record<string, string> }> | undefined;\n private nc: NatsConnection | undefined;\n private dispatcher: CodeModeDispatcher | undefined;\n\n constructor(params: {\n resolveHostUrl: (sandboxId: string) => Promise<string>;\n sandboxClientNatsUrl?: string;\n logger: Logger;\n }) {\n this.resolveHostUrl = params.resolveHostUrl;\n this.sandboxClientNatsUrl = params.sandboxClientNatsUrl ?? `ws://localhost:${String(DEFAULT_SANDBOX_NATS_WS_PORT)}`;\n this.logger = params.logger.child({ module: 'CodeModeNatsTransport' });\n }\n\n start(params: {\n codeModeDispatcher: CodeModeDispatcher;\n sandboxId: string;\n requestTimeoutSeconds: number;\n }): Promise<{ env: Record<string, string> }> {\n this.dispatcher = params.codeModeDispatcher;\n this.sessionPromise ??= this.connectSession(params).catch((e: unknown) => {\n this.sessionPromise = undefined;\n throw e;\n });\n return this.sessionPromise;\n }\n\n async stop(): Promise<void> {\n const pending = this.sessionPromise;\n this.sessionPromise = undefined;\n if (pending !== undefined) {\n try {\n await pending;\n } catch {\n // Connect failed; nothing to drain.\n }\n }\n const nc = this.nc;\n this.nc = undefined;\n if (nc === undefined) return;\n try {\n await withTimeout(nc.drain(), NATS_DRAIN_TIMEOUT_MS);\n } catch (e) {\n this.logger.warn('Code Mode NATS drain failed/timed out; forcing close', extractErrorLogFields(e));\n await nc.close().catch(() => {\n /* no-op */\n });\n }\n }\n\n private async connectSession(params: {\n sandboxId: string;\n requestTimeoutSeconds: number;\n }): Promise<{ env: Record<string, string> }> {\n const url = await this.resolveHostUrl(params.sandboxId);\n const subjectPrefix = `${SANDBOX_NATS_SUBJECT_ROOT}.${randomUUID()}`;\n let lastErr: unknown;\n let nc: NatsConnection | undefined;\n for (let attempt = 1; attempt <= NATS_CONNECT_RETRIES; attempt++) {\n try {\n nc = await context.with(suppressTracing(context.active()), () =>\n wsconnect({ servers: [url], timeout: NATS_CONNECT_TIMEOUT_MS }),\n );\n this.logger.info(`Connected to sandbox NATS (attempt ${String(attempt)})`, { subjectPrefix });\n break;\n } catch (e) {\n lastErr = e;\n this.logger.warn(`Code Mode NATS connect attempt ${String(attempt)} failed`, extractErrorLogFields(e));\n if (attempt < NATS_CONNECT_RETRIES) {\n await new Promise(resolve => setTimeout(resolve, NATS_CONNECT_BACKOFF_MS));\n }\n }\n }\n if (nc === undefined) {\n throw lastErr instanceof Error ? lastErr : new Error('Code Mode NATS connect failed');\n }\n\n this.nc = nc;\n this.subscribe(nc, subjectPrefix);\n\n const cachedPromise = this.sessionPromise;\n void nc.closed().then(() => {\n if (this.sessionPromise === cachedPromise) {\n this.sessionPromise = undefined;\n this.nc = undefined;\n this.logger.info('Code Mode NATS connection closed; session invalidated', {\n sandboxId: params.sandboxId,\n });\n }\n });\n\n return {\n env: {\n TFY_NATS_URL: this.sandboxClientNatsUrl,\n TFY_NATS_SUBJECT_PREFIX: subjectPrefix,\n TFY_CM_REQUEST_TIMEOUT_SECONDS: String(params.requestTimeoutSeconds),\n },\n };\n }\n\n private subscribe(nc: NatsConnection, subjectPrefix: string): void {\n nc.subscribe(`${subjectPrefix}.${SANDBOX_NATS_MCP_LEAF}`, {\n callback: (err, msg) => {\n void this.handleMessage(err, msg);\n },\n });\n }\n\n private async handleMessage(err: Error | null, msg: Msg): Promise<void> {\n if (err) {\n this.logger.error('Code Mode NATS subscription error', extractErrorLogFields(err));\n return;\n }\n if (!msg.reply) {\n this.logger.warn(`Code Mode NATS request on '${msg.subject}' has no reply subject; dropping`);\n return;\n }\n\n const dispatcher = this.dispatcher;\n if (dispatcher === undefined) {\n try {\n msg.respond(this.encode({ ok: false, error: 'Code Mode dispatcher is not configured', source: 'internal' }));\n } catch (e) {\n this.logger.warn(`Failed to send dispatcher-missing reply on '${msg.subject}'`, extractErrorLogFields(e));\n }\n return;\n }\n\n const carrier: Record<string, string> = {};\n const traceparent = msg.headers?.get('traceparent');\n const tracestate = msg.headers?.get('tracestate');\n if (traceparent) carrier['traceparent'] = traceparent;\n if (tracestate) carrier['tracestate'] = tracestate;\n\n let request: CodeModeRequest;\n try {\n request = this.decode(msg);\n } catch (e) {\n this.logger.error(`Failed to decode Code Mode NATS request on '${msg.subject}'`, extractErrorLogFields(e));\n try {\n msg.respond(this.encode({ ok: false, error: 'Malformed Code Mode request', source: 'caller' }));\n } catch (respondErr) {\n this.logger.warn(`Failed to send decode-error reply on '${msg.subject}'`, extractErrorLogFields(respondErr));\n }\n return;\n }\n\n const reply = await dispatcher.dispatch({ request, traceCarrier: carrier });\n try {\n msg.respond(this.encode(reply));\n } catch (e) {\n this.logger.error('Failed to publish Code Mode NATS reply', extractErrorLogFields(e));\n }\n }\n\n private encode(reply: CodeModeReply): Uint8Array {\n return new TextEncoder().encode(JSON.stringify(reply));\n }\n\n private decode(msg: Msg): CodeModeRequest {\n const raw: unknown = JSON.parse(new TextDecoder().decode(msg.data));\n return CodeModeRequestSchema.parse(raw);\n }\n}\n"],"mappings":"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","names":[]}