Skip to main content

larzagent

A tiny, zero-dependency AI agent framework. The tool-calling loop, function-to-schema tooling, and conversation memory you need to build an agent — in pure Python, over plain urllib, against any OpenAI-compatible endpoint.

from larzagent import Agent, LLM, tool

@tool
def get_price(symbol: str) -> float:
    """Get the current price of a ticker symbol."""
    return {"LARZ": 0.0, "BTC": 64000.0}.get(symbol, 0.0)

agent = Agent(
    LLM(model="gpt-4o-mini", api_key="sk-...",
        base_url="https://api.openai.com/v1"),
    system="You are a terse market assistant.",
    tools=[get_price],
)

print(agent.run("What's BTC trading at?"))
# -> the model calls get_price("BTC"), sees 64000.0, and answers.

No SDK. No async runtime. No dependencies. One small library you can read in an afternoon.

Why

  • Zero dependencies. Pure standard library — the model calls go over urllib. Nothing to install, nothing to compile.
  • Any backend. It speaks the OpenAI /v1/chat/completions shape, so point base_url at OpenAI, your own gateway, Ollama, LM Studio, vLLM, OpenRouter — the same agent code runs against all of them.
  • Tools are just functions. Decorate a function with @tool and larzagent reads its signature, type hints, and docstring to build the JSON schema. No hand-written schemas, no drift.
  • Robust loop. Tool errors, unknown tools, and bad JSON arguments are fed back to the model so it can recover instead of crashing. A step limit stops runaway loops.
  • Observable & persistable. Every model call and tool result flows through Memory, so it's trivial to log, save, replay, or inspect.
  • Testable offline. Inject a transport= callable and drive the whole loop with canned responses — no network, no keys. (That's how this repo's 26 tests run.)

Install

pip install larzagent

Tools from plain functions

from larzagent import tool

@tool
def search(query: str, limit: int = 5) -> list:
    """Search the knowledge base."""
    return kb.search(query)[:limit]

larzagent turns that into:

{"type": "function", "function": {
  "name": "search",
  "description": "Search the knowledge base.",
  "parameters": {"type": "object",
    "properties": {"query": {"type": "string"}, "limit": {"type": "integer"}},
    "required": ["query"]}}}

The decorated function is still directly callable in normal code (search("x")), so your tools are just... functions.

The loop

agent.run(message) does the standard agentic loop:

  1. Send system + memory + the new user message to the model, with your tools.
  2. If the model returns tool calls, run each one, append the results, and go back to step 1.
  3. When the model returns plain text, that's the answer.

Errors are handled defensively — a tool that raises, a call to a tool that doesn't exist, or malformed arguments all get returned to the model as a tool result it can react to, rather than blowing up your program. max_steps (default 8) guards against loops.

# trace every step
agent = Agent(llm, tools=[...], on_step=lambda step, msg, results: print(step, results))

# one-shot call that doesn't mutate memory
answer = agent.ask("quick question")

# persist / resume a conversation
agent.memory.save("session.json")

Point it at your own models

# OpenAI
LLM(model="gpt-4o-mini", api_key="sk-...", base_url="https://api.openai.com/v1")

# a local Ollama
LLM(model="llama3.1", base_url="http://localhost:11434/v1")

# your own gateway
LLM(model="my-model", api_key="...", base_url="https://gateway.example.com/v1")

API at a glance

@tool / @tool(name=, description=) make a function callable by the model
LLM(model, api_key=, base_url=, transport=, ...) OpenAI-compatible client
Agent(llm, system=, tools=, memory=, max_steps=, on_step=) the agent
agent.run(msg)str run the tool-calling loop, return the answer
agent.ask(msg) one-shot; leaves memory unchanged
agent.add_tool(func) register a tool at runtime
Memory(messages=, max_messages=) · .save() · .load() conversation state

Scope

larzagent is intentionally small: the loop, tools, and memory done well. It is not (yet) a streaming, multi-agent, or RAG-orchestration framework — it's the solid core you build those on. Bring your own vector store, your own model, your own app.

Tests

python -m unittest discover -s tests -v      # 26 tests, no network, zero deps

The Larz stack

Pure-Python, zero-dependency building blocks:

  • larz — money-native web framework
  • larzchain — from-scratch PoW blockchain
  • larzmoney — exact, penny-perfect money
  • larzcrypt — pure-Python cryptography toolkit
  • larzdb — crash-safe embedded database
  • larzagent — this framework

License

MIT © larz-scripter

Download files

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

Source Distribution

larzagent-0.1.0.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

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

larzagent-0.1.0-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for larzagent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0177d5df14c8ac82907a7fa943930c08e09f1d70dccb3e99cc4c8f8e3b0f9e83
MD5 2740324aaacbb7c91da073c55d5e1f5d
BLAKE2b-256 efcbb730f325c88455f8f99694e7b593eb38d2015c9c6bec529444bbc0b9afda

See more details on using hashes here.

File details

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

File metadata

  • Download URL: larzagent-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for larzagent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f4a6dd2c60e9723ef503ee54cd767f0708dc55f5d102881f2308a1a548c9ec23
MD5 f6061e9d37e88984080cc5bc0f2822c9
BLAKE2b-256 43ee2dc10e605447b08ca4912b4f51b88e153b97817a2396cedcf99d888e992a

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