{"version":3,"file":"resolve-attachment.mjs","names":[],"sources":["../../../../../../../ai/src/utils/resolve-attachment.ts"],"sourcesContent":["import type {\n  Attachment,\n  AttachmentSource,\n  ResolvedAttachment,\n} from \"../contracts/attachment.type\";\nimport { InvalidRequestError } from \"../errors\";\n\nconst REMOTE_URL_PATTERN = /^https?:\\/\\//i;\n\n/**\n * Normalize a user-supplied `Attachment` (or bare `AttachmentSource`)\n * into a `ResolvedAttachment` the agent can hand to file-reading code\n * without re-discriminating the input variant.\n *\n * Resolution rules:\n * - `{ base64, mediaType }` → `{ type: \"base64\", value, mediaType }`.\n * - `StorageFileShape` (`{ url?, absolutePath? }`) → `absolutePath` wins\n *   over `url` when both are present (prefer the local file over an extra\n *   remote hop). Absolute path becomes `{ type: \"path\" }`; url becomes\n *   `{ type: \"url\" }`.\n * - String starting with `http://` / `https://` → `{ type: \"url\" }`.\n * - Any other string → `{ type: \"path\" }`.\n * - Tagged `{ type: \"image\" | \"text\", source }` → recurses into `source`.\n *\n * Throws `InvalidRequestError` on obviously invalid input (empty\n * string, storage object with neither url nor absolutePath, missing\n * source field).\n *\n * @example\n * resolveAttachment(\"https://cdn.example.com/doc.pdf\");\n * // → { type: \"url\", value: \"https://cdn.example.com/doc.pdf\" }\n *\n * @example\n * resolveAttachment({ type: \"image\", source: \"/tmp/x.png\" });\n * // → { type: \"path\", value: \"/tmp/x.png\" }\n */\nexport function resolveAttachment(attachment: Attachment): ResolvedAttachment {\n  if (\n    typeof attachment === \"object\" &&\n    attachment !== null &&\n    \"type\" in attachment\n  ) {\n    return resolveSource(attachment.source);\n  }\n\n  return resolveSource(attachment);\n}\n\nfunction resolveSource(source: AttachmentSource): ResolvedAttachment {\n  if (typeof source === \"string\") {\n    if (!source) {\n      throw new InvalidRequestError(\"Cannot resolve empty attachment string\");\n    }\n\n    if (REMOTE_URL_PATTERN.test(source)) {\n      return { type: \"url\", value: source };\n    }\n\n    return { type: \"path\", value: source };\n  }\n\n  // StorageFile objects (from @warlock.js/core) can expose a `base64`\n  // property alongside `url` / `absolutePath`. Check storage shape\n  // first so we don't treat a StorageFile as an inline-bytes payload.\n  if (\"url\" in source || \"absolutePath\" in source) {\n    const storage = source as { url?: string; absolutePath?: string };\n\n    if (storage.absolutePath) {\n      return { type: \"path\", value: storage.absolutePath };\n    }\n\n    if (storage.url) {\n      return { type: \"url\", value: storage.url };\n    }\n\n    throw new InvalidRequestError(\n      \"Storage attachment has neither url nor absolutePath\",\n    );\n  }\n\n  if (\"base64\" in source) {\n    if (!source.base64 || !source.mediaType) {\n      throw new InvalidRequestError(\n        \"Inline attachment requires both `base64` and `mediaType`\",\n      );\n    }\n\n    return {\n      type: \"base64\",\n      value: source.base64,\n      mediaType: source.mediaType,\n    };\n  }\n\n  throw new InvalidRequestError(\n    \"Unrecognized attachment source — expected a string path/URL, a StorageFile, or `{ base64, mediaType }`\",\n  );\n}\n"],"mappings":";;;;AAOA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B3B,SAAgB,kBAAkB,YAA4C;CAC5E,IACE,OAAO,eAAe,YACtB,eAAe,QACf,UAAU,YAEV,OAAO,cAAc,WAAW,MAAM;CAGxC,OAAO,cAAc,UAAU;AACjC;AAEA,SAAS,cAAc,QAA8C;CACnE,IAAI,OAAO,WAAW,UAAU;EAC9B,IAAI,CAAC,QACH,MAAM,IAAI,oBAAoB,wCAAwC;EAGxE,IAAI,mBAAmB,KAAK,MAAM,GAChC,OAAO;GAAE,MAAM;GAAO,OAAO;EAAO;EAGtC,OAAO;GAAE,MAAM;GAAQ,OAAO;EAAO;CACvC;CAKA,IAAI,SAAS,UAAU,kBAAkB,QAAQ;EAC/C,MAAM,UAAU;EAEhB,IAAI,QAAQ,cACV,OAAO;GAAE,MAAM;GAAQ,OAAO,QAAQ;EAAa;EAGrD,IAAI,QAAQ,KACV,OAAO;GAAE,MAAM;GAAO,OAAO,QAAQ;EAAI;EAG3C,MAAM,IAAI,oBACR,qDACF;CACF;CAEA,IAAI,YAAY,QAAQ;EACtB,IAAI,CAAC,OAAO,UAAU,CAAC,OAAO,WAC5B,MAAM,IAAI,oBACR,0DACF;EAGF,OAAO;GACL,MAAM;GACN,OAAO,OAAO;GACd,WAAW,OAAO;EACpB;CACF;CAEA,MAAM,IAAI,oBACR,wGACF;AACF"}