noumen 0.6.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.
- package/README.md +237 -93
- package/dist/a2a/index.d.ts +5 -7
- package/dist/a2a/index.js +3 -4
- package/dist/a2a/index.js.map +1 -1
- package/dist/acp/index.d.ts +5 -7
- package/dist/acp/index.js +0 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/{agent-DWE4_P5X.d.ts → agent-D0gl-qYi.d.ts} +89 -34
- package/dist/{chunk-6MMYCGJQ.js → chunk-5HY4IYNT.js} +1529 -2321
- package/dist/chunk-5HY4IYNT.js.map +1 -0
- package/dist/chunk-BC5BLWBC.js +21 -0
- package/dist/chunk-BC5BLWBC.js.map +1 -0
- package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
- package/dist/chunk-CX4BL6PC.js.map +1 -0
- package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
- package/dist/chunk-HQISH4D7.js.map +1 -0
- package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
- package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
- package/dist/chunk-OPFFLQZL.js +40 -0
- package/dist/chunk-OPFFLQZL.js.map +1 -0
- package/dist/chunk-PDEAJ272.js +660 -0
- package/dist/chunk-PDEAJ272.js.map +1 -0
- package/dist/chunk-PKHLGGEC.js +115 -0
- package/dist/chunk-PKHLGGEC.js.map +1 -0
- package/dist/chunk-XQTNXRE7.js +176 -0
- package/dist/chunk-XQTNXRE7.js.map +1 -0
- package/dist/chunk-XZPAA5TO.js +817 -0
- package/dist/chunk-XZPAA5TO.js.map +1 -0
- package/dist/cli/index.js +77 -42
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.js +0 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client-JJFLE6RT.js +9 -0
- package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
- package/dist/docker.d.ts +2 -2
- package/dist/docker.js +0 -1
- package/dist/docker.js.map +1 -1
- package/dist/e2b.d.ts +2 -2
- package/dist/e2b.js +0 -1
- package/dist/e2b.js.map +1 -1
- package/dist/freestyle.d.ts +2 -2
- package/dist/freestyle.js +0 -1
- package/dist/freestyle.js.map +1 -1
- package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
- package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
- package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
- package/dist/index.d.ts +351 -72
- package/dist/index.js +54 -55
- package/dist/jsonrpc/index.js +0 -1
- package/dist/local.d.ts +168 -0
- package/dist/local.js +40 -0
- package/dist/local.js.map +1 -0
- package/dist/lsp/index.d.ts +4 -5
- package/dist/lsp/index.js +0 -1
- package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
- package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
- package/dist/mcp/index.d.ts +16 -8
- package/dist/mcp/index.js +5 -6
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
- package/dist/{provider-factory-TUHU3DIG.js → provider-factory-KNBSHXJ6.js} +3 -3
- package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
- package/dist/{resolve-6KUZNEYW.js → resolve-AGQZFMKD.js} +3 -3
- package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
- package/dist/sandbox-index-ODNREIFA.js +32 -0
- package/dist/sandbox-index-ODNREIFA.js.map +1 -0
- package/dist/server/index.d.ts +18 -7
- package/dist/server/index.js +9 -5
- package/dist/server/index.js.map +1 -1
- package/dist/{server-BzNGKTP6.d.ts → server-DFXdlqyX.d.ts} +1 -1
- package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
- package/dist/sprites.d.ts +2 -2
- package/dist/sprites.js +0 -1
- package/dist/sprites.js.map +1 -1
- package/dist/ssh.d.ts +2 -2
- package/dist/ssh.js +0 -1
- package/dist/ssh.js.map +1 -1
- package/dist/{types-DhXwOQwD.d.ts → types-BX4ALqoN.d.ts} +76 -4
- package/dist/{types-kiGBF35b.d.ts → types-DLZNyF5t.d.ts} +125 -1
- package/dist/unsandboxed.d.ts +59 -0
- package/dist/unsandboxed.js +32 -0
- package/dist/unsandboxed.js.map +1 -0
- package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
- package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
- package/package.json +35 -50
- package/dist/cache-BlBwXXPS.d.ts +0 -38
- package/dist/chunk-5GEX6ZSB.js.map +0 -1
- package/dist/chunk-6MMYCGJQ.js.map +0 -1
- package/dist/chunk-7IQCQI2G.js +0 -94
- package/dist/chunk-7IQCQI2G.js.map +0 -1
- package/dist/chunk-CCM2AXZG.js +0 -16
- package/dist/chunk-CCM2AXZG.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-HEQQQGK5.js +0 -131
- package/dist/chunk-HEQQQGK5.js.map +0 -1
- package/dist/chunk-I3JTUFPK.js +0 -171
- package/dist/chunk-I3JTUFPK.js.map +0 -1
- package/dist/chunk-XZN4QZLK.js.map +0 -1
- package/dist/chunk-ZXSDKBYB.js +0 -474
- package/dist/chunk-ZXSDKBYB.js.map +0 -1
- package/dist/client-CRRO2376.js +0 -10
- package/dist/providers/anthropic.d.ts +0 -19
- package/dist/providers/anthropic.js +0 -36
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/bedrock.d.ts +0 -39
- package/dist/providers/bedrock.js +0 -56
- package/dist/providers/bedrock.js.map +0 -1
- package/dist/providers/gemini.d.ts +0 -17
- package/dist/providers/gemini.js +0 -262
- package/dist/providers/gemini.js.map +0 -1
- package/dist/providers/ollama.d.ts +0 -13
- package/dist/providers/ollama.js +0 -20
- package/dist/providers/ollama.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -21
- package/dist/providers/openai.js +0 -9
- package/dist/providers/openrouter.d.ts +0 -16
- package/dist/providers/openrouter.js +0 -24
- package/dist/providers/openrouter.js.map +0 -1
- package/dist/providers/vertex.d.ts +0 -42
- package/dist/providers/vertex.js +0 -68
- package/dist/providers/vertex.js.map +0 -1
- package/dist/sandbox-9qeMTNrD.d.ts +0 -126
- package/dist/types-CD0rUKKT.d.ts +0 -109
- package/dist/uuid-RVN2T26F.js.map +0 -1
- package/dist/zod-7YXKWYMC.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
- /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
- /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
- /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
- /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
- /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
- /package/dist/{provider-factory-TUHU3DIG.js.map → render-4VEODRK7.js.map} +0 -0
- /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
- /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
- /package/dist/{resolve-6KUZNEYW.js.map → uuid-CVTNAPEB.js.map} +0 -0
- /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noumen",
|
|
3
|
-
"version": "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
|
-
"@
|
|
109
|
-
"@
|
|
110
|
-
"@
|
|
111
|
-
"@google
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
107
|
+
"@ai-sdk/amazon-bedrock": {
|
|
126
108
|
"optional": true
|
|
127
109
|
},
|
|
128
|
-
"@
|
|
110
|
+
"@ai-sdk/anthropic": {
|
|
129
111
|
"optional": true
|
|
130
112
|
},
|
|
131
|
-
"@
|
|
113
|
+
"@ai-sdk/google": {
|
|
132
114
|
"optional": true
|
|
133
115
|
},
|
|
134
|
-
"
|
|
116
|
+
"@ai-sdk/google-vertex": {
|
|
135
117
|
"optional": true
|
|
136
118
|
},
|
|
137
|
-
"
|
|
119
|
+
"@ai-sdk/openai": {
|
|
138
120
|
"optional": true
|
|
139
121
|
},
|
|
140
|
-
"@
|
|
141
|
-
"optional": true
|
|
142
|
-
},
|
|
143
|
-
"@anthropic-ai/bedrock-sdk": {
|
|
122
|
+
"@modelcontextprotocol/sdk": {
|
|
144
123
|
"optional": true
|
|
145
124
|
},
|
|
146
|
-
"@
|
|
125
|
+
"@openrouter/ai-sdk-provider": {
|
|
147
126
|
"optional": true
|
|
148
127
|
},
|
|
149
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
173
|
-
"@google
|
|
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",
|
package/dist/cache-BlBwXXPS.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { b as ChatMessage, T as ToolDefinition } from './types-kiGBF35b.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":";AASO,IAAM,4BAA4B,IAAI,OAAO;AAG7C,IAAM,wBAAwB,KAAK;AAAA,EACvC,4BAA4B,IAAK;AACpC;AAEO,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAmBhC,IAAI;AAEJ,eAAe,WAAgC;AAC7C,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI;AAEF,UAAM,aAAa;AACnB,UAAM,MAAM,MAAM;AAAA;AAAA,MAA0B;AAAA;AAC5C,aAAS,IAAI,WAAW;AACxB,WAAO;AAAA,EACT,QAAQ;AACN,aAAS;AACT,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,oCACpB,aACA,cACA,KACuB;AACvB,QAAM,QAAQ,MAAM,SAAS;AAC7B,MAAI,CAAC,OAAO;AACV,QAAI,YAAY,SAAS,uBAAuB;AAC9C,cAAQ;AAAA,QACN,sBAAsB,YAAY,SAAS,OAAO,MAAM,QAAQ,CAAC,CAAC;AAAA,MAEpE;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,eAAe,GAAG;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,MAAM,MAAM,WAAW;AAC3B,QAAM,OAAO,MAAM,IAAI,SAAS;AAChC,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,SAAS,KAAK,UAAU;AAE9B,MAAI,cACF,QAAQ,mBACR,SAAS,oBACT,YAAY,SAAS;AAEvB,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,eAAe,GAAG;AAAA,MAC7B,YAAY,EAAE,OAAO,OAAO;AAAA,IAC9B;AAAA,EACF;AAGA,MAAI,QAAQ,mBAAmB,SAAS,kBAAkB;AACxD,UAAM,QAAQ,KAAK,IAAI,kBAAkB,OAAO,mBAAmB,MAAM;AACzE,UAAM,WAAW,KAAK,MAAM,QAAQ,KAAK;AACzC,UAAM,YAAY,KAAK,MAAM,SAAS,KAAK;AAC3C,UAAM,IAAI,OAAO,UAAU,WAAW,EAAE,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAAA,EACnF;AAGA,QAAM,YAAY,CAAC,IAAI,IAAI,EAAE;AAC7B,aAAW,KAAK,WAAW;AACzB,UAAM,MAAM,MAAM,IAAI,KAAK,EAAE,SAAS,GAAG,SAAS,KAAK,CAAC,EAAE,SAAS;AACnE,QAAI,IAAI,UAAU,uBAAuB;AACvC,YAAM,UAAU,MAAM,MAAM,GAAG,EAAE,SAAS;AAC1C,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,YAAY;AAAA,UACV,OAAO,QAAQ,SAAS;AAAA,UACxB,QAAQ,QAAQ,UAAU;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,IAAI,IAAI,EAAE,SAAS,MAAM,SAAS,GAAG,CAAC,EAAE,SAAS;AACtE,MAAI,OAAO,UAAU,uBAAuB;AAC1C,UAAM,UAAU,MAAM,MAAM,MAAM,EAAE,SAAS;AAC7C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY;AAAA,QACV,OAAO,QAAQ,SAAS;AAAA,QACxB,QAAQ,QAAQ,UAAU;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,IAAI,KAAK,EAAE,SAAS,IAAI,SAAS,KAAK,CAAC,EAAE,SAAS;AACzE,QAAM,eAAe,MAAM,MAAM,QAAQ,EAAE,SAAS;AACpD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,MACV,OAAO,aAAa,SAAS;AAAA,MAC7B,QAAQ,aAAa,UAAU;AAAA,IACjC;AAAA,EACF;AACF;AAKA,eAAsB,mCAAmC,YAOtD;AACD,QAAM,cAAc,OAAO,KAAK,WAAW,MAAM,QAAQ;AACzD,QAAM,MAAM,WAAW,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK;AAEnD,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ,OAAO,SAAS,QAAQ;AAAA,IACtC,YAAY,SAAS,QAAQ,SAAS;AAAA,IACtC,YAAY,QAAQ;AAAA,EACtB;AACF;AAMA,eAAsB,kCACpB,aACA,WACA,mBACgC;AAChC,QAAM,iBAAiB,KAAK,MAAM,YAAY,KAAK;AACnD,QAAM,WAAW,KAAK,MAAM,iBAAiB,IAAI;AAEjD,QAAM,QAAQ,MAAM,SAAS;AAC7B,MAAI,CAAC,OAAO;AACV,UAAM,SAAS,YAAY,SAAS,QAAQ;AAC5C,WAAO;AAAA,MACL;AAAA,MACA,WAAW,mBAAmB,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,IAAI,IAAI,IAAI,EAAE;AACjC,aAAW,KAAK,WAAW;AACzB,UAAMA,OAAM,MAAM,MAAM,WAAW,EAChC,KAAK,EAAE,SAAS,GAAG,SAAS,KAAK,CAAC,EAClC,SAAS;AACZ,QAAIA,KAAI,UAAU,UAAU;AAC1B,aAAO,EAAE,QAAQA,KAAI,SAAS,QAAQ,GAAG,WAAW,OAAO;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,OAAO,MAAM,MAAM,WAAW,EAAE,SAAS;AAC/C,MAAI,IAAI,KAAK,SAAS;AACtB,MAAI,IAAI,KAAK,UAAU;AAEvB,WAAS,QAAQ,MAAM,SAAS,MAAM,SAAS,MAAM;AACnD,UAAM,KAAK,KAAK,MAAM,IAAI,KAAK;AAC/B,UAAM,KAAK,KAAK,MAAM,IAAI,KAAK;AAC/B,UAAMA,OAAM,MAAM,MAAM,WAAW,EAChC,OAAO,IAAI,IAAI,EAAE,KAAK,SAAS,CAAC,EAChC,KAAK,EAAE,SAAS,IAAI,SAAS,KAAK,CAAC,EACnC,SAAS;AACZ,QAAIA,KAAI,UAAU,UAAU;AAC1B,aAAO,EAAE,QAAQA,KAAI,SAAS,QAAQ,GAAG,WAAW,OAAO;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,MAAM,MAAM,MAAM,WAAW,EAChC,OAAO,KAAK,MAAM,IAAI,IAAI,GAAG,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,KAAK,SAAS,CAAC,EACpE,KAAK,EAAE,SAAS,IAAI,SAAS,KAAK,CAAC,EACnC,SAAS;AACZ,SAAO,EAAE,QAAQ,IAAI,SAAS,QAAQ,GAAG,WAAW,OAAO;AAC7D;AAEA,SAAS,eAAe,KAAqB;AAC3C,QAAM,QAAQ,IAAI,YAAY,EAAE,QAAQ,OAAO,EAAE;AACjD,UAAQ,OAAO;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,SAAS,wBAAwB,MAA+B;AACrE,SAAO,qBAAqB,KAAK,KAAK,OAAI,KAAK,MAAM;AACvD;","names":["buf"]}
|