Skip to main content

Pi Agent Python SDK

Your terminal agent. Your Python API.

Pi Agent Python SDK

PyPI Python 3.11+ MIT license

Pi is the coding agent that runs in your terminal. This unofficial community SDK puts your Pi behind a typed sync and async Python API — run prompts, stream events, and keep sessions going without leaving Python.

https://github.com/user-attachments/assets/c64dde3a-e812-42d4-a005-aa60df861e92

from pi_agent import PiClient

with PiClient() as pi:
    print(pi.run("Explain the current project without changing files.").text)

Requires an installed, configured Pi CLI — see Prerequisites.

Prerequisites · Quick start · Streaming · Async · Configuration · Thinking · RPC · Documentation · Troubleshooting · Support

What you can do

  • Run prompts from Python — get a final answer, or stream text, thinking, and tool events as they happen.
  • Keep conversations going — send follow-ups on the same client, or resume, fork, and clone sessions.
  • Control the agent — switch models, set thinking level, steer mid-run, and compact context.
  • Reuse your Pi setup — same configuration, tools, and extensions as the CLI, with sync or async clients.

Prerequisites

Requirement Notes
Python 3.11+ Package metadata requires 3.11 or newer
Node.js 22.19.0+ Required by Pi 0.87.0
Pi 0.85.1+ Minimum accepted version; 0.87.0 is the tested baseline
Model provider Required; configure with the Pi CLI (see Quick start)

Quick start

Install Pi with Node.js 22.19.0 or newer (pin matches the tested baseline):

npm install -g @earendil-works/pi-coding-agent@0.87.0
pi --version

Run pi once to configure your provider and model. The SDK uses that configuration when it starts Pi.

Install the Python package from PyPI:

python -m pip install pi-agent-python-sdk

The distribution is named pi-agent-python-sdk; import it as pi_agent.

from pi_agent import PiClient

with PiClient() as pi:
    result = pi.run("Explain the current project without changing files.")
    print(result.text)

The context manager starts and closes Pi. run() waits for the conversation to settle. The result includes finalized messages, session identity, elapsed time, and observed assistant usage.

Continue the conversation with another call on the same client:

from pi_agent import PiClient

with PiClient() as pi:
    print(pi.run("Explain this project's entry points without editing files.").text)
    print(pi.run("Which of those entry points handles configuration?").text)

Pi keeps the conversation context. Each result contains only the messages and answer from that call; a call with no assistant output has empty text.

Streaming

from pi_agent import PiClient

with PiClient() as pi:
    with pi.stream("Explain this project's entry points without editing files.") as stream:
        for event in stream:
            if event.text_delta is not None:
                print(event.text_delta, end="", flush=True)
        result = stream.result()
    print(f"\nStop reason: {result.stop_reason}")
Streaming details

event.raw contains the full Pi event, including fields the SDK does not yet recognize. Keep the stream inside its context: leaving early cleans up unfinished work. See errors and cancellation for handling timeouts and partial results.

Async usage

Use AsyncPiClient in applications that already run an event loop. Command arguments and results match the synchronous client.

import asyncio

from pi_agent import AsyncPiClient


async def main() -> None:
    async with AsyncPiClient() as pi:
        result = await pi.run("Explain the current project without changing files.")
        print(result.text)


if __name__ == "__main__":
    asyncio.run(main())
Async streaming

Use async with pi.stream(...), async for event in stream, and await stream.result(). See the complete streaming example.

Configuration

Choose the project directory and whether to save the conversation:

from pi_agent import PiClient

with PiClient(cwd=".", no_session=True) as pi:
    print(pi.run("Describe this project without changing files.").text)

Leave no_session unset to preserve Pi's normal session persistence. Use session= to open an existing session. For model overrides, see Models and thinking.

More configuration

See constructor options for environment overrides, executable paths, and deadlines.

Extensions are installed and configured through Pi. To load your own extension, pass extra_args=["--extension", "/absolute/path/to/your-extension.ts"] to either client. See using your own extensions for details and extension UI for an interactive example.

Models and thinking

By default the SDK uses whatever model you already configured in the Pi CLI. Override it when you construct the client, or switch later on the same client. Set the model and thinking level before run() or stream().

Select a model at construction:

from pi_agent import PiClient

