How to Handle File Uploads and Downloads During Tool Execution in Composio
Composio’s SDK automatically manages file transfers during tool execution by detecting file paths in arguments, streaming them to secure S3 storage, and downloading results to a local temporary directory when autoUploadDownloadFiles is enabled.
The Composio TypeScript SDK eliminates boilerplate for file operations by providing an integrated pipeline that handles uploads and downloads transparently during tool execution. When you invoke tools that declare file-related parameters in their schemas, the system intercepts file paths, manages cloud storage, and returns local URIs without manual intervention. This article examines the implementation details based on the ComposioHQ/composio source code, covering both automatic handling and manual overrides.
Automatic File Handling Pipeline
The SDK implements a three-stage pipeline for file operations that activates when autoUploadDownloadFiles remains enabled (the default behavior).
Stage 1: Detection
When initializing the Composio client, the SDK inspects tool schemas for properties marked with file_uploadable: true. According to the implementation in ts/packages/core/src/services/ToolExecutor.ts, the system scans incoming arguments for local file paths or remote URLs before executing the tool.
Stage 2: Upload
Detected files are read from disk or fetched from URLs, MIME-type detected, and streamed to Composio’s secure S3 infrastructure. The SDK replaces the original argument value with a structured metadata object containing name, mimetype, and s3key. This transformation occurs transparently before the tool receives the payload.
Stage 3: Download
If a tool’s response contains an s3url field with a corresponding mimetype, the SDK automatically fetches the object to ~/.composio/files/ and enriches the result with additional fields: uri (local temporary path), file_downloaded: true, and the original s3url.
import { Composio } from '@composio/core';
const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const result = await composio.tools.execute('document-processor', {
arguments: {
// Local path or HTTPS URL automatically uploaded
file: '/path/to/report.pdf'
}
});
// Access the downloaded file path
console.log(result.data.file?.uri); // e.g., ~/.composio/files/report-abc123.pdf
Configuring Automatic File Handling
The autoUploadDownloadFiles flag in the Composio constructor controls this behavior. Located in ts/packages/core/src/composio.ts, this boolean option defaults to true, enabling the automatic pipeline for all tool executions.
To disable automatic handling and implement custom file logic:
import { Composio } from '@composio/core';
const composio = new Composio({
apiKey: process.env.COMPOSIO_API_KEY,
autoUploadDownloadFiles: false // Disable automatic upload/download
});
When disabled, the SDK passes file arguments verbatim to tools without S3 interception, requiring manual management via the Files model.
Manual File Operations
For scenarios requiring explicit control, the Files class in ts/packages/core/src/models/Files.node.ts exposes low-level upload() and download() methods.
Manual Upload
When automatic handling is disabled, use composio.files.upload() to stream files to S3 and receive the metadata object required by tool schemas:
const uploaded = await composio.files.upload({
filePath: '/path/to/image.png', // Supports local paths or HTTP URLs
toolSlug: 'document-processor',
toolkitSlug: 'image-tools'
});
// Pass structured metadata to tool
const result = await composio.tools.execute('document-processor', {
arguments: {
file: uploaded // { name, mimetype, s3key }
}
});
Manual Download
Extract files from tool responses manually by invoking composio.files.download() with the S3 URL returned by the tool:
const result = await composio.tools.execute('document-processor', {
arguments: { documentId: 'doc-123' }
});
if (result.data.output?.s3url) {
const downloaded = await composio.files.download({
s3Url: result.data.output.s3url,
toolSlug: 'document-processor',
mimeType: result.data.output.mimetype ?? 'application/octet-stream'
});
console.log('File saved to:', downloaded.filePath);
}
Error Handling
The SDK throws ComposioFileUploadError for file operation failures, providing actionable context through the possibleFixes property. Import this error class from @composio/core to implement granular error handling:
import { ComposioFileUploadError } from '@composio/core';
try {
await composio.tools.execute('document-processor', {
arguments: { file: '/nonexistent/file.txt' }
});
} catch (err) {
if (err instanceof ComposioFileUploadError) {
console.error('Upload failed:', err.message);
console.log('Suggested fixes:', err.possibleFixes);
}
throw err;
}
Summary
- Automatic handling is enabled by default via
autoUploadDownloadFiles: truein theComposioconstructor, scanning forfile_uploadableschema properties. - The SDK streams files to S3 during upload and retrieves them to
~/.composio/files/during download, transforming arguments between local paths and{ name, mimetype, s3key }metadata. - Manual control is available through
composio.files.upload()andcomposio.files.download()ints/packages/core/src/models/Files.node.tswhen automatic handling is disabled. - Handle failures specifically using
ComposioFileUploadErrorto access diagnostic suggestions.
Frequently Asked Questions
How do I check if automatic file handling is working during tool execution?
Verify that the tool schema includes file_uploadable: true on the relevant property and ensure autoUploadDownloadFiles is not set to false in your Composio constructor. The SDK modifies arguments containing valid file paths into S3 metadata objects before transmission, and enriches responses containing s3url fields with local uri paths.
Can I use remote URLs instead of local file paths for uploads?
Yes. The upload() method in ts/packages/core/src/models/Files.node.ts accepts both local filesystem paths and HTTP/HTTPS URLs in the filePath parameter. The SDK fetches remote content and streams it to S3 storage automatically.
Where does Composio store downloaded files on my local machine?
Downloaded files are written to the ~/.composio/files/ directory by default. The SDK generates unique filenames to prevent collisions and returns the absolute path in the uri field of the response object.
What happens if a tool returns an S3 URL but automatic downloads are disabled?
When autoUploadDownloadFiles is false, the raw response containing s3url and mimetype passes through unchanged. You must explicitly call composio.files.download() with the S3 URL to retrieve the file to local storage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →