pi-python-core
English | 中文
An embeddable Python agent core, ported from Pi (pinned to v1.0.0). It does one job: send the conversation to a model, run the tools the model asks for, hand the results back, and repeat until the model answers. Tools are plain Python functions; the model can be Claude, GPT, DeepSeek, or an open model running on your own machine or cluster.
pi-agent-core on PyPI is a separate project that ports an older version from pi-mono (early 2026). This library follows the behavior of Pi v1.0.0, compared case by case with the upstream code's actual output, and ships its own connectors for Claude, OpenAI, DeepSeek and local models, with no model SDK required.
Install
Python 3.11–3.14 (including free-threaded 3.14t) and PyPy 3.11. No Node.js or model SDK needed.
pip install pi-python-core # or: uv add pi-python-core
You install pi-python-core and import pi_python.
| Option | What it adds |
|---|---|
| (none) | The agent core and the built-in model connectors: Claude, OpenAI, Codex, DeepSeek, and any OpenAI-compatible server (Ollama, vLLM, llama.cpp, …) |
[oauth] |
Verifies the identity token when you sign in with a ChatGPT account (openai-chatgpt); it brings in the compiled cryptography package. Claude subscription and Codex sign-in do not need it |
[providers] |
Same as [oauth]; keeps install commands from 0.8.1 and earlier working |
[mcp] |
Gives the agent the tools of MCP servers |
Dependencies are version ranges rather than pins, so the package fits into most existing environments.
Five-minute start
from pi_python import Agent, tool
from pi_python.providers import AnthropicProvider
@tool
def word_count(text: str) -> int:
"""Count the words in a text."""
return len(text.split())
agent = Agent(provider=AnthropicProvider(api_key="..."), model="claude-sonnet-4-5", tools=[word_count])
result = agent.prompt_sync("How many words are in 'to be or not to be'?")
print(result.messages[-1].content[0].text)
@tool builds a tool from the function's signature and docstring; both plain and async functions work. In async code, use await agent.prompt(...). Switching to a local model changes two lines:
from pi_python.providers import OpenAICompletionsProvider
llm = OpenAICompletionsProvider(base_url="http://localhost:11434/v1", name="ollama")
agent = Agent(provider=llm, model=llm.model("qwen3:8b", context_window=40960), tools=[word_count])
To try it offline first: python examples/quickstart.py.
What it does
| Need | How | Example |
|---|---|---|
| Write tools | Decorate a plain function with @tool; arguments such as pydantic models, dataclasses, enums and dates are converted automatically; hand-written or MCP-generated JSON Schema works too |
quickstart |
| Connect a model | Claude and GPT through an API key or subscription sign-in; DeepSeek; any OpenAI-compatible server | local_model, provider_chat |
| Use MCP tools | async with connect_stdio(...) as tools |
mcp_tools |
| Let one agent call another | Wrap the sub-agent as a tool; cancellation propagates down | subagent |
| Intervene mid-run | steer injects guidance, follow_up queues the next task, abort cancels at any time (callable from any thread) |
|
| Context full, service errors | is_context_overflow and is_retryable_error tell you why, continue_run() retries, transform_context compacts |
recovery |
| Save and restore conversations | encode_messages / decode_messages; your application decides where to store them |
save_restore |
| Observe and audit | Subscribe to events; hooks before and after tool execution can block or rewrite tool calls |
Apart from provider_chat, which needs real credentials, every example runs offline without an API key, and the tests run each one.
Relationship to Pi
The run loop, event order, hooks, queues, and the handling of errors and cancellation all match Pi, and this is checked differentially: the same inputs go to the pinned upstream code and to this library, and the model requests, tool calls, events and final transcript are compared item by item. All cases currently agree: 25 for the core loop, 50 for model connectors, 2 for multi-turn WebSocket, and 44 error-classification samples.
A few differences are deliberate, such as strict tool-argument validation without type coercion, and returning copies of state to callers. Others are additions for Python users, such as @tool, blocking calls, and calling continue_run() directly after a failure. Each one is recorded in the coverage map (Chinese). Features Pi keeps in its application layer (terminal UI, session file format, context compaction) are not in this core; compaction can be built with hooks, and an example shows the full approach. This project uses its own version numbers and is not an official Pi release.
Documentation
- Concepts on one page: five ideas and one turn
- Public API
- Model connectors, subscription sign-in and local models
- Implementation and verification results (Chinese)
- Item-by-item comparison with Pi, and deliberate differences (Chinese)
- Rebuilding the reference and checking release candidates (Chinese)
Development
uv sync --locked --extra oauth --extra mcp
uv run pytest -q
uv run python scripts/verify.py # every check, including the comparison with upstream (needs Node)
CI is defined in .github/workflows/ci.yml and runs on GitHub Actions for every push: each Python version on Linux (including 3.14t and PyPy), plus macOS and Windows.
Metadata
Release files for pi-python-core 0.8.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pi_python_core-0.8.2.tar.gz | 319.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pi_python_core-0.8.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 430.1 kB
Release files / pi_python_core-0.8.2.tar.gz
| Download URL | pi_python_core-0.8.2.tar.gz |
|---|---|
| Size | 319.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9751d5471931e2a1d2e41bdd5b25bb42e748a1f1647925010b55d9fc9c0eff03
|
|
BLAKE2b-256 checksum How to use checksums |
90cf0dba52fa9de82a02af314cc8921b083097881f6562cd0fdc3c796b7a4466
|
| 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 3, 2026.
Transparency logRelease files / pi_python_core-0.8.2-py3-none-any.whl
| Download URL | pi_python_core-0.8.2-py3-none-any.whl |
|---|---|
| Size | 111.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ea2d6bfc5a7f5ff464e2964d34345538008bb549eb9a71175b21beda998c132
|
|
BLAKE2b-256 checksum How to use checksums |
f443eea0f585d1386445e54eaf759ba02ddc8fc968c40167b9b068995f3edb59
|
| 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 3, 2026.
Transparency log