noumen 0.5.0 → 0.8.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 (137) hide show
  1. package/README.md +237 -93
  2. package/dist/a2a/index.d.ts +5 -7
  3. package/dist/a2a/index.js +3 -4
  4. package/dist/a2a/index.js.map +1 -1
  5. package/dist/acp/index.d.ts +5 -7
  6. package/dist/acp/index.js +0 -1
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/{agent-C3eDRsxs.d.ts → agent-D0gl-qYi.d.ts} +259 -31
  9. package/dist/{chunk-WPCYGZOE.js → chunk-5HY4IYNT.js} +2062 -2545
  10. package/dist/chunk-5HY4IYNT.js.map +1 -0
  11. package/dist/chunk-BC5BLWBC.js +21 -0
  12. package/dist/chunk-BC5BLWBC.js.map +1 -0
  13. package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
  14. package/dist/chunk-CX4BL6PC.js.map +1 -0
  15. package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
  16. package/dist/chunk-HQISH4D7.js.map +1 -0
  17. package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
  18. package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
  19. package/dist/chunk-OPFFLQZL.js +40 -0
  20. package/dist/chunk-OPFFLQZL.js.map +1 -0
  21. package/dist/chunk-PDEAJ272.js +660 -0
  22. package/dist/chunk-PDEAJ272.js.map +1 -0
  23. package/dist/chunk-PKHLGGEC.js +115 -0
  24. package/dist/chunk-PKHLGGEC.js.map +1 -0
  25. package/dist/chunk-XQTNXRE7.js +176 -0
  26. package/dist/chunk-XQTNXRE7.js.map +1 -0
  27. package/dist/chunk-XZPAA5TO.js +817 -0
  28. package/dist/chunk-XZPAA5TO.js.map +1 -0
  29. package/dist/cli/index.js +77 -42
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/client/index.d.ts +1 -2
  32. package/dist/client/index.js +0 -2
  33. package/dist/client/index.js.map +1 -1
  34. package/dist/client-JJFLE6RT.js +9 -0
  35. package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
  36. package/dist/docker.d.ts +2 -2
  37. package/dist/docker.js +0 -1
  38. package/dist/docker.js.map +1 -1
  39. package/dist/e2b.d.ts +2 -2
  40. package/dist/e2b.js +0 -1
  41. package/dist/e2b.js.map +1 -1
  42. package/dist/freestyle.d.ts +2 -2
  43. package/dist/freestyle.js +0 -1
  44. package/dist/freestyle.js.map +1 -1
  45. package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
  46. package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
  47. package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
  48. package/dist/index.d.ts +358 -72
  49. package/dist/index.js +68 -55
  50. package/dist/jsonrpc/index.js +0 -1
  51. package/dist/local.d.ts +168 -0
  52. package/dist/local.js +40 -0
  53. package/dist/local.js.map +1 -0
  54. package/dist/lsp/index.d.ts +4 -5
  55. package/dist/lsp/index.js +0 -1
  56. package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
  57. package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
  58. package/dist/mcp/index.d.ts +16 -8
  59. package/dist/mcp/index.js +5 -6
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
  62. package/dist/{provider-factory-KI7OZUY3.js → provider-factory-KNBSHXJ6.js} +3 -3
  63. package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
  64. package/dist/{resolve-GDSHNMG6.js → resolve-AGQZFMKD.js} +3 -3
  65. package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
  66. package/dist/sandbox-index-ODNREIFA.js +32 -0
  67. package/dist/sandbox-index-ODNREIFA.js.map +1 -0
  68. package/dist/server/index.d.ts +18 -7
  69. package/dist/server/index.js +9 -5
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/{server-Cu9gv1dk.d.ts → server-DFXdlqyX.d.ts} +1 -1
  72. package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
  73. package/dist/sprites.d.ts +2 -2
  74. package/dist/sprites.js +0 -1
  75. package/dist/sprites.js.map +1 -1
  76. package/dist/ssh.d.ts +2 -2
  77. package/dist/ssh.js +0 -1
  78. package/dist/ssh.js.map +1 -1
  79. package/dist/{types-BA87bHPV.d.ts → types-BX4ALqoN.d.ts} +76 -4
  80. package/dist/{types-LrU4LRmX.d.ts → types-DLZNyF5t.d.ts} +164 -2
  81. package/dist/unsandboxed.d.ts +59 -0
  82. package/dist/unsandboxed.js +32 -0
  83. package/dist/unsandboxed.js.map +1 -0
  84. package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
  85. package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
  86. package/package.json +35 -50
  87. package/dist/cache-DsRqxx6v.d.ts +0 -38
  88. package/dist/chunk-5GEX6ZSB.js.map +0 -1
  89. package/dist/chunk-CS6WNDCF.js +0 -171
  90. package/dist/chunk-CS6WNDCF.js.map +0 -1
  91. package/dist/chunk-DGUM43GV.js +0 -11
  92. package/dist/chunk-EKOGVTBT.js +0 -472
  93. package/dist/chunk-EKOGVTBT.js.map +0 -1
  94. package/dist/chunk-HEQQQGK5.js +0 -131
  95. package/dist/chunk-HEQQQGK5.js.map +0 -1
  96. package/dist/chunk-L3L3FG5T.js +0 -16
  97. package/dist/chunk-L3L3FG5T.js.map +0 -1
  98. package/dist/chunk-WPCYGZOE.js.map +0 -1
  99. package/dist/chunk-WTLK2ZAR.js +0 -94
  100. package/dist/chunk-WTLK2ZAR.js.map +0 -1
  101. package/dist/chunk-XZN4QZLK.js.map +0 -1
  102. package/dist/client-CRRO2376.js +0 -10
  103. package/dist/providers/anthropic.d.ts +0 -19
  104. package/dist/providers/anthropic.js +0 -35
  105. package/dist/providers/anthropic.js.map +0 -1
  106. package/dist/providers/bedrock.d.ts +0 -39
  107. package/dist/providers/bedrock.js +0 -56
  108. package/dist/providers/bedrock.js.map +0 -1
  109. package/dist/providers/gemini.d.ts +0 -17
  110. package/dist/providers/gemini.js +0 -262
  111. package/dist/providers/gemini.js.map +0 -1
  112. package/dist/providers/ollama.d.ts +0 -13
  113. package/dist/providers/ollama.js +0 -20
  114. package/dist/providers/ollama.js.map +0 -1
  115. package/dist/providers/openai.d.ts +0 -21
  116. package/dist/providers/openai.js +0 -9
  117. package/dist/providers/openrouter.d.ts +0 -16
  118. package/dist/providers/openrouter.js +0 -24
  119. package/dist/providers/openrouter.js.map +0 -1
  120. package/dist/providers/vertex.d.ts +0 -42
  121. package/dist/providers/vertex.js +0 -67
  122. package/dist/providers/vertex.js.map +0 -1
  123. package/dist/sandbox-9qeMTNrD.d.ts +0 -126
  124. package/dist/types-CD0rUKKT.d.ts +0 -109
  125. package/dist/uuid-RVN2T26F.js.map +0 -1
  126. package/dist/zod-7YXKWYMC.js.map +0 -1
  127. /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
  128. /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
  129. /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
  130. /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
  131. /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
  132. /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
  133. /package/dist/{provider-factory-KI7OZUY3.js.map → render-4VEODRK7.js.map} +0 -0
  134. /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
  135. /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
  136. /package/dist/{resolve-GDSHNMG6.js.map → uuid-CVTNAPEB.js.map} +0 -0
  137. /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
