@truefoundry/trueforge-core 0.1.0-rc.0 → 0.1.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 +27 -0
  2. package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
  3. package/dist/agent-session/TurnResourceResolver.js +6 -2
  4. package/dist/agent-session/TurnResourceResolver.js.map +1 -1
  5. package/dist/agent-session/TurnResourceResolver.mjs +6 -2
  6. package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
  7. package/dist/agent-session/schemas/turn.d.ts.map +1 -1
  8. package/dist/agent-session/schemas/turn.js +3 -1
  9. package/dist/agent-session/schemas/turn.js.map +1 -1
  10. package/dist/agent-session/schemas/turn.mjs +3 -1
  11. package/dist/agent-session/schemas/turn.mjs.map +1 -1
  12. package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
  13. package/dist/agent-session/store/InMemorySessionStore.js +24 -8
  14. package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
  15. package/dist/agent-session/store/InMemorySessionStore.mjs +24 -8
  16. package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
  17. package/dist/agent-session/store/OffsetPageToken.d.ts.map +1 -1
  18. package/dist/agent-session/store/OffsetPageToken.js +3 -1
  19. package/dist/agent-session/store/OffsetPageToken.js.map +1 -1
  20. package/dist/agent-session/store/OffsetPageToken.mjs +3 -1
  21. package/dist/agent-session/store/OffsetPageToken.mjs.map +1 -1
  22. package/dist/agent-session/store/SessionListPageToken.d.ts.map +1 -1
  23. package/dist/agent-session/store/SessionListPageToken.js +3 -1
  24. package/dist/agent-session/store/SessionListPageToken.js.map +1 -1
  25. package/dist/agent-session/store/SessionListPageToken.mjs +3 -1
  26. package/dist/agent-session/store/SessionListPageToken.mjs.map +1 -1
  27. package/dist/core/InstructionBuilder.d.ts.map +1 -1
  28. package/dist/core/InstructionBuilder.js +12 -4
  29. package/dist/core/InstructionBuilder.js.map +1 -1
  30. package/dist/core/InstructionBuilder.mjs +12 -4
  31. package/dist/core/InstructionBuilder.mjs.map +1 -1
  32. package/dist/core/capabilities/builtins/AskUserQuestion.d.ts.map +1 -1
  33. package/dist/core/capabilities/builtins/AskUserQuestion.js +5 -0
  34. package/dist/core/capabilities/builtins/AskUserQuestion.js.map +1 -1
  35. package/dist/core/capabilities/builtins/AskUserQuestion.mjs +5 -0
  36. package/dist/core/capabilities/builtins/AskUserQuestion.mjs.map +1 -1
  37. package/dist/core/capabilities/builtins/LargeToolResponse.d.ts.map +1 -1
  38. package/dist/core/capabilities/builtins/LargeToolResponse.js +6 -2
  39. package/dist/core/capabilities/builtins/LargeToolResponse.js.map +1 -1
  40. package/dist/core/capabilities/builtins/LargeToolResponse.mjs +6 -2
  41. package/dist/core/capabilities/builtins/LargeToolResponse.mjs.map +1 -1
  42. package/dist/core/index.d.ts +9 -3
  43. package/dist/core/index.d.ts.map +1 -1
  44. package/dist/core/index.js +25 -0
  45. package/dist/core/index.js.map +1 -1
  46. package/dist/core/index.mjs +24 -2
  47. package/dist/core/index.mjs.map +1 -1
  48. package/dist/core/llm/VercelAILLM.d.ts +1 -0
  49. package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
  50. package/dist/core/llm/VercelAILLM.js +13 -14
  51. package/dist/core/llm/VercelAILLM.js.map +1 -1
  52. package/dist/core/llm/VercelAILLM.mjs +13 -15
  53. package/dist/core/llm/VercelAILLM.mjs.map +1 -1
  54. package/dist/core/mcp/RemoteMCP.d.ts.map +1 -1
  55. package/dist/core/mcp/RemoteMCP.js +15 -5
  56. package/dist/core/mcp/RemoteMCP.js.map +1 -1
  57. package/dist/core/mcp/RemoteMCP.mjs +15 -5
  58. package/dist/core/mcp/RemoteMCP.mjs.map +1 -1
  59. package/dist/core/mcp/ToolSelectorPolicy.d.ts.map +1 -1
  60. package/dist/core/mcp/ToolSelectorPolicy.js +3 -1
  61. package/dist/core/mcp/ToolSelectorPolicy.js.map +1 -1
  62. package/dist/core/mcp/ToolSelectorPolicy.mjs +3 -1
  63. package/dist/core/mcp/ToolSelectorPolicy.mjs.map +1 -1
  64. package/dist/core/mcp/ToolSet.d.ts.map +1 -1
  65. package/dist/core/mcp/ToolSet.js +9 -3
  66. package/dist/core/mcp/ToolSet.js.map +1 -1
  67. package/dist/core/mcp/ToolSet.mjs +9 -3
  68. package/dist/core/mcp/ToolSet.mjs.map +1 -1
  69. package/dist/core/mcp/convertMCPServers.d.ts.map +1 -1
  70. package/dist/core/mcp/convertMCPServers.js +6 -2
  71. package/dist/core/mcp/convertMCPServers.js.map +1 -1
  72. package/dist/core/mcp/convertMCPServers.mjs +6 -2
  73. package/dist/core/mcp/convertMCPServers.mjs.map +1 -1
  74. package/dist/core/mcp/remoteMcpClient.d.ts.map +1 -1
  75. package/dist/core/mcp/remoteMcpClient.js +21 -7
  76. package/dist/core/mcp/remoteMcpClient.js.map +1 -1
  77. package/dist/core/mcp/remoteMcpClient.mjs +21 -7
  78. package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
  79. package/dist/core/mcp/toolSelectors.d.ts.map +1 -1
  80. package/dist/core/mcp/toolSelectors.js +18 -6
  81. package/dist/core/mcp/toolSelectors.js.map +1 -1
  82. package/dist/core/mcp/toolSelectors.mjs +18 -6
  83. package/dist/core/mcp/toolSelectors.mjs.map +1 -1
  84. package/dist/core/runtime/AgentThread.d.ts.map +1 -1
  85. package/dist/core/runtime/AgentThread.js +45 -15
  86. package/dist/core/runtime/AgentThread.js.map +1 -1
  87. package/dist/core/runtime/AgentThread.mjs +45 -15
  88. package/dist/core/runtime/AgentThread.mjs.map +1 -1
  89. package/dist/core/runtime/AgentThreadOrchestrator.d.ts.map +1 -1
  90. package/dist/core/runtime/AgentThreadOrchestrator.js +27 -9
  91. package/dist/core/runtime/AgentThreadOrchestrator.js.map +1 -1
  92. package/dist/core/runtime/AgentThreadOrchestrator.mjs +27 -9
  93. package/dist/core/runtime/AgentThreadOrchestrator.mjs.map +1 -1
  94. package/dist/core/runtime/DeferredTool.d.ts.map +1 -1
  95. package/dist/core/runtime/DeferredTool.js +15 -5
  96. package/dist/core/runtime/DeferredTool.js.map +1 -1
  97. package/dist/core/runtime/DeferredTool.mjs +15 -5
  98. package/dist/core/runtime/DeferredTool.mjs.map +1 -1
  99. package/dist/core/runtime/contextUtils.d.ts.map +1 -1
  100. package/dist/core/runtime/contextUtils.js +3 -1
  101. package/dist/core/runtime/contextUtils.js.map +1 -1
  102. package/dist/core/runtime/contextUtils.mjs +3 -1
  103. package/dist/core/runtime/contextUtils.mjs.map +1 -1
  104. package/dist/core/sandbox/Sandbox.d.ts +7 -9
  105. package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
  106. package/dist/core/sandbox/Sandbox.js +55 -63
  107. package/dist/core/sandbox/Sandbox.js.map +1 -1
  108. package/dist/core/sandbox/Sandbox.mjs +56 -64
  109. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  110. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts +29 -0
  111. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -0
  112. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +134 -0
  113. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -0
  114. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +113 -0
  115. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -0
  116. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +21 -0
  117. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -0
  118. package/dist/core/sandbox/codeMode/CodeModeTransport.js +19 -0
  119. package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -0
  120. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs +1 -0
  121. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs.map +1 -0
  122. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +34 -0
  123. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -0
  124. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +193 -0
  125. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -0
  126. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +168 -0
  127. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -0
  128. package/dist/core/sandbox/codeMode/types.d.ts +34 -0
  129. package/dist/core/sandbox/codeMode/types.d.ts.map +1 -0
  130. package/dist/core/sandbox/codeMode/types.js +59 -0
  131. package/dist/core/sandbox/codeMode/types.js.map +1 -0
  132. package/dist/core/sandbox/codeMode/types.mjs +32 -0
  133. package/dist/core/sandbox/codeMode/types.mjs.map +1 -0
  134. package/dist/core/sandbox/provider/DaytonaProvider.d.ts +19 -1
  135. package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
  136. package/dist/core/sandbox/provider/DaytonaProvider.js +96 -23
  137. package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
  138. package/dist/core/sandbox/provider/DaytonaProvider.mjs +96 -23
  139. package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
  140. package/dist/core/sandbox/provider/Provider.d.ts +4 -3
  141. package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
  142. package/dist/core/sandbox/provider/Provider.js.map +1 -1
  143. package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
  144. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +2 -1
  145. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
  146. package/dist/core/sandbox/provider/TFYSandboxProvider.js +20 -6
  147. package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
  148. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +20 -6
  149. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
  150. package/dist/core/sandbox/sandboxImage.d.ts +1 -1
  151. package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
  152. package/dist/core/sandbox/sandboxImage.js +1 -1
  153. package/dist/core/sandbox/sandboxImage.js.map +1 -1
  154. package/dist/core/sandbox/sandboxImage.mjs +1 -1
  155. package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
  156. package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
  157. package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
  158. package/dist/core/sandbox/sandboxScripts.gen.js +8 -8
  159. package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
  160. package/dist/core/sandbox/sandboxScripts.gen.mjs +8 -8
  161. package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
  162. package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
  163. package/dist/core/sandbox/skills/SkillMounter.js +3 -1
  164. package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
  165. package/dist/core/sandbox/skills/SkillMounter.mjs +3 -1
  166. package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
  167. package/dist/core/util/abort.d.ts.map +1 -1
  168. package/dist/core/util/abort.js +3 -1
  169. package/dist/core/util/abort.js.map +1 -1
  170. package/dist/core/util/abort.mjs +3 -1
  171. package/dist/core/util/abort.mjs.map +1 -1
  172. package/dist/core/util/errorLogFields.d.ts +5 -0
  173. package/dist/core/util/errorLogFields.d.ts.map +1 -1
  174. package/dist/core/util/errorLogFields.js +38 -2
  175. package/dist/core/util/errorLogFields.js.map +1 -1
  176. package/dist/core/util/errorLogFields.mjs +37 -2
  177. package/dist/core/util/errorLogFields.mjs.map +1 -1
  178. package/package.json +10 -6
  179. package/dist/core/sandbox/SandboxNatsBridge.d.ts +0 -33
  180. package/dist/core/sandbox/SandboxNatsBridge.d.ts.map +0 -1
  181. package/dist/core/sandbox/SandboxNatsBridge.js +0 -222
  182. package/dist/core/sandbox/SandboxNatsBridge.js.map +0 -1
  183. package/dist/core/sandbox/SandboxNatsBridge.mjs +0 -201
  184. package/dist/core/sandbox/SandboxNatsBridge.mjs.map +0 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared Code Mode request/reply wire shapes (NATS body and UDS JSON).
