Skip to main content

pi-py

Python port of pi's core libraries, published on PyPI as one package, pi-ai-python, with two import packages:

Import Upstream What it does
pi_ai @earendil-works/pi-ai Unified LLM API: provider collections, auth resolution (API keys, OAuth), streaming events, token and cost tracking, tool calling, cross-provider context hand-off, image generation, classification
pi_agent @earendil-works/pi-agent-core Stateful agent: tool execution (parallel or sequential), steering and follow-up queues, lifecycle events, hooks
pip install pi-ai-python               # httpx + official SDKs: anthropic, openai, google-genai
pip install "pi-ai-python[bedrock]"    # + boto3 for Amazon Bedrock
pip install "pi-ai-python[all]"        # + orjson, websockets, pydantic, boto3

中文说明见 README.zh-CN.md。

import asyncio

from pi_ai import Context, UserMessage
from pi_ai.providers.all import builtin_models


async def main() -> None:
    models = builtin_models()  # every built-in provider; auth comes from env vars such as ANTHROPIC_API_KEY
    model = models.get_model("anthropic", "claude-sonnet-4-5")
    stream = models.stream(model, Context(system_prompt="Be brief.", messages=[UserMessage("Hello!")]))
    async for event in stream:
        if event.type == "text_delta":
            print(event.delta, end="", flush=True)
    message = await stream.result()
    print(f"\n{message.usage.input} in / {message.usage.output} out, ${message.usage.cost.total:.4f}")


asyncio.run(main())
from pi_agent import Agent, AgentInitialState, agent_tool


@agent_tool
async def get_time(timezone: str = "UTC") -> str:
    """Get the current time.

    Args:
        timezone: IANA timezone name.
    """
    ...


agent = Agent(
    initial_state=AgentInitialState(system_prompt="You are helpful.", model=model, tools=[get_time]),
    stream_fn=models.stream_simple,
)
async for event in agent.events("What time is it in Tokyo?"):
    print(event.type)

Same API, Python conventions

The port keeps pi's architecture and semantics: the same Models/Provider runtime, the same event protocol (start → text_delta… → done/error), the same transcript model (system prompt and tools carried by system messages), the same auth precedence rules, the same model catalog, and the same agent loop. Names follow Python conventions:

TypeScript Python
createModels(), models.streamSimple(...) create_models(), models.stream_simple(...)
{ apiKey, sessionId, maxTokens } options api_key=..., session_id=..., max_tokens=... keyword arguments (or a dict)
message.stopReason, usage.cacheRead message.stop_reason, usage.cache_read
{ role: "user", content: "hi", timestamp } UserMessage("hi") (timestamp defaults to now)
Type.Object({...}) (TypeBox) Type.Object({...}) (built in) or a Pydantic model
AbortController / signal pi_ai.AbortController / signal=
for await (const e of stream) / await stream.result() async for e in stream / await stream.result()
agent.continue() agent.continue_() (alias agent.resume())

String values that appear on the wire or in persisted transcripts are unchanged ("toolUse", "toolResult", "text_delta", API ids, provider ids), and pi_ai.serialization reads and writes pi's camelCase JSON, so sessions, model definitions and auth.json credential files are interchangeable with TypeScript pi.

Design notes

  • Official vendor SDKs. As in pi, the Anthropic, OpenAI (Chat Completions, Responses, Azure, OpenRouter images), Google (Gemini, Vertex) and Bedrock adapters use the vendors' official SDKs: anthropic, openai, google-genai and boto3 (pi-ai-python[bedrock]). The SDK clients share one pooled httpx.AsyncClient per event loop. APIs that pi calls without an SDK (Mistral, OpenAI Codex, pi-messages, classifiers) use httpx directly.
  • Fast streaming path. Slotted data classes, an allocation-light event queue, zero-copy forwarding between wrapped streams, an incremental partial-JSON parser for tool-call arguments (about 60x faster than re-parsing each delta on large arguments), linear-time accumulation of streamed text, optional orjson decoding, and compiled, cached tool-argument validators. On one core the anthropic-messages adapter processes about 110,000 stream events per second and openai-completions about 70,000, where the openai SDK's SSE decoder is the limit (see benchmarks/).
  • Lazy everything. Model catalogs load per provider on first use; API implementations and OAuth flows import on first request.
  • Async-native cancellation. AbortSignal aborts interrupt pending network reads immediately (task cancellation scoped by abort_scope), and aborted requests end their stream with stop_reason == "aborted" instead of raising.
  • Python-friendly additions. Pydantic models as tool parameter schemas, @agent_tool to build tools from typed functions, Agent.events() as an async iterator, FileCredentialStore (pi's auth.json format with cross-process locking), keyword-argument options, streams that can be created outside an event loop and closed with async with.

Development

uv sync                      # create .venv with the package (editable) and dev tools
uv run pytest                # run all tests (offline; HTTP is mocked)
uv run ruff check . && uv run ruff format --check .
uv run pyright
uv run python benchmarks/bench_partial_json.py
uv run python benchmarks/bench_stream.py

Model catalog data (packages/ai/src/pi_ai/providers/data/*.json) is the generated catalog shipped with @earendil-works/pi-ai 1.3.0.

License

MIT. Based on pi by Mario Zechner and contributors.

Metadata

Release files for pi-ai-python 1.3.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 pi-ai-python 1.3.0
File Size Uploaded
pi_ai_python-1.3.0.tar.gz 548.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pi-ai-python 1.3.0
File Interpreter ABI Platform
pi_ai_python-1.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 996.4 kB

Release files / pi_ai_python-1.3.0.tar.gz

Download URL pi_ai_python-1.3.0.tar.gz
Size 548.9 kB
Tags Source
SHA-256 checksum
How to use checksums
092b270ad64a8ee02467d99323644a6ed4864e8e7143a53f8bf425fb6db683c2
BLAKE2b-256 checksum
How to use checksums
0f1e336dcfa949d37087f34c145afc79f2c41c325f055347811d45d042d26c1d
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 / pi_ai_python-1.3.0-py3-none-any.whl

Download URL pi_ai_python-1.3.0-py3-none-any.whl
Size 447.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ba6e6297fec7ceac3a3fa03a4022469e078534cc8abb67196a85e9f70b1e42e8
BLAKE2b-256 checksum
How to use checksums
48b7144758e3a59996e906a3b5f4abd4eef8233ff4b1fa3523df84b56e945912
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 history Release notifications | RSS feed

1.4.0

2 release files

This release

1.3.0 This release

2 release files

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