@@ -0,0 +1,59 @@
1
+ import { A as AgentOptions, a as Agent } from './agent-D0gl-qYi.js';
2
+ import { S as Sandbox } from './sandbox-DAqQo0Tj.js';
3
+ import './types-DLZNyF5t.js';
4
+ import './types-BX4ALqoN.js';
5
+ import './computer-DzMR92tK.js';
6
+ import './types-2kTLUCnD.js';
7
+ import '@modelcontextprotocol/sdk/client/index.js';
8
+ import '@modelcontextprotocol/sdk/client/auth.js';
9
+ import '@modelcontextprotocol/sdk/shared/auth.js';
10
+
11
+ interface UnsandboxedLocalOptions {
12
+ /** Working directory for both file resolution and command execution. */
13
+ cwd?: string;
14
+ /** Default timeout (ms) for shell commands. */
15
+ defaultTimeout?: number;
16
+ }
17
+ /**
18
+ * Create a `Sandbox` backed by the host filesystem and shell with **no
19
+ * OS-level isolation**. The agent can access anything the host process can.
20
+ *
21
+ * Use this for development or fully-trusted environments where sandboxing
22
+ * overhead is unwanted. For production use, prefer `LocalSandbox()` (which
23
+ * wraps commands with `@anthropic-ai/sandbox-runtime`).
24
+ */
25
+ declare function UnsandboxedLocal(opts?: UnsandboxedLocalOptions): Sandbox;
26
+
27
+ /**
28
+ * Options for {@link UnsandboxedAgent} — the full `AgentOptions` surface
29
+ * minus `sandbox`, plus an optional `unsandboxed` block for tuning the
30
+ * default-created {@link UnsandboxedLocal} (timeouts, etc.).
31
+ */
32
+ interface UnsandboxedAgentOptions extends Omit<AgentOptions, "sandbox"> {
33
+ /**
34
+ * Forwarded to {@link UnsandboxedLocal}. If `cwd` is omitted here it
35
+ * defaults to `opts.cwd` / `opts.options.cwd` / `process.cwd()`.
36
+ */
37
+ unsandboxed?: Omit<UnsandboxedLocalOptions, "cwd"> & {
38
+ cwd?: string;
39
+ };
40
+ }
41
+ /**
42
+ * Convenience factory that constructs an {@link Agent} backed by an
43
+ * {@link UnsandboxedLocal} sandbox. Equivalent to:
44
+ *
45
+ * ```ts
46
+ * new Agent({ ...opts, sandbox: UnsandboxedLocal({ cwd }) })
47
+ * ```
48
+ *
49
+ * Lives on the `noumen/unsandboxed` subpath rather than the root barrel
50
+ * so that `import { Agent } from "noumen"` never transitively pulls
51
+ * `node:child_process` into the module graph. Callers who want raw host
52
+ * access opt into that cost at the import line.
53
+ *
54
+ * For production, prefer {@link "./local".LocalAgent} (OS-level sandboxing)
55
+ * or a remote sandbox subpath.
56
+ */
57
+ declare function UnsandboxedAgent(opts: UnsandboxedAgentOptions): Agent;
58
+
59
+ export { UnsandboxedAgent, type UnsandboxedAgentOptions, UnsandboxedLocal, type UnsandboxedLocalOptions };
@@ -0,0 +1,32 @@
1
+ import {
2
+ UnsandboxedLocal
3
+ } from "./chunk-BC5BLWBC.js";
4
+ import "./chunk-XQTNXRE7.js";
5
+ import {
6
+ Agent
7
+ } from "./chunk-5HY4IYNT.js";
8
+ import "./chunk-42PHHZUA.js";
9
+ import "./chunk-OPFFLQZL.js";
10
+ import "./chunk-3HEYCV26.js";
11
+ import "./chunk-CX4BL6PC.js";
12
+ import "./chunk-3SK5GCI6.js";
13
+ import "./chunk-HQISH4D7.js";
14
+ import "./chunk-JACGEMTF.js";
15
+
16
+ // src/unsandboxed.ts
17
+ function UnsandboxedAgent(opts) {
18
+ const cwd = opts.unsandboxed?.cwd ?? opts.cwd ?? opts.options?.cwd ?? process.cwd();
19
+ const { unsandboxed, ...rest } = opts;
20
+ return new Agent({
21
+ ...rest,
22
+ sandbox: UnsandboxedLocal({
23
+ cwd,
24
+ defaultTimeout: unsandboxed?.defaultTimeout
25
+ })
26
+ });
27
+ }
28
+ export {
29
+ UnsandboxedAgent,
30
+ UnsandboxedLocal
31
+ };
32
+ //# sourceMappingURL=unsandboxed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/unsandboxed.ts"],"sourcesContent":["// Unsandboxed local binding — raw host access, no isolation.\n//\n// Importing this subpath is the explicit opt-in to a sandbox that gives the\n// agent everything the host process has. The root barrel (`noumen`) does not\n// re-export this module, so reaching for unsandboxed execution always shows\n// up as a dedicated import line.\n//\n// import { UnsandboxedLocal } from \"noumen/unsandboxed\";\n\nimport { Agent, type AgentOptions } from \"./agent.js\";\nimport { UnsandboxedLocal, type UnsandboxedLocalOptions } from \"./virtual/unsandboxed.js\";\n\nexport {\n UnsandboxedLocal,\n type UnsandboxedLocalOptions,\n} from \"./virtual/unsandboxed.js\";\n\n/**\n * Options for {@link UnsandboxedAgent} — the full `AgentOptions` surface\n * minus `sandbox`, plus an optional `unsandboxed` block for tuning the\n * default-created {@link UnsandboxedLocal} (timeouts, etc.).\n */\nexport interface UnsandboxedAgentOptions extends Omit<AgentOptions, \"sandbox\"> {\n /**\n * Forwarded to {@link UnsandboxedLocal}. If `cwd` is omitted here it\n * defaults to `opts.cwd` / `opts.options.cwd` / `process.cwd()`.\n */\n unsandboxed?: Omit<UnsandboxedLocalOptions, \"cwd\"> & { cwd?: string };\n}\n\n/**\n * Convenience factory that constructs an {@link Agent} backed by an\n * {@link UnsandboxedLocal} sandbox. Equivalent to:\n *\n * ```ts\n * new Agent({ ...opts, sandbox: UnsandboxedLocal({ cwd }) })\n * ```\n *\n * Lives on the `noumen/unsandboxed` subpath rather than the root barrel\n * so that `import { Agent } from \"noumen\"` never transitively pulls\n * `node:child_process` into the module graph. Callers who want raw host\n * access opt into that cost at the import line.\n *\n * For production, prefer {@link \"./local\".LocalAgent} (OS-level sandboxing)\n * or a remote sandbox subpath.\n */\nexport function UnsandboxedAgent(opts: UnsandboxedAgentOptions): Agent {\n const cwd = opts.unsandboxed?.cwd ?? opts.cwd ?? opts.options?.cwd ?? process.cwd();\n const { unsandboxed, ...rest } = opts;\n return new Agent({\n ...rest,\n sandbox: UnsandboxedLocal({\n cwd,\n defaultTimeout: unsandboxed?.defaultTimeout,\n }),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8CO,SAAS,iBAAiB,MAAsC;AACrE,QAAM,MAAM,KAAK,aAAa,OAAO,KAAK,OAAO,KAAK,SAAS,OAAO,QAAQ,IAAI;AAClF,QAAM,EAAE,aAAa,GAAG,KAAK,IAAI;AACjC,SAAO,IAAI,MAAM;AAAA,IACf,GAAG;AAAA,IACH,SAAS,iBAAiB;AAAA,MACxB;AAAA,MACA,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
@@ -1,8 +1,7 @@
1
1
  import {
2
2
  generateUUID
3
3
  } from "./chunk-3HEYCV26.js";
