var2_upload_asset
Upload a file the user ATTACHED to the chat (a photo from their phone, "my logo as a PNG", a voice memo) when NO link exists for it yet. If the message already contains a link or placeholder_id for the file, this tool is WRONG — a www.var2.ai / api.var2.ai / .supabase.co link is already inside var2; hand it to the matching create/modify/get tool. Sole pasted-link exception: NON-var2 link + explicit "import / pull it into var2". Text-only request, no file ("I want a song and cover art") → the matching create_ generator. When it IS an upload: call this FIRST, then pass the returned url verbatim as image_url / first_frame_url / reference_image_urls / audio_url / source_video_url. If your host filled in file (a native attachment object), just send it as-is — no url, no base64. Stores bytes durably in var2 storage; returns a first-party url (no expiry) + placeholder_id for var2_join_videos chaining. ≤100MB per file. base64 data: ALWAYS pass expected_bytes (+ sha256 if known) so truncation is rejected; >1.4M chars → parts via chunk_index/chunk_total/upload_id. Never pre-shrink a file to fit.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public https URL of the asset to rehost/import. Must be reachable from Vercel's egress; private/loopback hostnames are rejected. Provide EITHER `url` or `data` (not both). | |
| data | No | Base64 (or a `data:` URL) of the raw bytes — for a SMALL local file with no public URL when the client has no shell to PUT with. Hard-capped at 1MB; larger files MUST use var2_request_upload. Provide EITHER `url` or `data` (not both). | |
| file | No | NATIVE attachment input. Hosts that support file params (ChatGPT via `_meta["openai/fileParams"]`) fill this in themselves when the user attaches a file — you do NOT construct it. The server reads its `download_url` and imports the bytes directly, so no PUT, no base64 and no browser step is involved. Hosts without file-param support never send this; use `url` or `data` there. | |
| name | No | Optional display name. Stored in the generation row's prompt/title so it shows up cleanly in the user's asset library. | |
| type | Yes | Modality of the asset. The server validates the bytes (Content-Type for `url`, plus a magic-byte signature check either way) match image/* / video/* / audio/*; a mismatch rejects the upload. | |
| sha256 | No | Hex sha256 of the original file — verified end-to-end when provided. | |
| upload_id | No | Chunk-session id. Omit on part 0 (response returns one); pass it on every later part. The final part assembles, validates and stores. | |
| chunk_index | No | Chunked upload for files whose base64 exceeds one call: slice the base64 STRING into parts (~200K chars each recommended — a part is emitted as tool-call tokens, so keep it small enough to produce reliably; 1.4M hard cap; any split point) and send one part per call in `data`. 0-based part number. | |
| chunk_total | No | Total parts. Required with chunk_index. | |
| content_type | No | MIME of the inline `data` (e.g. "image/png"). Optional — the magic-byte check derives the real type regardless. | |
| expected_bytes | No | Size of the ORIGINAL file in bytes. STRONGLY recommended with `data`: a decoded-size mismatch is rejected instead of storing a truncated file. |