Moonshot File Input

Upload a file to Kimi, extract its text, and reuse retrievable file IDs across stored history.

Kimi does not accept inline file attachments. Instead each file is uploaded to Kimi's Files endpoint with purpose="file-extract", its text is extracted server-side, and that text is injected into the message - all handled automatically by the MoonShot model.

The stored file ID is reused while Kimi can still read it; a stale or unavailable ID can trigger another upload. Upload or extraction failures are logged and omit the file while the agent can still generate an answer. Verify the extracted context when the answer must depend on the attachment.

This example does not delete remote uploads. Manage uploaded resources through Kimi's Files API after all required follow-ups. Delete only file IDs you own and no longer need; removing the local SQLite file does not remove provider uploads.

file_input.py
"""
Moonshot File Input
===================

Kimi does not accept inline file attachments. Instead each file is uploaded to Kimi's
Files endpoint with purpose="file-extract", its text is extracted server-side, and that
text is injected into the message - all handled automatically by the MoonShot model.

Files are uploaded once - the Moonshot file id is stored on the File object - so
add_history_to_context does not re-upload the same file on later turns.
"""

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.media import File
from agno.models.moonshot import MoonShot

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------

agent = Agent(
    model=MoonShot(id="kimi-k3", reasoning_effort="low"),
    db=SqliteDb(db_file="tmp/moonshot_file_input.db"),
    markdown=True,
    add_history_to_context=True,
)

# ---------------------------------------------------------------------------
# Run Agent
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    agent.print_response(
        "Summarize the contents of the attached file.",
        files=[
            File(url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf")
        ],
    )
    # The file is not re-uploaded here - its stored file id is reused.
    agent.print_response("Suggest me a recipe from the attached file.")

Run the Example

Set up your virtual environment

uv venv --python 3.12
source .venv/bin/activate

Install dependencies

uv pip install -U agno openai sqlalchemy

Export your Moonshot API key

export MOONSHOT_API_KEY="your_moonshot_api_key_here"

Run the example

Save the code above as file_input.py, then run:

python file_input.py

Full source: cookbook/90_models/moonshot/file_input.py