dsh-agy 0.2.2 → 0.2.4

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 (33) hide show
  1. package/README.md +41 -4
  2. package/lib/{session-KoIh3xdB.mjs → accounts-DbTTxX_z.mjs} +1125 -546
  3. package/lib/accounts-DbTTxX_z.mjs.map +1 -0
  4. package/lib/{models-1rf_Wfo2.mjs → catalog-iuikPZIb.mjs} +29 -81
  5. package/lib/catalog-iuikPZIb.mjs.map +1 -0
  6. package/lib/cli/index.d.mts.map +1 -1
  7. package/lib/cli/index.mjs +149 -12
  8. package/lib/cli/index.mjs.map +1 -1
  9. package/lib/{exchange-DBRzR2M-.mjs → exchange-BvrLu2E4.mjs} +8 -5
  10. package/lib/exchange-BvrLu2E4.mjs.map +1 -0
  11. package/lib/{import-C4CRBTbi.mjs → import-DSvpbB0T.mjs} +30 -8
  12. package/lib/import-DSvpbB0T.mjs.map +1 -0
  13. package/lib/index.d.mts.map +1 -1
  14. package/lib/index.mjs +6 -1
  15. package/lib/index.mjs.map +1 -1
  16. package/lib/models-DRWVi33p.mjs +136 -0
  17. package/lib/models-DRWVi33p.mjs.map +1 -0
  18. package/lib/{plugin-common-CQoDUeqE.mjs → plugin-common-D7lc-W6b.mjs} +79 -11
  19. package/lib/plugin-common-D7lc-W6b.mjs.map +1 -0
  20. package/lib/proxy-DQPIwUov.mjs +269 -0
  21. package/lib/proxy-DQPIwUov.mjs.map +1 -0
  22. package/lib/{translate-BQuSQW35.mjs → translate-COjBTH4-.mjs} +27 -6
  23. package/lib/translate-COjBTH4-.mjs.map +1 -0
  24. package/lib/web/plugin.d.mts.map +1 -1
  25. package/lib/web/plugin.mjs +202 -8
  26. package/lib/web/plugin.mjs.map +1 -1
  27. package/package.json +4 -1
  28. package/lib/exchange-DBRzR2M-.mjs.map +0 -1
  29. package/lib/import-C4CRBTbi.mjs.map +0 -1
  30. package/lib/models-1rf_Wfo2.mjs.map +0 -1
  31. package/lib/plugin-common-CQoDUeqE.mjs.map +0 -1
  32. package/lib/session-KoIh3xdB.mjs.map +0 -1
  33. package/lib/translate-BQuSQW35.mjs.map +0 -1
@@ -0,0 +1,269 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { EnvHttpProxyAgent, ProxyAgent } from "undici";
3
+ import { createConnection } from "node:net";
4
+ //#region src/proxy.ts
5
+ /**
6
+ * Proxy-aware fetch: per-account proxy (http/https/socks5) + env fallback.
7
+ * - account.proxy present => per-account dispatcher (fail-closed, not affected by NO_PROXY)
8
+ * - otherwise => EnvHttpProxyAgent (honours HTTP_PROXY/HTTPS_PROXY/NO_PROXY)
9
+ * Applied per-request via dispatcher option so the host's global dispatcher stays untouched.
10
+ */
11
+ var proxy_exports = /* @__PURE__ */ __exportAll({
12
+ _envAgentForTest: () => envAgent,
13
+ dispatcherForAsync: () => dispatcherForAsync,
14
+ isProxyReachable: () => isProxyReachable,
15
+ isProxyUnreachableError: () => isProxyUnreachableError,
16
+ normalizeProxyUrl: () => normalizeProxyUrl,
17
+ proxiedFetch: () => proxiedFetch,
18
+ proxyUrlForLogs: () => proxyUrlForLogs,
19
+ tagProxyUnreachable: () => tagProxyUnreachable
20
+ });
21
+ const envAgent = new EnvHttpProxyAgent();
22
+ const dispatcherCache = /* @__PURE__ */ new Map();
23
+ const SUPPORTED = /* @__PURE__ */ new Set([
24
+ "http:",
25
+ "https:",
26
+ "socks5:",
27
+ "socks5h:"
28
+ ]);
29
+ function defaultPort(protocol) {
30
+ if (protocol === "https:") return "443";
31
+ if (protocol === "socks5:" || protocol === "socks5h:") return "1080";
32
+ return "8080";
33
+ }
34
+ function normalizeProxyUrl(proxyUrl) {
35
+ let raw = proxyUrl.trim();
36
+ if (!raw) throw new Error("[proxy] empty proxy URL");
37
+ if (raw.toLowerCase().startsWith("socks://")) raw = "socks5://" + raw.slice(8);
38
+ const familyMatch = raw.match(/\?family=(ipv4|ipv6)$/);
39
+ const familySuffix = familyMatch ? familyMatch[0] : "";
40
+ const baseRaw = familySuffix ? raw.slice(0, -familySuffix.length) : raw;
41
+ let parsed;
42
+ try {
43
+ parsed = new URL(baseRaw);
44
+ } catch {
45
+ throw new Error(`[proxy] invalid proxy URL: ${proxyUrlForLogs(proxyUrl)}`);
46
+ }
47
+ let protocol = parsed.protocol.toLowerCase();
48
+ if (protocol === "socks5h:") protocol = "socks5:";
49
+ if (!SUPPORTED.has(protocol) && protocol !== "socks5:") {
50
+ if (!SUPPORTED.has(parsed.protocol.toLowerCase())) throw new Error(`[proxy] unsupported protocol: ${parsed.protocol}`);
51
+ }
52
+ if (![
53
+ "http:",
54
+ "https:",
55
+ "socks5:"
56
+ ].includes(protocol)) throw new Error(`[proxy] unsupported protocol: ${parsed.protocol}`);
57
+ if (!parsed.hostname) throw new Error("[proxy] missing host");
58
+ let port = parsed.port;
59
+ if (!port) port = defaultPort(protocol);
60
+ const portNum = Number(port);
61
+ if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) throw new Error("[proxy] invalid port");
62
+ const auth = parsed.username ? `${encodeURIComponent(parsed.username)}${parsed.password ? `:${encodeURIComponent(parsed.password)}` : ""}@` : "";
63
+ const normalizedBase = `${protocol}//${auth}${parsed.hostname}:${port}`;
64
+ return familySuffix ? `${normalizedBase}${familySuffix}` : normalizedBase;
65
+ }
66
+ function proxyUrlForLogs(proxyUrl) {
67
+ try {
68
+ const fam = proxyUrl.match(/\?family=(ipv4|ipv6)$/);
69
+ const base = fam ? proxyUrl.slice(0, -fam[0].length) : proxyUrl;
70
+ const u = new URL(base);
71
+ const port = u.port || defaultPort(u.protocol);
72
+ return `${u.protocol}//${u.hostname}:${port}`;
73
+ } catch {
74
+ return proxyUrl;
75
+ }
76
+ }
77
+ const PROXY_UNREACHABLE_CODES = /* @__PURE__ */ new Set([
78
+ "ECONNREFUSED",
79
+ "ECONNRESET",
80
+ "ETIMEDOUT",
81
+ "ENETUNREACH",
82
+ "EHOSTUNREACH",
83
+ "EPIPE",
84
+ "UND_ERR_CONNECT_TIMEOUT",
85
+ "UND_ERR_SOCKET"
86
+ ]);
87
+ function isLoopbackUrl(url) {
88
+ try {
89
+ const h = (typeof url === "string" ? new URL(url) : url).hostname.toLowerCase();
90
+ return h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "::ffff:127.0.0.1";
91
+ } catch {
92
+ return false;
93
+ }
94
+ }
95
+ function isProxyUnreachableError(err) {
96
+ const seen = /* @__PURE__ */ new Set();
97
+ let cur = err;
98
+ for (let depth = 0; cur && depth < 5 && !seen.has(cur); depth++) {
99
+ seen.add(cur);
100
+ if (cur && typeof cur === "object") {
101
+ const code = cur.code;
102
+ if (typeof code === "string" && PROXY_UNREACHABLE_CODES.has(code)) return true;
103
+ const errorCode = cur.errorCode;
104
+ if (errorCode === "proxy_unreachable" || errorCode === "PROXY_UNREACHABLE") return true;
105
+ if (cur.statusCode === 503) {
106
+ const m = cur.message;
107
+ if (typeof m === "string" && m.includes("Proxy unreachable")) return true;
108
+ }
109
+ const msg = cur.message;
110
+ if (typeof msg === "string") {
111
+ if (msg.includes("proxy_unreachable") || msg.includes("PROXY_UNREACHABLE")) return true;
112
+ for (const c of PROXY_UNREACHABLE_CODES) if (msg.includes(c)) return true;
113
+ }
114
+ }
115
+ cur = cur?.cause;
116
+ if (!cur && err?.errors && depth === 0) {
117
+ const errs = err.errors;
118
+ if (Array.isArray(errs)) {
119
+ for (const e of errs) if (isProxyUnreachableError(e)) return true;
120
+ }
121
+ }
122
+ }
123
+ return false;
124
+ }
125
+ function tagProxyUnreachable(err) {
126
+ if (isProxyUnreachableError(err)) {
127
+ const e = err;
128
+ e.code = "PROXY_UNREACHABLE";
129
+ e.errorCode = "proxy_unreachable";
130
+ }
131
+ return err;
132
+ }
133
+ const FAST_FAIL_TIMEOUT_MS = 2e3;
134
+ const HEALTHY_TTL_MS = 3e4;
135
+ const UNHEALTHY_TTL_MS = 2e3;
136
+ const healthCache = /* @__PURE__ */ new Map();
137
+ const healthInflight = /* @__PURE__ */ new Map();
138
+ function tcpCheck(host, port, timeoutMs) {
139
+ return new Promise((resolve) => {
140
+ const socket = createConnection({
141
+ host,
142
+ port
143
+ }, () => {
144
+ socket.destroy();
145
+ resolve(true);
146
+ });
147
+ socket.setTimeout(timeoutMs);
148
+ socket.on("error", () => resolve(false));
149
+ socket.on("timeout", () => {
150
+ socket.destroy();
151
+ resolve(false);
152
+ });
153
+ });
154
+ }
155
+ async function isProxyReachable(proxyUrl, timeoutMs = FAST_FAIL_TIMEOUT_MS) {
156
+ const key = normalizeProxyUrl(proxyUrl);
157
+ const cached = healthCache.get(key);
158
+ if (cached && Date.now() - cached.at < cached.ttl) return cached.healthy;
159
+ const existing = healthInflight.get(key);
160
+ if (existing) return existing;
161
+ let url;
162
+ try {
163
+ const base = key.replace(/\?family=(ipv4|ipv6)$/, "");
164
+ url = new URL(base);
165
+ } catch {
166
+ healthCache.set(key, {
167
+ healthy: false,
168
+ at: Date.now(),
169
+ ttl: UNHEALTHY_TTL_MS
170
+ });
171
+ return false;
172
+ }
173
+ const probe = tcpCheck(url.hostname.replace(/^\[/, "").replace(/\]$/, ""), Number(url.port || defaultPort(url.protocol)), timeoutMs).then((healthy) => {
174
+ healthCache.set(key, {
175
+ healthy,
176
+ at: Date.now(),
177
+ ttl: healthy ? HEALTHY_TTL_MS : UNHEALTHY_TTL_MS
178
+ });
179
+ return healthy;
180
+ });
181
+ healthInflight.set(key, probe);
182
+ try {
183
+ return await probe;
184
+ } finally {
185
+ if (healthInflight.get(key) === probe) healthInflight.delete(key);
186
+ }
187
+ }
188
+ async function createSocksDispatcher(proxyUrl, dispatcherOpts) {
189
+ const { SocksProxyAgent } = await import("socks-proxy-agent");
190
+ return new SocksProxyAgent(proxyUrl);
191
+ }
192
+ function createHttpDispatcher(proxyUrl, dispatcherOpts) {
193
+ const clean = proxyUrl.replace(/\?family=(ipv4|ipv6)$/, "");
194
+ return new ProxyAgent({
195
+ uri: clean,
196
+ proxyTunnel: true,
197
+ ...dispatcherOpts
198
+ });
199
+ }
200
+ const DISPATCHER_OPTS = {
201
+ headersTimeout: 3e4,
202
+ bodyTimeout: 3e4,
203
+ connectTimeout: 1e4,
204
+ keepAliveTimeout: 1,
205
+ keepAliveMaxTimeout: 1,
206
+ pipelining: 0
207
+ };
208
+ async function dispatcherForAsync(proxyUrl) {
209
+ if (!proxyUrl) return envAgent;
210
+ const normalized = normalizeProxyUrl(proxyUrl);
211
+ const cached = dispatcherCache.get(normalized);
212
+ if (cached) return cached;
213
+ const famClean = normalized.replace(/\?family=(ipv4|ipv6)$/, "");
214
+ let dispatcher;
215
+ if (famClean.startsWith("socks5:")) dispatcher = await createSocksDispatcher(normalized, DISPATCHER_OPTS);
216
+ else dispatcher = createHttpDispatcher(normalized, DISPATCHER_OPTS);
217
+ dispatcherCache.set(normalized, dispatcher);
218
+ return dispatcher;
219
+ }
220
+ function getTargetUrlString(input) {
221
+ if (typeof input === "string") return input;
222
+ try {
223
+ if (input instanceof URL) return input.toString();
224
+ if (typeof input.url === "string") return input.url;
225
+ } catch {}
226
+ return "";
227
+ }
228
+ /** fetch() that respects per-account proxyUrl (when given) otherwise env. */
229
+ const proxiedFetch = async (input, init, opts) => {
230
+ const proxyUrl = opts?.proxyUrl ?? init?.proxyUrl;
231
+ const cleanInit = { ...init };
232
+ if (cleanInit.proxyUrl) delete cleanInit.proxyUrl;
233
+ if (!proxyUrl) return fetch(input, {
234
+ ...cleanInit,
235
+ dispatcher: envAgent
236
+ });
237
+ const targetStr = getTargetUrlString(input);
238
+ if (targetStr && isLoopbackUrl(targetStr)) return fetch(input, cleanInit);
239
+ try {
240
+ if (!await isProxyReachable(proxyUrl)) {
241
+ const err = /* @__PURE__ */ new Error(`[Proxy Fast-Fail] Proxy unreachable: ${proxyUrlForLogs(proxyUrl)}`);
242
+ err.code = "PROXY_UNREACHABLE";
243
+ err.errorCode = "proxy_unreachable";
244
+ err.statusCode = 503;
245
+ throw err;
246
+ }
247
+ } catch (e) {
248
+ if (e?.errorCode === "proxy_unreachable") throw e;
249
+ if (e instanceof Error && e.message.startsWith("[proxy]")) throw e;
250
+ }
251
+ let dispatcher;
252
+ try {
253
+ dispatcher = await dispatcherForAsync(proxyUrl);
254
+ } catch (e) {
255
+ throw tagProxyUnreachable(e);
256
+ }
257
+ try {
258
+ return await fetch(input, {
259
+ ...cleanInit,
260
+ dispatcher
261
+ });
262
+ } catch (err) {
263
+ throw tagProxyUnreachable(err);
264
+ }
265
+ };
266
+ //#endregion
267
+ export { proxyUrlForLogs as a, proxiedFetch as i, isProxyUnreachableError as n, proxy_exports as o, normalizeProxyUrl as r, isProxyReachable as t };
268
+
269
+ //# sourceMappingURL=proxy-DQPIwUov.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-DQPIwUov.mjs","names":[],"sources":["../src/proxy.ts"],"sourcesContent":["/**\n * Proxy-aware fetch: per-account proxy (http/https/socks5) + env fallback.\n * - account.proxy present => per-account dispatcher (fail-closed, not affected by NO_PROXY)\n * - otherwise => EnvHttpProxyAgent (honours HTTP_PROXY/HTTPS_PROXY/NO_PROXY)\n * Applied per-request via dispatcher option so the host's global dispatcher stays untouched.\n */\n\nimport { EnvHttpProxyAgent, ProxyAgent } from 'undici'\nimport { createConnection } from 'node:net'\nimport { createRequire } from 'node:module'\n\nconst envAgent = new EnvHttpProxyAgent()\n\n/** The env proxy agent (exported for tests). */\nexport const proxyAgent = envAgent\n\n// ── Dispatcher cache (bounded by MAX_ACCOUNTS=10, no leak concern) ──\nconst dispatcherCache = new Map<string, any>()\n\n// ── Proxy URL normalization ──\nconst SUPPORTED = new Set(['http:', 'https:', 'socks5:', 'socks5h:'])\n\nfunction defaultPort(protocol: string): string {\n if (protocol === 'https:') return '443'\n if (protocol === 'socks5:' || protocol === 'socks5h:') return '1080'\n return '8080'\n}\n\nexport function normalizeProxyUrl(proxyUrl: string): string {\n let raw = proxyUrl.trim()\n if (!raw) throw new Error('[proxy] empty proxy URL')\n // alias socks:// -> socks5://\n if (raw.toLowerCase().startsWith('socks://')) raw = 'socks5://' + raw.slice('socks://'.length)\n // strip family marker before parse, re-append after\n const familyMatch = raw.match(/\\?family=(ipv4|ipv6)$/)\n const familySuffix = familyMatch ? familyMatch[0] : ''\n const baseRaw = familySuffix ? raw.slice(0, -familySuffix.length) : raw\n\n let parsed: URL\n try {\n parsed = new URL(baseRaw)\n } catch {\n throw new Error(`[proxy] invalid proxy URL: ${proxyUrlForLogs(proxyUrl)}`)\n }\n // normalize socks5h -> socks5 (remote DNS, same agent)\n let protocol = parsed.protocol.toLowerCase()\n if (protocol === 'socks5h:') protocol = 'socks5:'\n if (!SUPPORTED.has(protocol) && protocol !== 'socks5:') {\n // allow socks5h already normalized\n if (!SUPPORTED.has(parsed.protocol.toLowerCase())) {\n throw new Error(`[proxy] unsupported protocol: ${parsed.protocol}`)\n }\n }\n // ensure protocol is one of http/https/socks5\n if (!['http:', 'https:', 'socks5:'].includes(protocol)) {\n throw new Error(`[proxy] unsupported protocol: ${parsed.protocol}`)\n }\n if (!parsed.hostname) throw new Error('[proxy] missing host')\n\n let port = parsed.port\n if (!port) port = defaultPort(protocol)\n const portNum = Number(port)\n if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) {\n throw new Error('[proxy] invalid port')\n }\n // Build auth with proper encoding (parsed.username/password are decoded)\n const auth = parsed.username\n ? `${encodeURIComponent(parsed.username)}${parsed.password ? `:${encodeURIComponent(parsed.password)}` : ''}@`\n : ''\n const normalizedBase = `${protocol}//${auth}${parsed.hostname}:${port}`\n return familySuffix ? `${normalizedBase}${familySuffix}` : normalizedBase\n}\n\nexport function proxyUrlForLogs(proxyUrl: string): string {\n try {\n // handle family suffix\n const fam = proxyUrl.match(/\\?family=(ipv4|ipv6)$/)\n const base = fam ? proxyUrl.slice(0, -fam[0].length) : proxyUrl\n const u = new URL(base)\n const port = u.port || defaultPort(u.protocol)\n return `${u.protocol}//${u.hostname}:${port}`\n } catch {\n return proxyUrl\n }\n}\n\n// ── Proxy unreachable detection (mirrors OmniRoute proxyFetch.ts:30) ──\nconst PROXY_UNREACHABLE_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'ENETUNREACH',\n 'EHOSTUNREACH',\n 'EPIPE',\n 'UND_ERR_CONNECT_TIMEOUT',\n 'UND_ERR_SOCKET',\n])\n\nfunction isLoopbackUrl(url: string | URL): boolean {\n try {\n const u = typeof url === 'string' ? new URL(url as string) : (url as URL)\n const h = u.hostname.toLowerCase()\n return h === 'localhost' || h === '127.0.0.1' || h === '::1' || h === '::ffff:127.0.0.1'\n } catch {\n return false\n }\n}\n\nexport function isProxyUnreachableError(err: unknown): boolean {\n const seen = new Set<unknown>()\n let cur: unknown = err\n for (let depth = 0; cur && depth < 5 && !seen.has(cur); depth++) {\n seen.add(cur)\n if (cur && typeof cur === 'object') {\n const code = (cur as { code?: unknown }).code\n if (typeof code === 'string' && PROXY_UNREACHABLE_CODES.has(code)) return true\n const errorCode = (cur as { errorCode?: unknown }).errorCode\n if (errorCode === 'proxy_unreachable' || errorCode === 'PROXY_UNREACHABLE') return true\n const statusCode = (cur as { statusCode?: unknown }).statusCode\n if (statusCode === 503) {\n const m = (cur as { message?: unknown }).message\n if (typeof m === 'string' && m.includes('Proxy unreachable')) return true\n }\n const msg = (cur as { message?: unknown }).message\n if (typeof msg === 'string') {\n if (msg.includes('proxy_unreachable') || msg.includes('PROXY_UNREACHABLE')) return true\n for (const c of PROXY_UNREACHABLE_CODES) {\n if (msg.includes(c)) return true\n }\n }\n }\n cur = (cur as { cause?: unknown })?.cause\n // Also handle AggregateError.errors (undici Happy Eyeballs)\n if (!cur && (err as { errors?: unknown })?.errors && depth === 0) {\n const errs = (err as { errors?: unknown[] }).errors\n if (Array.isArray(errs)) {\n for (const e of errs) if (isProxyUnreachableError(e)) return true\n }\n }\n }\n return false\n}\n\nexport function tagProxyUnreachable<T>(err: T): T {\n if (isProxyUnreachableError(err)) {\n const e = err as unknown as Error & { code?: string; errorCode?: string }\n e.code = 'PROXY_UNREACHABLE'\n e.errorCode = 'proxy_unreachable'\n }\n return err\n}\n\n// ── Fast-fail TCP reachability (2s, 30s healthy / 2s unhealthy cache) ──\nconst FAST_FAIL_TIMEOUT_MS = 2000\nconst HEALTHY_TTL_MS = 30_000\nconst UNHEALTHY_TTL_MS = 2000\ntype HealthEntry = { healthy: boolean; at: number; ttl: number }\nconst healthCache = new Map<string, HealthEntry>()\nconst healthInflight = new Map<string, Promise<boolean>>()\n\nfunction tcpCheck(host: string, port: number, timeoutMs: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ host, port }, () => {\n socket.destroy()\n resolve(true)\n })\n socket.setTimeout(timeoutMs)\n socket.on('error', () => resolve(false))\n socket.on('timeout', () => {\n socket.destroy()\n resolve(false)\n })\n })\n}\n\nexport async function isProxyReachable(proxyUrl: string, timeoutMs = FAST_FAIL_TIMEOUT_MS): Promise<boolean> {\n const key = normalizeProxyUrl(proxyUrl)\n const cached = healthCache.get(key)\n if (cached && Date.now() - cached.at < cached.ttl) return cached.healthy\n const existing = healthInflight.get(key)\n if (existing) return existing\n let url: URL\n try {\n const base = key.replace(/\\?family=(ipv4|ipv6)$/, '')\n url = new URL(base)\n } catch {\n healthCache.set(key, { healthy: false, at: Date.now(), ttl: UNHEALTHY_TTL_MS })\n return false\n }\n const host = url.hostname.replace(/^\\[/, '').replace(/\\]$/, '')\n const port = Number(url.port || defaultPort(url.protocol))\n const probe = tcpCheck(host, port, timeoutMs).then((healthy) => {\n healthCache.set(key, { healthy, at: Date.now(), ttl: healthy ? HEALTHY_TTL_MS : UNHEALTHY_TTL_MS })\n return healthy\n })\n healthInflight.set(key, probe)\n try {\n return await probe\n } finally {\n if (healthInflight.get(key) === probe) healthInflight.delete(key)\n }\n}\n\nexport function _clearProxyHealthCacheForTest(): void {\n healthCache.clear()\n healthInflight.clear()\n}\n\n// ── Dispatcher creation (cached) ──\nasync function createSocksDispatcher(proxyUrl: string, dispatcherOpts: Record<string, unknown>): Promise<any> {\n // @ts-ignore — optional dep, only required for socks5\n const { SocksProxyAgent } = await import('socks-proxy-agent')\n // socks-proxy-agent is compatible with undici dispatcher interface via fetch\n return new (SocksProxyAgent as any)(proxyUrl) as any\n}\n\nfunction createHttpDispatcher(proxyUrl: string, dispatcherOpts: Record<string, unknown>): any {\n const clean = proxyUrl.replace(/\\?family=(ipv4|ipv6)$/, '')\n return new ProxyAgent({\n uri: clean,\n // tunnel all (http+https) via CONNECT, same as OmniRoute\n proxyTunnel: true,\n ...dispatcherOpts,\n } as any)\n}\n\nconst DISPATCHER_OPTS = {\n headersTimeout: 30_000,\n bodyTimeout: 30_000,\n connectTimeout: 10_000,\n keepAliveTimeout: 1,\n keepAliveMaxTimeout: 1,\n pipelining: 0,\n} as const\n\nexport function dispatcherFor(proxyUrl?: string): any | undefined {\n if (!proxyUrl) return envAgent as any\n const normalized = normalizeProxyUrl(proxyUrl)\n const cached = dispatcherCache.get(normalized)\n if (cached) return cached\n const famClean = normalized.replace(/\\?family=(ipv4|ipv6)$/, '')\n let dispatcher: any\n if (famClean.startsWith('socks5:')) {\n // SOCKS needs SocksProxyAgent. Try sync require for cached case; otherwise prefer async path (proxiedFetch uses dispatcherForAsync).\n try {\n const rq = createRequire(import.meta.url)\n const mod = rq('socks-proxy-agent') as { SocksProxyAgent?: new (u: string) => unknown }\n const Cls = mod.SocksProxyAgent\n if (Cls) {\n dispatcher = new (Cls as unknown as new (u: string) => unknown)(normalized) as unknown\n } else {\n throw new Error('no SocksProxyAgent')\n }\n } catch {\n throw new Error('[proxy] socks dispatcher requires async creation — use dispatcherForAsync or proxiedFetch with proxyUrl')\n }\n } else {\n dispatcher = createHttpDispatcher(normalized, DISPATCHER_OPTS as any)\n }\n dispatcherCache.set(normalized, dispatcher)\n return dispatcher\n}\n\nexport async function dispatcherForAsync(proxyUrl?: string): Promise<any | undefined> {\n if (!proxyUrl) return envAgent as any\n const normalized = normalizeProxyUrl(proxyUrl)\n const cached = dispatcherCache.get(normalized)\n if (cached) return cached\n const famClean = normalized.replace(/\\?family=(ipv4|ipv6)$/, '')\n let dispatcher: any\n if (famClean.startsWith('socks5:')) {\n dispatcher = await createSocksDispatcher(normalized, DISPATCHER_OPTS as any)\n } else {\n dispatcher = createHttpDispatcher(normalized, DISPATCHER_OPTS as any)\n }\n dispatcherCache.set(normalized, dispatcher)\n return dispatcher\n}\n\nexport function _clearDispatcherCacheForTest(): void {\n dispatcherCache.clear()\n}\n\nfunction getTargetUrlString(input: Parameters<typeof fetch>[0]): string {\n if (typeof input === 'string') return input\n try {\n if (input instanceof URL) return input.toString()\n if (typeof (input as Request).url === 'string') return (input as Request).url\n } catch {\n // ignore\n }\n return ''\n}\n\n/** fetch() that respects per-account proxyUrl (when given) otherwise env. */\nexport const proxiedFetch = async (\n input: Parameters<typeof fetch>[0],\n init?: Parameters<typeof fetch>[1] & { proxyUrl?: string },\n opts?: { proxyUrl?: string },\n): Promise<Response> => {\n const proxyUrl = (opts as any)?.proxyUrl ?? (init as any)?.proxyUrl\n // Normalize init without proxyUrl leakage\n const cleanInit = { ...init } as any\n if (cleanInit.proxyUrl) delete cleanInit.proxyUrl\n if (!proxyUrl) {\n return fetch(input, { ...cleanInit, dispatcher: envAgent as any })\n }\n // Loopback bypass: per-account proxy must never intercept OAuth loopback callback (spec 1)\n const targetStr = getTargetUrlString(input)\n if (targetStr && isLoopbackUrl(targetStr)) {\n return fetch(input, cleanInit as RequestInit)\n }\n // Fast-fail pre-check (skip for env path)\n try {\n const reachable = await isProxyReachable(proxyUrl)\n if (!reachable) {\n const err = new Error(`[Proxy Fast-Fail] Proxy unreachable: ${proxyUrlForLogs(proxyUrl)}`) as Error & { code?: string; errorCode?: string; statusCode?: number }\n err.code = 'PROXY_UNREACHABLE'\n err.errorCode = 'proxy_unreachable'\n ;(err as any).statusCode = 503\n throw err\n }\n } catch (e) {\n if ((e as any)?.errorCode === 'proxy_unreachable') throw e\n // normalization failure -> throw\n if (e instanceof Error && e.message.startsWith('[proxy]')) throw e\n }\n\n let dispatcher: any\n try {\n dispatcher = await dispatcherForAsync(proxyUrl)\n } catch (e) {\n throw tagProxyUnreachable(e)\n }\n try {\n return await fetch(input, { ...cleanInit, dispatcher })\n } catch (err) {\n // Tag proxy unreachable so caller can classify\n throw tagProxyUnreachable(err)\n }\n}\n\n// Keep named export for tests that assert instanceof\nexport { envAgent as _envAgentForTest }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAWA,MAAM,WAAW,IAAI,kBAAkB;AAMvC,MAAM,kCAAkB,IAAI,IAAiB;AAG7C,MAAM,4BAAY,IAAI,IAAI;CAAC;CAAS;CAAU;CAAW;AAAU,CAAC;AAEpE,SAAS,YAAY,UAA0B;CAC7C,IAAI,aAAa,UAAU,OAAO;CAClC,IAAI,aAAa,aAAa,aAAa,YAAY,OAAO;CAC9D,OAAO;AACT;AAEA,SAAgB,kBAAkB,UAA0B;CAC1D,IAAI,MAAM,SAAS,KAAK;CACxB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,yBAAyB;CAEnD,IAAI,IAAI,YAAY,CAAC,CAAC,WAAW,UAAU,GAAG,MAAM,cAAc,IAAI,MAAM,CAAiB;CAE7F,MAAM,cAAc,IAAI,MAAM,uBAAuB;CACrD,MAAM,eAAe,cAAc,YAAY,KAAK;CACpD,MAAM,UAAU,eAAe,IAAI,MAAM,GAAG,CAAC,aAAa,MAAM,IAAI;CAEpE,IAAI;CACJ,IAAI;EACF,SAAS,IAAI,IAAI,OAAO;CAC1B,QAAQ;EACN,MAAM,IAAI,MAAM,8BAA8B,gBAAgB,QAAQ,GAAG;CAC3E;CAEA,IAAI,WAAW,OAAO,SAAS,YAAY;CAC3C,IAAI,aAAa,YAAY,WAAW;CACxC,IAAI,CAAC,UAAU,IAAI,QAAQ,KAAK,aAAa,WAEvC;MAAA,CAAC,UAAU,IAAI,OAAO,SAAS,YAAY,CAAC,GAC9C,MAAM,IAAI,MAAM,iCAAiC,OAAO,UAAU;CAAA;CAItE,IAAI,CAAC;EAAC;EAAS;EAAU;CAAS,CAAC,CAAC,SAAS,QAAQ,GACnD,MAAM,IAAI,MAAM,iCAAiC,OAAO,UAAU;CAEpE,IAAI,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,sBAAsB;CAE5D,IAAI,OAAO,OAAO;CAClB,IAAI,CAAC,MAAM,OAAO,YAAY,QAAQ;CACtC,MAAM,UAAU,OAAO,IAAI;CAC3B,IAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,KAAK,UAAU,OACzD,MAAM,IAAI,MAAM,sBAAsB;CAGxC,MAAM,OAAO,OAAO,WAChB,GAAG,mBAAmB,OAAO,QAAQ,IAAI,OAAO,WAAW,IAAI,mBAAmB,OAAO,QAAQ,MAAM,GAAG,KAC1G;CACJ,MAAM,iBAAiB,GAAG,SAAS,IAAI,OAAO,OAAO,SAAS,GAAG;CACjE,OAAO,eAAe,GAAG,iBAAiB,iBAAiB;AAC7D;AAEA,SAAgB,gBAAgB,UAA0B;CACxD,IAAI;EAEF,MAAM,MAAM,SAAS,MAAM,uBAAuB;EAClD,MAAM,OAAO,MAAM,SAAS,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI;EACvD,MAAM,IAAI,IAAI,IAAI,IAAI;EACtB,MAAM,OAAO,EAAE,QAAQ,YAAY,EAAE,QAAQ;EAC7C,OAAO,GAAG,EAAE,SAAS,IAAI,EAAE,SAAS,GAAG;CACzC,QAAQ;EACN,OAAO;CACT;AACF;AAGA,MAAM,0CAA0B,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,cAAc,KAA4B;CACjD,IAAI;EAEF,MAAM,KADI,OAAO,QAAQ,WAAW,IAAI,IAAI,GAAa,IAAK,IAAA,CAClD,SAAS,YAAY;EACjC,OAAO,MAAM,eAAe,MAAM,eAAe,MAAM,SAAS,MAAM;CACxE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,wBAAwB,KAAuB;CAC7D,MAAM,uBAAO,IAAI,IAAa;CAC9B,IAAI,MAAe;CACnB,KAAK,IAAI,QAAQ,GAAG,OAAO,QAAQ,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG,SAAS;EAC/D,KAAK,IAAI,GAAG;EACZ,IAAI,OAAO,OAAO,QAAQ,UAAU;GAClC,MAAM,OAAQ,IAA2B;GACzC,IAAI,OAAO,SAAS,YAAY,wBAAwB,IAAI,IAAI,GAAG,OAAO;GAC1E,MAAM,YAAa,IAAgC;GACnD,IAAI,cAAc,uBAAuB,cAAc,qBAAqB,OAAO;GAEnF,IADoB,IAAiC,eAClC,KAAK;IACtB,MAAM,IAAK,IAA8B;IACzC,IAAI,OAAO,MAAM,YAAY,EAAE,SAAS,mBAAmB,GAAG,OAAO;GACvE;GACA,MAAM,MAAO,IAA8B;GAC3C,IAAI,OAAO,QAAQ,UAAU;IAC3B,IAAI,IAAI,SAAS,mBAAmB,KAAK,IAAI,SAAS,mBAAmB,GAAG,OAAO;IACnF,KAAK,MAAM,KAAK,yBACd,IAAI,IAAI,SAAS,CAAC,GAAG,OAAO;GAEhC;EACF;EACA,MAAO,KAA6B;EAEpC,IAAI,CAAC,OAAQ,KAA8B,UAAU,UAAU,GAAG;GAChE,MAAM,OAAQ,IAA+B;GAC7C,IAAI,MAAM,QAAQ,IAAI,GACf;SAAA,MAAM,KAAK,MAAM,IAAI,wBAAwB,CAAC,GAAG,OAAO;GAAA;EAEjE;CACF;CACA,OAAO;AACT;AAEA,SAAgB,oBAAuB,KAAW;CAChD,IAAI,wBAAwB,GAAG,GAAG;EAChC,MAAM,IAAI;EACV,EAAE,OAAO;EACT,EAAE,YAAY;CAChB;CACA,OAAO;AACT;AAGA,MAAM,uBAAuB;AAC7B,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AAEzB,MAAM,8BAAc,IAAI,IAAyB;AACjD,MAAM,iCAAiB,IAAI,IAA8B;AAEzD,SAAS,SAAS,MAAc,MAAc,WAAqC;CACjF,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,SAAS,iBAAiB;GAAE;GAAM;EAAK,SAAS;GACpD,OAAO,QAAQ;GACf,QAAQ,IAAI;EACd,CAAC;EACD,OAAO,WAAW,SAAS;EAC3B,OAAO,GAAG,eAAe,QAAQ,KAAK,CAAC;EACvC,OAAO,GAAG,iBAAiB;GACzB,OAAO,QAAQ;GACf,QAAQ,KAAK;EACf,CAAC;CACH,CAAC;AACH;AAEA,eAAsB,iBAAiB,UAAkB,YAAY,sBAAwC;CAC3G,MAAM,MAAM,kBAAkB,QAAQ;CACtC,MAAM,SAAS,YAAY,IAAI,GAAG;CAClC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,KAAK,OAAO,KAAK,OAAO,OAAO;CACjE,MAAM,WAAW,eAAe,IAAI,GAAG;CACvC,IAAI,UAAU,OAAO;CACrB,IAAI;CACJ,IAAI;EACF,MAAM,OAAO,IAAI,QAAQ,yBAAyB,EAAE;EACpD,MAAM,IAAI,IAAI,IAAI;CACpB,QAAQ;EACN,YAAY,IAAI,KAAK;GAAE,SAAS;GAAO,IAAI,KAAK,IAAI;GAAG,KAAK;EAAiB,CAAC;EAC9E,OAAO;CACT;CAGA,MAAM,QAAQ,SAFD,IAAI,SAAS,QAAQ,OAAO,EAAE,CAAC,CAAC,QAAQ,OAAO,EAElC,GADb,OAAO,IAAI,QAAQ,YAAY,IAAI,QAAQ,CACxB,GAAG,SAAS,CAAC,CAAC,MAAM,YAAY;EAC9D,YAAY,IAAI,KAAK;GAAE;GAAS,IAAI,KAAK,IAAI;GAAG,KAAK,UAAU,iBAAiB;EAAiB,CAAC;EAClG,OAAO;CACT,CAAC;CACD,eAAe,IAAI,KAAK,KAAK;CAC7B,IAAI;EACF,OAAO,MAAM;CACf,UAAU;EACR,IAAI,eAAe,IAAI,GAAG,MAAM,OAAO,eAAe,OAAO,GAAG;CAClE;AACF;AAQA,eAAe,sBAAsB,UAAkB,gBAAuD;CAE5G,MAAM,EAAE,oBAAoB,MAAM,OAAO;CAEzC,OAAO,IAAK,gBAAwB,QAAQ;AAC9C;AAEA,SAAS,qBAAqB,UAAkB,gBAA8C;CAC5F,MAAM,QAAQ,SAAS,QAAQ,yBAAyB,EAAE;CAC1D,OAAO,IAAI,WAAW;EACpB,KAAK;EAEL,aAAa;EACb,GAAG;CACL,CAAQ;AACV;AAEA,MAAM,kBAAkB;CACtB,gBAAgB;CAChB,aAAa;CACb,gBAAgB;CAChB,kBAAkB;CAClB,qBAAqB;CACrB,YAAY;AACd;AA8BA,eAAsB,mBAAmB,UAA6C;CACpF,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,aAAa,kBAAkB,QAAQ;CAC7C,MAAM,SAAS,gBAAgB,IAAI,UAAU;CAC7C,IAAI,QAAQ,OAAO;CACnB,MAAM,WAAW,WAAW,QAAQ,yBAAyB,EAAE;CAC/D,IAAI;CACJ,IAAI,SAAS,WAAW,SAAS,GAC/B,aAAa,MAAM,sBAAsB,YAAY,eAAsB;MAE3E,aAAa,qBAAqB,YAAY,eAAsB;CAEtE,gBAAgB,IAAI,YAAY,UAAU;CAC1C,OAAO;AACT;AAMA,SAAS,mBAAmB,OAA4C;CACtE,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,IAAI,iBAAiB,KAAK,OAAO,MAAM,SAAS;EAChD,IAAI,OAAQ,MAAkB,QAAQ,UAAU,OAAQ,MAAkB;CAC5E,QAAQ,CAER;CACA,OAAO;AACT;;AAGA,MAAa,eAAe,OAC1B,OACA,MACA,SACsB;CACtB,MAAM,WAAY,MAAc,YAAa,MAAc;CAE3D,MAAM,YAAY,EAAE,GAAG,KAAK;CAC5B,IAAI,UAAU,UAAU,OAAO,UAAU;CACzC,IAAI,CAAC,UACH,OAAO,MAAM,OAAO;EAAE,GAAG;EAAW,YAAY;CAAgB,CAAC;CAGnE,MAAM,YAAY,mBAAmB,KAAK;CAC1C,IAAI,aAAa,cAAc,SAAS,GACtC,OAAO,MAAM,OAAO,SAAwB;CAG9C,IAAI;EAEF,IAAI,CAAC,MADmB,iBAAiB,QAAQ,GACjC;GACd,MAAM,sBAAM,IAAI,MAAM,wCAAwC,gBAAgB,QAAQ,GAAG;GACzF,IAAI,OAAO;GACX,IAAI,YAAY;GACf,IAAa,aAAa;GAC3B,MAAM;EACR;CACF,SAAS,GAAG;EACV,IAAK,GAAW,cAAc,qBAAqB,MAAM;EAEzD,IAAI,aAAa,SAAS,EAAE,QAAQ,WAAW,SAAS,GAAG,MAAM;CACnE;CAEA,IAAI;CACJ,IAAI;EACF,aAAa,MAAM,mBAAmB,QAAQ;CAChD,SAAS,GAAG;EACV,MAAM,oBAAoB,CAAC;CAC7B;CACA,IAAI;EACF,OAAO,MAAM,MAAM,OAAO;GAAE,GAAG;GAAW;EAAW,CAAC;CACxD,SAAS,KAAK;EAEZ,MAAM,oBAAoB,GAAG;CAC/B;AACF"}
@@ -1,5 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { g as generateAntigravityRequestId } from "./session-KoIh3xdB.mjs";
2
+ import { v as generateAntigravityRequestId } from "./accounts-DbTTxX_z.mjs";
3
+ import { i as isLevelThinkingModel } from "./catalog-iuikPZIb.mjs";
3
4
  import { createHash } from "node:crypto";