4
- import "./chunk-DGUM43GV.js";
5
4
  export {
6
5
  generateUUID
7
6
  };
8
- //# sourceMappingURL=uuid-RVN2T26F.js.map
7
+ //# sourceMappingURL=uuid-CVTNAPEB.js.map
@@ -3,10 +3,9 @@ import {
3
3
  registerZodToJsonSchema,
4
4
  zodToJsonSchema
5
5
  } from "./chunk-3SK5GCI6.js";
6
- import "./chunk-DGUM43GV.js";
7
6
  export {
8
7
  formatZodValidationError,
9
8
  registerZodToJsonSchema,
10
9
  zodToJsonSchema
11
10
  };
12
- //# sourceMappingURL=zod-7YXKWYMC.js.map
11
+ //# sourceMappingURL=zod-VKURGPRT.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noumen",
3
- "version": "0.5.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "Programmatic AI agent runtime with pluggable providers and sandboxed virtual infrastructure",
6
6
  "main": "./dist/index.js",
@@ -14,34 +14,6 @@
14
14
  "import": "./dist/index.js",
15
15
  "types": "./dist/index.d.ts"
16
16
  },
17
- "./openai": {
18
- "import": "./dist/providers/openai.js",
19
- "types": "./dist/providers/openai.d.ts"
20
- },
21
- "./anthropic": {
22
- "import": "./dist/providers/anthropic.js",
23
- "types": "./dist/providers/anthropic.d.ts"
24
- },
25
- "./gemini": {
26
- "import": "./dist/providers/gemini.js",
27
- "types": "./dist/providers/gemini.d.ts"
28
- },
29
- "./openrouter": {
30
- "import": "./dist/providers/openrouter.js",
31
- "types": "./dist/providers/openrouter.d.ts"
32
- },
33
- "./bedrock": {
34
- "import": "./dist/providers/bedrock.js",
35
- "types": "./dist/providers/bedrock.d.ts"
36
- },
37
- "./vertex": {
38
- "import": "./dist/providers/vertex.js",
39
- "types": "./dist/providers/vertex.d.ts"
40
- },
41
- "./ollama": {
42
- "import": "./dist/providers/ollama.js",
43
- "types": "./dist/providers/ollama.d.ts"
44
- },
45
17
  "./mcp": {
46
18
  "import": "./dist/mcp/index.js",
47
19
  "types": "./dist/mcp/index.d.ts"
@@ -89,6 +61,14 @@
89
61
  "./sprites": {
90
62
  "import": "./dist/sprites.js",
91
63
  "types": "./dist/sprites.d.ts"
64
+ },
65
+ "./local": {
66
+ "import": "./dist/local.js",
67
+ "types": "./dist/local.d.ts"
68
+ },
69
+ "./unsandboxed": {
70
+ "import": "./dist/unsandboxed.js",
71
+ "types": "./dist/unsandboxed.d.ts"
92
72
  }
93
73
  },