with PiClient(provider="openai", model="gpt-5") as pi:
    print(pi.run("Summarise this repo without changing files.").text)

Thinking levels depend on the current model. Query them, set one, then confirm what Pi actually applied:

from pi_agent import PiClient

with PiClient() as pi:
    levels = pi.get_available_thinking_levels()
    print("available:", levels)
    if "high" in levels:
        pi.set_thinking_level("high")
    print("effective:", pi.get_state()["thinkingLevel"])
    print(pi.run("Analyse this project's architecture without changing files.").text)

Replace the example provider/model ids with ones from your Pi install (pi --list-models or get_available_models()).

List models and switch after start
from pi_agent import PiClient

with PiClient() as pi:
    for model in pi.get_available_models():
        print(model["provider"], model["id"])
    selected = pi.set_model("openai", "gpt-5")
    print("using", selected["provider"], selected["id"])
    print(pi.run("Summarise this repo without changing files.").text)

RPC access

The SDK speaks Pi's existing JSONL protocol over stdin/stdout:

Your Python application
    PiClient / AsyncPiClient
        pi --mode rpc
            Models · tools · extensions · sessions

Inspect session state without starting a model run:

from pi_agent import PiClient

with PiClient() as pi:
    state = pi.get_state()
    print(state["sessionId"])
Which interface to use
You need Use
A completed conversation result run()
Events while a conversation runs stream()
Prompt acknowledgement and your own event handling prompt() with events()
Session events through the next settlement prompt_and_wait() or collect_events()
Every event without retaining history on_event(callback)
A specific Pi operation get_state(), set_model(), fork(), and other command methods
A raw command response envelope request()

Python arguments use snake_case; wire dictionaries retain Pi's camelCase fields. prompt() acknowledges submission, which may be handled entirely by an extension. It does not wait for a completed answer.

Each client starts its own Pi subprocess. Use one client per conversation and wait for each run() or stream to finish before starting the next. After using prompt() for your own event handling, use a fresh client for run() or stream() so results cannot include delayed events from earlier work.

See RPC structure for the protocol mapping and module layout, and the command reference for every method.

Documentation

Guide Contents
Usage Sessions, images, concurrency, events, and extension UI
API reference Constructors, commands, types, and results
Errors and cancellation Deadlines, partial results, cleanup, and recovery
RPC structure How the Python client maps to Pi's protocol
Compatibility Runtime versions and platform validation
Examples Runnable sync, async, streaming, sessions, steering, and UI examples
Release notes Changes included in 0.2.3

Examples use your configured Pi and may make provider calls. Development checks use an isolated local test provider; see CONTRIBUTING.md for setup and validation commands.

Troubleshooting

Symptom What to check
pi not found / launch fails Ensure the Pi CLI is on PATH, or pass executable= to the client
Version rejected Upgrade to Pi 0.85.1+; prefer the tested baseline 0.87.0
No model / auth errors Run pi once and complete provider setup
Unexpected file or command changes Review Pi tool/extension settings before automation

Support

License

MIT

Metadata

Release files for pi-agent-python-sdk 0.2.3

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-agent-python-sdk 0.2.3
File Size Uploaded
pi_agent_python_sdk-0.2.3.tar.gz 42.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pi-agent-python-sdk 0.2.3
File Interpreter ABI Platform
pi_agent_python_sdk-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 91.2 kB

Release files / pi_agent_python_sdk-0.2.3.tar.gz

Download URL pi_agent_python_sdk-0.2.3.tar.gz
Size 42.8 kB
Tags Source
SHA-256 checksum
How to use checksums
87cd4b399c06c84a386b1800c3ac361c5de3bce368448ddb90eb9b6880cd388f
BLAKE2b-256 checksum
How to use checksums
cf1399b14f0ec069fd769dab58d8d096d2af79e7db11397fcd51b40ae620ef89
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 Sep 23, 2026.

Transparency log

Release files / pi_agent_python_sdk-0.2.3-py3-none-any.whl

Download URL pi_agent_python_sdk-0.2.3-py3-none-any.whl
Size 48.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b63a5677a4bd80aa15106748de711fc3843418b47cf689bace88cd3cf6247b0c
BLAKE2b-256 checksum
How to use checksums
a649e12d44051c9debfe35ef9f9b6348831153fbc2be7299e5916a0de28211d5
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 Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

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