3
+ */
4
+ import { z } from 'zod';
5
+ export declare const CodeModeRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6
+ op: z.ZodLiteral<"list_tools">;
7
+ server: z.ZodString;
8
+ }, z.core.$strip>, z.ZodObject<{
9
+ op: z.ZodLiteral<"call_tool">;
10
+ server: z.ZodString;
11
+ tool: z.ZodString;
12
+ arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
13
+ }, z.core.$strip>], "op">;
14
+ export type CodeModeRequest = z.infer<typeof CodeModeRequestSchema>;
15
+ export declare const CodeModeErrorSourceSchema: z.ZodEnum<{
16
+ caller: "caller";
17
+ internal: "internal";
18
+ transport: "transport";
19
+ }>;
20
+ export type CodeModeErrorSource = z.infer<typeof CodeModeErrorSourceSchema>;
21
+ export declare const CodeModeReplySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22
+ ok: z.ZodLiteral<true>;
23
+ result: z.ZodUnknown;
24
+ }, z.core.$strip>, z.ZodObject<{
25
+ ok: z.ZodLiteral<false>;
26
+ error: z.ZodString;
27
+ source: z.ZodEnum<{
28
+ caller: "caller";
29
+ internal: "internal";
30
+ transport: "transport";
31
+ }>;
32
+ }, z.core.$strip>], "ok">;
33
+ export type CodeModeReply = z.infer<typeof CodeModeReplySchema>;
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/sandbox/codeMode/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qBAAqB;;;;;;;;yBAWhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,yBAAyB;;;;EAA8C,CAAC;AACrF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,mBAAmB;;;;;;;;;;;yBAU9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,59 @@
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/types.ts
21
+ var types_exports = {};
22
+ __export(types_exports, {
23
+ CodeModeErrorSourceSchema: () => CodeModeErrorSourceSchema,
24
+ CodeModeReplySchema: () => CodeModeReplySchema,
25
+ CodeModeRequestSchema: () => CodeModeRequestSchema
26
+ });
27
+ module.exports = __toCommonJS(types_exports);
28
+ var import_zod = require("zod");
29
+ var CodeModeRequestSchema = import_zod.z.discriminatedUnion("op", [
30
+ import_zod.z.object({
31
+ op: import_zod.z.literal("list_tools"),
32
+ server: import_zod.z.string().min(1)
33
+ }),
34
+ import_zod.z.object({
35
+ op: import_zod.z.literal("call_tool"),
36
+ server: import_zod.z.string().min(1),
37
+ tool: import_zod.z.string().min(1),
38
+ arguments: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional()
39
+ })
40
+ ]);
41
+ var CodeModeErrorSourceSchema = import_zod.z.enum(["internal", "caller", "transport"]);
42
+ var CodeModeReplySchema = import_zod.z.discriminatedUnion("ok", [
43
+ import_zod.z.object({
44
+ ok: import_zod.z.literal(true),
45
+ result: import_zod.z.unknown()
46
+ }),
47
+ import_zod.z.object({
48
+ ok: import_zod.z.literal(false),
49
+ error: import_zod.z.string(),
50
+ source: CodeModeErrorSourceSchema
51
+ })
52
+ ]);
53
+ // Annotate the CommonJS export names for ESM import in node:
54
+ 0 && (module.exports = {
55
+ CodeModeErrorSourceSchema,
56
+ CodeModeReplySchema,
57
+ CodeModeRequestSchema
58
+ });
59
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/sandbox/codeMode/types.ts"],"sourcesContent":["/**\n * Shared Code Mode request/reply wire shapes (NATS body and UDS JSON).\n */\nimport { z } from 'zod';\n\nexport const CodeModeRequestSchema = z.discriminatedUnion('op', [\n z.object({\n op: z.literal('list_tools'),\n server: z.string().min(1),\n }),\n z.object({\n op: z.literal('call_tool'),\n server: z.string().min(1),\n tool: z.string().min(1),\n arguments: z.record(z.string(), z.unknown()).optional(),\n }),\n]);\nexport type CodeModeRequest = z.infer<typeof CodeModeRequestSchema>;\n\nexport const CodeModeErrorSourceSchema = z.enum(['internal', 'caller', 'transport']);\nexport type CodeModeErrorSource = z.infer<typeof CodeModeErrorSourceSchema>;\n\nexport const CodeModeReplySchema = z.discriminatedUnion('ok', [\n z.object({\n ok: z.literal(true),\n result: z.unknown(),\n }),\n z.object({\n ok: z.literal(false),\n error: z.string(),\n source: CodeModeErrorSourceSchema,\n }),\n]);\nexport type CodeModeReply = z.infer<typeof CodeModeReplySchema>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAkB;AAEX,IAAM,wBAAwB,aAAE,mBAAmB,MAAM;AAAA,EAC9D,aAAE,OAAO;AAAA,IACP,IAAI,aAAE,QAAQ,YAAY;AAAA,IAC1B,QAAQ,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,CAAC;AAAA,EACD,aAAE,OAAO;AAAA,IACP,IAAI,aAAE,QAAQ,WAAW;AAAA,IACzB,QAAQ,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxB,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACtB,WAAW,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACxD,CAAC;AACH,CAAC;AAGM,IAAM,4BAA4B,aAAE,KAAK,CAAC,YAAY,UAAU,WAAW,CAAC;AAG5E,IAAM,sBAAsB,aAAE,mBAAmB,MAAM;AAAA,EAC5D,aAAE,OAAO;AAAA,IACP,IAAI,aAAE,QAAQ,IAAI;AAAA,IAClB,QAAQ,aAAE,QAAQ;AAAA,EACpB,CAAC;AAAA,EACD,aAAE,OAAO;AAAA,IACP,IAAI,aAAE,QAAQ,KAAK;AAAA,IACnB,OAAO,aAAE,OAAO;AAAA,IAChB,QAAQ;AAAA,EACV,CAAC;AACH,CAAC;","names":[]}
@@ -0,0 +1,32 @@
1
+ // src/core/sandbox/codeMode/types.ts
2
+ import { z } from "zod";
3
+ var CodeModeRequestSchema = z.discriminatedUnion("op", [
4
+ z.object({
5
+ op: z.literal("list_tools"),
6
+ server: z.string().min(1)
7
+ }),
8
+ z.object({
9
+ op: z.literal("call_tool"),
10
+ server: z.string().min(1),
11
+ tool: z.string().min(1),
12
+ arguments: z.record(z.string(), z.unknown()).optional()
13
+ })
14
+ ]);
15
+ var CodeModeErrorSourceSchema = z.enum(["internal", "caller", "transport"]);
16
+ var CodeModeReplySchema = z.discriminatedUnion("ok", [
17
+ z.object({
18
+ ok: z.literal(true),
19
+ result: z.unknown()
20
+ }),
21
+ z.object({
22
+ ok: z.literal(false),
23
+ error: z.string(),
24
+ source: CodeModeErrorSourceSchema
25
+ })
26
+ ]);
27
+ export {
28
+ CodeModeErrorSourceSchema,
29
+ CodeModeReplySchema,
30
+ CodeModeRequestSchema
31
+ };
32
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/core/sandbox/codeMode/types.ts"],"sourcesContent":["/**\n * Shared Code Mode request/reply wire shapes (NATS body and UDS JSON).\n */\nimport { z } from 'zod';\n\nexport const CodeModeRequestSchema = z.discriminatedUnion('op', [\n z.object({\n op: z.literal('list_tools'),\n server: z.string().min(1),\n }),\n z.object({\n op: z.literal('call_tool'),\n server: z.string().min(1),\n tool: z.string().min(1),\n arguments: z.record(z.string(), z.unknown()).optional(),\n }),\n]);\nexport type CodeModeRequest = z.infer<typeof CodeModeRequestSchema>;\n\nexport const CodeModeErrorSourceSchema = z.enum(['internal', 'caller', 'transport']);\nexport type CodeModeErrorSource = z.infer<typeof CodeModeErrorSourceSchema>;\n\nexport const CodeModeReplySchema = z.discriminatedUnion('ok', [\n z.object({\n ok: z.literal(true),\n result: z.unknown(),\n }),\n z.object({\n ok: z.literal(false),\n error: z.string(),\n source: CodeModeErrorSourceSchema,\n }),\n]);\nexport type CodeModeReply = z.infer<typeof CodeModeReplySchema>;\n"],"mappings":";AAGA,SAAS,SAAS;AAEX,IAAM,wBAAwB,EAAE,mBAAmB,MAAM;AAAA,EAC9D,EAAE,OAAO;AAAA,IACP,IAAI,EAAE,QAAQ,YAAY;AAAA,IAC1B,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,IAAI,EAAE,QAAQ,WAAW;AAAA,IACzB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACtB,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACxD,CAAC;AACH,CAAC;AAGM,IAAM,4BAA4B,EAAE,KAAK,CAAC,YAAY,UAAU,WAAW,CAAC;AAG5E,IAAM,sBAAsB,EAAE,mBAAmB,MAAM;AAAA,EAC5D,EAAE,OAAO;AAAA,IACP,IAAI,EAAE,QAAQ,IAAI;AAAA,IAClB,QAAQ,EAAE,QAAQ;AAAA,EACpB,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,IAAI,EAAE,QAAQ,KAAK;AAAA,IACnB,OAAO,EAAE,OAAO;AAAA,IAChB,QAAQ;AAAA,EACV,CAAC;AACH,CAAC;","names":[]}
@@ -1,9 +1,17 @@
1
1
  import { Daytona } from '@daytona/sdk';
