Agent File Upload Configuration#
Overview#
Agent file upload configuration controls which files users can attach to conversations with an Agent V2 app. It lives inside AgentSoulAppFeaturesConfig as the file_upload field and is stored as part of the versioned AgentSoulConfig JSON snapshot. Changes take effect only on publish; the runtime validates the snapshot before any LLM call is made.
Configuration Model#
AgentFileUploadFeatureConfig (Pydantic model, api/models/agent_config_entities.py) defines all upload policy fields:
| Field | Type | Default |
|---|---|---|
enabled | bool | True |
allowed_file_types | list[FileType] | [DOCUMENT, IMAGE, AUDIO, VIDEO] |
allowed_file_extensions | list[str] | ["JPG","JPEG","PNG","GIF","WEBP","SVG"] |
allowed_file_upload_methods | list[FileTransferMethod] | [LOCAL_FILE, REMOTE_URL] |
image | AgentFileUploadImageFeatureConfig | enabled=True |
number_limits | int | 3 |
FileType and FileTransferMethod are enums from the graphon library .
Semantic File Type Buckets#
FileType groups files into four semantic categories: DOCUMENT, IMAGE, AUDIO, VIDEO, plus a catch-all CUSTOM bucket. allowed_file_types controls which categories are accepted. The CUSTOM bucket is the escape hatch β when it is included, validation falls through to the allowed_file_extensions whitelist.
The UI surfaces the same five categories :
audio | custom | document | image | video
Custom Extension Whitelisting#
When a file's type does not match any category in allowed_file_types, or the type is explicitly CUSTOM, the allowed_file_extensions list is the sole gate .
Rules enforced by is_file_valid_with_config():
- Extension comparison is case- and dot-insensitive via
_normalize_extension(). - An empty whitelist (
[]) denies all files in the custom bucket. The UI never submits an empty list, but this guards DSL/API paths that bypass the UI . - If
allowed_file_extensionsisNone(not set), the extension check is skipped entirely.
Validation Logic#
is_file_valid_with_config() is invoked after a File object is built from a mapping, if a FileUploadConfig is present. The four-step check:
- Tool files bypass validation β
TOOL_FILEtransfer method always passes . - Type allowlist β file type must be in
allowed_file_types, orCUSTOMmust be present . - Extension whitelist (CUSTOM bucket) β enforces
allowed_file_extensionswhen the file falls into the custom bucket . - Transfer method β
IMAGEfiles checkimage_config.transfer_methods; all others checkallowed_file_upload_methods.
Agent-Configured Files vs. Message Attachments#
There are two distinct file contexts in an agent conversation:
Agent-configured files (persistent)#
Files uploaded by the agent builder into the agent's configuration β analogous to pre-loaded context. They follow a two-step commit: first uploaded via POST /files/upload, then committed to the agent config version via POST /agent/{agent_id}/config/files . The agent-server fetches them at runtime through a two-step flow: first, it requests download metadata from the inner-API endpoint POST /agent-config/{agent_id}/download-request, which validates authorization and returns a short-lived, origin-free /files/* URI; then the agent-server fetches the file bytes directly from the Dify API data plane using that URI . This unified endpoint handles both file and skill downloads. These files persist across all conversations for that agent version.
Message attachments (conversation-scoped)#
Files attached by end-users during a conversation turn. They are validated against FileUploadConfig at upload time. Once stored in message history, they are not re-validated on replay β re-validation would break history whenever the agent's upload config drifts between configuration versions.
Frontend Integration#
chat-features-panel.tsx converts between the generic Features['file'] type (shared feature panel UI) and AgentSoulAppFeaturesConfig['file_upload']. chat-config.ts collapses the agent config's file_upload into the legacy ChatConfig['file_upload'] shape for the preview β falling back to SupportUploadFileTypes.image if allowed_file_types is empty, and defaulting number_limits to 3 .
Size Limits#
Per-type size limits are enforced at upload time by FileService.is_file_size_within_limit(), routing to the appropriate config variable (UPLOAD_IMAGE_FILE_SIZE_LIMIT, UPLOAD_VIDEO_FILE_SIZE_LIMIT, UPLOAD_AUDIO_FILE_SIZE_LIMIT, UPLOAD_FILE_SIZE_LIMIT) based on the file extension. The upload dialog surfaces these limits via useFileUploadConfig() and useFileSizeLimit() .
Key Source Files#
| File | Purpose |
|---|---|
api/models/agent_config_entities.py | AgentFileUploadFeatureConfig model definition |
api/factories/file_factory/validation.py | is_file_valid_with_config() β runtime validation gate |
api/services/file_service.py | Upload handler, size checks, storage I/O |
api/controllers/inner_api/plugin/agent_config.py | Inner API for agent config file pull |
web/.../chat-features-panel.tsx | UI feature panel β agent config adapter |
web/.../upload-dialog.tsx | Agent config file upload dialog |
web/.../chat-config.ts | Preview chat config builder |