Skip to main content

Python agent loop

Project description

TinyAgent

tinyAgent Logo

A small, modular agent framework for building LLM-powered applications in Python.

Inspired by smolagents and Pi — borrowing the minimal-abstraction philosophy from the former and the conversational agent loop from the latter.

Beta — TinyAgent is usable but not production-ready. APIs may change between minor versions.

Note: The optional tinyagent._alchemy binding now lives in https://github.com/tunahorse/tinyagent-alchemy and is not built from this repo.

Overview

TinyAgent provides a lightweight foundation for creating conversational AI agents with tool use capabilities. It features:

  • Streaming-first architecture: All LLM interactions support streaming responses
  • Tool execution: Define and execute tools with structured outputs
  • Event-driven: Subscribe to agent events for real-time UI updates
  • Provider agnostic: Works with any OpenAI-compatible /chat/completions endpoint (OpenRouter, OpenAI, Chutes, local servers)
  • Prompt caching: Reduce token costs and latency with Anthropic-style cache breakpoints
  • Provider paths: Optional external alchemy binding adapter plus proxy integration
  • Type-safe: Full type hints throughout

Quick Start

This example uses the optional tinyagent._alchemy binding via tinyagent.alchemy_provider. Install that binding from the external repo first, or use the proxy path instead.

import asyncio
from tinyagent import Agent, AgentOptions
from tinyagent.alchemy_provider import OpenAICompatModel, stream_alchemy_openai_completions

# Create an agent
agent = Agent(
    AgentOptions(
        stream_fn=stream_alchemy_openai_completions,
        session_id="my-session"
    )
)

# Configure
agent.set_system_prompt("You are a helpful assistant.")
agent.set_model(
    OpenAICompatModel(
        provider="openrouter",
        id="anthropic/claude-3.5-sonnet",
        base_url="https://openrouter.ai/api/v1/chat/completions",
    )
)
# Optional: any OpenAI-compatible /chat/completions endpoint
# agent.set_model(OpenAICompatModel(provider="openai", id="gpt-4o-mini", base_url="https://api.openai.com/v1/chat/completions"))

# Simple prompt
async def main():
    response = await agent.prompt_text("What is the capital of France?")
    print(response)

asyncio.run(main())

Installation

pip install tiny-agent-os

Optional binding:

  • PyPI wheels may include the compiled tinyagent._alchemy extension for supported platforms, but the source distribution does not.
  • Install/build tinyagent._alchemy from https://github.com/tunahorse/tinyagent-alchemy if you want stream_alchemy_openai_completions and no matching wheel is available.
  • Otherwise, use the proxy path in tinyagent.proxy.

Core Concepts

Agent

The Agent class is the main entry point. It manages:

  • Conversation state (messages, tools, system prompt)
  • Streaming responses
  • Tool execution
  • Event subscription

Messages

Messages are Pydantic models (use attribute access):

  • UserMessage: Input from the user
  • AssistantMessage: Response from the LLM
  • ToolResultMessage: Result from tool execution

Tools

Tools are functions the LLM can call:

from tinyagent import AgentTool, AgentToolResult, TextContent

async def calculate_sum(tool_call_id: str, args: dict, signal, on_update) -> AgentToolResult:
    result = args["a"] + args["b"]
    return AgentToolResult(
        content=[TextContent(text=str(result))]
    )

tool = AgentTool(
    name="sum",
    description="Add two numbers",
    parameters={
        "type": "object",
        "properties": {
            "a": {"type": "number"},
            "b": {"type": "number"}
        },
        "required": ["a", "b"]
    },
    execute=calculate_sum
)

agent.set_tools([tool])

Events

The agent emits events during execution:

  • AgentStartEvent / AgentEndEvent: Agent run lifecycle
  • TurnStartEvent / TurnEndEvent: Single turn lifecycle
  • MessageStartEvent / MessageUpdateEvent / MessageEndEvent: Message streaming
  • ToolExecutionStartEvent / ToolExecutionUpdateEvent / ToolExecutionEndEvent: Tool execution

Subscribe to events:

def on_event(event):
    print(f"Event: {event.type}")

unsubscribe = agent.subscribe(on_event)

Prompt Caching

TinyAgent supports Anthropic-style prompt caching to reduce costs on multi-turn conversations. Enable it when creating the agent:

agent = Agent(
    AgentOptions(
        stream_fn=stream_alchemy_openai_completions,
        session_id="my-session",
        enable_prompt_caching=True,
    )
)

Cache breakpoints are automatically placed on user message content blocks so the prompt prefix stays cached across turns. See Prompt Caching for details.

Optional Binding: tinyagent._alchemy

This repo keeps tinyagent/alchemy_provider.py as a compatibility adapter for the optional external tinyagent._alchemy extension. The binding source, build instructions, and low-level binding API now live in:

  • https://github.com/tunahorse/tinyagent-alchemy