2
2
  import type { Logger } from 'winston';
3
+ import type { CodeModeTransport } from '../codeMode/CodeModeTransport';
3
4
  import type { ExecResult, SandboxBuild, SandboxExecParams, SandboxProvider } from './Provider';
4
5
  export interface DaytonaSandboxProviderOptions {
5
6
  /** Caller-owned Daytona SDK client (credentials / lifetime). */
6
7
  client: Daytona;
8
+ /**
9
+ * Same API key the client was built with; used for the register-only snapshot POST because the
10
+ * SDK's `snapshot.create` polls to a terminal state instead of returning once registered.
11
+ */
12
+ apiKey: string;
13
+ /** Daytona API base URL (including `/api`). Defaults to the SDK's public cloud endpoint. */
14
+ apiUrl?: string | undefined;
7
15
  tenantName: string;
8
16
  /** Release-owned sandbox image reference; built into a Daytona snapshot and cloned per sandbox. */
9
17
  sandboxImage: string;
@@ -37,6 +45,8 @@ export declare class DaytonaSandboxProvider implements SandboxProvider {
37
45
  private readonly fileMaxBytesForDownload;
38
46
  private readonly natsBridgePort;
39
47
  private readonly previewUrlExpirySeconds;
48
+ private readonly apiKey;
49
+ private readonly apiUrl;
40
50
  private readonly logger;
41
51
  private readonly daytona;
42
52
  private static readonly cachedSandboxes;
@@ -58,6 +68,14 @@ export declare class DaytonaSandboxProvider implements SandboxProvider {
58
68
  */
59
69
  private deleteFailedBuild;
60
70
  private toBuild;
71
+ /**
72
+ * Registers the snapshot and returns its initial state without waiting for the build.
73
+ *
74
+ * The SDK's `snapshot.create` issues this same POST and then polls until the snapshot is active
75
+ * or failed (minutes on a cold image pull). Configure only needs the registration result, so
76
+ * credential errors surface on the request while build progress stays observable via `getSnapshot`.
77
+ */
78
+ private registerSnapshot;
61
79
  buildImage(): Promise<SandboxBuild>;
62
80
  getImageBuildStatus(): Promise<SandboxBuild>;
63
81
  exec(params: SandboxExecParams): Promise<ExecResult>;
@@ -72,7 +90,7 @@ export declare class DaytonaSandboxProvider implements SandboxProvider {
72
90
  content: Buffer;
73
91
  }): Promise<void>;
74
92
  private getPreviewUrl;
75
- getNatsBridgeUrl(sandboxId: string): Promise<string>;
93
+ createCodeModeTransport(): CodeModeTransport;
76
94
  getAdditionalInstructions(): string | undefined;
77
95
  getToolResultDumpDir(): string;
78
96
  getGitCredentialsPath(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"DaytonaProvider.d.ts","sourceRoot":"","sources":["../../../../src/core/sandbox/provider/DaytonaProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DaytonaProvider.d.ts","sourceRoot":"","sources":["../../../../src/core/sandbox/provider/DaytonaProvider.ts"],"names":[],"mappings":"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"}
@@ -29,14 +29,20 @@ var import_core = require("@opentelemetry/core");
29
29
  var import_crypto = require("crypto");
30
30
  var import_errorLogFields = require("../../util/errorLogFields.js");
31
31
  var import_SandboxErrors = require("../SandboxErrors.js");
32
+ var import_CodeModeNatsTransport = require("../codeMode/nats/CodeModeNatsTransport.js");
32
33
  var import_constants = require("../constants.js");
33
34
  var SANDBOX_NOT_FOUND_STATUS = 404;
35
+ var SNAPSHOT_CONFLICT_STATUS = 409;
34
36
  var SANDBOX_STATE_STARTED = "started";
35
37
  var BUILD_STATE_ACTIVE = "active";
36
38
  var BUILD_STATE_INACTIVE = "inactive";
37
39
  var BUILD_STATE_ERROR = "error";
38
40
  var BUILD_STATE_BUILD_FAILED = "build_failed";
39
41
  var IMAGE_BUILD_NAME_PREFIX = "trueforge-build-";
42
+ var DEFAULT_DAYTONA_API_URL = "https://app.daytona.io/api";
43
+ function isRecord(value) {
44
+ return typeof value === "object" && value !== null;
45
+ }
40
46
  function imageDigest(image) {
41
47
  const lastSegment = image.slice(image.lastIndexOf("/") + 1);
42
48
  const colon = lastSegment.lastIndexOf(":");
@@ -53,8 +59,11 @@ function isFailedBuildState(state) {
53
59
  }
54
60
  function httpUrlToWsUrl(url) {
55
61
  const parsed = new URL(url);
56
- if (parsed.protocol === "https:") parsed.protocol = "wss:";
57
- else if (parsed.protocol === "http:") parsed.protocol = "ws:";
62
+ if (parsed.protocol === "https:") {
63
+ parsed.protocol = "wss:";
64
+ } else if (parsed.protocol === "http:") {
65
+ parsed.protocol = "ws:";
66
+ }
58
67
  return parsed.toString();
59
68
  }
60
69
  var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
@@ -70,6 +79,8 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
70
79
  fileMaxBytesForDownload;
71
80
  natsBridgePort;
72
81
  previewUrlExpirySeconds;
82
+ apiKey;
83
+ apiUrl;
73
84
  logger;
74
85
  daytona;
75
86
  static cachedSandboxes = /* @__PURE__ */ new Map();
@@ -77,6 +88,8 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
77
88
  static inFlightRecoveries = /* @__PURE__ */ new Map();
78
89
  constructor(options) {
79
90
  this.daytona = options.client;
91
+ this.apiKey = options.apiKey;
92
+ this.apiUrl = options.apiUrl ?? DEFAULT_DAYTONA_API_URL;
80
93
  this.tenantName = options.tenantName;
81
94
  this.imageUri = options.sandboxImage;
82
95
  this.buildRef = options.buildRef ?? deriveImageBuildName(imageDigest(options.sandboxImage));
@@ -92,7 +105,9 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
92
105
  async getOrCreateSandbox(sandboxId) {
93
106
  if (sandboxId) {
94
107
  const cached = _DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);
95
- if (cached) return cached;
108
+ if (cached) {
109
+ return cached;
110
+ }
96
111
  }
97
112
  const sandbox = sandboxId ? await this.restoreExistingSandbox(sandboxId) : await this.daytona.create({
98
113
  name: `${this.tenantName}.${(0, import_crypto.randomUUID)()}`,
@@ -108,12 +123,18 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
108
123
  // Returns true iff the caller should retry: either we restarted a stopped sandbox, or the cache entry is missing and the retry will rebuild it via the cold path.
109
124
  static recoverSandboxIfStopped(sandboxId) {
110
125
  const existing = _DaytonaSandboxProvider.inFlightRecoveries.get(sandboxId);
111
- if (existing) return existing;
126
+ if (existing) {
127
+ return existing;
128
+ }
112
129
  const cached = _DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);
113
- if (!cached) return Promise.resolve(true);
130
+ if (!cached) {
131
+ return Promise.resolve(true);
132
+ }
114
133
  const recovery = (async () => {
115
134
  await cached.sandbox.refreshData();
116
- if (cached.sandbox.state === SANDBOX_STATE_STARTED) return false;
135
+ if (cached.sandbox.state === SANDBOX_STATE_STARTED) {
136
+ return false;
137
+ }
117
138
  await cached.sandbox.start();
118
139
  return true;
119
140
  })().finally(() => {
@@ -126,7 +147,9 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
126
147
  try {
127
148
  return await operation();
128
149
  } catch (originalError) {
129
- if (!(originalError instanceof import_sdk.DaytonaError)) throw originalError;
150
+ if (!(originalError instanceof import_sdk.DaytonaError)) {
151
+ throw originalError;
152
+ }
130
153
  let recovered;
131
154
  try {
132
155
  recovered = await _DaytonaSandboxProvider.recoverSandboxIfStopped(sandboxId);
@@ -137,7 +160,9 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
137
160
  });
138
161
  throw new Error("Sandbox is unavailable; recovery attempt failed.", { cause: recoveryError });
139
162
  }
140
- if (!recovered) throw originalError;
163
+ if (!recovered) {
164
+ throw originalError;
165
+ }
141
166
  try {
142
167
  return await operation();
143
168
  } catch (retryError) {
@@ -208,6 +233,40 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
208
233
  return { status: "pending", reason: `Sandbox image build in progress (${state}).`, metadata };
209
234
  }
210
235
  }
236
+ /**
237
+ * Registers the snapshot and returns its initial state without waiting for the build.
238
+ *
239
+ * The SDK's `snapshot.create` issues this same POST and then polls until the snapshot is active
240
+ * or failed (minutes on a cold image pull). Configure only needs the registration result, so
241
+ * credential errors surface on the request while build progress stays observable via `getSnapshot`.
242
+ */
243
+ async registerSnapshot() {
244
+ let response;
245
+ try {
246
+ response = await fetch(`${this.apiUrl}/snapshots`, {
247
+ method: "POST",
248
+ headers: {
249
+ Authorization: `Bearer ${this.apiKey}`,
250
+ "Content-Type": "application/json"
251
+ },
252
+ body: JSON.stringify({ name: this.buildRef, imageName: this.imageUri })
253
+ });
254
+ } catch (error) {
255
+ throw new Error("Daytona snapshot registration request failed.", { cause: error });
256
+ }
257
+ const body = await response.json().catch(() => null);
258
+ if (!response.ok) {
259
+ const message = isRecord(body) && typeof body["message"] === "string" ? body["message"] : `Daytona snapshot registration failed (${String(response.status)})`;
260
+ throw new import_sdk.DaytonaError(message, response.status);
261
+ }
262
+ if (!isRecord(body) || typeof body["state"] !== "string") {
263
+ throw new import_sdk.DaytonaError("Failed to register snapshot. Daytona didn't return a snapshot state.");
264
+ }
265
+ return {
266
+ state: body["state"],
267
+ errorReason: typeof body["errorReason"] === "string" ? body["errorReason"] : null
268
+ };
269
+ }
211
270
  async buildImage() {
212
271
  const existing = await this.getSnapshot(this.buildRef);
213
272
  if (existing) {
@@ -220,14 +279,20 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
220
279
  }
221
280
  await this.deleteFailedBuild(existing);
222
281
  }
223
- void this.daytona.snapshot.create({ name: this.buildRef, image: this.imageUri }).catch((error) => {
224
- this.logger.error(`Daytona snapshot create failed: name=${this.buildRef}`, (0, import_errorLogFields.extractErrorLogFields)(error));
225
- });
226
- return {
227
- status: "pending",
228
- reason: "Sandbox image build started.",
229
- metadata: { build_ref: this.buildRef, image_uri: this.imageUri }
230
- };
282
+ try {
283
+ const registered = await this.registerSnapshot();
284
+ return this.toBuild(registered.state, registered.errorReason);
285
+ } catch (error) {
286
+ if (error instanceof import_sdk.DaytonaError && error.statusCode === SNAPSHOT_CONFLICT_STATUS) {
287
+ this.logger.info(`Daytona snapshot already created concurrently: name=${this.buildRef}`);
288
+ return {
289
+ status: "pending",
290
+ reason: "Sandbox image build started by another server replica.",
291
+ metadata: { build_ref: this.buildRef, image_uri: this.imageUri }
292
+ };
293
+ }
294
+ throw error;
295
+ }
231
296
  }
232
297
  async getImageBuildStatus() {
233
298
  const snapshot = await this.getSnapshot(this.buildRef);
@@ -283,7 +348,9 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
283
348
  return await sandbox.fs.downloadFile(params.path);
284
349
  });
285
350
  } catch (e) {
286
- if (e instanceof import_SandboxErrors.SandboxPathIsDirectoryError || e instanceof import_SandboxErrors.SandboxFileTooLargeError) throw e;
351
+ if (e instanceof import_SandboxErrors.SandboxPathIsDirectoryError || e instanceof import_SandboxErrors.SandboxFileTooLargeError) {
352
+ throw e;
353
+ }
287
354
  if (e instanceof import_sdk.DaytonaError && e.statusCode === SANDBOX_NOT_FOUND_STATUS) {
288
355
  throw new import_SandboxErrors.SandboxFileNotFoundError(params.path);
289
356
  }
@@ -321,13 +388,19 @@ var DaytonaSandboxProvider = class _DaytonaSandboxProvider {
321
388
  }
322
389
  });
323
390
  }
324
- async getNatsBridgeUrl(sandboxId) {
325
- const previewUrl = await this.getPreviewUrl({
326
- sandboxId,
327
- port: this.natsBridgePort,
328
- expiresInSeconds: this.previewUrlExpirySeconds
391
+ createCodeModeTransport() {
392
+ return new import_CodeModeNatsTransport.CodeModeNatsTransport({
393
+ resolveHostUrl: async (sandboxId) => {
394
+ const previewUrl = await this.getPreviewUrl({
395
+ sandboxId,
396
+ port: this.natsBridgePort,
397
+ expiresInSeconds: this.previewUrlExpirySeconds
398
+ });
399
+ return httpUrlToWsUrl(previewUrl);
400
+ },
401
+ sandboxClientNatsUrl: `ws://localhost:${String(this.natsBridgePort)}`,
402
+ logger: this.logger
329
403
  });
330
- return httpUrlToWsUrl(previewUrl);
331
404
  }
332
405
  getAdditionalInstructions() {
333
406
  return void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/sandbox/provider/DaytonaProvider.ts"],"sourcesContent":["import type { Sandbox, Snapshot } from '@daytona/sdk';\nimport { Daytona, DaytonaError } from '@daytona/sdk';\nimport { context } from '@opentelemetry/api';\nimport { suppressTracing } from '@opentelemetry/core';\nimport { randomUUID } from 'crypto';\nimport type { Logger } from 'winston';\nimport { extractErrorLogFields } from '../../util/errorLogFields';\nimport {\n SandboxFileNotFoundError,\n SandboxFileTooLargeError,\n SandboxNotAvailableError,\n SandboxPathIsDirectoryError,\n} from '../SandboxErrors';\nimport { DEFAULT_PREVIEW_URL_EXPIRY_SECONDS, DEFAULT_SANDBOX_NATS_WS_PORT } from '../constants';\nimport type { ExecResult, SandboxBuild, SandboxExecParams, SandboxFileInfo, SandboxProvider } from './Provider';\n\nconst SANDBOX_NOT_FOUND_STATUS = 404;\nconst SANDBOX_STATE_STARTED = 'started';\n\nconst BUILD_STATE_ACTIVE = 'active';\nconst BUILD_STATE_INACTIVE = 'inactive';\nconst BUILD_STATE_ERROR = 'error';\nconst BUILD_STATE_BUILD_FAILED = 'build_failed';\n\nconst IMAGE_BUILD_NAME_PREFIX = 'trueforge-build-';\n\n/**\n * Digest portion of a container image reference (the tag/digest after the final `:`)\n * The release image is always published with an explicit digest tag\n */\nfunction imageDigest(image: string): string {\n const lastSegment = image.slice(image.lastIndexOf('/') + 1);\n const colon = lastSegment.lastIndexOf(':');\n if (colon === -1) {\n throw new Error(`Sandbox image reference has no tag/digest: ${image}`);\n }\n return lastSegment.slice(colon + 1);\n}\n\n/** Deterministic build name per image digest so every server replica converges on one build. */\nfunction deriveImageBuildName(digest: string): string {\n return `${IMAGE_BUILD_NAME_PREFIX}${digest}`;\n}\n\n/** Terminal-failure build states: a build stuck here never becomes ready on its own. */\nfunction isFailedBuildState(state: Snapshot['state']): boolean {\n return state === BUILD_STATE_ERROR || state === BUILD_STATE_BUILD_FAILED;\n}\n\n/** Convert Daytona https preview URLs to wss for the NATS client. */\nfunction httpUrlToWsUrl(url: string): string {\n const parsed = new URL(url);\n if (parsed.protocol === 'https:') parsed.protocol = 'wss:';\n else if (parsed.protocol === 'http:') parsed.protocol = 'ws:';\n return parsed.toString();\n}\n\nexport interface DaytonaSandboxProviderOptions {\n /** Caller-owned Daytona SDK client (credentials / lifetime). */\n client: Daytona;\n tenantName: string;\n /** Release-owned sandbox image reference; built into a Daytona snapshot and cloned per sandbox. */\n sandboxImage: string;\n /**\n * Daytona snapshot name to clone sandboxes from. When omitted it is derived from the image\n * digest. Callers that create sandboxes pass the persisted build_ref so cloning targets the\n * snapshot that was actually built, not a speculative name derived from the current image.\n */\n buildRef?: string | undefined;\n timeoutMs: number;\n autoStopIntervalInMinutes: number;\n autoArchiveIntervalInMinutes: number;\n autoDeleteIntervalInMinutes: number;\n fileMaxBytesForDownload: number;\n /** Defaults to the built-in sandbox NATS WebSocket port (4444). */\n natsBridgePort?: number;\n /** Defaults to 1 hour (same as the gateway's max agent execution time). */\n previewUrlExpirySeconds?: number;\n logger: Logger;\n}\n\nexport class DaytonaSandboxProvider implements SandboxProvider {\n private readonly tenantName: string;\n /** Release-owned sandbox image reference; built into a Daytona snapshot and cloned per sandbox. */\n private readonly imageUri: string;\n /** Daytona snapshot name sandboxes are cloned from; the persisted build_ref, or derived from the image digest. */\n private readonly buildRef: string;\n private readonly timeoutMs: number;\n private readonly autoStopIntervalInMinutes: number;\n private readonly autoArchiveIntervalInMinutes: number;\n private readonly autoDeleteIntervalInMinutes: number;\n private readonly fileMaxBytesForDownload: number;\n private readonly natsBridgePort: number;\n private readonly previewUrlExpirySeconds: number;\n private readonly logger: Logger;\n private readonly daytona: Daytona;\n private static readonly cachedSandboxes = new Map<string, { sandbox: Sandbox; defaultTimeoutMs: number }>();\n // De-dupes concurrent recovery attempts on the same sandbox to a single refreshData+start round-trip.\n private static readonly inFlightRecoveries = new Map<string, Promise<boolean>>();\n\n constructor(options: DaytonaSandboxProviderOptions) {\n this.daytona = options.client;\n this.tenantName = options.tenantName;\n this.imageUri = options.sandboxImage;\n this.buildRef = options.buildRef ?? deriveImageBuildName(imageDigest(options.sandboxImage));\n this.timeoutMs = options.timeoutMs;\n this.autoStopIntervalInMinutes = options.autoStopIntervalInMinutes;\n this.autoArchiveIntervalInMinutes = options.autoArchiveIntervalInMinutes;\n this.autoDeleteIntervalInMinutes = options.autoDeleteIntervalInMinutes;\n this.fileMaxBytesForDownload = options.fileMaxBytesForDownload;\n this.natsBridgePort = options.natsBridgePort ?? DEFAULT_SANDBOX_NATS_WS_PORT;\n this.previewUrlExpirySeconds = options.previewUrlExpirySeconds ?? DEFAULT_PREVIEW_URL_EXPIRY_SECONDS;\n this.logger = options.logger.child({ module: 'DaytonaProvider' });\n }\n\n private async getOrCreateSandbox(sandboxId?: string): Promise<{ sandbox: Sandbox; defaultTimeoutMs: number }> {\n if (sandboxId) {\n const cached = DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);\n if (cached) return cached;\n }\n\n const sandbox = sandboxId\n ? await this.restoreExistingSandbox(sandboxId)\n : await this.daytona.create({\n name: `${this.tenantName}.${randomUUID()}`,\n snapshot: this.buildRef,\n autoStopInterval: this.autoStopIntervalInMinutes,\n autoArchiveInterval: this.autoArchiveIntervalInMinutes,\n autoDeleteInterval: this.autoDeleteIntervalInMinutes,\n });\n\n const entry = { sandbox, defaultTimeoutMs: this.timeoutMs };\n DaytonaSandboxProvider.cachedSandboxes.set(sandbox.name, entry);\n return entry;\n }\n\n // Returns true iff the caller should retry: either we restarted a stopped sandbox, or the cache entry is missing and the retry will rebuild it via the cold path.\n private static recoverSandboxIfStopped(sandboxId: string): Promise<boolean> {\n const existing = DaytonaSandboxProvider.inFlightRecoveries.get(sandboxId);\n if (existing) return existing;\n\n const cached = DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);\n // Cache may have been evicted by a concurrent error path; signal retry so getOrCreateSandbox rebuilds via restoreExistingSandbox.\n if (!cached) return Promise.resolve(true);\n\n const recovery = (async () => {\n await cached.sandbox.refreshData();\n if (cached.sandbox.state === SANDBOX_STATE_STARTED) return false;\n // start() covers both stopped and archived per Daytona; throws on unrecoverable states (error/destroyed).\n await cached.sandbox.start();\n return true;\n })().finally(() => {\n DaytonaSandboxProvider.inFlightRecoveries.delete(sandboxId);\n });\n\n DaytonaSandboxProvider.inFlightRecoveries.set(sandboxId, recovery);\n return recovery;\n }\n\n private async executeWithSandboxRecovery<T>(sandboxId: string, operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (originalError) {\n // TODO: Narrow to a specific Daytona error code once @daytona/sdk exposes one for \"sandbox not running\".\n if (!(originalError instanceof DaytonaError)) throw originalError;\n\n let recovered: boolean;\n try {\n recovered = await DaytonaSandboxProvider.recoverSandboxIfStopped(sandboxId);\n } catch (recoveryError) {\n this.logger.error('Sandbox recovery failed', {\n ...extractErrorLogFields(recoveryError),\n originalError: extractErrorLogFields(originalError),\n });\n throw new Error('Sandbox is unavailable; recovery attempt failed.', { cause: recoveryError });\n }\n\n if (!recovered) throw originalError;\n\n try {\n return await operation();\n } catch (retryError) {\n this.logger.error('Sandbox operation failed after successful recovery', {\n ...extractErrorLogFields(retryError),\n originalError: extractErrorLogFields(originalError),\n });\n // Rethrow as-is so callers can match domain error types (SandboxPathIsDirectoryError, DaytonaError statusCode mappings, etc.).\n throw retryError;\n }\n }\n }\n\n private async restoreExistingSandbox(sandboxId: string): Promise<Sandbox> {\n try {\n const sandbox = await this.daytona.get(sandboxId);\n if (sandbox.state !== SANDBOX_STATE_STARTED) {\n await sandbox.start();\n }\n return sandbox;\n } catch (ex) {\n if (ex instanceof DaytonaError && ex.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n throw new SandboxNotAvailableError(sandboxId);\n }\n throw ex;\n }\n }\n\n async createSandbox(): Promise<{ sandboxId: string }> {\n return context.with(suppressTracing(context.active()), async () => {\n const { sandbox } = await this.getOrCreateSandbox();\n this.logger.debug(`Sandbox created: name=${sandbox.name}`);\n return { sandboxId: sandbox.name };\n });\n }\n\n /** Resolves undefined when no snapshot carries that name; auth/other failures throw. */\n private async getSnapshot(name: string): Promise<Snapshot | undefined> {\n try {\n return await this.daytona.snapshot.get(name);\n } catch (error) {\n if (error instanceof DaytonaError && error.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * Drops a build stuck in a terminal-failure state so a fresh create can reuse its\n * deterministic name. A concurrent replica may have deleted it already (404) — that\n * is fine and treated as success.\n */\n private async deleteFailedBuild(snapshot: Snapshot): Promise<void> {\n try {\n await this.daytona.snapshot.delete(snapshot);\n } catch (error) {\n if (error instanceof DaytonaError && error.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n return;\n }\n throw error;\n }\n }\n\n private toBuild(state: Snapshot['state'], errorReason: string | null): SandboxBuild {\n const metadata = { build_ref: this.buildRef, image_uri: this.imageUri };\n switch (state) {\n case BUILD_STATE_ACTIVE:\n return { status: 'ready', reason: null, metadata };\n case BUILD_STATE_ERROR:\n case BUILD_STATE_BUILD_FAILED:\n return { status: 'failed', reason: errorReason ?? `Sandbox image build failed (${state}).`, metadata };\n default:\n // pending / building / pulling / removing / future states: not ready yet.\n return { status: 'pending', reason: `Sandbox image build in progress (${state}).`, metadata };\n }\n }\n\n async buildImage(): Promise<SandboxBuild> {\n const existing = await this.getSnapshot(this.buildRef);\n if (existing) {\n // Daytona parks unused snapshots as 'inactive' after ~2 idle weeks; reactivate rather than rebuild.\n if (existing.state === BUILD_STATE_INACTIVE) {\n const activated = await this.daytona.snapshot.activate(existing);\n return this.toBuild(activated.state, activated.errorReason);\n }\n if (!isFailedBuildState(existing.state)) {\n return this.toBuild(existing.state, existing.errorReason);\n }\n // A failed build keeps the deterministic name occupied and never self-heals, so\n // re-saving settings (which calls buildImage) could never retry. Drop it, then recreate.\n await this.deleteFailedBuild(existing);\n }\n // Fire the create in the background: the SDK's snapshot.create polls until the snapshot is\n // terminal (minutes on a cold image pull), but Daytona registers it on the first request, so\n // progress is observed via getImageBuildStatus. A concurrent-create conflict is harmless.\n void this.daytona.snapshot.create({ name: this.buildRef, image: this.imageUri }).catch((error: unknown) => {\n this.logger.error(`Daytona snapshot create failed: name=${this.buildRef}`, extractErrorLogFields(error));\n });\n return {\n status: 'pending',\n reason: 'Sandbox image build started.',\n metadata: { build_ref: this.buildRef, image_uri: this.imageUri },\n };\n }\n\n async getImageBuildStatus(): Promise<SandboxBuild> {\n const snapshot = await this.getSnapshot(this.buildRef);\n // Read-only: a missing build reports pending; PUT /settings/sandbox-providers starts the build.\n if (!snapshot) {\n return {\n status: 'pending',\n reason: 'Sandbox image build not started.',\n metadata: { build_ref: this.buildRef, image_uri: this.imageUri },\n };\n }\n return this.toBuild(snapshot.state, snapshot.errorReason);\n }\n\n async exec(params: SandboxExecParams): Promise<ExecResult> {\n return context.with(suppressTracing(context.active()), async (): Promise<ExecResult> => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox, defaultTimeoutMs } = await this.getOrCreateSandbox(params.sandboxId);\n const response = await sandbox.process.executeCommand(\n params.command,\n params.cwd,\n params.env ?? {},\n params.timeoutSeconds ?? defaultTimeoutMs / 1000,\n );\n return {\n success: true,\n response: { exitCode: response.exitCode, result: response.result },\n };\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n this.logger.error('Sandbox execution error', extractErrorLogFields(e));\n const message = e instanceof Error ? e.message : 'Unknown error';\n return { success: false, error: message };\n }\n });\n }\n\n private async getFileInfo(sandbox: Sandbox, path: string): Promise<SandboxFileInfo> {\n const details = await sandbox.fs.getFileDetails(path);\n return { size: details.size, isDir: details.isDir };\n }\n\n async downloadFile(params: { sandboxId: string; path: string }): Promise<Buffer> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n\n const info = await this.getFileInfo(sandbox, params.path);\n if (info.isDir) {\n throw new SandboxPathIsDirectoryError(params.path);\n }\n if (info.size > this.fileMaxBytesForDownload) {\n throw new SandboxFileTooLargeError(params.path, info.size, this.fileMaxBytesForDownload);\n }\n\n return await sandbox.fs.downloadFile(params.path);\n });\n } catch (e: unknown) {\n if (e instanceof SandboxPathIsDirectoryError || e instanceof SandboxFileTooLargeError) throw e;\n if (e instanceof DaytonaError && e.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n throw new SandboxFileNotFoundError(params.path);\n }\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n throw e;\n }\n });\n }\n\n async uploadFile(params: { sandboxId: string; remotePath: string; content: Buffer }): Promise<void> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n await sandbox.fs.uploadFile(params.content, params.remotePath);\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n throw e;\n }\n });\n }\n\n // Mints a signed, time-limited https preview URL exposing the given sandbox port.\n private async getPreviewUrl(params: { sandboxId: string; port: number; expiresInSeconds: number }): Promise<string> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n const signed = await sandbox.getSignedPreviewUrl(params.port, params.expiresInSeconds);\n return signed.url;\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n this.logger.error('Failed to create signed preview URL', extractErrorLogFields(e));\n throw e;\n }\n });\n }\n\n async getNatsBridgeUrl(sandboxId: string): Promise<string> {\n // Daytona hands us a signed https preview URL; convert http(s) -> ws(s) for the NATS client.\n const previewUrl = await this.getPreviewUrl({\n sandboxId,\n port: this.natsBridgePort,\n expiresInSeconds: this.previewUrlExpirySeconds,\n });\n return httpUrlToWsUrl(previewUrl);\n }\n\n getAdditionalInstructions(): string | undefined {\n return undefined;\n }\n\n getToolResultDumpDir(): string {\n return '/tmp/tool-results';\n }\n\n getGitCredentialsPath(): string {\n // Isolated container per sandbox; absolute path so GIT_CONFIG_* needs no $HOME expansion.\n return '/tmp/.git-credentials';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAsC;AACtC,iBAAwB;AACxB,kBAAgC;AAChC,oBAA2B;AAE3B,4BAAsC;AACtC,2BAKO;AACP,uBAAiF;AAGjF,IAAM,2BAA2B;AACjC,IAAM,wBAAwB;AAE9B,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AAEjC,IAAM,0BAA0B;AAMhC,SAAS,YAAY,OAAuB;AAC1C,QAAM,cAAc,MAAM,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1D,QAAM,QAAQ,YAAY,YAAY,GAAG;AACzC,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI,MAAM,8CAA8C,KAAK,EAAE;AAAA,EACvE;AACA,SAAO,YAAY,MAAM,QAAQ,CAAC;AACpC;AAGA,SAAS,qBAAqB,QAAwB;AACpD,SAAO,GAAG,uBAAuB,GAAG,MAAM;AAC5C;AAGA,SAAS,mBAAmB,OAAmC;AAC7D,SAAO,UAAU,qBAAqB,UAAU;AAClD;AAGA,SAAS,eAAe,KAAqB;AAC3C,QAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,MAAI,OAAO,aAAa,SAAU,QAAO,WAAW;AAAA,WAC3C,OAAO,aAAa,QAAS,QAAO,WAAW;AACxD,SAAO,OAAO,SAAS;AACzB;AA0BO,IAAM,yBAAN,MAAM,wBAAkD;AAAA,EAC5C;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACjB,OAAwB,kBAAkB,oBAAI,IAA4D;AAAA;AAAA,EAE1G,OAAwB,qBAAqB,oBAAI,IAA8B;AAAA,EAE/E,YAAY,SAAwC;AAClD,SAAK,UAAU,QAAQ;AACvB,SAAK,aAAa,QAAQ;AAC1B,SAAK,WAAW,QAAQ;AACxB,SAAK,WAAW,QAAQ,YAAY,qBAAqB,YAAY,QAAQ,YAAY,CAAC;AAC1F,SAAK,YAAY,QAAQ;AACzB,SAAK,4BAA4B,QAAQ;AACzC,SAAK,+BAA+B,QAAQ;AAC5C,SAAK,8BAA8B,QAAQ;AAC3C,SAAK,0BAA0B,QAAQ;AACvC,SAAK,iBAAiB,QAAQ,kBAAkB;AAChD,SAAK,0BAA0B,QAAQ,2BAA2B;AAClE,SAAK,SAAS,QAAQ,OAAO,MAAM,EAAE,QAAQ,kBAAkB,CAAC;AAAA,EAClE;AAAA,EAEA,MAAc,mBAAmB,WAA6E;AAC5G,QAAI,WAAW;AACb,YAAM,SAAS,wBAAuB,gBAAgB,IAAI,SAAS;AACnE,UAAI,OAAQ,QAAO;AAAA,IACrB;AAEA,UAAM,UAAU,YACZ,MAAM,KAAK,uBAAuB,SAAS,IAC3C,MAAM,KAAK,QAAQ,OAAO;AAAA,MACxB,MAAM,GAAG,KAAK,UAAU,QAAI,0BAAW,CAAC;AAAA,MACxC,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK;AAAA,MACvB,qBAAqB,KAAK;AAAA,MAC1B,oBAAoB,KAAK;AAAA,IAC3B,CAAC;AAEL,UAAM,QAAQ,EAAE,SAAS,kBAAkB,KAAK,UAAU;AAC1D,4BAAuB,gBAAgB,IAAI,QAAQ,MAAM,KAAK;AAC9D,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAe,wBAAwB,WAAqC;AAC1E,UAAM,WAAW,wBAAuB,mBAAmB,IAAI,SAAS;AACxE,QAAI,SAAU,QAAO;AAErB,UAAM,SAAS,wBAAuB,gBAAgB,IAAI,SAAS;AAEnE,QAAI,CAAC,OAAQ,QAAO,QAAQ,QAAQ,IAAI;AAExC,UAAM,YAAY,YAAY;AAC5B,YAAM,OAAO,QAAQ,YAAY;AACjC,UAAI,OAAO,QAAQ,UAAU,sBAAuB,QAAO;AAE3D,YAAM,OAAO,QAAQ,MAAM;AAC3B,aAAO;AAAA,IACT,GAAG,EAAE,QAAQ,MAAM;AACjB,8BAAuB,mBAAmB,OAAO,SAAS;AAAA,IAC5D,CAAC;AAED,4BAAuB,mBAAmB,IAAI,WAAW,QAAQ;AACjE,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,2BAA8B,WAAmB,WAAyC;AACtG,QAAI;AACF,aAAO,MAAM,UAAU;AAAA,IACzB,SAAS,eAAe;AAEtB,UAAI,EAAE,yBAAyB,yBAAe,OAAM;AAEpD,UAAI;AACJ,UAAI;AACF,oBAAY,MAAM,wBAAuB,wBAAwB,SAAS;AAAA,MAC5E,SAAS,eAAe;AACtB,aAAK,OAAO,MAAM,2BAA2B;AAAA,UAC3C,OAAG,6CAAsB,aAAa;AAAA,UACtC,mBAAe,6CAAsB,aAAa;AAAA,QACpD,CAAC;AACD,cAAM,IAAI,MAAM,oDAAoD,EAAE,OAAO,cAAc,CAAC;AAAA,MAC9F;AAEA,UAAI,CAAC,UAAW,OAAM;AAEtB,UAAI;AACF,eAAO,MAAM,UAAU;AAAA,MACzB,SAAS,YAAY;AACnB,aAAK,OAAO,MAAM,sDAAsD;AAAA,UACtE,OAAG,6CAAsB,UAAU;AAAA,UACnC,mBAAe,6CAAsB,aAAa;AAAA,QACpD,CAAC;AAED,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,uBAAuB,WAAqC;AACxE,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,QAAQ,IAAI,SAAS;AAChD,UAAI,QAAQ,UAAU,uBAAuB;AAC3C,cAAM,QAAQ,MAAM;AAAA,MACtB;AACA,aAAO;AAAA,IACT,SAAS,IAAI;AACX,UAAI,cAAc,2BAAgB,GAAG,eAAe,0BAA0B;AAC5E,cAAM,IAAI,8CAAyB,SAAS;AAAA,MAC9C;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,mBAAQ,SAAK,6BAAgB,mBAAQ,OAAO,CAAC,GAAG,YAAY;AACjE,YAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,mBAAmB;AAClD,WAAK,OAAO,MAAM,yBAAyB,QAAQ,IAAI,EAAE;AACzD,aAAO,EAAE,WAAW,QAAQ,KAAK;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAc,YAAY,MAA6C;AACrE,QAAI;AACF,aAAO,MAAM,KAAK,QAAQ,SAAS,IAAI,IAAI;AAAA,IAC7C,SAAS,OAAO;AACd,UAAI,iBAAiB,2BAAgB,MAAM,eAAe,0BAA0B;AAClF,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,kBAAkB,UAAmC;AACjE,QAAI;AACF,YAAM,KAAK,QAAQ,SAAS,OAAO,QAAQ;AAAA,IAC7C,SAAS,OAAO;AACd,UAAI,iBAAiB,2BAAgB,MAAM,eAAe,0BAA0B;AAClF;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,QAAQ,OAA0B,aAA0C;AAClF,UAAM,WAAW,EAAE,WAAW,KAAK,UAAU,WAAW,KAAK,SAAS;AACtE,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,eAAO,EAAE,QAAQ,SAAS,QAAQ,MAAM,SAAS;AAAA,MACnD,KAAK;AAAA,MACL,KAAK;AACH,eAAO,EAAE,QAAQ,UAAU,QAAQ,eAAe,+BAA+B,KAAK,MAAM,SAAS;AAAA,MACvG;AAEE,eAAO,EAAE,QAAQ,WAAW,QAAQ,oCAAoC,KAAK,MAAM,SAAS;AAAA,IAChG;AAAA,EACF;AAAA,EAEA,MAAM,aAAoC;AACxC,UAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AACrD,QAAI,UAAU;AAEZ,UAAI,SAAS,UAAU,sBAAsB;AAC3C,cAAM,YAAY,MAAM,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAC/D,eAAO,KAAK,QAAQ,UAAU,OAAO,UAAU,WAAW;AAAA,MAC5D;AACA,UAAI,CAAC,mBAAmB,SAAS,KAAK,GAAG;AACvC,eAAO,KAAK,QAAQ,SAAS,OAAO,SAAS,WAAW;AAAA,MAC1D;AAGA,YAAM,KAAK,kBAAkB,QAAQ;AAAA,IACvC;AAIA,SAAK,KAAK,QAAQ,SAAS,OAAO,EAAE,MAAM,KAAK,UAAU,OAAO,KAAK,SAAS,CAAC,EAAE,MAAM,CAAC,UAAmB;AACzG,WAAK,OAAO,MAAM,wCAAwC,KAAK,QAAQ,QAAI,6CAAsB,KAAK,CAAC;AAAA,IACzG,CAAC;AACD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU,EAAE,WAAW,KAAK,UAAU,WAAW,KAAK,SAAS;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,sBAA6C;AACjD,UAAM,WAAW,MAAM,KAAK,YAAY,KAAK,QAAQ;AAErD,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU,EAAE,WAAW,KAAK,UAAU,WAAW,KAAK,SAAS;AAAA,MACjE;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,SAAS,OAAO,SAAS,WAAW;AAAA,EAC1D;AAAA,EAEA,MAAM,KAAK,QAAgD;AACzD,WAAO,mBAAQ,SAAK,6BAAgB,mBAAQ,OAAO,CAAC,GAAG,YAAiC;AACtF,UAAI;AACF,eAAO,MAAM,KAAK,2BAA2B,OAAO,WAAW,YAAY;AACzE,gBAAM,EAAE,SAAS,iBAAiB,IAAI,MAAM,KAAK,mBAAmB,OAAO,SAAS;AACpF,gBAAM,WAAW,MAAM,QAAQ,QAAQ;AAAA,YACrC,OAAO;AAAA,YACP,OAAO;AAAA,YACP,OAAO,OAAO,CAAC;AAAA,YACf,OAAO,kBAAkB,mBAAmB;AAAA,UAC9C;AACA,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU,EAAE,UAAU,SAAS,UAAU,QAAQ,SAAS,OAAO;AAAA,UACnE;AAAA,QACF,CAAC;AAAA,MACH,SAAS,GAAY;AACnB,gCAAuB,gBAAgB,OAAO,OAAO,SAAS;AAC9D,aAAK,OAAO,MAAM,+BAA2B,6CAAsB,CAAC,CAAC;AACrE,cAAM,UAAU,aAAa,QAAQ,EAAE,UAAU;AACjD,eAAO,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,YAAY,SAAkB,MAAwC;AAClF,UAAM,UAAU,MAAM,QAAQ,GAAG,eAAe,IAAI;AACpD,WAAO,EAAE,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM;AAAA,EACpD;AAAA,EAEA,MAAM,aAAa,QAA8D;AAC/E,WAAO,mBAAQ,SAAK,6BAAgB,mBAAQ,OAAO,CAAC,GAAG,YAAY;AACjE,UAAI;AACF,eAAO,MAAM,KAAK,2BAA2B,OAAO,WAAW,YAAY;AACzE,gBAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,mBAAmB,OAAO,SAAS;AAElE,gBAAM,OAAO,MAAM,KAAK,YAAY,SAAS,OAAO,IAAI;AACxD,cAAI,KAAK,OAAO;AACd,kBAAM,IAAI,iDAA4B,OAAO,IAAI;AAAA,UACnD;AACA,cAAI,KAAK,OAAO,KAAK,yBAAyB;AAC5C,kBAAM,IAAI,8CAAyB,OAAO,MAAM,KAAK,MAAM,KAAK,uBAAuB;AAAA,UACzF;AAEA,iBAAO,MAAM,QAAQ,GAAG,aAAa,OAAO,IAAI;AAAA,QAClD,CAAC;AAAA,MACH,SAAS,GAAY;AACnB,YAAI,aAAa,oDAA+B,aAAa,8CAA0B,OAAM;AAC7F,YAAI,aAAa,2BAAgB,EAAE,eAAe,0BAA0B;AAC1E,gBAAM,IAAI,8CAAyB,OAAO,IAAI;AAAA,QAChD;AACA,gCAAuB,gBAAgB,OAAO,OAAO,SAAS;AAC9D,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,QAAmF;AAClG,WAAO,mBAAQ,SAAK,6BAAgB,mBAAQ,OAAO,CAAC,GAAG,YAAY;AACjE,UAAI;AACF,cAAM,KAAK,2BAA2B,OAAO,WAAW,YAAY;AAClE,gBAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,mBAAmB,OAAO,SAAS;AAClE,gBAAM,QAAQ,GAAG,WAAW,OAAO,SAAS,OAAO,UAAU;AAAA,QAC/D,CAAC;AAAA,MACH,SAAS,GAAY;AACnB,gCAAuB,gBAAgB,OAAO,OAAO,SAAS;AAC9D,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAc,cAAc,QAAwF;AAClH,WAAO,mBAAQ,SAAK,6BAAgB,mBAAQ,OAAO,CAAC,GAAG,YAAY;AACjE,UAAI;AACF,eAAO,MAAM,KAAK,2BAA2B,OAAO,WAAW,YAAY;AACzE,gBAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,mBAAmB,OAAO,SAAS;AAClE,gBAAM,SAAS,MAAM,QAAQ,oBAAoB,OAAO,MAAM,OAAO,gBAAgB;AACrF,iBAAO,OAAO;AAAA,QAChB,CAAC;AAAA,MACH,SAAS,GAAY;AACnB,gCAAuB,gBAAgB,OAAO,OAAO,SAAS;AAC9D,aAAK,OAAO,MAAM,2CAAuC,6CAAsB,CAAC,CAAC;AACjF,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,WAAoC;AAEzD,UAAM,aAAa,MAAM,KAAK,cAAc;AAAA,MAC1C;AAAA,MACA,MAAM,KAAK;AAAA,MACX,kBAAkB,KAAK;AAAA,IACzB,CAAC;AACD,WAAO,eAAe,UAAU;AAAA,EAClC;AAAA,EAEA,4BAAgD;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,uBAA+B;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,wBAAgC;AAE9B,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/sandbox/provider/DaytonaProvider.ts"],"sourcesContent":["import type { Sandbox, Snapshot } from '@daytona/sdk';\nimport { Daytona, DaytonaError } from '@daytona/sdk';\nimport { context } from '@opentelemetry/api';\nimport { suppressTracing } from '@opentelemetry/core';\nimport { randomUUID } from 'crypto';\nimport type { Logger } from 'winston';\nimport { extractErrorLogFields } from '../../util/errorLogFields';\nimport {\n SandboxFileNotFoundError,\n SandboxFileTooLargeError,\n SandboxNotAvailableError,\n SandboxPathIsDirectoryError,\n} from '../SandboxErrors';\nimport type { CodeModeTransport } from '../codeMode/CodeModeTransport';\nimport { CodeModeNatsTransport } from '../codeMode/nats/CodeModeNatsTransport';\nimport { DEFAULT_PREVIEW_URL_EXPIRY_SECONDS, DEFAULT_SANDBOX_NATS_WS_PORT } from '../constants';\nimport type { ExecResult, SandboxBuild, SandboxExecParams, SandboxFileInfo, SandboxProvider } from './Provider';\n\nconst SANDBOX_NOT_FOUND_STATUS = 404;\n/** Another replica already registered this build name; its create is the one that counts. */\nconst SNAPSHOT_CONFLICT_STATUS = 409;\nconst SANDBOX_STATE_STARTED = 'started';\n\nconst BUILD_STATE_ACTIVE = 'active';\nconst BUILD_STATE_INACTIVE = 'inactive';\nconst BUILD_STATE_ERROR = 'error';\nconst BUILD_STATE_BUILD_FAILED = 'build_failed';\n\nconst IMAGE_BUILD_NAME_PREFIX = 'trueforge-build-';\n/** Same default the Daytona SDK applies when `DaytonaConfig.apiUrl` is omitted. */\nconst DEFAULT_DAYTONA_API_URL = 'https://app.daytona.io/api';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Digest portion of a container image reference (the tag/digest after the final `:`)\n * The release image is always published with an explicit digest tag\n */\nfunction imageDigest(image: string): string {\n const lastSegment = image.slice(image.lastIndexOf('/') + 1);\n const colon = lastSegment.lastIndexOf(':');\n if (colon === -1) {\n throw new Error(`Sandbox image reference has no tag/digest: ${image}`);\n }\n return lastSegment.slice(colon + 1);\n}\n\n/** Deterministic build name per image digest so every server replica converges on one build. */\nfunction deriveImageBuildName(digest: string): string {\n return `${IMAGE_BUILD_NAME_PREFIX}${digest}`;\n}\n\n/** Terminal-failure build states: a build stuck here never becomes ready on its own. */\nfunction isFailedBuildState(state: Snapshot['state']): boolean {\n return state === BUILD_STATE_ERROR || state === BUILD_STATE_BUILD_FAILED;\n}\n\n/** Convert Daytona https preview URLs to wss for the NATS client. */\nfunction httpUrlToWsUrl(url: string): string {\n const parsed = new URL(url);\n if (parsed.protocol === 'https:') {\n parsed.protocol = 'wss:';\n } else if (parsed.protocol === 'http:') {\n parsed.protocol = 'ws:';\n }\n return parsed.toString();\n}\n\nexport interface DaytonaSandboxProviderOptions {\n /** Caller-owned Daytona SDK client (credentials / lifetime). */\n client: Daytona;\n /**\n * Same API key the client was built with; used for the register-only snapshot POST because the\n * SDK's `snapshot.create` polls to a terminal state instead of returning once registered.\n */\n apiKey: string;\n /** Daytona API base URL (including `/api`). Defaults to the SDK's public cloud endpoint. */\n apiUrl?: string | undefined;\n tenantName: string;\n /** Release-owned sandbox image reference; built into a Daytona snapshot and cloned per sandbox. */\n sandboxImage: string;\n /**\n * Daytona snapshot name to clone sandboxes from. When omitted it is derived from the image\n * digest. Callers that create sandboxes pass the persisted build_ref so cloning targets the\n * snapshot that was actually built, not a speculative name derived from the current image.\n */\n buildRef?: string | undefined;\n timeoutMs: number;\n autoStopIntervalInMinutes: number;\n autoArchiveIntervalInMinutes: number;\n autoDeleteIntervalInMinutes: number;\n fileMaxBytesForDownload: number;\n /** Defaults to the built-in sandbox NATS WebSocket port (4444). */\n natsBridgePort?: number;\n /** Defaults to 1 hour (same as the gateway's max agent execution time). */\n previewUrlExpirySeconds?: number;\n logger: Logger;\n}\n\nexport class DaytonaSandboxProvider implements SandboxProvider {\n private readonly tenantName: string;\n /** Release-owned sandbox image reference; built into a Daytona snapshot and cloned per sandbox. */\n private readonly imageUri: string;\n /** Daytona snapshot name sandboxes are cloned from; the persisted build_ref, or derived from the image digest. */\n private readonly buildRef: string;\n private readonly timeoutMs: number;\n private readonly autoStopIntervalInMinutes: number;\n private readonly autoArchiveIntervalInMinutes: number;\n private readonly autoDeleteIntervalInMinutes: number;\n private readonly fileMaxBytesForDownload: number;\n private readonly natsBridgePort: number;\n private readonly previewUrlExpirySeconds: number;\n private readonly apiKey: string;\n private readonly apiUrl: string;\n private readonly logger: Logger;\n private readonly daytona: Daytona;\n private static readonly cachedSandboxes = new Map<string, { sandbox: Sandbox; defaultTimeoutMs: number }>();\n // De-dupes concurrent recovery attempts on the same sandbox to a single refreshData+start round-trip.\n private static readonly inFlightRecoveries = new Map<string, Promise<boolean>>();\n\n constructor(options: DaytonaSandboxProviderOptions) {\n this.daytona = options.client;\n this.apiKey = options.apiKey;\n this.apiUrl = options.apiUrl ?? DEFAULT_DAYTONA_API_URL;\n this.tenantName = options.tenantName;\n this.imageUri = options.sandboxImage;\n this.buildRef = options.buildRef ?? deriveImageBuildName(imageDigest(options.sandboxImage));\n this.timeoutMs = options.timeoutMs;\n this.autoStopIntervalInMinutes = options.autoStopIntervalInMinutes;\n this.autoArchiveIntervalInMinutes = options.autoArchiveIntervalInMinutes;\n this.autoDeleteIntervalInMinutes = options.autoDeleteIntervalInMinutes;\n this.fileMaxBytesForDownload = options.fileMaxBytesForDownload;\n this.natsBridgePort = options.natsBridgePort ?? DEFAULT_SANDBOX_NATS_WS_PORT;\n this.previewUrlExpirySeconds = options.previewUrlExpirySeconds ?? DEFAULT_PREVIEW_URL_EXPIRY_SECONDS;\n this.logger = options.logger.child({ module: 'DaytonaProvider' });\n }\n\n private async getOrCreateSandbox(sandboxId?: string): Promise<{ sandbox: Sandbox; defaultTimeoutMs: number }> {\n if (sandboxId) {\n const cached = DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);\n if (cached) {\n return cached;\n }\n }\n\n const sandbox = sandboxId\n ? await this.restoreExistingSandbox(sandboxId)\n : await this.daytona.create({\n name: `${this.tenantName}.${randomUUID()}`,\n snapshot: this.buildRef,\n autoStopInterval: this.autoStopIntervalInMinutes,\n autoArchiveInterval: this.autoArchiveIntervalInMinutes,\n autoDeleteInterval: this.autoDeleteIntervalInMinutes,\n });\n\n const entry = { sandbox, defaultTimeoutMs: this.timeoutMs };\n DaytonaSandboxProvider.cachedSandboxes.set(sandbox.name, entry);\n return entry;\n }\n\n // Returns true iff the caller should retry: either we restarted a stopped sandbox, or the cache entry is missing and the retry will rebuild it via the cold path.\n private static recoverSandboxIfStopped(sandboxId: string): Promise<boolean> {\n const existing = DaytonaSandboxProvider.inFlightRecoveries.get(sandboxId);\n if (existing) {\n return existing;\n }\n\n const cached = DaytonaSandboxProvider.cachedSandboxes.get(sandboxId);\n // Cache may have been evicted by a concurrent error path; signal retry so getOrCreateSandbox rebuilds via restoreExistingSandbox.\n if (!cached) {\n return Promise.resolve(true);\n }\n\n const recovery = (async () => {\n await cached.sandbox.refreshData();\n if (cached.sandbox.state === SANDBOX_STATE_STARTED) {\n return false;\n }\n // start() covers both stopped and archived per Daytona; throws on unrecoverable states (error/destroyed).\n await cached.sandbox.start();\n return true;\n })().finally(() => {\n DaytonaSandboxProvider.inFlightRecoveries.delete(sandboxId);\n });\n\n DaytonaSandboxProvider.inFlightRecoveries.set(sandboxId, recovery);\n return recovery;\n }\n\n private async executeWithSandboxRecovery<T>(sandboxId: string, operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (originalError) {\n // TODO: Narrow to a specific Daytona error code once @daytona/sdk exposes one for \"sandbox not running\".\n if (!(originalError instanceof DaytonaError)) {\n throw originalError;\n }\n\n let recovered: boolean;\n try {\n recovered = await DaytonaSandboxProvider.recoverSandboxIfStopped(sandboxId);\n } catch (recoveryError) {\n this.logger.error('Sandbox recovery failed', {\n ...extractErrorLogFields(recoveryError),\n originalError: extractErrorLogFields(originalError),\n });\n throw new Error('Sandbox is unavailable; recovery attempt failed.', { cause: recoveryError });\n }\n\n if (!recovered) {\n throw originalError;\n }\n\n try {\n return await operation();\n } catch (retryError) {\n this.logger.error('Sandbox operation failed after successful recovery', {\n ...extractErrorLogFields(retryError),\n originalError: extractErrorLogFields(originalError),\n });\n // Rethrow as-is so callers can match domain error types (SandboxPathIsDirectoryError, DaytonaError statusCode mappings, etc.).\n throw retryError;\n }\n }\n }\n\n private async restoreExistingSandbox(sandboxId: string): Promise<Sandbox> {\n try {\n const sandbox = await this.daytona.get(sandboxId);\n if (sandbox.state !== SANDBOX_STATE_STARTED) {\n await sandbox.start();\n }\n return sandbox;\n } catch (ex) {\n if (ex instanceof DaytonaError && ex.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n throw new SandboxNotAvailableError(sandboxId);\n }\n throw ex;\n }\n }\n\n async createSandbox(): Promise<{ sandboxId: string }> {\n return context.with(suppressTracing(context.active()), async () => {\n const { sandbox } = await this.getOrCreateSandbox();\n this.logger.debug(`Sandbox created: name=${sandbox.name}`);\n return { sandboxId: sandbox.name };\n });\n }\n\n /** Resolves undefined when no snapshot carries that name; auth/other failures throw. */\n private async getSnapshot(name: string): Promise<Snapshot | undefined> {\n try {\n return await this.daytona.snapshot.get(name);\n } catch (error) {\n if (error instanceof DaytonaError && error.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * Drops a build stuck in a terminal-failure state so a fresh create can reuse its\n * deterministic name. A concurrent replica may have deleted it already (404) — that\n * is fine and treated as success.\n */\n private async deleteFailedBuild(snapshot: Snapshot): Promise<void> {\n try {\n await this.daytona.snapshot.delete(snapshot);\n } catch (error) {\n if (error instanceof DaytonaError && error.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n return;\n }\n throw error;\n }\n }\n\n private toBuild(state: string, errorReason: string | null): SandboxBuild {\n const metadata = { build_ref: this.buildRef, image_uri: this.imageUri };\n switch (state) {\n case BUILD_STATE_ACTIVE:\n return { status: 'ready', reason: null, metadata };\n case BUILD_STATE_ERROR:\n case BUILD_STATE_BUILD_FAILED:\n return { status: 'failed', reason: errorReason ?? `Sandbox image build failed (${state}).`, metadata };\n default:\n // pending / building / pulling / removing / future states: not ready yet.\n return { status: 'pending', reason: `Sandbox image build in progress (${state}).`, metadata };\n }\n }\n\n /**\n * Registers the snapshot and returns its initial state without waiting for the build.\n *\n * The SDK's `snapshot.create` issues this same POST and then polls until the snapshot is active\n * or failed (minutes on a cold image pull). Configure only needs the registration result, so\n * credential errors surface on the request while build progress stays observable via `getSnapshot`.\n */\n private async registerSnapshot(): Promise<{ state: string; errorReason: string | null }> {\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/snapshots`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name: this.buildRef, imageName: this.imageUri }),\n });\n } catch (error) {\n throw new Error('Daytona snapshot registration request failed.', { cause: error });\n }\n\n const body: unknown = await response.json().catch(() => null);\n if (!response.ok) {\n const message =\n isRecord(body) && typeof body['message'] === 'string'\n ? body['message']\n : `Daytona snapshot registration failed (${String(response.status)})`;\n throw new DaytonaError(message, response.status);\n }\n if (!isRecord(body) || typeof body['state'] !== 'string') {\n throw new DaytonaError(\"Failed to register snapshot. Daytona didn't return a snapshot state.\");\n }\n return {\n state: body['state'],\n errorReason: typeof body['errorReason'] === 'string' ? body['errorReason'] : null,\n };\n }\n\n async buildImage(): Promise<SandboxBuild> {\n const existing = await this.getSnapshot(this.buildRef);\n if (existing) {\n // Daytona parks unused snapshots as 'inactive' after ~2 idle weeks; reactivate rather than rebuild.\n if (existing.state === BUILD_STATE_INACTIVE) {\n const activated = await this.daytona.snapshot.activate(existing);\n return this.toBuild(activated.state, activated.errorReason);\n }\n if (!isFailedBuildState(existing.state)) {\n return this.toBuild(existing.state, existing.errorReason);\n }\n // A failed build keeps the deterministic name occupied and never self-heals, so\n // re-saving settings (which calls buildImage) could never retry. Drop it, then recreate.\n await this.deleteFailedBuild(existing);\n }\n\n try {\n const registered = await this.registerSnapshot();\n // Registration returns pending almost always; map whatever Daytona sent so a fast\n // active/error still surfaces correctly without a follow-up GET.\n return this.toBuild(registered.state, registered.errorReason);\n } catch (error) {\n // A losing concurrent create is not a build failure: the winner owns the deterministic name.\n if (error instanceof DaytonaError && error.statusCode === SNAPSHOT_CONFLICT_STATUS) {\n this.logger.info(`Daytona snapshot already created concurrently: name=${this.buildRef}`);\n return {\n status: 'pending',\n reason: 'Sandbox image build started by another server replica.',\n metadata: { build_ref: this.buildRef, image_uri: this.imageUri },\n };\n }\n throw error;\n }\n }\n\n async getImageBuildStatus(): Promise<SandboxBuild> {\n const snapshot = await this.getSnapshot(this.buildRef);\n // Read-only: a missing build reports pending; PUT /settings/sandbox-providers starts the build.\n if (!snapshot) {\n return {\n status: 'pending',\n reason: 'Sandbox image build not started.',\n metadata: { build_ref: this.buildRef, image_uri: this.imageUri },\n };\n }\n return this.toBuild(snapshot.state, snapshot.errorReason);\n }\n\n async exec(params: SandboxExecParams): Promise<ExecResult> {\n return context.with(suppressTracing(context.active()), async (): Promise<ExecResult> => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox, defaultTimeoutMs } = await this.getOrCreateSandbox(params.sandboxId);\n const response = await sandbox.process.executeCommand(\n params.command,\n params.cwd,\n params.env ?? {},\n params.timeoutSeconds ?? defaultTimeoutMs / 1000,\n );\n return {\n success: true,\n response: { exitCode: response.exitCode, result: response.result },\n };\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n this.logger.error('Sandbox execution error', extractErrorLogFields(e));\n const message = e instanceof Error ? e.message : 'Unknown error';\n return { success: false, error: message };\n }\n });\n }\n\n private async getFileInfo(sandbox: Sandbox, path: string): Promise<SandboxFileInfo> {\n const details = await sandbox.fs.getFileDetails(path);\n return { size: details.size, isDir: details.isDir };\n }\n\n async downloadFile(params: { sandboxId: string; path: string }): Promise<Buffer> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n\n const info = await this.getFileInfo(sandbox, params.path);\n if (info.isDir) {\n throw new SandboxPathIsDirectoryError(params.path);\n }\n if (info.size > this.fileMaxBytesForDownload) {\n throw new SandboxFileTooLargeError(params.path, info.size, this.fileMaxBytesForDownload);\n }\n\n return await sandbox.fs.downloadFile(params.path);\n });\n } catch (e: unknown) {\n if (e instanceof SandboxPathIsDirectoryError || e instanceof SandboxFileTooLargeError) {\n throw e;\n }\n if (e instanceof DaytonaError && e.statusCode === SANDBOX_NOT_FOUND_STATUS) {\n throw new SandboxFileNotFoundError(params.path);\n }\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n throw e;\n }\n });\n }\n\n async uploadFile(params: { sandboxId: string; remotePath: string; content: Buffer }): Promise<void> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n await sandbox.fs.uploadFile(params.content, params.remotePath);\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n throw e;\n }\n });\n }\n\n // Mints a signed, time-limited https preview URL exposing the given sandbox port.\n private async getPreviewUrl(params: { sandboxId: string; port: number; expiresInSeconds: number }): Promise<string> {\n return context.with(suppressTracing(context.active()), async () => {\n try {\n return await this.executeWithSandboxRecovery(params.sandboxId, async () => {\n const { sandbox } = await this.getOrCreateSandbox(params.sandboxId);\n const signed = await sandbox.getSignedPreviewUrl(params.port, params.expiresInSeconds);\n return signed.url;\n });\n } catch (e: unknown) {\n DaytonaSandboxProvider.cachedSandboxes.delete(params.sandboxId);\n this.logger.error('Failed to create signed preview URL', extractErrorLogFields(e));\n throw e;\n }\n });\n }\n\n createCodeModeTransport(): CodeModeTransport {\n return new CodeModeNatsTransport({\n resolveHostUrl: async (sandboxId: string) => {\n const previewUrl = await this.getPreviewUrl({\n sandboxId,\n port: this.natsBridgePort,\n expiresInSeconds: this.previewUrlExpirySeconds,\n });\n return httpUrlToWsUrl(previewUrl);\n },\n sandboxClientNatsUrl: `ws://localhost:${String(this.natsBridgePort)}`,\n logger: this.logger,\n });\n }\n\n getAdditionalInstructions(): string | undefined {\n return undefined;\n }\n\n getToolResultDumpDir(): string {\n return '/tmp/tool-results';\n }\n\n getGitCredentialsPath(): string {\n // Isolated container per sandbox; absolute path so GIT_CONFIG_* needs no $HOME expansion.\n return '/tmp/.git-credentials';\n }\n}\n"],"mappings":"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","names":[]}