> ## Documentation Index
> Fetch the complete documentation index at: https://agentstack.beeai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Files

> Upload and generate files in agents

One of the most common use cases for AI agents is working with files. Your agent should be able to read files from user uploads and generate new files as outputs. The Agent Stack makes this seamless through the A2A protocol's `FilePart`.

## Example of File Processing

Here's how to build an agent that can accept and modify files:

```python theme={null}
# Copyright 2025 © BeeAI a Series of LF Projects, LLC
# SPDX-License-Identifier: Apache-2.0

import os
from typing import Annotated

from a2a.types import FilePart, Message
from agentstack_sdk.a2a.extensions import PlatformApiExtensionServer, PlatformApiExtensionSpec
from agentstack_sdk.platform import File
from agentstack_sdk.server import Server
from agentstack_sdk.util.file import load_file

server = Server()


@server.agent(
    default_input_modes=["text/plain", "application/pdf", "image/*"],
    default_output_modes=["text/plain", "application/pdf", "image/*"],
)
async def file_processing_example(
    input: Message,
    _: Annotated[PlatformApiExtensionServer, PlatformApiExtensionSpec()],
):
    """Agent that handles both text and binary files"""

    for file_part in input.parts:
        file_part_root = file_part.root

        if isinstance(file_part_root, FilePart):
            mime_type = file_part_root.file.mime_type or "application/octet-stream"

            async with load_file(file_part_root) as loaded_content:
                # Determine if file is text or binary based on MIME type
                is_text_file = mime_type.startswith("text/") or mime_type in [
                    "application/json",
                    "application/xml",
                    "text/xml",
                ]

                if is_text_file:
                    # For text files, use .text and encode to bytes
                    content = loaded_content.text.encode()
                else:
                    # For binary files (PDFs, images, etc.), use .content directly
                    content = loaded_content.content

                # Create new file with appropriate content
                new_file = await File.create(
                    filename=f"processed_{file_part_root.file.name}",
                    content_type=mime_type,
                    content=content,
                )
                yield new_file.to_file_part()

    yield "File processing complete"


def run():
    server.run(host=os.getenv("HOST", "127.0.0.1"), port=int(os.getenv("PORT", 8000)))


if __name__ == "__main__":
    run()

```

<Steps>
  <Step title="Enable file uploads in your agent (optional)">
    Add the `default_input_modes` parameter to your agent decorator only if you want users to upload files to your agent. This specifies which file types users can upload.
  </Step>

  <Step title="Inject the Platform API extension">
    Import and use the `PlatformApiExtensionServer` to access file creation capabilities. This extension provides your agent with the proper context and authentication needed to use the Agent Stack API for creating and managing files. If not provided, your agent will receive unauthorized responses when working with files.
  </Step>

  <Step title="Process uploaded files">
    Iterate through message parts to find `FilePart` objects and load their content using `load_file` helper.
  </Step>

  <Step title="Generate new files">
    Use the `File.create()` method to generate new files and yield them as `FilePart` objects with `to_file_part()`.
  </Step>
</Steps>

## How to work with files

Here's what you need to know to add file processing capabilities to your agent:

**Enable file uploads**: Add `default_input_modes` to your agent decorator with a list of MIME types you want to accept (e.g., `["text/plain", "application/pdf", "image/jpeg"]`).

**Enable producing of files**: Add `default_output_modes` to your agent decorator with a list of MIME types that your agent can potentially produce (e.g., `["text/plain", "application/pdf", "image/jpeg"]`).

**Access the Platform API**: Import and use `PlatformApiExtensionServer` to get access to file manipulation capabilities.

**Process message parts**: Iterate through `input.parts` to find FilePart objects that represent uploaded files.

**Load file content**: Use `load_file()` with an async context manager to safely access file content.

**Create new files**: Use `File.create()` to generate new files with custom names, content types, and content.

**Yield file outputs**: The `File` object created by the SDK can be easily converted to a `FilePart` using the `to_file_part()` method and then yielded as agent outputs.

## File Upload Configuration

The `default_input_modes` parameter controls which file types users can upload:

```python theme={null}
@server.agent(
    default_input_modes=[
        "text/plain",           # Plain text files
        "application/pdf",      # PDF documents
        "image/jpeg",           # JPEG images
        "image/png",            # PNG images
        "application/json",     # JSON files
        "text/csv"              # CSV files
    ]
)
```

The `default_output_modes` parameter controls which file agent can produce:

```python theme={null}
@server.agent(
    default_output_modes=[
        "text/plain",           # Plain text files
        "application/pdf",      # PDF documents
        "image/jpeg",           # JPEG images
        "image/png",            # PNG images
        "application/json",     # JSON files
        "text/csv"              # CSV files
    ]
)
```

Common MIME types you might want to support:

| Category       | MIME Types                                                                                                                 |
| -------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Text files** | `text/plain`<br />`text/markdown`<br />`text/csv`                                                                          |
| **Documents**  | `application/pdf`<br />`application/msword`<br />`application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
| **Images**     | `image/jpeg`<br />`image/png`<br />`image/gif`<br />`image/svg+xml`                                                        |
| **Data**       | `application/json`<br />`application/xml`<br />`text/xml`                                                                  |

## Handling Text vs Binary Files

When processing files, it's important to handle text and binary files differently. The `load_file` helper provides both `.text` and `.content` properties:

<Note>
  **Key differences:**

  * **Text files** (text/plain, text/markdown, application/json, etc.): Use `loaded_content.text.encode()` to get bytes.
  * **Binary files** (application/pdf, image/\*, etc.): Use `loaded_content.content` directly to preserve binary content.
</Note>