4
5
  const DEFAULT_TTL_MS = 36e5;
5
6
  const MAX_ENTRIES = 2e3;
@@ -145,7 +146,7 @@ function buildToolNameIndex(messages) {
145
146
  for (const message of messages) for (const block of message.content) if (block.type === "tool-call") index.set(block.id, block.name);
146
147
  return index;
147
148
  }
148
- function blockToParts(block, toolNames) {
149
+ function blockToParts(block, toolNames, images) {
149
150
  switch (block.type) {
150
151
  case "text": return [{ text: block.text }];
151
152
  case "reasoning": return [{
@@ -175,11 +176,19 @@ function blockToParts(block, toolNames) {
175
176
  is_error: block.isError === true
176
177
  }
177
178
  } }];
179
+ case "image": {
180
+ const resolved = images.get(block.attachment.attachmentId);
181
+ if (!resolved) throw new Error(`agy translate: unresolved image attachment "${block.attachment.attachmentId}"`);
182
+ return [{ inlineData: {
183
+ mimeType: resolved.mediaType,
184
+ data: resolved.data
185
+ } }];
186
+ }
178
187
  default: return [];
179
188
  }
180
189
  }
181
- function messageToContent(message, toolNames) {
182
- const parts = message.content.flatMap((block) => blockToParts(block, toolNames));
190
+ function messageToContent(message, toolNames, images) {
191
+ const parts = message.content.flatMap((block) => block.type === "image" && message.role !== "user" ? [] : blockToParts(block, toolNames, images));
183
192
  if (parts.length === 0) return null;
184
193
  return {
185
194
  role: message.role === "assistant" ? "model" : "user",
@@ -196,6 +205,12 @@ const AGY_BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
196
205
  "search_web",
197
206
  "googleSearch"
198
207
  ]);
208
+ /** Level-thinking: single id + selectable low/medium/high via thinkingLevel (catalog thinking:'level'). */
209
+ const LEVEL_THINKING_LEVELS = /* @__PURE__ */ new Set([
210
+ "low",
211
+ "medium",
212
+ "high"
213
+ ]);
199
214
  /** Upstream functionDeclarations names are `[a-zA-Z0-9_]` and ≤64 chars (OmniRoute-verified). */
200
215
  const AGY_TOOL_NAME_MAX_LENGTH = 64;
201
216
  /** Sanitize a tool name to the upstream charset/length; dedupe via a short hash. */
@@ -229,13 +244,19 @@ function toolsToDeclarations(tools) {
229
244
  /** Build the wrapped Antigravity request body for one call. */
230
245
  function toAgyRequestBody(options, context) {
231
246
  const toolNames = buildToolNameIndex(options.messages);
232
- let contents = options.messages.map((message) => messageToContent(message, toolNames)).filter((c) => c !== null);
247
+ const images = context.images ?? /* @__PURE__ */ new Map();
248
+ let contents = options.messages.map((message) => messageToContent(message, toolNames, images)).filter((c) => c !== null);
233
249
  if (isClaudeModel(options.model)) contents = stripTrailingModelTurn(contents);
234
250
  const tools = toolsToDeclarations(options.tools);
235
251
  const generationConfig = {};
236
252
  if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
237
253
  if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
238
254
  if (options.stop !== void 0 && options.stop.length > 0) generationConfig.stopSequences = options.stop;
255
+ const effort = options.reasoningEffort?.toLowerCase();
256
+ if (effort && isLevelThinkingModel(options.model) && LEVEL_THINKING_LEVELS.has(effort)) generationConfig.thinkingConfig = {
257
+ thinkingLevel: effort,
258
+ includeThoughts: true
259
+ };
239
260
  return {
240
261
  project: context.projectId || void 0,
241
262
  requestId: generateAntigravityRequestId(),
@@ -255,4 +276,4 @@ function toAgyRequestBody(options, context) {
255
276
  //#endregion
256
277
  export { translate_exports as n, setThoughtSignature as r, toAgyRequestBody as t };
257
278
 
258
- //# sourceMappingURL=translate-BQuSQW35.mjs.map
279
+ //# sourceMappingURL=translate-COjBTH4-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate-COjBTH4-.mjs","names":[],"sources":["../src/runtime/signature-cache.ts","../src/adapter/translate.ts"],"sourcesContent":["/**\n * Gemini thought-signature cache for Antigravity tool calls.\n *\n * The Antigravity backend requires every outbound `functionCall` part to carry\n * a `thoughtSignature` (400 \"Function call is missing a thought_signature\"\n * otherwise). Signatures arrive on the *response* side — as a sibling field of\n * functionCall parts, and on thought parts — and must be replayed on the next\n * turn for the same tool call id. When nothing is cached, the translator\n * injects the `skip_thought_signature_validator` sentinel (the established\n * bypass both reference implementations use by default).\n *\n * Process-local with TTL; a cold process falls back to the sentinel, which the\n * upstream accepts, so cross-process persistence is not required for\n * correctness.\n */\n\nexport const THOUGHT_SIGNATURE_SENTINEL = 'skip_thought_signature_validator'\n\ninterface CacheEntry {\n signature: string\n expiresAt: number\n}\n\nconst DEFAULT_TTL_MS = 60 * 60 * 1000\nconst MAX_ENTRIES = 2000\n\nconst store = new Map<string, CacheEntry>()\n\nfunction pruneExpired(now = Date.now()): void {\n if (store.size < MAX_ENTRIES / 2) return\n for (const [key, entry] of store) {\n if (entry.expiresAt <= now) store.delete(key)\n }\n}\n\n/** Store the signature observed for one tool call id (response side). */\nexport function setThoughtSignature(toolCallId: string, signature: string, ttlMs = DEFAULT_TTL_MS): void {\n if (!toolCallId || !signature) return\n pruneExpired()\n if (store.size >= MAX_ENTRIES) {\n // Evict the oldest entry to keep the cache bounded.\n let oldestKey: string | null = null\n let oldestExpiry = Infinity\n for (const [key, entry] of store) {\n if (entry.expiresAt < oldestExpiry) {\n oldestExpiry = entry.expiresAt\n oldestKey = key\n }\n }\n if (oldestKey) store.delete(oldestKey)\n }\n store.set(toolCallId, { signature, expiresAt: Date.now() + ttlMs })\n}\n\n/** Resolve the signature for one tool call id, or null when unknown/expired. */\nexport function getThoughtSignature(toolCallId: string): string | null {\n if (!toolCallId) return null\n const entry = store.get(toolCallId)\n if (!entry) return null\n if (entry.expiresAt <= Date.now()) {\n store.delete(toolCallId)\n return null\n }\n return entry.signature\n}\n","/**\n * Translate a DSH GenerateOptions into the Antigravity wrapped request.\n *\n * Envelope shape follows the actively-maintained OmniRoute wire format\n * (the archived opencode reference predates it): top-level `project`,\n * `requestId`, `model`, `userAgent`, `requestType`, with the Gemini-style\n * body under `request` (contents/systemInstruction/tools/generationConfig/\n * sessionId). `toolConfig` VALIDATED is attached when tools are present, and\n * Claude-path requests strip trailing model turns (Vertex rejects \"assistant\n * message prefill\").\n *\n * Thinking blocks are carried as-is (Gemini `thought` parts); nothing is\n * stripped or re-signed — that signature dance was an artifact of the\n * reference plugin's interception architecture (see docs/ARCHITECTURE.md).\n */\n\nimport { createHash } from 'node:crypto'\nimport type { ContentBlock, GenerateOptions, Message, ToolSchema } from '@deepseek-ai/dsh-llm'\nimport { generateAntigravityRequestId } from '../runtime/identity.ts'\nimport { getThoughtSignature, THOUGHT_SIGNATURE_SENTINEL } from '../runtime/signature-cache.ts'\nimport { catalogModel, isLevelThinkingModel } from './catalog.ts'\n\nexport type AgyPart =\n | { text: string }\n | { thought: true; text: string }\n | { thoughtSignature: string; functionCall: { id: string; name: string; args: unknown } }\n | { functionResponse: { name: string; response: unknown } }\n | { inlineData: { mimeType: string; data: string } }\n\n/** Image bytes pre-resolved from the durable attachment store, keyed by attachment id. */\nexport interface AgyResolvedImage {\n mediaType: string\n /** Pure base64 (no data: prefix). */\n data: string\n}\n\nexport interface AgyContent {\n role: 'user' | 'model'\n parts: AgyPart[]\n}\n\nexport interface AgyRequestBody {\n project?: string\n requestId?: string\n model: string\n userAgent?: string\n requestType?: 'agent'\n request: {\n contents: AgyContent[]\n systemInstruction?: { parts: Array<{ text: string }> }\n tools?: Array<{ functionDeclarations: Array<{ name: string; description: string; parameters: unknown }> }>\n toolConfig?: { functionCallingConfig: { mode: 'VALIDATED' } }\n generationConfig?: {\n temperature?: number\n maxOutputTokens?: number\n stopSequences?: string[]\n thinkingConfig?: { thinkingLevel: string; includeThoughts: boolean }\n }\n sessionId?: string\n }\n}\n\n/** Whether a model id belongs to a Claude-branded model (Vertex-hosted). */\nexport function isClaudeModel(model: string): boolean {\n return model.startsWith('claude-') || model.includes('/claude')\n}\n\n/**\n * Vertex (the Antigravity Claude backend) rejects conversations ending on an\n * assistant/model turn (\"assistant message prefill\"); never strip to empty.\n */\nexport function stripTrailingModelTurn(contents: AgyContent[]): AgyContent[] {\n while (contents.length > 1 && contents[contents.length - 1]?.role === 'model') {\n contents.pop()\n }\n return contents\n}\n\n/**\n * The Antigravity backend parses tool `parameters` as a strict protobuf\n * schema and rejects ANY unknown keyword with 400 (verified empirically:\n * `$schema`, `propertyNames`, `pattern`, `minLength`, ... each fail in turn).\n * Denylisting is whack-a-mole, so keep only the keywords the upstream\n * accepts. Container shapes are handled distinctly: `properties` is a\n * name->schema map (keys preserved), `items`/`additionalProperties` are\n * nested schemas (additionalProperties also accepts a boolean — live-verified\n * against the Antigravity upstream), `required`/`enum` are plain arrays.\n *\n * Keyword VALUES are also constrained by the protobuf shape (verified\n * empirically): `type` must be a single enum string (union arrays like\n * `[\"string\",\"number\"]` are rejected) and every `enum` item must be a\n * string (booleans/numbers are rejected). Values are normalized to the\n * nearest valid form instead of being dropped wholesale.\n */\n// Exported for the contract invariant test (tests/adapter.test.ts); not part of\n// the package public API (translate.ts is an internal module).\nexport const AGY_SCHEMA_ALLOWLIST = new Set([\n 'type', 'format', 'title', 'description', 'nullable',\n 'items', 'enum', 'default', 'properties', 'required', 'additionalProperties',\n])\nconst AGY_SCHEMA_MAP_KEYS = new Set(['properties'])\nconst AGY_SCHEMA_NESTED_KEYS = new Set(['items', 'additionalProperties'])\nconst AGY_SCHEMA_LIST_KEYS = new Set(['required', 'enum'])\n\nfunction sanitizeToolSchema(schema: unknown): unknown {\n if (!schema || typeof schema !== 'object') return schema\n if (Array.isArray(schema)) return schema.map((entry) => sanitizeToolSchema(entry))\n\n // Normalize union types: upstream `type` is a single enum string. Pick the\n // first non-null string type (`\"null\"` maps to the `nullable` keyword);\n // fall back to `string` when no usable type remains.\n let normalized = schema as Record<string, unknown>\n if (Array.isArray(normalized.type)) {\n const types = normalized.type.filter((t): t is string => typeof t === 'string' && t !== 'null')\n normalized = { ...normalized, type: types[0] ?? 'string' }\n }\n\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(normalized)) {\n if (!AGY_SCHEMA_ALLOWLIST.has(key)) continue\n if (AGY_SCHEMA_MAP_KEYS.has(key)) {\n const map: Record<string, unknown> = {}\n for (const [name, child] of Object.entries(value as Record<string, unknown>)) {\n map[name] = sanitizeToolSchema(child)\n }\n result[key] = map\n continue\n }\n if (AGY_SCHEMA_NESTED_KEYS.has(key)) {\n result[key] = sanitizeToolSchema(value)\n continue\n }\n if (AGY_SCHEMA_LIST_KEYS.has(key)) {\n // Upstream `enum` items must be strings; filter the rest and omit an\n // empty enum entirely (an empty array would be rejected too).\n if (key === 'enum' && Array.isArray(value)) {\n const filtered = value.filter((v): v is string => typeof v === 'string')\n if (filtered.length > 0) result[key] = filtered\n } else {\n result[key] = value\n }\n continue\n }\n result[key] = value\n }\n return result\n}\n\n/** Collect tool-call names by id so tool-result blocks can name their function. */\nfunction buildToolNameIndex(messages: readonly Message[]): Map<string, string> {\n const index = new Map<string, string>()\n for (const message of messages) {\n for (const block of message.content) {\n if (block.type === 'tool-call') {\n index.set(block.id, block.name)\n }\n }\n }\n return index\n}\n\nfunction blockToParts(\n block: ContentBlock,\n toolNames: Map<string, string>,\n images: Map<string, AgyResolvedImage>,\n): AgyPart[] {\n switch (block.type) {\n case 'text':\n return [{ text: block.text }]\n case 'reasoning':\n return [{ thought: true, text: block.text }]\n case 'tool-call': {\n // Upstream parses functionCall.args as google.protobuf.Struct and\n // rejects a raw string with 400. Guarantee an object: parse the string\n // form, fall back to {} when it is truncated/malformed (the failure\n // mode for long multi-turn histories).\n let args: unknown = {}\n if (typeof block.arguments === 'object' && block.arguments !== null && !Array.isArray(block.arguments)) {\n args = block.arguments\n } else if (typeof block.arguments === 'string') {\n try {\n const parsed: unknown = JSON.parse(block.arguments)\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n args = parsed\n }\n } catch {\n // truncated/malformed JSON -> empty object\n }\n }\n // Antigravity rejects functionCall parts without a thoughtSignature\n // (400). Replay the signature captured for this tool call id on the\n // previous turn; the sentinel is the established bypass when nothing is\n // cached (both reference implementations default to it).\n const signature = getThoughtSignature(block.id) ?? THOUGHT_SIGNATURE_SENTINEL\n return [{\n thoughtSignature: signature,\n functionCall: { id: block.id, name: block.name, args },\n }]\n }\n case 'tool-result': {\n const name = toolNames.get(block.toolCallId) ?? block.toolCallId\n const text = block.content\n .filter((b): b is Extract<ContentBlock, { type: 'text' }> => b.type === 'text')\n .map((b) => b.text)\n .join('\\n')\n return [{\n functionResponse: {\n name,\n response: { result: text, is_error: block.isError === true },\n },\n }]\n }\n case 'image': {\n // Bytes are pre-resolved by the adapter before translation; a missing\n // entry breaks that invariant and must fail loudly, never silently drop.\n const resolved = images.get(block.attachment.attachmentId)\n if (!resolved) {\n throw new Error(`agy translate: unresolved image attachment \"${block.attachment.attachmentId}\"`)\n }\n return [{ inlineData: { mimeType: resolved.mediaType, data: resolved.data } }]\n }\n default:\n return [] // unknown block types (merge-extensible) are skipped\n }\n}\n\nfunction messageToContent(\n message: Message,\n toolNames: Map<string, string>,\n images: Map<string, AgyResolvedImage>,\n): AgyContent | null {\n const parts = message.content.flatMap((block) =>\n // Non-user images are out of scope by policy (docs ANTIGRAVITY-API §3.2):\n // skip them like any other untranslatable block instead of tripping the\n // unresolved-map guard, which protects only the user-image invariant.\n block.type === 'image' && message.role !== 'user'\n ? []\n : blockToParts(block, toolNames, images),\n )\n if (parts.length === 0) return null\n const role = message.role === 'assistant' ? 'model' : 'user'\n return { role, parts }\n}\n\n/**\n * Builtin Gemini tools must not shadow functionDeclarations names (upstream\n * treats them as native tools; verified by OmniRoute's GEMINI_BUILTIN_TOOL_NAMES).\n */\nconst AGY_BUILTIN_TOOL_NAMES = new Set(['google_search', 'web_search', 'search_web', 'googleSearch'])\n\n/** Level-thinking: single id + selectable low/medium/high via thinkingLevel (catalog thinking:'level'). */\nconst LEVEL_THINKING_LEVELS = new Set(['low', 'medium', 'high'])\n\n/** Upstream functionDeclarations names are `[a-zA-Z0-9_]` and ≤64 chars (OmniRoute-verified). */\nconst AGY_TOOL_NAME_MAX_LENGTH = 64\n\n/** Sanitize a tool name to the upstream charset/length; dedupe via a short hash. */\nfunction sanitizeToolName(name: string, seen: Set<string>): string {\n let candidate = name.replace(/[^a-zA-Z0-9_]/g, '_') || 'tool'\n if (candidate.length > AGY_TOOL_NAME_MAX_LENGTH || seen.has(candidate)) {\n const hash = createHash('sha256').update(candidate).digest('hex').slice(0, 8)\n const prefix = candidate.slice(0, AGY_TOOL_NAME_MAX_LENGTH - hash.length - 1)\n candidate = `${prefix}_${hash}`\n let i = 2\n while (seen.has(candidate)) candidate = `${prefix}_${i++}_${hash}`\n }\n seen.add(candidate)\n return candidate\n}\n\nfunction toolsToDeclarations(tools: ToolSchema[] | undefined): AgyRequestBody['request']['tools'] {\n if (!tools || tools.length === 0) return undefined\n const seenNames = new Set<string>()\n const declarations = []\n for (const tool of tools) {\n if (AGY_BUILTIN_TOOL_NAMES.has(tool.name)) continue\n declarations.push({\n name: sanitizeToolName(tool.name, seenNames),\n description: tool.description,\n parameters: sanitizeToolSchema(tool.parameters),\n })\n }\n if (declarations.length === 0) return undefined\n return [{ functionDeclarations: declarations }]\n}\n\n/** Build the wrapped Antigravity request body for one call. */\nexport function toAgyRequestBody(\n options: GenerateOptions,\n context: { projectId?: string; sessionId?: string; images?: Map<string, AgyResolvedImage> },\n): AgyRequestBody {\n const toolNames = buildToolNameIndex(options.messages)\n const images = context.images ?? new Map<string, AgyResolvedImage>()\n let contents = options.messages\n .map((message) => messageToContent(message, toolNames, images))\n .filter((c): c is AgyContent => c !== null)\n if (isClaudeModel(options.model)) {\n contents = stripTrailingModelTurn(contents)\n }\n\n const tools = toolsToDeclarations(options.tools)\n const generationConfig: NonNullable<AgyRequestBody['request']['generationConfig']> = {}\n if (options.temperature !== undefined) generationConfig.temperature = options.temperature\n if (options.maxTokens !== undefined) generationConfig.maxOutputTokens = options.maxTokens\n if (options.stop !== undefined && options.stop.length > 0) generationConfig.stopSequences = options.stop\n // Level-thinking: map the DSH reasoning effort to thinkingConfig.\n // Id-bound models (thinking !== 'level') never emit it — default is UI hint, not wire default.\n const effort = options.reasoningEffort?.toLowerCase()\n if (effort && isLevelThinkingModel(options.model) && LEVEL_THINKING_LEVELS.has(effort)) {\n generationConfig.thinkingConfig = { thinkingLevel: effort, includeThoughts: true }\n }\n\n return {\n project: context.projectId || undefined,\n requestId: generateAntigravityRequestId(),\n model: options.model,\n userAgent: 'antigravity',\n requestType: 'agent',\n request: {\n contents,\n ...(options.system ? { systemInstruction: { parts: [{ text: options.system }] } } : {}),\n ...(tools ? { tools } : {}),\n ...(tools ? { toolConfig: { functionCallingConfig: { mode: 'VALIDATED' } } } : {}),\n ...(Object.keys(generationConfig).length > 0 ? { generationConfig } : {}),\n ...(context.sessionId ? { sessionId: context.sessionId } : {}),\n },\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/web/plugin.ts"],"mappings":";;cAYa;cAEA;iBAEG,MAAM,KAAK"}
1
+ {"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/web/plugin.ts"],"mappings":";;cAaa;cAEA;iBAEG,MAAM,KAAK"}