Skip to main content

Runlet

Runlet is a tiny observable runtime for Python agents.

The project is a library, not an application framework. Its core direction is a provider-neutral, async-first agent runtime with strict context budgeting, structured observability, and flexible hooks around model and tool execution.

Current Status

This repository now contains an MVP runtime skeleton with core contracts, events, tools, hooks, context budgeting, streaming, provider adapters, and in-memory state. The API is not stable yet.

Design Goals

  • Keep the core runtime small and embeddable.
  • Treat context budgeting and compression as mandatory runtime safety checks.
  • Expose hooks before and after model calls, tool calls, state operations, and context compression.
  • Emit structured events for runs, steps, model calls, tool calls, context changes, state changes, and failures.
  • Stay provider-neutral: model SDKs integrate through adapters, not core dependencies.

Non-Goals

Runlet core does not aim to provide:

  • A web application framework.
  • A hosted agent platform.
  • A task queue or worker system.
  • A UI or trace viewer.
  • A multi-tenant control plane.
  • A graph workflow engine in the first release.

Project Documents

Minimal Shape

from runlet import Agent, Runtime, tool


@tool
async def lookup(order_id: str) -> str:
    return f"order {order_id}"


agent = Agent(
    name="support",
    instructions="Help users with orders.",
    model=my_model_provider,
    tools=(lookup,),
)

result = await Runtime().run(agent, "Where is order 123?")

OpenAI Provider

Install the optional OpenAI dependency:

pip install "runlet[openai]"

Minimal example:

from runlet import Agent, Runtime
from runlet.providers import OpenAIResponsesProvider


provider = OpenAIResponsesProvider(model="gpt-5.5")

agent = Agent(
    name="assistant",
    instructions="Be helpful.",
    model=provider,
)

result = await Runtime().run(agent, "Say hello in one sentence.")

Custom base URL:

from runlet.providers import OpenAIResponsesProvider


provider = OpenAIResponsesProvider(
    model="gpt-5.5",
    base_url="https://your-endpoint.example/v1",
)

Provider-specific request options:

from runlet.core import Message
from runlet.core.models import ModelRequest
from runlet.providers import OpenAIResponsesProvider


provider = OpenAIResponsesProvider(model="gpt-5.5")


request = ModelRequest(
    messages=[Message.user("Summarize this briefly.")],
    options={
        "openai": {
            "extra_body": {
                "reasoning": {"effort": "medium"},
            },
        },
    },
)

response = await provider.complete(request)

Streaming text deltas:

from runlet import Agent, Runtime
from runlet.providers import OpenAIResponsesProvider


provider = OpenAIResponsesProvider(model="gpt-5.5")
agent = Agent(
    name="assistant",
    instructions="Be helpful.",
    model=provider,
)

async for event in Runtime().stream(agent, "Explain recursion in one sentence."):
    if event.type == "model.stream.delta":
        print(event.payload["delta"], end="")

Streaming with tool execution:

from runlet import Agent, Runtime, tool
from runlet.providers import OpenAIResponsesProvider


@tool
async def lookup_order(order_id: str) -> str:
    return f"order {order_id} shipped"


provider = OpenAIResponsesProvider(model="gpt-5.5")
agent = Agent(
    name="assistant",
    instructions="Use tools when needed.",
    model=provider,
    tools=(lookup_order,),
)

async for event in Runtime().stream(agent, "Check order 123 and tell me the result."):
    if event.type == "model.stream.delta":
        print(event.payload["delta"], end="")

When the provider emits a tool call during streaming, Runtime.stream() now executes the tool, appends the tool result to the conversation, and continues the next model round until the run completes.

Current scope of the provider:

  • complete() supported
  • capabilities() supported
  • stream() supported
  • text deltas supported
  • streaming tool execution through Runtime.stream() supported
  • base_url supported
  • options["openai"]["extra_body"] supported
  • provider-specific request options stay under ModelRequest.options["openai"]

Current streaming contract:

  • providers can emit provider-neutral streaming step events internally
  • Runtime.stream() handles multi-round tool execution loops
  • OpenAI is the first provider implementation of this contract

Development

Run the current test suite:

PYTHONPATH=src python3 -m unittest discover tests

Releasing

Runlet publishes to PyPI from Git tags through GitHub Actions.

Release flow:

  1. Update [project].version in pyproject.toml
  2. Merge the release commit to main
  3. Create a version tag such as v0.1.0
  4. Push the tag to GitHub

The publish workflow will:

  • verify the Git tag matches pyproject.toml
  • run the test suite
  • build sdist and wheel
  • validate package metadata
  • publish to PyPI through Trusted Publishing

Example:

git tag v0.1.0
git push origin v0.1.0

Repository setup requirement:

  • configure PyPI Trusted Publishing for this GitHub repository and the .github/workflows/publish.yml workflow

Metadata

Release files for runlet 0.1.0

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

Source distribution (sdist)

Source distribution for runlet 0.1.0
File Size Uploaded
runlet-0.1.0.tar.gz 21.4 kB Details

Built distribution (wheel)

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

Total release size: 39.0 kB

Release files / runlet-0.1.0.tar.gz

Download URL runlet-0.1.0.tar.gz
Size 21.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5cadf3b6ea6d4c5f827eaca0a6132fe8f70f840ee6b338a66fc3c78b50f858da
BLAKE2b-256 checksum
How to use checksums
425854c0bf25ab4257b08b73815b6a6f62317c80e396f99d97b7bab10b0ca310
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 27, 2026.

Transparency log

Release files / runlet-0.1.0-py3-none-any.whl

Download URL runlet-0.1.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28b040105fb5eeaa9781e24218e4ac0cdda1039b538c3f26c0b49623cc814e85
BLAKE2b-256 checksum
How to use checksums
b25b4bb53f4834a9b7ea919ad3fb92270992119db3e4eb84371623abebd7bb2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 27, 2026.

Transparency log
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