Minimal OpenAI Chat Completions agent (session + tools).
Project description
pagent (English)
Language: 中文 | English · Docs · For agents · llms.txt
pagent is a small async Python library for an Agent + tools loop over OpenAI-compatible Chat Completions. Good for scripts, experiments, and teaching—transparent message history, your own tools.
Documentation
https://synclionpaw.github.io/pagent/ — install, quick start, tools, events, Wire, providers.
Install
Requires Python 3.11+.
pip
pip install pagent
pip install "pagent[search]" # optional web_search tool
uv
uv is a fast Python package and project manager (official docs).
uv pip install pagent
uv pip install "pagent[search]"
# or in a uv-managed project
uv add pagent
uv add "pagent[search]"
conda
conda activate your-env
pip install pagent
pip install "pagent[search]"
Conda envs usually install PyPI packages with pip inside the activated environment. Check conda-forge if you prefer a conda package when available.
Quick start
import asyncio
import os
from pagent import Agent, LLM, Session, tool
@tool()
def get_weather(city: str) -> str:
"""Return a fake weather summary for the city."""
return f"It's sunny in {city} today."
async def main() -> None:
if not os.getenv("OPENAI_API_KEY"):
raise SystemExit("Please set OPENAI_API_KEY first.")
agent = Agent(
llm=LLM("gpt-4o-mini"),
session=Session("You are a concise assistant. Use tools when needed."),
tools=[get_weather],
max_turns=8,
)
result = await agent.run("What's the weather in Xiamen?")
print(result.content)
print(agent.stats)
asyncio.run(main())
run() returns RunEnd; use .content for the answer.
Streaming & events
One agent timeline — pick an API by consumer (not two different event systems):
| API | You get | Best for |
|---|---|---|
agent.run(prompt) |
Final RunEnd |
No streaming |
agent.arun(prompt) |
Answer text str |
Simple typing effect in scripts |
agent.arun_events(prompt) |
Python Event dataclasses |
In-process Python: CLI, services, match / types |
agent.arun_wire(prompt) |
NDJSON lines (JSON-RPC 2.0) | Cross-language / frontend: SSE, WebSocket, TS switch (method) |
Wire serializes the same events as native Event; see docs/events.md and docs/wire.md.
Minimal event consumer (build your own UI or logs):
import asyncio
from pagent import (
Agent,
LLM,
RunEnd,
Session,
TextDelta,
ToolCallBegin,
ToolResult,
)
async def main():
agent = Agent(LLM("gpt-4o-mini"), Session("You are helpful."), tools=[])
async for event in agent.arun_events("What is 2 + 2?"):
if isinstance(event, TextDelta):
print(event.text, end="", flush=True)
elif isinstance(event, ToolCallBegin):
print(f"\n[calling {event.name}]", flush=True)
elif isinstance(event, ToolResult):
print(f" {event.content}", flush=True)
elif isinstance(event, RunEnd):
print(f"\n\n(done, {event.content!r})")
asyncio.run(main())
Common events: TextDelta (answer stream), ReasoningDelta (model thinking, if supported), ToolCallBegin / ToolResult, RunEnd (final result with .content and .reasoning_content).
Full list: docs/events.md. Frontend / JSON: docs/wire.md — each line is {"jsonrpc":"2.0","method":"TextDelta","params":{...}}.
async for line in agent.arun_wire("Hello"):
# send `line` over SSE / WebSocket (already ends with \n)
...
Runnable demos: examples/reasoning_stream.py, examples/cli.py (uses arun internally).
Models & API keys
| Class | Env var |
|---|---|
LLM("gpt-4o-mini") |
OPENAI_API_KEY |
DeepSeek() |
DEEPSEEK_API_KEY |
Ollama(...), Vllm, Sglang |
optional provider keys |
from pagent import DeepSeek, Ollama
llm = DeepSeek("deepseek-v4-flash")
llm = Ollama("llama3.2")
Server must expose OpenAI-compatible /v1/chat/completions.
Examples
| Command | Description |
|---|---|
uv run examples/cli.py |
Interactive CLI (DEEPSEEK_API_KEY), /context for usage |
uv run examples/simple_qa.py |
Tools demo |
uv run examples/reasoning_run.py |
reasoning_content (non-streaming) |
uv run examples/reasoning_stream.py |
Stream reasoning + answer |
uv run --with fastapi --with uvicorn python examples/wire_demo/server.py |
Wire NDJSON + browser UI |
Guide: docs/reasoning.md. Full-stack wire demo: examples/wire_demo/.
export DEEPSEEK_API_KEY="your-key"
uv run examples/reasoning_stream.py --zh
Optional built-in tools
from pagent import Agent, LLM, Session, web_search
agent = Agent(LLM("gpt-4o-mini"), Session("..."), tools=[web_search])
See clock, region in pagent.defaults.
Notes
- Requires an OpenAI Chat Completions–compatible API.
- A minimal embeddable loop—not a full coding-agent product with file edit/shell.
- Development & internals: docs/development.md
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pagent-0.3.2.tar.gz.
File metadata
- Download URL: pagent-0.3.2.tar.gz
- Upload date:
- Size: 19.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad805c7ab39e54c30785c0234dc67df21f0bffbbd7a740cc58ce51a37064ba46
|
|
| MD5 |
064b4397dad9ef70367caac2f69d7698
|
|
| BLAKE2b-256 |
6361f6c329047d5f950bb88422077a577bc11f97857151d9b3e84faf781c4a38
|
Provenance
The following attestation bundles were made for pagent-0.3.2.tar.gz:
Publisher:
publish.yml on SyncLionPaw/pagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pagent-0.3.2.tar.gz -
Subject digest:
ad805c7ab39e54c30785c0234dc67df21f0bffbbd7a740cc58ce51a37064ba46 - Sigstore transparency entry: 1970287829
- Sigstore integration time:
-
Permalink:
SyncLionPaw/pagent@9cb0ad0e8f8bdd0d3cc8bd5a88fe8fc911155f0b -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/SyncLionPaw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9cb0ad0e8f8bdd0d3cc8bd5a88fe8fc911155f0b -
Trigger Event:
release
-
Statement type:
File details
Details for the file pagent-0.3.2-py3-none-any.whl.
File metadata
- Download URL: pagent-0.3.2-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
117166d1ab36cd7a745e957b3f9d8eb5540af52ce171e0674d920db6a37f7ed2
|
|
| MD5 |
c7ea3c6a7e5aca0e16812b4b06fbe708
|
|
| BLAKE2b-256 |
32fad0ea79826db3bbac9e5131d0dd0890b8788bf16a23896f5c032b64ebbc4d
|
Provenance
The following attestation bundles were made for pagent-0.3.2-py3-none-any.whl:
Publisher:
publish.yml on SyncLionPaw/pagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pagent-0.3.2-py3-none-any.whl -
Subject digest:
117166d1ab36cd7a745e957b3f9d8eb5540af52ce171e0674d920db6a37f7ed2 - Sigstore transparency entry: 1970287977
- Sigstore integration time:
-
Permalink:
SyncLionPaw/pagent@9cb0ad0e8f8bdd0d3cc8bd5a88fe8fc911155f0b -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/SyncLionPaw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9cb0ad0e8f8bdd0d3cc8bd5a88fe8fc911155f0b -
Trigger Event:
release
-
Statement type: