Lightweight async client for OpenAI, Gemini, Mistral, Grok, Anthropic, ElevenLabs (experimental), Gradium (experimental), TypeSafe (JEV, experimental), and any OpenAI-compatible API.
Why #
Most LLM client libraries pull in a stack of dependencies and lock you into a single provider's SDK. Padwan AI takes a different approach:
- One dependency βniquests , nothing else. No provider SDKs: Padwan talks to each API directly.
- TypedDict-only β all request/response types are plain
TypedDicts, no validation framework required. No runtime cost, full editor support. - Multi-provider, extensible β supports the major providers (OpenAI, Gemini, Mistral, Grok, Anthropic) with a shared base class that makes adding new ones straightforward.
Features #
- Unified interface - Single API for multiple LLM providers
- Async-first - Built on async/await for high performance
- HTTP/2 and HTTP/3 - Automatic protocol negotiation vianiquests
- Fully typed - Complete type hints with Python 3.13+ generics
- Streaming support - Real-time token streaming for all providers
- Conversation management - Built-in conversation history handling
- Agentic loop -
AgentSessiondrives multi-turn conversations with tool dispatch, parallel execution, approval hooks, and snapshot persistence - MCP support - Streamable HTTP and stdio transports forModel Context Protocol tool servers
- Thinking models - Stream Gemini, Claude, Mistral, Grok and vLLM thought tokens separately via an
on_thoughtcallback - Realtime voice - Speech-to-speech WebSocket sessions (OpenAI Realtime, Gemini Live, Grok Voice) via
RealtimeClient - Text-to-speech - Single and two-speaker Gemini TTS via
GeminiClient.generate_speech(details ), ElevenLabs and Gradium TTS (REST, streaming and WebSocket), transcription and speech-to-speech, plus ElevenLabs sound effects and music, viaElevenLabsClientandGradiumClient
Supported Providers #
| Provider | Chat | Streaming | Batch | Realtime | Transcription | TTS | Embeddings |
|---|---|---|---|---|---|---|---|
| OpenAI | β | β | β | β | β | β | β |
| Gemini | β | β | β | β | β | β | β |
| Mistral | β | β | β | β | β | β | β |
| Grok | β | β | β | β | β | β | β |
| Anthropic | β | β | β | β | β | β | β |
| Voyage AI | β | β | β | β | β | β | β |
| ElevenLabs (experimental) | β | β | β | β | β | β | β |
| Gradium (experimental) | β | β | β | β | β | β | β |
| OpenAI-Compatible | β | β | β | β | β | β | β |
- β = the provider offers it, Padwan does not implement it yet.
- β = the provider has no such API (Gemini transcribes through chat audio input; Anthropic recommends Voyage AI for embeddings).
- β = depends on the endpoint: the request is sent in OpenAI's wire format; support is up to the server.
- Realtime: Gradium's is speech-to-speech translation, not a voice-agent session; ElevenLabs and Gradium also stream TTS and STT over WebSocket.
Quick Example #
export OPENAI_API_KEY="sk-..."
uvx padwan-ai "Hello!" -m gpt-5.4-mini
python
from padwan_ai import LLMClient
async with LLMClient(model="gpt-5.5") as client:
response, usage = await client.complete_chat(
[{"role": "user", "content": "Hello!"}]
)
print(response["content"])
Installation #
pip install padwan-ai
Or with uv:
uv add padwan-ai
Agentic loop #
AgentSession wraps a conversation with the loop that calls the LLM, dispatches any tool calls, feeds the results back,
and repeats until the model produces a plain text answer.
It accepts individual McpTool instances and whole McpTransport servers in the same list, transports are entered as part of the session lifecycle:
from padwan_ai import AgentSession, LLMClient, McpStdio
async with AgentSession(
client=LLMClient(model="gpt-5.5"),
mcp_tools=[McpStdio(command="uvx", args=["weather-mcp"])],
system="You have access to weather tools.",
) as session:
text = await session.send("What is the weather in Paris?")
See the Agents page for approval hooks, parallel execution, and snapshot persistence.
MCP (Model Context Protocol) #
Connect to MCP tool servers over streamable HTTP or stdio:
from padwan_ai import McpStreamable, McpStdio
async with McpStreamable(url="https://mcp.example.com/mcp", token="sk-...") as mcp:
result = await mcp.tools[0].handler({"query": "test"})
See the MCP page for architecture diagrams, the dual-channel design of McpStreamable, the stdio reader model, and the reconnection flow.
CLI / TUI #
The interactive CLI/TUI is available as a separate package: padwan-cli.
uvx padwan-cli "Explain Python decorators" -m gemini-3.8-flash
uvx padwan-cli chat -m gpt-5.5