Catalog PyPI
PACKAGE EXPLORERView in registry

agentforge-mini

PyPI

A tiny, provider-agnostic framework for building tool-using AI agents.

agentagentsaifunction-callingllmopenaitool-calling
Versions collected1
Direct dependencies1From release 0.2.0
Last observed20 Oct, 21:58 UTC

README

Version 0.2.0 documentation

AgentForge

A tiny, provider-agnostic framework for building tool-using AI agents in Python.

No SDK lock-in, no heavy dependencies (just requests), no magic. One small Agent class, a @tool decorator, and a clean reason-act loop you can actually read in one sitting. Works with any OpenAI-compatible endpoint: OpenAI, OpenRouter, Groq, Together, Mistral, or a local llama.cpp / Ollama server.

from agentforge import Agent, tool

@tool
def add(a: int, b: int) -> int:
    "Add two numbers."
    return a + b

agent = Agent(model="gpt-4o-mini", tools=[add])
print(agent.run("What is 21 + 21?"))
# -> "21 + 21 equals 42."

Why

Most agent frameworks are huge. If all you want is "call my Python functions from an LLM and loop until done," you shouldn't need 40 dependencies and a graph DSL. AgentForge is ~200 lines of readable code that does exactly that.

  • Provider-agnostic — point base_url at any OpenAI-compatible API.
  • Zero ceremony — a function + a docstring becomes a tool. Types are inferred from annotations into JSON schema automatically.
  • Transparent loop — the whole reason-act cycle lives in one method you can read and patch.
  • Resilient — automatic retry with exponential backoff on 429 / 5xx / network errors.
  • Streaming + async — stream the final answer token-by-token, or await the agent from async code.
  • Tested offline — the test suite mocks the provider, so it runs with no API key and no network.

Install

pip install agentforge-mini

Or from source:

git clone https://github.com/kangbaxso/agent-forge
cd agent-forge
pip install -e .

Usage

1. Define tools

Any function with a docstring becomes a tool. Parameter types come from annotations:

from agentforge import tool

@tool
def get_weather(city: str) -> dict:
    "Get the current weather for a city."
    ...

2. Build an agent

from agentforge import Agent

agent = Agent(
    model="gpt-4o-mini",
    tools=[get_weather],
    system="You are a concise assistant.",
    verbose=True,        # log each tool call
    max_steps=8,         # safety cap on the loop
)

3. Run it

answer = agent.run("What's the weather in Tokyo?")

Stream the answer

for token in agent.stream("Explain async IO in one paragraph."):
    print(token, end="", flush=True)

Tool-calling rounds run first (non-streamed); once the model is ready to answer in plain text, that answer streams token-by-token.

Use it from async code

answer = await agent.arun("What's 21 + 21?")

Resilience

The provider retries automatically on 429 and 5xx responses and on network errors, with exponential backoff. Tune it:

agent = Agent(model="gpt-4o-mini", max_retries=5)

After exhausting retries it raises agentforge.ProviderError.

Point it at any provider

Set two environment variables — that's the whole config:

# OpenAI (default)
export OPENAI_API_KEY=sk-...

# OpenRouter
export OPENAI_BASE_URL=https://openrouter.ai/api/v1
export OPENAI_API_KEY=sk-or-...

# Groq
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
export OPENAI_API_KEY=gsk_...

# Local llama.cpp / Ollama
export OPENAI_BASE_URL=http://localhost:8080/v1
export OPENAI_API_KEY=not-needed

…or pass base_url= / api_key= directly to Agent(...).

Run the example

export OPENAI_API_KEY=sk-...
python examples/quickstart.py

Run the tests

No API key needed — the provider is mocked:

python tests/test_agent.py
# or
python -m pytest tests/ -q

How the loop works

  1. Send the conversation + your tool schemas to the model.
  2. If the model asks to call tools, AgentForge runs them locally and feeds the results back as role: tool messages.
  3. Repeat until the model returns a plain answer or max_steps is reached.

That's it. The entire loop is in agentforge/agent.py.

License

MIT — see LICENSE.

Downloads & popularity

