What an asset carries
description and alt are two different fields with two different audiences, and mixing them up is the classic mistake: one decides whether the image is chosen, the other is what a blind visitor hears.
Uploading
From the console, an upload can be an image (PNG, JPEG, WebP, GIF or AVIF, up to 8 MB) or a video (MP4 with H.264/AAC, or WebM with VP9/Opus, up to 15 MB and 60 seconds). The format is decided by the file’s own bytes, never by its name or its declared type: a.png that is really something else, or a video with an unreadable codec, is refused rather than served from wondeya’s origin. A video past 60 seconds is refused with wondeya.asset.video_too_long.
The API (
/v1/assets) and MCP’s upload_asset accept images only, today. Video upload is a console-only surface; a video already registered from the console shows up in both regardless, and the agent can place it the same way it places an image.Curation on upload
Every upload goes through a vision pass that drafts the description, the topics and both alt texts (Spanish and English): what the asset actually shows, not what the filename claims. For a video, the pass reads its poster frame (the still wondeya extracts on upload), never the moving image. Topics you set yourself on upload are kept over the model’s suggestion. The pass runs inside the upload, because an asset with no description is an asset the agent will never choose. Leaving that for later means a registry that quietly does nothing. Two consequences worth knowing:- Curation never blocks an upload. If the vision model is unavailable your image still arrives; what you lose is a draft description you can write yourself.
- Editing anything makes it yours. As soon as you correct the text, the asset is marked
manual, the console stops presenting it as a suggestion, and no future re-curation will overwrite your words.
How the agent uses an asset
While knowledge is being selected, a parallel selection stage reads the agent’s whole curated registry, workspace pool included, against a query derived from the visitor’s question and picks at most four assets. Per asset it sees id, kind, orientation and description. Never a URL, never the file, never the storage location. Assets already shown in the conversation are excluded in code, not just in the prompt. The agent then places ids into components:media, mediaCard, gallery, and optionally timeline, metrics or grid. After the component passes validation, the server swaps each id for a signed URL to the file in wondeya’s own storage. This is why a prompt injection hidden in an uploaded document cannot put an arbitrary image, tracking pixel or link in front of a visitor: the model never had a field to write an address in.
Orientation is not decoration either. A portrait screenshot in a full-width slot grows unreadably tall, so the model sees each asset’s orientation when composing, and the resolved payload carries it so the renderer can place portrait images beside copy instead of full width.
Writing descriptions that work
- Say what is visible: “a bakery counter with sourdough loaves and a price chalkboard”, not “our brand promise”.
- Name the thing a visitor would ask about: the product, the screen, the space.
- Keep it to one or two sentences. Longer text does not help the agent choose better.
- Add topics that match the questions the image answers (
storefront, products).
Renaming and deleting
Thekey is what the agent emits, so changing it changes which image a future answer points to. Keys are unique inside an agent’s registry: two agents in one workspace can each have a hero, and a second hero inside one agent is refused. Pages that share an agent share its assets and its keys.
Deleting an asset is real: the registry entry and the stored file go together. Deleting a page removes only the page: its agent keeps every image, wherever else that agent answers. Deleting the agent is what removes its registry and the stored files, and that is refused while a page still answers with it.
In the console, you upload assets from an agent’s Assets tab and they belong to that agent. Through the API, sending
agentId: null (or omitting it) places the image in a workspace-wide pool that every agent of the workspace can use.