94
74
  "files": [
@@ -98,6 +78,7 @@
98
78
  "node": ">=18.0.0"
99
79
  },
100
80
  "dependencies": {
81
+ "@ai-sdk/provider": "^3.0.8",
101
82
  "@anthropic-ai/sandbox-runtime": "^0.0.49",
102
83
  "chalk": "^5.4.1",
103
84
  "commander": "^13.1.0",
@@ -105,48 +86,46 @@
105
86
  "uuid": "^11.1.0"
106
87
  },
107
88
  "peerDependencies": {
108
- "@anthropic-ai/bedrock-sdk": ">=0.10.0",
109
- "@anthropic-ai/sdk": "^0.39.0",
110
- "@anthropic-ai/vertex-sdk": ">=0.4.0",
111
- "@google/genai": "^1.48.0",
89
+ "@ai-sdk/amazon-bedrock": ">=4.0.0",
90
+ "@ai-sdk/anthropic": ">=3.0.0",
91
+ "@ai-sdk/google": ">=3.0.0",
92
+ "@ai-sdk/google-vertex": ">=4.0.0",
93
+ "@ai-sdk/openai": ">=3.0.0",
112
94
  "@modelcontextprotocol/sdk": "^1.29.0",
95
+ "@openrouter/ai-sdk-provider": ">=2.0.0",
113
96
  "@opentelemetry/api": "^1.0.0",
114
97
  "dockerode": ">=4.0.0",
115
98
  "e2b": ">=2.0.0",
116
99
  "freestyle-sandboxes": ">=0.1.0",
117
- "google-auth-library": ">=9.0.0",
118
- "openai": "^4.85.0",
100
+ "ollama-ai-provider-v2": ">=3.0.0",
119
101
  "sharp": ">=0.33.0",
120
102
  "ssh2": ">=1.0.0",
121
103
  "vscode-jsonrpc": "^8.2.1",
122
104
  "ws": ">=8.0.0"
123
105
  },
