Skip to content
v0.1.0agentling is now on PyPI

The agent framework you can read in one sitting

A tiny async framework where nothing is hidden: one readable loop, typed memory you can persist and replay, events that narrate every step, and failures the model recovers from. Small enough to audit before lunch.

Get started

1

loop for everything

2

runtime dependencies

More

tests than source

0

magic: no metaclasses, no registry, no DSL

Why agentling

Read the source. All of it. Tonight.

Agents fail in weird ways, and in most frameworks you cannot see why: the decision happened somewhere inside a graph, a registry, or a callback forest. agentling is an agent that is just a loop you can read. Every step is typed, every event is observable, every failure is recoverable, and every run is resumable and testable offline.

Async first

The loop, tools, and model calls are all async. Tool calls in a single step run concurrently by default.

One code path

Blocking and streaming share the exact same loop. There is a single async generator; blocking mode just drains it.

Typed memory

A run is a list of typed steps that serialize to JSON, so persistence, replay, and multi-turn continuation come for free.

Streaming events

Five frozen event types narrate every run: text deltas, tool calls, results, recorded steps, and the final answer.

Self-healing

A tool that raises becomes an observation the model can recover from, not a crash. Stuck loops get a nudge.

Progressive skills

Drop a SKILL.md folder in and the model sees only its name until it decides to load it. Big skill libraries stay cheap.

The loop

One iteration, one step

Each step streams a model turn, runs the tools it asked for, records the outcome, and checks whether the run is done. Blocking and streaming, persistence and resume, skills and self-healing all hang off this one generator.

  1. 1Render the promptTyped memory becomes model messages.
  2. 2Stream the model turnText deltas surface as they arrive.
  3. 3Run the tool callsConcurrently, with schema validation.
  4. 4Record the stepUsage, duration, and results, all typed.
  5. 5Check for an answerfinal_answer, plain text, or step limit.
import asyncio
 
from agentling import Agent, OpenAIModel, tool
 
 
@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city.
 
    Args:
        city: The city to look up.
    """
    return f"It is 22C and sunny in {city}."
 
 
async def main() -> None:
    agent = Agent(model=OpenAIModel("gpt-4o-mini"), tools=[get_weather])
    print(await agent.run("What's the weather in Paris?"))
 
 
asyncio.run(main())

Observability

Every run narrates itself

Five frozen event types describe everything an agent does. Feed them to a terminal, a UI, a logger, or a metrics store; the stream and the durable memory can never disagree.

TextDeltaa chunk of streamed textToolCallEventa tool is about to runToolResultEventa tool finishedStepEventa step hit memoryFinalEventthe run is done

An honest filter

Is agentling right for your project?

Reach for agentling when

  • You want to audit every decision an agent makes: a service calling trusted tools, a CLI assistant, a background worker.
  • You need runs you can persist, replay, resume, and test offline without an API key.
  • You want a framework your whole team can read end to end and reason about.

Look elsewhere when

  • You want orchestration graphs and a built-in tracing dashboard out of the box.
  • You need sandboxed execution for untrusted tools; agentling tools run as trusted code.
  • You expect automatic context summarization on very long runs; you supply the context_manager.

Know exactly what your agent will do

No metaclasses, no plugin registry, no DSL. Install it, read the loop, and ship an agent you can explain.