3downloads
1-day window · source-reported counts20 Oct 2026
73.50
2026-07-23: 4 · observed 2026-10-21T09:52:36.6417321Z · period 2026-07-23–2026-07-232026-07-27: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-07-27–2026-07-272026-08-02: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-02–2026-08-022026-08-04: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-04–2026-08-042026-08-06: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-06–2026-08-062026-08-09: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-09–2026-08-092026-08-14: 4 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-14–2026-08-142026-08-17: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-17–2026-08-172026-08-23: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-23–2026-08-232026-08-24: 6 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-24–2026-08-242026-08-28: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-08-31–2026-08-312026-09-06: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-06–2026-09-062026-09-07: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-07–2026-09-072026-09-08: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-08–2026-09-082026-09-10: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-10–2026-09-102026-09-12: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-12–2026-09-122026-09-13: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-13–2026-09-132026-09-14: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-14–2026-09-142026-09-16: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-16–2026-09-162026-09-19: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-19–2026-09-192026-09-20: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-20–2026-09-202026-09-22: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-22–2026-09-222026-09-23: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-23–2026-09-232026-09-26: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-26–2026-09-262026-09-27: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-27–2026-09-272026-09-30: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-09-30–2026-09-302026-10-02: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-02–2026-10-022026-10-06: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-06–2026-10-062026-10-09: 2 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-09–2026-10-092026-10-12: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-12–2026-10-122026-10-13: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-13–2026-10-132026-10-14: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-14–2026-10-142026-10-15: 4 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-15–2026-10-152026-10-16: 1 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-16–2026-10-162026-10-17: 7 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-17–2026-10-172026-10-18: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-18–2026-10-182026-10-20: 3 · observed 2026-10-21T09:52:36.6417321Z · period 2026-10-20–2026-10-20
23 Jul20 Oct

pypistats · 38 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-20 – 2026-10-2032026-10-21T09:52:36.6417321Z
2026-10-18 – 2026-10-1832026-10-21T09:52:36.6417321Z
2026-10-17 – 2026-10-1772026-10-21T09:52:36.6417321Z
2026-10-16 – 2026-10-1612026-10-21T09:52:36.6417321Z
2026-10-15 – 2026-10-1542026-10-21T09:52:36.6417321Z
2026-10-14 – 2026-10-1412026-10-21T09:52:36.6417321Z
2026-10-13 – 2026-10-1312026-10-21T09:52:36.6417321Z
2026-10-12 – 2026-10-1232026-10-21T09:52:36.6417321Z
2026-10-09 – 2026-10-0922026-10-21T09:52:36.6417321Z
2026-10-06 – 2026-10-0612026-10-21T09:52:36.6417321Z
2026-10-02 – 2026-10-0212026-10-21T09:52:36.6417321Z
2026-09-30 – 2026-09-3012026-10-21T09:52:36.6417321Z
2026-09-27 – 2026-09-2712026-10-21T09:52:36.6417321Z
2026-09-26 – 2026-09-2612026-10-21T09:52:36.6417321Z
2026-09-23 – 2026-09-2322026-10-21T09:52:36.6417321Z
2026-09-22 – 2026-09-2212026-10-21T09:52:36.6417321Z
2026-09-20 – 2026-09-2032026-10-21T09:52:36.6417321Z
2026-09-19 – 2026-09-1922026-10-21T09:52:36.6417321Z
2026-09-16 – 2026-09-1612026-10-21T09:52:36.6417321Z
2026-09-14 – 2026-09-1422026-10-21T09:52:36.6417321Z
2026-09-13 – 2026-09-1322026-10-21T09:52:36.6417321Z
2026-09-12 – 2026-09-1212026-10-21T09:52:36.6417321Z
2026-09-10 – 2026-09-1012026-10-21T09:52:36.6417321Z
2026-09-08 – 2026-09-0812026-10-21T09:52:36.6417321Z
2026-09-07 – 2026-09-0732026-10-21T09:52:36.6417321Z
2026-09-06 – 2026-09-0622026-10-21T09:52:36.6417321Z
2026-08-31 – 2026-08-3122026-10-21T09:52:36.6417321Z
2026-08-28 – 2026-08-2812026-10-21T09:52:36.6417321Z
2026-08-24 – 2026-08-2462026-10-21T09:52:36.6417321Z
2026-08-23 – 2026-08-2332026-10-21T09:52:36.6417321Z
2026-08-17 – 2026-08-1722026-10-21T09:52:36.6417321Z
2026-08-14 – 2026-08-1442026-10-21T09:52:36.6417321Z
2026-08-09 – 2026-08-0912026-10-21T09:52:36.6417321Z
2026-08-06 – 2026-08-0622026-10-21T09:52:36.6417321Z
2026-08-04 – 2026-08-0432026-10-21T09:52:36.6417321Z
2026-08-02 – 2026-08-0212026-10-21T09:52:36.6417321Z
2026-07-27 – 2026-07-2732026-10-21T09:52:36.6417321Z
2026-07-23 – 2026-07-2342026-10-21T09:52:36.6417321Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.2.07 Jun 20261

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
kangbaxso/agent-forge

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:58 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:27d9594ead490d725eff2c00ab8e4f974b9e96e1f83dcbc51f4a562aea4c1d17