"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.a = readResponseWithLimit;exports.i = fetchRemoteMedia;exports.n = getDefaultMediaLocalRoots;exports.r = void 0;exports.t = getAgentScopedMediaLocalRoots;var _runWithConcurrency2ga3CMk = require("./run-with-concurrency-2ga3-CMk.js"); var _pathsEFexkPEh = require("./paths-eFexkPEh.js"); var _loggerU3s76KST = require("./logger-U3s76KST.js"); var _imageOpsZjRT9yvG = require("./image-ops-ZjRT9yvG.js"); var _fetchGuardBMQY_BjF = require("./fetch-guard-BMQY_BjF.js"); var _nodePath = _interopRequireDefault(require("node:path"));function _interopRequireDefault(e) {return e && e.__esModule ? e : { default: e };} //#region src/media/read-response-with-limit.ts async function readChunkWithIdleTimeout(reader, chunkTimeoutMs) { let timeoutId; let timedOut = false; return await new Promise((resolve, reject) => { const clear = () => { if (timeoutId !== void 0) { clearTimeout(timeoutId); timeoutId = void 0; } }; timeoutId = setTimeout(() => { timedOut = true; clear(); reader.cancel().catch(() => void 0); reject(/* @__PURE__ */new Error(`Media download stalled: no data received for ${chunkTimeoutMs}ms`)); }, chunkTimeoutMs); reader.read().then((result) => { clear(); if (!timedOut) resolve(result); }, (err) => { clear(); if (!timedOut) reject(err); }); }); } async function readResponseWithLimit(res, maxBytes, opts) { const onOverflow = opts?.onOverflow ?? ((params) => /* @__PURE__ */new Error(`Content too large: ${params.size} bytes (limit: ${params.maxBytes} bytes)`)); const chunkTimeoutMs = opts?.chunkTimeoutMs; const body = res.body; if (!body || typeof body.getReader !== "function") { const fallback = Buffer.from(await res.arrayBuffer()); if (fallback.length > maxBytes) throw onOverflow({ size: fallback.length, maxBytes, res }); return fallback; } const reader = body.getReader(); const chunks = []; let total = 0; try { while (true) { const { done, value } = chunkTimeoutMs ? await readChunkWithIdleTimeout(reader, chunkTimeoutMs) : await reader.read(); if (done) break; if (value?.length) { total += value.length; if (total > maxBytes) { try { await reader.cancel(); } catch {} throw onOverflow({ size: total, maxBytes, res }); } chunks.push(value); } } } finally { try { reader.releaseLock(); } catch {} } return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total); } //#endregion //#region src/media/fetch.ts var MediaFetchError = class extends Error { constructor(code, message) { super(message); this.code = code; this.name = "MediaFetchError"; } };exports.r = MediaFetchError; function stripQuotes(value) { return value.replace(/^["']|["']$/g, ""); } function parseContentDispositionFileName(header) { if (!header) return; const starMatch = /filename\*\s*=\s*([^;]+)/i.exec(header); if (starMatch?.[1]) { const cleaned = stripQuotes(starMatch[1].trim()); const encoded = cleaned.split("''").slice(1).join("''") || cleaned; try { return _nodePath.default.basename(decodeURIComponent(encoded)); } catch { return _nodePath.default.basename(encoded); } } const match = /filename\s*=\s*([^;]+)/i.exec(header); if (match?.[1]) return _nodePath.default.basename(stripQuotes(match[1].trim())); } async function readErrorBodySnippet(res, maxChars = 200) { try { const text = await res.text(); if (!text) return; const collapsed = text.replace(/\s+/g, " ").trim(); if (!collapsed) return; if (collapsed.length <= maxChars) return collapsed; return `${collapsed.slice(0, maxChars)}…`; } catch { return; } } async function fetchRemoteMedia(options) { const { url, fetchImpl, requestInit, filePathHint, maxBytes, maxRedirects, readIdleTimeoutMs, ssrfPolicy, lookupFn } = options; let res; let finalUrl = url; let release = null; try { const result = await (0, _fetchGuardBMQY_BjF.t)((0, _fetchGuardBMQY_BjF.n)({ url, fetchImpl, init: requestInit, maxRedirects, policy: ssrfPolicy, lookupFn })); res = result.response; finalUrl = result.finalUrl; release = result.release; } catch (err) { throw new MediaFetchError("fetch_failed", `Failed to fetch media from ${url}: ${String(err)}`); } try { if (!res.ok) { const statusText = res.statusText ? ` ${res.statusText}` : ""; const redirected = finalUrl !== url ? ` (redirected to ${finalUrl})` : ""; let detail = `HTTP ${res.status}${statusText}`; if (!res.body) detail = `HTTP ${res.status}${statusText}; empty response body`;else { const snippet = await readErrorBodySnippet(res); if (snippet) detail += `; body: ${snippet}`; } throw new MediaFetchError("http_error", `Failed to fetch media from ${url}${redirected}: ${detail}`); } const contentLength = res.headers.get("content-length"); if (maxBytes && contentLength) { const length = Number(contentLength); if (Number.isFinite(length) && length > maxBytes) throw new MediaFetchError("max_bytes", `Failed to fetch media from ${url}: content length ${length} exceeds maxBytes ${maxBytes}`); } let buffer; try { buffer = maxBytes ? await readResponseWithLimit(res, maxBytes, { onOverflow: ({ maxBytes, res }) => new MediaFetchError("max_bytes", `Failed to fetch media from ${res.url || url}: payload exceeds maxBytes ${maxBytes}`), chunkTimeoutMs: readIdleTimeoutMs }) : Buffer.from(await res.arrayBuffer()); } catch (err) { if (err instanceof MediaFetchError) throw err; throw new MediaFetchError("fetch_failed", `Failed to fetch media from ${res.url || url}: ${String(err)}`); } let fileNameFromUrl; try { const parsed = new URL(finalUrl); fileNameFromUrl = _nodePath.default.basename(parsed.pathname) || void 0; } catch {} const headerFileName = parseContentDispositionFileName(res.headers.get("content-disposition")); let fileName = headerFileName || fileNameFromUrl || (filePathHint ? _nodePath.default.basename(filePathHint) : void 0); const filePathForMime = headerFileName && _nodePath.default.extname(headerFileName) ? headerFileName : filePathHint ?? finalUrl; const contentType = await (0, _imageOpsZjRT9yvG.c)({ buffer, headerMime: res.headers.get("content-type"), filePath: filePathForMime }); if (fileName && !_nodePath.default.extname(fileName) && contentType) { const ext = (0, _imageOpsZjRT9yvG.l)(contentType); if (ext) fileName = `${fileName}${ext}`; } return { buffer, contentType: contentType ?? void 0, fileName }; } finally { if (release) await release(); } } //#endregion //#region src/media/local-roots.ts let cachedPreferredTmpDir; function resolveCachedPreferredTmpDir() { if (!cachedPreferredTmpDir) cachedPreferredTmpDir = (0, _loggerU3s76KST.Z)(); return cachedPreferredTmpDir; } function buildMediaLocalRoots(stateDir, options = {}) { const resolvedStateDir = _nodePath.default.resolve(stateDir); return [ options.preferredTmpDir ?? resolveCachedPreferredTmpDir(), _nodePath.default.join(resolvedStateDir, "media"), _nodePath.default.join(resolvedStateDir, "agents"), _nodePath.default.join(resolvedStateDir, "workspace"), _nodePath.default.join(resolvedStateDir, "sandboxes")]; } function getDefaultMediaLocalRoots() { return buildMediaLocalRoots((0, _pathsEFexkPEh.c)()); } function getAgentScopedMediaLocalRoots(cfg, agentId) { const roots = buildMediaLocalRoots((0, _pathsEFexkPEh.c)()); if (!agentId?.trim()) return roots; const workspaceDir = (0, _runWithConcurrency2ga3CMk.c)(cfg, agentId); if (!workspaceDir) return roots; const normalizedWorkspaceDir = _nodePath.default.resolve(workspaceDir); if (!roots.includes(normalizedWorkspaceDir)) roots.push(normalizedWorkspaceDir); return roots; } //#endregion /* v9-7870dda8f32ff8e6 */