124
106
  "peerDependenciesMeta": {
125
- "@anthropic-ai/sdk": {
107
+ "@ai-sdk/amazon-bedrock": {
126
108
  "optional": true
127
109
  },
128
- "@google/genai": {
110
+ "@ai-sdk/anthropic": {
129
111
  "optional": true
130
112
  },
131
- "@modelcontextprotocol/sdk": {
113
+ "@ai-sdk/google": {
132
114
  "optional": true
133
115
  },
134
- "openai": {
116
+ "@ai-sdk/google-vertex": {
135
117
  "optional": true
136
118
  },
137
- "vscode-jsonrpc": {
119
+ "@ai-sdk/openai": {
138
120
  "optional": true
139
121
  },
140
- "@opentelemetry/api": {
141
- "optional": true
142
- },
143
- "@anthropic-ai/bedrock-sdk": {
122
+ "@modelcontextprotocol/sdk": {
144
123
  "optional": true
145
124
  },
146
- "@anthropic-ai/vertex-sdk": {
125
+ "@openrouter/ai-sdk-provider": {
147
126
  "optional": true
148
127
  },
149
- "google-auth-library": {
128
+ "@opentelemetry/api": {
150
129
  "optional": true
151
130
  },
152
131
  "dockerode": {
@@ -158,7 +137,7 @@
158
137
  "freestyle-sandboxes": {
159
138
  "optional": true
160
139
  },
161
- "ws": {
140
+ "ollama-ai-provider-v2": {
162
141
  "optional": true
163
142
  },
164
143
  "sharp": {
@@ -166,11 +145,18 @@
166
145
  },
167
146
  "ssh2": {
168
147
  "optional": true
148
+ },
149
+ "vscode-jsonrpc": {
150
+ "optional": true
151
+ },
152
+ "ws": {
153
+ "optional": true
169
154
  }
170
155
  },
171
156
  "devDependencies": {
172
- "@anthropic-ai/sdk": "^0.39.0",
173
- "@google/genai": "^1.48.0",
157
+ "@ai-sdk/anthropic": "^3.0.71",
158
+ "@ai-sdk/google": "^3.0.64",
159
+ "@ai-sdk/openai": "^3.0.53",
174
160
  "@modelcontextprotocol/sdk": "^1.29.0",
175
161
  "@opentelemetry/api": "^1.9.1",
176
162
  "@types/dockerode": "^4.0.1",
@@ -180,7 +166,6 @@
180
166
  "@vitest/coverage-v8": "^3.2.4",
181
167
  "concurrently": "^9.2.1",
182
168
  "freestyle-sandboxes": "^0.1.42",
183
- "openai": "^4.85.0",
184
169
  "tsup": "^8.4.0",
185
170
  "tsx": "^4.21.0",
186
171
  "typescript": "^5.7.0",
@@ -1,38 +0,0 @@
1
- import { b as ChatMessage, T as ToolDefinition } from './types-LrU4LRmX.js';
2
-
3
- /**
4
- * Provider-agnostic prompt caching utilities.
5
- *
6
- * Stable tool ordering prevents cache invalidation when the tool set is
7
- * unchanged. The breakpoint index helper determines which message gets a
8
- * single cache_control marker per request (matching claude-code's strategy).
9
- */
10
-
11
- type CacheScope = "global" | "org";
12
- interface CacheControlConfig {
13
- enabled: boolean;
14
- /** TTL for cached content. When set, produces `ttl: '1h'` in cache_control. */
15
- ttl?: "1h";
16
- /** Scope for shared cache across sessions/orgs. */
17
- scope?: CacheScope;
18
- }
19
- /**
20
- * Sort tool definitions deterministically for prompt cache stability.
21
- *
22
- * Strategy (matching claude-code's assembleToolPool): built-in tools form a
23
- * contiguous prefix sorted by name, followed by MCP/external tools sorted by
24
- * name. Tools with `mcpInfo` on the original Tool object are treated as MCP;
25
- * everything else is built-in. Since ToolDefinition doesn't carry mcpInfo,
26
- * callers can pass an optional set of MCP tool names to partition correctly.
27
- */
28
- declare function sortToolDefinitionsForCache(tools: ToolDefinition[], mcpToolNames?: ReadonlySet<string>): ToolDefinition[];
29
- /**
30
- * Determine which message index should receive the cache_control breakpoint.
31
- *
32
- * Exactly one message per request is marked. Normally the last message;
33
- * for forked agents with skipCacheWrite the second-to-last so the fork
34
- * doesn't write its own tail into the cache.
35
- */
36
- declare function getMessageCacheBreakpointIndex(messages: ChatMessage[], skipCacheWrite?: boolean): number;
37
-
38
- export { type CacheControlConfig as C, type CacheScope as a, getMessageCacheBreakpointIndex as g, sortToolDefinitionsForCache as s };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/image-resizer.ts"],"sourcesContent":["/**\n * Image resize / compress pipeline.\n *\n * Ported from claude-code's imageResizer.ts. Uses `sharp` (optional peer\n * dependency) for dimension caps, iterative quality reduction, and API\n * base64 size guards. Gracefully degrades when sharp is not installed.\n */\n\n/** Maximum base64-encoded image size (API enforced by most providers). */\nexport const API_IMAGE_MAX_BASE64_SIZE = 5 * 1024 * 1024; // 5 MB\n\n/** Target raw size before base64 encoding (base64 inflates by ~4/3). */\nexport const IMAGE_TARGET_RAW_SIZE = Math.floor(\n (API_IMAGE_MAX_BASE64_SIZE * 3) / 4,\n); // ~3.75 MB\n\nexport const IMAGE_MAX_WIDTH = 8000;\nexport const IMAGE_MAX_HEIGHT = 8000;\n\nexport interface ImageDimensions {\n width: number;\n height: number;\n}\n\nexport interface ResizedImage {\n buffer: Buffer;\n mediaType: string;\n dimensions?: ImageDimensions;\n}\n\nexport interface CompressedImageResult {\n base64: string;\n mediaType: string;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet _sharp: any | null | undefined;\n\nasync function getSharp(): Promise<any | null> {\n if (_sharp !== undefined) return _sharp;\n try {\n // Dynamic import with variable to prevent TypeScript from resolving at compile time\n const moduleName = \"sharp\";\n const mod = await import(/* @vite-ignore */ moduleName);\n _sharp = mod.default ?? mod;\n return _sharp;\n } catch {\n _sharp = null;\n return null;\n }\n}\n\n/**\n * Resize and downsample an image buffer if it exceeds dimension or size\n * limits. Returns the (possibly unchanged) buffer with mediaType info.\n */\nexport async function maybeResizeAndDownsampleImageBuffer(\n imageBuffer: Buffer,\n originalSize: number,\n ext: string,\n): Promise<ResizedImage> {\n const sharp = await getSharp();\n if (!sharp) {\n if (imageBuffer.length > IMAGE_TARGET_RAW_SIZE) {\n console.warn(\n `[noumen] Image is ${(imageBuffer.length / 1024 / 1024).toFixed(1)}MB ` +\n `but sharp is not installed — cannot resize. Install sharp for image optimization.`,\n );\n }\n return {\n buffer: imageBuffer,\n mediaType: extToMediaType(ext),\n };\n }\n\n let img = sharp(imageBuffer);\n const meta = await img.metadata();\n const width = meta.width ?? 0;\n const height = meta.height ?? 0;\n\n let needsResize =\n width > IMAGE_MAX_WIDTH ||\n height > IMAGE_MAX_HEIGHT ||\n imageBuffer.length > IMAGE_TARGET_RAW_SIZE;\n\n if (!needsResize) {\n return {\n buffer: imageBuffer,\n mediaType: extToMediaType(ext),\n dimensions: { width, height },\n };\n }\n\n // Dimension cap\n if (width > IMAGE_MAX_WIDTH || height > IMAGE_MAX_HEIGHT) {\n const scale = Math.min(IMAGE_MAX_WIDTH / width, IMAGE_MAX_HEIGHT / height);\n const newWidth = Math.round(width * scale);\n const newHeight = Math.round(height * scale);\n img = img.resize(newWidth, newHeight, { fit: \"inside\", withoutEnlargement: true });\n }\n\n // Try JPEG at decreasing quality levels\n const qualities = [85, 60, 40];\n for (const q of qualities) {\n const buf = await img.jpeg({ quality: q, mozjpeg: true }).toBuffer();\n if (buf.length <= IMAGE_TARGET_RAW_SIZE) {\n const jpgMeta = await sharp(buf).metadata();\n return {\n buffer: buf,\n mediaType: \"jpeg\",\n dimensions: {\n width: jpgMeta.width ?? 0,\n height: jpgMeta.height ?? 0,\n },\n };\n }\n }\n\n // Try PNG palette mode as last resort\n const pngBuf = await img.png({ palette: true, quality: 40 }).toBuffer();\n if (pngBuf.length <= IMAGE_TARGET_RAW_SIZE) {\n const pngMeta = await sharp(pngBuf).metadata();\n return {\n buffer: pngBuf,\n mediaType: \"png\",\n dimensions: {\n width: pngMeta.width ?? 0,\n height: pngMeta.height ?? 0,\n },\n };\n }\n\n // Return best-effort JPEG Q40 even if over budget\n const fallback = await img.jpeg({ quality: 40, mozjpeg: true }).toBuffer();\n const fallbackMeta = await sharp(fallback).metadata();\n return {\n buffer: fallback,\n mediaType: \"jpeg\",\n dimensions: {\n width: fallbackMeta.width ?? 0,\n height: fallbackMeta.height ?? 0,\n },\n };\n}\n\n/**\n * Decode base64 image block, resize, re-encode.\n */\nexport async function maybeResizeAndDownsampleImageBlock(imageBlock: {\n data: string;\n media_type: string;\n}): Promise<{\n data: string;\n media_type: string;\n dimensions?: ImageDimensions;\n}> {\n const imageBuffer = Buffer.from(imageBlock.data, \"base64\");\n const ext = imageBlock.media_type.split(\"/\")[1] || \"png\";\n\n const resized = await maybeResizeAndDownsampleImageBuffer(\n imageBuffer,\n imageBuffer.length,\n ext,\n );\n\n return {\n data: resized.buffer.toString(\"base64\"),\n media_type: `image/${resized.mediaType}`,\n dimensions: resized.dimensions,\n };\n}\n\n/**\n * Compress an image to fit within a token budget.\n * Token formula: tokens ≈ base64_chars × 0.125\n */\nexport async function compressImageBufferWithTokenLimit(\n imageBuffer: Buffer,\n maxTokens: number,\n originalMediaType?: string,\n): Promise<CompressedImageResult> {\n const maxBase64Chars = Math.floor(maxTokens / 0.125);\n const maxBytes = Math.floor(maxBase64Chars * 0.75);\n\n const sharp = await getSharp();\n if (!sharp) {\n const base64 = imageBuffer.toString(\"base64\");\n return {\n base64,\n mediaType: originalMediaType?.split(\"/\")[1] || \"png\",\n };\n }\n\n const qualities = [85, 60, 40, 20];\n for (const q of qualities) {\n const buf = await sharp(imageBuffer)\n .jpeg({ quality: q, mozjpeg: true })\n .toBuffer();\n if (buf.length <= maxBytes) {\n return { base64: buf.toString(\"base64\"), mediaType: \"jpeg\" };\n }\n }\n\n // Progressive dimension reduction\n const meta = await sharp(imageBuffer).metadata();\n let w = meta.width ?? 800;\n let h = meta.height ?? 600;\n\n for (let scale = 0.75; scale >= 0.25; scale -= 0.25) {\n const nw = Math.round(w * scale);\n const nh = Math.round(h * scale);\n const buf = await sharp(imageBuffer)\n .resize(nw, nh, { fit: \"inside\" })\n .jpeg({ quality: 40, mozjpeg: true })\n .toBuffer();\n if (buf.length <= maxBytes) {\n return { base64: buf.toString(\"base64\"), mediaType: \"jpeg\" };\n }\n }\n\n // Best effort\n const buf = await sharp(imageBuffer)\n .resize(Math.round(w * 0.25), Math.round(h * 0.25), { fit: \"inside\" })\n .jpeg({ quality: 20, mozjpeg: true })\n .toBuffer();\n return { base64: buf.toString(\"base64\"), mediaType: \"jpeg\" };\n}\n\nfunction extToMediaType(ext: string): string {\n const lower = ext.toLowerCase().replace(/^\\./, \"\");\n switch (lower) {\n case \"jpg\":\n case \"jpeg\":\n return \"jpeg\";\n case \"png\":\n return \"png\";\n case \"gif\":\n return \"gif\";\n case \"webp\":\n return \"webp\";\n case \"svg\":\n return \"svg+xml\";\n default:\n return \"png\";\n }\n}\n\nexport const IMAGE_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".svg\",\n]);\n\n/**\n * Create dimension metadata text for the model (helps with coordinate reasoning).\n */\nexport function createImageMetadataText(dims: ImageDimensions): string {\n return `Image dimensions: ${dims.width}×${dims.height}px`;\n}\n"],"mappings":"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","names":["buf"]}
@@ -1,171 +0,0 @@
1
- import {
2
- ChatStreamError
3
- } from "./chunk-L3L3FG5T.js";
4
-
5
- // src/providers/openai.ts
6
- import OpenAI from "openai";
7
- var O_SERIES_PATTERN = /^o[1-9]/;
8
- var OpenAIProvider = class _OpenAIProvider {
9
- client;
10
- defaultModel;
11
- compatMode;
12
- constructor(opts) {
13
- this.client = new OpenAI({
14
- apiKey: opts.apiKey ?? "not-needed",
15
- baseURL: opts.baseURL,
16
- defaultHeaders: opts.defaultHeaders,
17
- maxRetries: 0
18
- });
19
- this.defaultModel = opts.model ?? "gpt-5.4";
20
- this.compatMode = opts.compatMode ?? false;
21
- }
22
- async *chat(params) {
23
- const messages = this.buildMessages(params.system, params.messages);
24
- const model = params.model ?? this.defaultModel;
25
- const isOSeries = O_SERIES_PATTERN.test(model);
26
- const createParams = {
27
- model,
28
- messages,
29
- tools: params.tools?.map((t) => ({
30
- type: "function",
31
- function: t.function
32
- })),
33
- stream: true,
34
- ...this.compatMode ? {} : { stream_options: { include_usage: true } }
35
- };
36
- if (isOSeries) {
37
- createParams.max_completion_tokens = params.max_tokens ?? 16384;
38
- if (params.thinking?.type === "enabled") {
39
- createParams.reasoning_effort = "high";
40
- }
41
- } else {
42
- createParams.max_tokens = params.max_tokens;
43
- createParams.temperature = params.temperature;
44
- }
45
- if (params.outputFormat?.type === "json_schema") {
46
- createParams.response_format = {
47
- type: "json_schema",
48
- json_schema: {
49
- name: params.outputFormat.name ?? "response",
50
- schema: params.outputFormat.schema,
51
- strict: params.outputFormat.strict ?? false
52
- }
53
- };
54
- } else if (params.outputFormat?.type === "json_object") {
55
- createParams.response_format = {
56
- type: "json_object"
57
- };
58
- }
59
- try {
60
- const stream = await this.client.chat.completions.create(createParams, {
61
- ...params.signal ? { signal: params.signal } : {}
62
- });
63
- for await (const chunk of stream) {
64
- const usage = chunk.usage;
65
- let mappedUsage;
66
- if (usage) {
67
- const u = usage;
68
- const promptDetails = u.prompt_tokens_details;
69
- const completionDetails = u.completion_tokens_details;
70
- mappedUsage = {
71
- prompt_tokens: usage.prompt_tokens,
72
- completion_tokens: usage.completion_tokens,
73
- total_tokens: usage.total_tokens,
74
- cache_read_tokens: promptDetails?.cached_tokens,
75
- cache_creation_tokens: promptDetails?.cache_creation_tokens,
76
- thinking_tokens: completionDetails?.reasoning_tokens
77
- };
78
- }
79
- const choices = chunk.choices ?? [];
80
- if (choices.length === 0 && mappedUsage) {
81
- yield { id: chunk.id, model: chunk.model, choices: [], usage: mappedUsage };
82
- continue;
83
- }
84
- yield {
85
- id: chunk.id,
86
- model: chunk.model,
87
- choices: choices.map((c) => ({
88
- index: c.index,
89
- delta: {
90
- role: c.delta.role,
91
- content: c.delta.content,
92
- thinking_content: c.delta.reasoning_content,
93
- tool_calls: c.delta.tool_calls?.map((tc) => ({
94
- index: tc.index,
95
- id: tc.id,
96
- type: tc.type,
97
- function: tc.function ? {
98
- name: tc.function.name,
99
- arguments: tc.function.arguments
100
- } : void 0
101
- }))
102
- },
103
- finish_reason: c.finish_reason
104
- })),
105
- usage: mappedUsage
106
- };
107
- }
108
- } catch (err) {
109
- if (err instanceof ChatStreamError) throw err;
110
- const apiErr = err;
111
- throw new ChatStreamError(
112
- err instanceof Error ? err.message : String(err),
113
- {
114
- status: apiErr.status,
115
- retryAfter: apiErr.headers?.get?.("retry-after") ?? apiErr.headers?.["retry-after"] ?? void 0,
116
- cause: err
117
- }
118
- );
119
- }
120
- }
121
- static contentPartsToOpenAI(parts) {
122
- return parts.map((part) => {
123
- if (part.type === "text") {
124
- return { type: "text", text: part.text };
125
- }
126
- if (part.type === "image") {
127
- return {
128
- type: "image_url",
129
- image_url: { url: `data:${part.media_type};base64,${part.data}` }
130
- };
131
- }
132
- return { type: "image_url", image_url: { url: part.url } };
133
- });
134
- }
135
- buildMessages(system, messages) {
136
- const result = [];
137
- if (system) {
138
- result.push({ role: "system", content: system });
139
- }
140
- for (const msg of messages) {
141
- if (msg.role === "tool") {
142
- const content = Array.isArray(msg.content) ? _OpenAIProvider.contentPartsToOpenAI(msg.content) : msg.content;
143
- result.push({
144
- role: "tool",
145
- tool_call_id: msg.tool_call_id,
146
- content
147
- });
148
- } else if (msg.role === "assistant") {
149
- const entry = {
150
- role: "assistant",
151
- content: msg.content
152
- };
153
- if (msg.tool_calls) {
154
- entry.tool_calls = msg.tool_calls;
155
- }
156
- result.push(entry);
157
- } else if (msg.role === "user") {
158
- const content = Array.isArray(msg.content) ? _OpenAIProvider.contentPartsToOpenAI(msg.content) : msg.content;
159
- result.push({ role: "user", content });
160
- } else {
161
- result.push({ role: msg.role, content: msg.content });
162
- }
163
- }
164
- return result;
165
- }
166
- };
167
-
168
- export {
169
- OpenAIProvider
170
- };
171
- //# sourceMappingURL=chunk-CS6WNDCF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/openai.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport type {\n AIProvider,\n ChatParams,\n ChatStreamChunk,\n} from \"./types.js\";\nimport { ChatStreamError } from \"./types.js\";\nimport type { ChatMessage, ContentPart } from \"../session/types.js\";\n\nexport interface OpenAIProviderOptions {\n apiKey?: string;\n baseURL?: string;\n model?: string;\n defaultHeaders?: Record<string, string | undefined>;\n /** When true, omits `stream_options` that some OpenAI-compatible endpoints don't support. */\n compatMode?: boolean;\n}\n\nconst O_SERIES_PATTERN = /^o[1-9]/;\n\nexport class OpenAIProvider implements AIProvider {\n private client: OpenAI;\n private defaultModel: string;\n protected compatMode: boolean;\n\n constructor(opts: OpenAIProviderOptions) {\n this.client = new OpenAI({\n apiKey: opts.apiKey ?? \"not-needed\",\n baseURL: opts.baseURL,\n defaultHeaders: opts.defaultHeaders,\n maxRetries: 0,\n });\n this.defaultModel = opts.model ?? \"gpt-5.4\";\n this.compatMode = opts.compatMode ?? false;\n }\n\n async *chat(params: ChatParams): AsyncIterable<ChatStreamChunk> {\n const messages = this.buildMessages(params.system, params.messages);\n const model = params.model ?? this.defaultModel;\n const isOSeries = O_SERIES_PATTERN.test(model);\n\n const createParams: OpenAI.ChatCompletionCreateParamsStreaming = {\n model,\n messages: messages as unknown as OpenAI.ChatCompletionMessageParam[],\n tools: params.tools?.map((t) => ({\n type: \"function\" as const,\n function: t.function,\n })),\n stream: true,\n ...(this.compatMode ? {} : { stream_options: { include_usage: true } }),\n };\n\n if (isOSeries) {\n (createParams as unknown as Record<string, unknown>).max_completion_tokens = params.max_tokens ?? 16384;\n if (params.thinking?.type === \"enabled\") {\n (createParams as unknown as Record<string, unknown>).reasoning_effort = \"high\";\n }\n } else {\n createParams.max_tokens = params.max_tokens;\n createParams.temperature = params.temperature;\n }\n\n if (params.outputFormat?.type === \"json_schema\") {\n (createParams as unknown as Record<string, unknown>).response_format = {\n type: \"json_schema\",\n json_schema: {\n name: params.outputFormat.name ?? \"response\",\n schema: params.outputFormat.schema,\n strict: params.outputFormat.strict ?? false,\n },\n };\n } else if (params.outputFormat?.type === \"json_object\") {\n (createParams as unknown as Record<string, unknown>).response_format = {\n type: \"json_object\",\n };\n }\n\n try {\n const stream = await this.client.chat.completions.create(createParams, {\n ...(params.signal ? { signal: params.signal } : {}),\n });\n\n for await (const chunk of stream) {\n const usage = chunk.usage;\n let mappedUsage: ChatStreamChunk[\"usage\"] | undefined;\n if (usage) {\n const u = usage as unknown as Record<string, unknown>;\n const promptDetails = u.prompt_tokens_details as Record<string, unknown> | undefined;\n const completionDetails = u.completion_tokens_details as Record<string, unknown> | undefined;\n mappedUsage = {\n prompt_tokens: usage.prompt_tokens,\n completion_tokens: usage.completion_tokens,\n total_tokens: usage.total_tokens,\n cache_read_tokens: promptDetails?.cached_tokens as number | undefined,\n cache_creation_tokens: promptDetails?.cache_creation_tokens as number | undefined,\n thinking_tokens: completionDetails?.reasoning_tokens as number | undefined,\n };\n }\n\n const choices = chunk.choices ?? [];\n if (choices.length === 0 && mappedUsage) {\n yield { id: chunk.id, model: chunk.model, choices: [], usage: mappedUsage };\n continue;\n }\n\n yield {\n id: chunk.id,\n model: chunk.model,\n choices: choices.map((c) => ({\n index: c.index,\n delta: {\n role: c.delta.role as \"assistant\" | undefined,\n content: c.delta.content,\n thinking_content: (c.delta as Record<string, unknown>).reasoning_content as string | undefined,\n tool_calls: c.delta.tool_calls?.map((tc) => ({\n index: tc.index,\n id: tc.id,\n type: tc.type as \"function\" | undefined,\n function: tc.function\n ? {\n name: tc.function.name,\n arguments: tc.function.arguments,\n }\n : undefined,\n })),\n },\n finish_reason: c.finish_reason,\n })),\n usage: mappedUsage,\n };\n }\n } catch (err: unknown) {\n if (err instanceof ChatStreamError) throw err;\n const apiErr = err as { status?: number; headers?: Record<string, string> & { get?(k: string): string | null } };\n throw new ChatStreamError(\n err instanceof Error ? err.message : String(err),\n {\n status: apiErr.status,\n retryAfter: apiErr.headers?.get?.(\"retry-after\") ?? apiErr.headers?.[\"retry-after\"] ?? undefined,\n cause: err,\n },\n );\n }\n }\n\n private static contentPartsToOpenAI(\n parts: ContentPart[],\n ): Array<Record<string, unknown>> {\n return parts.map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\", text: part.text };\n }\n if (part.type === \"image\") {\n return {\n type: \"image_url\",\n image_url: { url: `data:${part.media_type};base64,${part.data}` },\n };\n }\n // image_url\n return { type: \"image_url\", image_url: { url: part.url } };\n });\n }\n\n private buildMessages(\n system: string | undefined,\n messages: ChatMessage[],\n ): Array<Record<string, unknown>> {\n const result: Array<Record<string, unknown>> = [];\n if (system) {\n result.push({ role: \"system\", content: system });\n }\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n const content = Array.isArray(msg.content)\n ? OpenAIProvider.contentPartsToOpenAI(msg.content as ContentPart[])\n : msg.content;\n result.push({\n role: \"tool\",\n tool_call_id: msg.tool_call_id,\n content,\n });\n } else if (msg.role === \"assistant\") {\n const entry: Record<string, unknown> = {\n role: \"assistant\",\n content: msg.content,\n };\n if (msg.tool_calls) {\n entry.tool_calls = msg.tool_calls;\n }\n result.push(entry);\n } else if (msg.role === \"user\") {\n const content = Array.isArray(msg.content)\n ? OpenAIProvider.contentPartsToOpenAI(msg.content as ContentPart[])\n : msg.content;\n result.push({ role: \"user\", content });\n } else {\n result.push({ role: msg.role, content: msg.content });\n }\n }\n return result;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- export {
9
- __require
10
- };
11
- //# sourceMappingURL=chunk-DGUM43GV.js.map