Skip to main content

looplet

CI codecov PyPI version Python 3.11+ License: Apache 2.0

A Python loop for agents that call tools.

You provide the model, tools, task, and limits. Looplet checks each tool call, runs the tool, and records the result. It yields a Step after each call. Your code can inspect each step and stop iteration.

Looplet also provides context management for longer runs and hooks to control each stage of the loop. Add only the features that your agent needs. Start in Python; use a cartridge when you need an agent stored and shared as files. The Quickstart runs one agent, checks its answer, saves its calls, and replays them.

A short loop is enough if it already meets your needs. Use Looplet when you need these controls without separate code for each agent. The loop stays visible, and your code still controls iteration.

Looplet requires Python 3.11 or newer. The core package has no third-party runtime dependencies. It does not require a workflow graph, a hosted service, or a cartridge.

Documentation | Quickstart | Python API

Run one loop

Install the fixed release for the examples and fixes in these guides. No Git installation or local repository checkout is needed.

python -m pip install "looplet==0.4.1"

Run this inside a virtual environment; see Install. This installs a non-editable package and needs network access.

The latest PyPI release is 0.4.1. It includes the safety fixes missing from 0.4.0. Pin the version and artifact hashes in your dependency lockfile for deployment.

The example uses fixed model responses. It runs without a model service or an API key.

from contextlib import closing

from looplet import DefaultState, LoopConfig, MockLLMBackend, RunResult, composable_loop, tools_from


def lookup_owner(service: str) -> dict:
    """Find the team that owns a service."""
    owners = {"payments": "fintech-platform", "search": "discovery"}
    return {"service": service, "owner": owners.get(service)}


llm = MockLLMBackend([
    '{"tool":"lookup_owner","args":{"service":"payments"}}',
    '{"tool":"done","args":{"summary":"The payments owner is fintech-platform."}}',
], cycle=False)
tools = tools_from([lookup_owner], include_done=True, validate=True)
state = DefaultState(max_steps=2)

with closing(composable_loop(
    llm=llm,
    tools=tools,
    state=state,
    config=LoopConfig(max_steps=2, use_native_tools=False),
    task={"goal": "Find the payments owner, then finish."},
)) as steps:
    for step in steps:
        print(step.tool_call.tool, step.tool_result.data)

print(RunResult.from_state(state).termination_reason)

The loop calls lookup_owner, then done. The lookup returns fintech-platform as the payments owner. The last line prints done, the stop reason. cycle=False rejects unexpected extra model calls instead of repeating the script.

The tool remains a normal Python function. You can also call lookup_owner("payments") directly.

Each yielded step follows a tool call. The tool has already run when your code receives that step. Use break to stop iteration before requesting another step. For native batches, preventing later calls requires the serial-dispatch fix in 0.4.1. Published 0.4.0 may execute the batch before yielding its first step. With concurrent_dispatch=True, the batch runs before its results are yielded. closing closes the loop and runs its end hooks. Your code must close resources that it creates.

validate=True checks top-level argument types, nullability, and enum choices before tools run. Nested data and other constraints remain the tool's responsibility. Without this option, the base registry checks argument names and required fields, not full types.

This example selects the JSON-text protocol for its fixed responses. Real models use native tool calls by default. See Install for provider adapters and configuration.

The Quickstart adds a result helper, pytest checks, capture, and replay to this same agent. For async code, use async_composable_loop() with contextlib.aclosing.

Add only what you need

The same loop supports these optional features. You do not need a new execution engine to use them.

Need Feature Guide
Keep a long run within context limits Context budgets, summaries, and truncation Context management
Add context or change the prompt Hooks before the model call Hooks
Check or change calls and results Hooks before and after tools run Hooks
Limit calls or detect repeated actions Step limits, tool-call limits, and repetition checks Run controls
Save prompts, responses, and steps ProvenanceSink Capture and replay
Check files or other results Collectors and graders Tests and graders
Build a fresh agent run for each task A Python factory returning AgentPreset Python API
Store an agent in files A cartridge directory Cartridges
Use an agent from a shell new, run, inspect, and eval Command-line guide
Connect tools or other hosts Protocol adapters Portability

Looplet 0.4.0 includes the Python helpers and unified CLI. The guides identify behavior added in 0.4.1. Older commands, such as run-cartridge, describe, and show, remain supported.

Check results

A done step means that the loop accepted completion. It does not prove that the answer is correct.

Use a collector to read the files or records that the agent produced. Use a grader to compare that evidence with the expected result. Required graders can fail a test or a continuous integration check.

Run the regression example after installation:

looplet-proof

The example records fixed model responses and an incorrect report. It changes one tool line and replays the responses with the corrected tool. A collector reads the new report. The required grader changes from fail to pass. See the walkthrough for the files and limits.

Replay fixes model responses, not tool effects. Tools, networks, clocks, and random values can change unless your host controls them. A prompt or model change needs new model runs.

An agent's own tests are not protected acceptance checks. Keep release checks outside the code that a candidate can change. Run untrusted code in an isolated process or operating system environment.

Use it in an agent that you have

Keep your provider and tool functions. Replace the control loop first. Check that the new loop preserves the behavior you need. Then add capture, hooks, or result checks as needed.

See the Migration guide for the full procedure.

When Looplet fits

Use Looplet when:

  • One model calls tools until the task ends.
  • Your team uses Python, Git, and pytest.
  • Your code must control when tools run.
  • You need saved runs and tests for agent changes.

Use something else when:

  • Your main task needs a durable workflow graph.
  • You need a complete assistant, not a Python library.
  • You need a managed dashboard as your main interface.
  • A small loop that you wrote already meets your needs.

Looplet can run inside a workflow engine. It can export evidence to other systems. It does not replace those systems.

Documentation

Guide Purpose
Quickstart Run, inspect, and stop one loop
Install Choose a version and configure a model
Python API Find the classes and functions you need
Migration Replace a loop without new tool implementations
Report-agent tutorial Add a case, collector, and grader to a file-based agent
Operations Use async code, retries, cancellation, and checkpoints
Examples Run complete examples

See the documentation site for the full guide list.

Stability

Looplet follows semantic versioning. Before version 1.0, a minor release can change an API incompatibly. Pin the minor version for a published install:

looplet>=0.4.1,<0.5

The latest PyPI release is 0.4.1. See the changelog and release plan.

Contributing

Report bugs or propose examples and backend adapters. A core feature must work across task domains. Include checks for the behavior that your change affects.

See CONTRIBUTING.md. Report security issues as described in SECURITY.md.

License

Apache License 2.0. See LICENSE.

Metadata

Release files for looplet 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for looplet 0.4.1
File Size Uploaded Provenance
looplet-0.4.1.tar.gz 1.1 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for looplet 0.4.1
File Interpreter ABI Platform
looplet-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.9 MB

Release files / looplet-0.4.1.tar.gz

Download URL looplet-0.4.1.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
189e9fe4ea2ead171b3cd92549f15e2c6899a693276b7dbff56324365bb828f2
BLAKE2b-256 checksum
How to use checksums
187f88b20cdfeff7f1cb564b88cf7b21d6bec3438c23c83086f5965fac5f1214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / looplet-0.4.1-py3-none-any.whl

Download URL looplet-0.4.1-py3-none-any.whl
Size 748.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3090e9a54eb0d9fcb903e01e2eab89c6cb79d4a06ef78f106ef928a693d1015e
BLAKE2b-256 checksum
How to use checksums
3282cfdb7f92599021c026400bd1567b5a0900e2d1e275b70841346fcea4d33a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Security for looplet 0.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for looplet-0.4.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page