The compiled path is still useful when you want OpenAI-compatible streaming without routing through a separate proxy, but it is no longer bundled or built from this repository.

Using via TinyAgent

You don't need to call the Rust binding directly. Use the alchemy_provider module:

from tinyagent import Agent, AgentOptions
from tinyagent.alchemy_provider import OpenAICompatModel, stream_alchemy_openai_completions

agent = Agent(
    AgentOptions(
        stream_fn=stream_alchemy_openai_completions,
        session_id="my-session",
    )
)
agent.set_model(
    OpenAICompatModel(
        provider="openrouter",
        id="anthropic/claude-3.5-sonnet",
        base_url="https://openrouter.ai/api/v1/chat/completions",
    )
)

MiniMax global:

agent.set_model(
    OpenAICompatModel(
        provider="minimax",
        id="MiniMax-M2.5",
        base_url="https://api.minimax.io/v1/chat/completions",
        # api is optional here; inferred as "minimax-completions"
    )
)

MiniMax CN:

agent.set_model(
    OpenAICompatModel(
        provider="minimax-cn",
        id="MiniMax-M2.5",
        base_url="https://api.minimax.chat/v1/chat/completions",
        # api is optional here; inferred as "minimax-completions"
    )
)

Smoke validation after installing the external binding:

  • uv run python scripts/smoke_rust_tool_calls_three_providers.py

Limitations

  • The optional binding currently dispatches only openai-completions and minimax-completions.
  • Image blocks are not yet supported (text and thinking blocks work).
  • next_event() is blocking and runs in a thread via asyncio.to_thread -- this adds slight overhead compared to a native async generator, but keeps the GIL released during the native work.

Documentation

Project Structure

tinyagent/
├── agent.py              # Agent class
├── agent_loop.py         # Core agent execution loop
├── agent_tool_execution.py  # Tool execution helpers
├── agent_types.py        # Type definitions
├── caching.py            # Prompt caching utilities
├── alchemy_provider.py   # Adapter for the optional external binding
├── proxy.py              # Proxy server integration
└── proxy_event_handlers.py  # Proxy event parsing

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tiny_agent_os-1.2.16.tar.gz (44.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tiny_agent_os-1.2.16-cp310-abi3-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.10+Windows x86-64

tiny_agent_os-1.2.16-cp310-abi3-manylinux_2_38_x86_64.whl (4.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.38+ x86-64

tiny_agent_os-1.2.16-cp310-abi3-macosx_11_0_universal2.whl (1.8 MB view details)

Uploaded CPython 3.10+macOS 11.0+ universal2 (ARM64, x86-64)

File details

Details for the file tiny_agent_os-1.2.16.tar.gz.

File metadata

  • Download URL: tiny_agent_os-1.2.16.tar.gz
  • Upload date:
  • Size: 44.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for tiny_agent_os-1.2.16.tar.gz
Algorithm Hash digest
SHA256 609818bc2abb31026b60226c976147fe70ca14049f5750763c9190651357a377
MD5 1aa47a4bd9d23e1b04ec9380c209884f
BLAKE2b-256 2fff9fecefd657225c64843162bf76d8db5bcc9489c037d8bffc5e64531ed953

See more details on using hashes here.

File details

Details for the file tiny_agent_os-1.2.16-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tiny_agent_os-1.2.16-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 b32af858903760ccead9f25d8230fa00ffb8a05e75668ed7c1bfef4b00a8b85e
MD5 fca5ec581ca76f8e8c1afaacfa9796f5
BLAKE2b-256 215656c479498bb68a0dc041cb0525152f37b4c1c4df25097afad500063b3d57

See more details on using hashes here.

File details

Details for the file tiny_agent_os-1.2.16-cp310-abi3-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for tiny_agent_os-1.2.16-cp310-abi3-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 2de40cf6d18963245fdc3b9cc21cf9fdde00c0fb55c862e3a68ad0fdda50a0a6
MD5 8337f5939b9f78e4cebf6626dbcb0675
BLAKE2b-256 7e80974f05d4c65d7120138bf0f10e47a9d9e2b019710cb8335f9532e10ed2a2

See more details on using hashes here.

File details

Details for the file tiny_agent_os-1.2.16-cp310-abi3-macosx_11_0_universal2.whl.

File metadata

File hashes

Hashes for tiny_agent_os-1.2.16-cp310-abi3-macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 9e4f92242cf66127cb8f3a3ba3cce64b2d7265bab90080e300bc1d2a2b7461d7
MD5 b0b72a63f4d7332acc37a108328c056d
BLAKE2b-256 b32e926958c101b0e8018645c0b68a0fcb4ea582434a94b411854e32fdab0851

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page