Skip to main content

A minimal, reusable Python framework for building LLM agents with tools and an observe-act loop.

Project description

agentloop

A small, reusable Python agentic framework for building LLM agents with tools, memory, and an observe–act loop. Other developers can extend it by registering tools, swapping LLM providers, and hooking lifecycle events—without pulling in a heavy dependency stack.

Features

  • Agent loop — model → tool calls → tool results → repeat until done or max_iterations
  • Tool registry — decorate functions; JSON schema inferred from type hints
  • Pluggable LLM providers — OpenAI-compatible API built-in; implement one method for custom backends
  • Memory — conversation history with optional system prompt
  • Eventson_tool_call, on_iteration, on_run_end, generic subscribe() hooks
  • Mock provider — run examples and tests without an API key

Install

From PyPI (after you publish — see PUBLISHING.md):

pip install agentloop-framework
pip install "agentloop-framework[openai]"   # OpenAI-compatible provider

From source (development):

cd agentloop
pip install -e .

# For OpenAI / Azure / Ollama (OpenAI-compatible HTTP API):
pip install -e ".[openai]"

# Development:
pip install -e ".[dev]"

The PyPI name is agentloop-framework because agentloop is already taken. Imports remain from agentloop import ....

Quick start (no API key)

import asyncio
from agentloop import Agent
from agentloop.providers import MockProvider
from agentloop.tools import ToolRegistry

tools = ToolRegistry()

@tools.register(description="Echo text back.")
def echo(text: str) -> str:
    return text

agent = Agent.create(
    provider=MockProvider(MockProvider.tool_then_answer("echo", {"text": "hi"}, final="Done.")),
    system="You are helpful.",
    tools=tools,
)

asyncio.run(agent.run("Say hi"))

Run the bundled example:

python examples/basic_mock.py

Example agents

Chatbot (multi-turn)

Interactive CLI chat with persistent memory and tools (time, calculator):

python examples/chatbot.py --mock          # offline, no API key
python examples/chatbot.py --live          # needs OPENAI_API_KEY

Voice agent

Speak to the agent and hear replies (or use --text to type):

python examples/voice_agent.py --text --mock   # easiest start
pip install -e ".[voice]"
python examples/voice_agent.py --mock          # microphone + speaker

See examples/README.md for full details.

Cloud Run + Pinecone RAG + React UI

Production-style deployment with vector search:

# See deploy/cloud-run/README.md for full steps
docker build -f deploy/cloud-run/Dockerfile -t agentloop-chat .

Stack: React chat UIFastAPI /api/chatagentloopPinecone on Google Cloud Run.

Live LLM (OpenAI-compatible)

import asyncio
from agentloop import Agent
from agentloop.providers import OpenAICompatibleProvider
from agentloop.tools import ToolRegistry

tools = ToolRegistry()

@tools.register(description="Add two integers.")
def add(a: int, b: int) -> int:
    return a + b

agent = Agent.create(
    provider=OpenAICompatibleProvider(model="gpt-4o-mini"),
    system="Use tools when math is needed.",
    tools=tools,
)

asyncio.run(agent.run("What is 12 + 30?"))

Environment variables:

Variable Purpose
OPENAI_API_KEY API key
OPENAI_BASE_URL Base URL (default https://api.openai.com/v1; use for Ollama, Azure, vLLM)
OPENAI_MODEL Model id (example script only)

Architecture

flowchart LR
  User[User task] --> Loop[AgentLoop]
  Loop --> LLM[LLMProvider.chat]
  LLM -->|tool_calls| Tools[ToolRegistry.execute]
  Tools --> Memory[ConversationMemory]
  Memory --> Loop
  LLM -->|final text| Result[RunResult]

Extension points

Piece How to extend
LLM Class with async def chat(messages, tools) -> LLMResponse — see examples/custom_provider.py
Tools @registry.register or registry.add(name, handler, ...)
Memory Pass ConversationMemory(system_prompt=...) into AgentLoop
Observability AgentEvents(on_tool_call=..., subscribe=lambda e, p: ...)
Low-level control Use AgentLoop directly instead of Agent

Project layout

agentloop/
  agent.py          # Agent.create() builder
  loop.py           # Core observe–act loop
  tools.py          # ToolRegistry
  memory.py         # ConversationMemory
  events.py         # AgentEvents
  types.py          # Message, ToolCall, RunResult, ...
  providers/
    base.py         # LLMProvider protocol
    openai_compatible.py
    mock.py
examples/
  chatbot.py        # Multi-turn interactive chat
  voice_agent.py    # Speech input / spoken output
  helpers.py        # Shared tools + agent factory
  README.md
tests/

Tests

pytest

Design choices

  • Minimal core — zero required runtime dependencies; httpx only for the optional OpenAI provider.
  • Async-firstasyncio throughout; sync wrappers can wrap asyncio.run in your app.
  • Provider-agnostic — not tied to Cursor or any single vendor; bring your own model endpoint.

License

MIT

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

agentloop_framework-0.1.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

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

agentloop_framework-0.1.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file agentloop_framework-0.1.0.tar.gz.

File metadata

  • Download URL: agentloop_framework-0.1.0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for agentloop_framework-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b739dd30cafb5429ce89200bd23597a2501404b876e640cb9ba5f87be02d78ae
MD5 d90c2217053ab618c5b8c570c03996bf
BLAKE2b-256 6ebda53c6e66eda83413f71f7d012bd3a253d197808501f232e398d8bccb8f7a

See more details on using hashes here.

File details

Details for the file agentloop_framework-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agentloop_framework-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e5f2dd18c1a6838c589d4b0081a312f02f99ab6af5001557484dd49d3a1b4cfd
MD5 2c6b47feed30ea9c481c746b9e66f7f5
BLAKE2b-256 4f6024e98d8449c74284440b8df6c18a91df3df5ca73ef6df04f8fb6364400ac

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