Allow Your Agent to Ask for Uploads¶
Walk-through for enabling the asset-upload tool on an agent and verifying end-to-end that a user can upload a file in the chat, the agent can read it back, and the asset persists across sessions.
For the conceptual picture (limits, lifecycle, encryption, deferred follow-ups), see the asset upload reference. For the design rationale of why assets and references are separate primitives, see Assets vs. References.
Prerequisites¶
- An organization you're an admin of (the toggle requires admin role on the agent's organization).
- An agent that already has an AI config and at least one read-write memory attached. Asset upload binds uploaded files to the user's per-agent memory, so the agent needs somewhere to put them.
- A chat surface to test from — the Chat tab on the agent detail page is the simplest option.
Step 1: Turn on the asset-upload tool¶
- Open the agent detail page.
- Switch to the Settings tab.
- Find the Capabilities section.
- Check Allow this agent to ask users for uploads.
The toggle saves on click. Behind the scenes it adds the canonical
key asset:upload to the App's agentTools allowlist for the App
that shares the agent's URN.
If the toggle is greyed out with a "No caller-identity App for this agent" message, the agent doesn't have a 1:1 App backing it yet. Create an App at the agent's URN first (Step 3 of Building an agent) and come back.
Step 2: How the agent invokes it¶
With the toggle on, the agent gets a new tool in its schema:
h-asset-request-upload. The agent calls it mid-turn with a
prompt and (optionally) constraints:
{
"prompt": "Could you upload your business plan PDF?",
"allowedMimeTypes": ["application/pdf"],
"maxSizeBytes": 10485760
}
The platform suspends the turn, surfaces the prompt to the user, and resumes once the user uploads, declines, or times out. The agent doesn't poll — the tool call returns when there's a result.
Without the toggle, calling this tool returns TOOL_NOT_ENABLED
and the chat continues without the prompt being shown.
Step 3: What the user sees¶
In the portal Chat tab the user sees:
- An in-chat upload card with the agent's prompt, an "Attach file" button, and a "Decline" button.
- A paperclip icon in the composer, available any time the agent is enabled — users can volunteer an upload without being asked.
When the user picks a file, the bytes go directly from the browser to object storage (R2 or MinIO in dev). The portal never proxies the bytes. A chip appears above the composer showing the filename, size, and scan status.
Possible outcomes:
uploaded— the bytes are in. Agent receivesassetId,filename,mimeType,sizeBytes,description.declined— the user dismissed the prompt.timeout— 5 minutes elapsed without a response.
Step 4: What the agent does with the result¶
In the next turn, the agent's tool result includes the asset metadata. From there it can:
- Reference the asset by URN in subsequent messages —
<memory-urn>:assets:<asset-id>is stable. - Read the bytes — call the platform's download endpoint to mint a short-TTL presigned URL (default 5 min, max 1 hour), then fetch and feed into a model context, OCR, or whatever the next step needs.
- List prior uploads —
agentAssets(agentUrn, mimeType?, ...)returns assets in the user's per-agent memory, paginated and filterable by MIME type.
Downloads are gated on scanStatus = CLEAN. PENDING returns
SCAN_PENDING (try again in a few seconds), BLOCKED returns
SCAN_BLOCKED (the asset failed virus scanning and cannot be
downloaded).
Step 5: Verify end-to-end¶
A 60-second smoke test:
- With the toggle on, open the agent's Chat tab.
- In the composer, click the paperclip and pick a small PDF or image.
- Confirm the chip appears above the composer with the filename, size, and "✓ Clean" once the scan completes.
- Reload the page. The chat resumes; the upload chip is part of the message history.
- Open the agent's conversations editor
or call
agentAssetsdirectly from the GraphQL API — the asset shows up in the user's per-agent memory. - Toggle the capability off, start a new chat, and ask the agent (in plain English) to request an upload. The agent should reply that the upload tool is unavailable rather than surfacing a prompt.
Troubleshooting¶
| Symptom | What to check |
|---|---|
| Toggle disabled, "No caller-identity App" message | Agent doesn't have a 1:1 App at the same URN. Create one (see Building an agent). |
PERMISSION_DENIED on toggle save |
The mutation is gated to org admin. Ask an admin to flip it, or have your role upgraded. |
| Paperclip icon missing in composer | Toggle is off, or the agent's agentUrn isn't being passed into <AgentChat>. Reload after enabling. |
Upload returns SIZE_EXCEEDED |
The agent's per-call cap (maxSizeBytes) or the platform default (50 MB) was exceeded. Either send a smaller file or have the agent raise its cap. |
Upload returns MIME_NOT_ALLOWED |
File's MIME type isn't in the agent's allowedMimeTypes list. The list is set per call. |
Download returns SCAN_PENDING |
Scanner hasn't finished. Retry in a few seconds; scan latency is typically <10s. |
Download returns SCAN_BLOCKED |
Asset flagged by virus scanning. Cannot be downloaded; the user should re-upload a clean copy. |
Related¶
- Asset upload reference — full shape of the feature (limits, lifecycle, encryption, deferred).
- Assets vs. References — why assets and references are separate primitives.
- Building an agent — agent setup the asset-upload toggle assumes is already done.
- Portal chat testing — broader manual-test checklist for the Chat tab.