Padwan AI
Lightweight async client for OpenAI, Gemini, Mistral, Grok, Anthropic, ElevenLabs (experimental), Gradium (experimental), TypeSafe (JEV, experimental), and any OpenAI-compatible API.
One dependency (niquests), TypedDict everywhere, HTTP/2 and HTTP/3 out of the box.
Documentation · PyPI · Changelog
Install
pip install padwan-ai
Extras: [realtime] for voice sessions, [otel] for OpenTelemetry, [langfuse] for the Langfuse adapter.
Quickstart
Requires Python 3.13+. The provider is picked from the model name; only the matching *_API_KEY env var is needed
(OPENAI_API_KEY here). Behind a gateway? Set PADWAN_BASE_URL and PADWAN_API_KEY instead and every model routes
through it (gateway mode).
import asyncio
from padwan_ai import LLMClient
async def main() -> None:
async with LLMClient(model="gpt-5.5") as client:
response, usage = await client.complete_chat(
[{"role": "user", "content": "Hello!"}]
)
print(response["content"])
asyncio.run(main())
The examples below skip the asyncio.run(main()) wrapper; paste them into python -m asyncio or a notebook, or wrap
them the same way.
Streaming
from padwan_ai import ConversationState, LLMClient
state = ConversationState(system="You are a concise assistant.")
state.add_user_message("What's Python?")
async with LLMClient(model="gemini-3.5-flash") as client:
chunks: list[str] = []
async for text in client.stream_chat(state.messages):
print(text, end="", flush=True)
chunks.append(text)
state.add_assistant_message("".join(chunks))
Agent with tools
AgentSession runs the tool loop: call the model, dispatch tool calls, feed results back, repeat until a final answer. Tools come from typed Python functions or from MCP servers.
@tool validates plain types out of the box. Constraints and Struct/BaseModel types use msgspec or pydantic;
with both installed, pick one with @tool(validator="msgspec") or PADWAN_TOOL_VALIDATOR=msgspec.
from padwan_ai import AgentSession, LLMClient, McpStdio
from padwan_ai.tools import tool
@tool
async def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
async with AgentSession(
client=LLMClient(model="claude-sonnet-5"),
mcp_tools=[add, McpStdio(command="uvx", args=["mcp-server-time"])],
system="Use tools when helpful.",
) as session:
print(await session.send("What is 2 + 3, and what time is it in Paris?"))
Typed final answers (AgentOutput), approval hooks, parallel tool execution and snapshot persistence are covered in the agents guide.
One-shot from the shell
uvx padwan-ai "Hello!" -m gpt-5.4-mini
For an interactive chat TUI use padwan-cli.
Providers
| Provider | Chat + streaming | Batch | Realtime voice | Transcription | TTS | Embeddings |
|---|---|---|---|---|---|---|
| OpenAI | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Gemini | ✅ | ✅ | ✅ | ➖ | ✅ | ✅ |
| Anthropic | ✅ | ❌ | ➖ | ➖ | ➖ | ➖ |
| Mistral | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ |
| Grok | ✅ | ✅ | ✅ | ➖ | ❌ | ➖ |
| Voyage AI | ➖ | ➖ | ➖ | ➖ | ➖ | ✅ |
| ElevenLabs (experimental) | ➖ | ➖ | ✅ | ✅ | ✅ | ➖ |
| Gradium (experimental) | ➖ | ➖ | ✅ | ✅ | ✅ | ➖ |
OpenAI-compatible (base_url=) |
✅ | depends on the server | depends on the server | depends on the server | ❌ | depends on the server |
- ❌ = the provider offers it, not implemented yet.
- ➖ = the provider has no such API.
- Realtime: Gradium's is speech-to-speech translation, not a voice-agent session; ElevenLabs and Gradium also stream TTS and STT over WebSocket.
Thinking tokens stream separately through an on_thought callback on every client that exposes them. Per-provider details, multimodal input (images, audio, files) and embeddings: docs/clients, docs/multimodal.md.
TypeSafe (JEV, experimental) structured evaluations (Noul, Choice, Score questions) use the standalone TypeSafeClient.
More
- MCP: streamable-HTTP and stdio transports, usable standalone or inside an agent. docs/mcp.md
- Realtime voice:
RealtimeClientspeech-to-speech over WebSocket for OpenAI, Gemini Live and Grok Voice. docs/clients/openai.md - Text-to-speech:
GeminiClient.generate_speechfor Gemini TTS models, single voice or scripted two-speaker dialogue. docs/clients/gemini.md - Observability: opt-in OpenTelemetry GenAI spans and metrics with
otel.instrument(), or a one-call Langfuse adapter. Ships a Grafana dashboard. docs/observability.md - Gateway mode: route every model through one OpenAI-compatible endpoint with
PADWAN_BASE_URLandPADWAN_API_KEY. docs/clients/openai-compatible.md - Testing agents:
padwan_ai.testing.ScriptedClientreplays scripted responses, no API key needed. docs/agents.md
Development
uv sync --all-extras --all-groups
just ci # ruff + pyright + pytest
just e2e # live provider tests, keys from .env (see env.template)
just e2e --full # same, plus a local vLLM server (Docker + NVIDIA GPU)
just docs # serve the docs site locally
Metadata
Release files for padwan-ai 0.19.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| padwan_ai-0.19.0.tar.gz | 138.4 kB | Without provenance | Details for padwan_ai-0.19.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| padwan_ai-0.19.0-py3-none-any.whl | Python 3 | none | any | Details for padwan_ai-0.19.0-py3-none-any.whl |
Total release size: 303.3 kB
Release files / padwan_ai-0.19.0.tar.gz
| Download URL | padwan_ai-0.19.0.tar.gz |
|---|---|
| Size | 138.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
545b34e8be4376edc29e181dfac302176cb8baf738df8c2648b4b1e1f4752ab1
|
|
BLAKE2b-256 checksum How to use checksums |
fb5dd56d27d8e40129fbc5c691ace7596184db9d21fecec8149bdc66eec0a0d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / padwan_ai-0.19.0-py3-none-any.whl
| Download URL | padwan_ai-0.19.0-py3-none-any.whl |
|---|---|
| Size | 164.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85e7de5b0b489f911ae6f060e3c05c5a146e06ee7ab44ec0653155a62d43423b
|
|
BLAKE2b-256 checksum How to use checksums |
8771b074133c57099858fdb06e8e1aca7c3e1149a166ae7bb9e095156c0f1430
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for padwan-ai 0.19.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.