Provider-agnostic AI library with tier-based routing and automatic fallback.
Project description
daz-agent-sdk
Your AI Swiss Army knife. One library that handles text, images, and speech — from any provider — without the hassle of writing boilerplate, managing API quirks, or worrying about what happens when a service goes down.
from daz_agent_sdk import agent
answer = await agent.ask("Explain quantum tunnelling in one paragraph")
print(answer.text)
That's genuinely all it takes. daz-agent-sdk figures out which model to use, makes the call, and hands you the answer. If something goes wrong — rate limits, outages, the usual — it quietly tries another provider and you never have to think about it.
Why You'll Love It
Most AI projects end up drowning in boilerplate: retry logic, provider-specific SDKs, response parsing, error handling, and hardcoded model names scattered across files. daz-agent-sdk replaces all of that with a single, consistent interface.
You describe what you need — a quick answer, a structured result, a long conversation, an image, some audio — and daz-agent-sdk handles the rest. Switch providers, change models, add fallbacks — all without touching your application code.
Installation
pip install daz-agent-sdk
For local development:
git clone https://github.com/darrenoakey/daz-agent-sdk
cd daz-agent-sdk
./run install
Test it immediately from the command line:
daz-agent-sdk ask "What's the capital of France?"
Getting Started
Everything lives on the agent object. Import it and you're ready:
from daz_agent_sdk import agent, Tier
No setup, no API key wrangling, no configuration required to get going. It picks sensible defaults automatically.
Features
Ask a Question
The most common thing you'll do. Ask something, get a text answer back.
answer = await agent.ask("What are three tips for better sleep?")
print(answer.text)
Choose Your Quality Level
Not every question needs the most powerful (and most expensive) model. Use tiers to match quality to the task:
| Tier | What You Get | Best For |
|---|---|---|
Tier.HIGH |
Best available model (this is the default) | Important work, creative projects |
Tier.MEDIUM |
Great quality, faster | Everyday tasks |
Tier.LOW |
Fast and economical | Summaries, simple classification |
Tier.FREE_FAST |
Local models, completely free | Bulk processing, drafts |
Tier.FREE_THINKING |
Local models with deeper reasoning | Complex analysis without cloud costs |
# Quick and cheap — great for processing lots of items
summary = await agent.ask("Summarise this article: ...", tier=Tier.LOW)
# Free, runs entirely on your machine
tag = await agent.ask("Tag this email as urgent/normal/low", tier=Tier.FREE_FAST)
Get Structured Data Back
Instead of parsing text responses yourself, describe the shape of the data you want using a Pydantic model and get clean, validated results back.
from pydantic import BaseModel
class Sentiment(BaseModel):
label: str # "positive", "negative", or "neutral"
confidence: float
result = await agent.ask(
"Classify the sentiment: 'I love this product!'",
schema=Sentiment,
tier=Tier.LOW,
)
print(result.parsed.label) # "positive"
print(result.parsed.confidence) # 0.95
No regex. No JSON parsing. No surprises. Works with any Pydantic model you define.
Have a Conversation
For tasks that take multiple back-and-forths, use a conversation. It remembers everything you've said.
async with agent.conversation("writing-helper") as chat:
outline = await chat.say("Write an outline for a thriller novel set in Tokyo")
chapter1 = await chat.say("Write chapter 1 based on that outline")
# Stream long responses so you see them arrive in real time
async for chunk in chat.stream("Now write chapter 2"):
print(chunk, end="", flush=True)
Conversations handle rate limits and provider hiccups transparently. If your provider goes down mid-conversation, daz-agent-sdk backs off, summarises what you've discussed so far, and seamlessly continues on another provider. Your code never knows the switch happened.
Fork a Conversation to Explore Alternatives
Working on something creative and want to explore two different directions without losing your place? Fork the conversation.
async with agent.conversation("brainstorm") as chat:
await chat.say("Give me a premise for a short story about a lighthouse keeper")
# Explore two different directions from the same starting point
spooky = chat.fork("horror-version")
funny = chat.fork("comedy-version")
await spooky.say("Develop this as a ghost story")
await funny.say("Develop this as a comedy")
Generate Images
Create images from text descriptions. Powered by Nano Banana 2 (via Gemini) by default.
result = await agent.image(
"A serene Japanese garden at dawn, soft mist over a koi pond",
width=1024,
height=1024,
output="garden.png",
)
print(result.path)
Need a transparent background? Just ask:
logo = await agent.image(
"A minimalist fox logo",
width=512,
height=512,
transparent=True,
output="logo.png",
)
Or use your local machine for generation:
result = await agent.image("Robot portrait", provider="mflux")
Install the extras you need:
pip install "daz-agent-sdk[transparent]" # Enables transparent background removal
pip install "daz-agent-sdk[mflux]" # Enables local image generation
Text-to-Speech
Turn any text into spoken audio with a choice of voices.
audio = await agent.speak(
"Welcome to today's episode. I'm your host, and we have a great show lined up.",
voice="gary",
output="intro.mp3",
)
print(audio.path) # Ready to play or share
Speech-to-Text
Transcribe audio files to text.
transcript = await agent.transcribe("interview.wav")
print(transcript)
See What's Available
Curious which models and providers are ready to use right now?
from daz_agent_sdk import agent, Tier, Capability
# Everything currently available
all_models = await agent.models()
for m in all_models:
print(f"{m.provider}: {m.display_name}")
# Just local models (no cloud required)
local = await agent.models(provider="ollama")
# What can do structured output at the highest quality?
best_structured = await agent.models(tier=Tier.HIGH, capability=Capability.STRUCTURED)
Using the Command Line
You don't need to write Python for quick tasks.
# Ask a question
daz-agent-sdk ask "What year was Python created?"
# Use a specific tier
daz-agent-sdk ask --tier low "Summarise this: ..."
# Generate an image
daz-agent-sdk image --prompt "A red fox in a snowy forest" --width 512 --height 512
# With transparent background
daz-agent-sdk image --prompt "Company logo" --width 256 --height 256 --transparent --output logo.png
# See what models are available
daz-agent-sdk models
Supported Providers
| Provider | What You Need |
|---|---|
| Claude (Anthropic) | API access or Claude Code authentication |
| Codex (OpenAI) | OpenAI API key |
| Gemini (Google) | Google AI API key |
| Ollama | Ollama running locally (ollama serve) |
Don't have all of them? No problem. daz-agent-sdk automatically detects which providers are available and skips the ones that aren't. Even a single provider works perfectly — you get fallback across whatever you have set up.
Configuration (Optional)
daz-agent-sdk works out of the box with no configuration at all. When you're ready to customise, create ~/.daz-agent-sdk/config.yaml:
# Which providers to try for each tier (first = preferred)
tiers:
high:
- claude:claude-opus-4-6
- gemini:gemini-2.5-pro
medium:
- claude:claude-sonnet-4-6
- gemini:gemini-2.5-flash
low:
- claude:claude-haiku-4-5-20251001
- ollama:qwen3-8b
free_fast:
- ollama:qwen3-8b
# Provider settings
providers:
ollama:
base_url: http://localhost:11434
gemini:
api_key_env: GEMINI_API_KEY
Each tier lists providers in order of preference. The first one that's available and responding gets used. Everything else is automatic.
Automatic Fallback: The Killer Feature
This is the thing that makes daz-agent-sdk genuinely different.
For single questions: Hit a rate limit? The next provider in your tier's list takes over immediately. No delay, no error in your code.
For conversations: Hits a rate limit? It tries waiting a bit first — rate limits often clear on their own. If it's still down after a while, it summarises your conversation so far and picks up seamlessly on another provider. You keep talking; it handles everything else.
Auth problems skip a provider entirely (it's not going to work anyway). Mistakes in your request raise an error right away so you can fix them. Every fallback event gets logged so you can see exactly what happened.
Everything Gets Logged
Every conversation is automatically saved to ~/.daz-agent-sdk/logs/. Each one gets its own folder containing:
- Everything that was said
- Which models were used and when
- Any fallbacks or provider switches
- How long things took
Useful for debugging, understanding costs, or just reviewing what happened. You don't have to do anything — it's always on.
Tips and Tricks
Start with zero configuration. The defaults are sensible. Get something working first, then customise if you need to.
Say Tier.LOW instead of a model name. If you hardcode ollama:qwen3-8b, you'll need to change every file if you switch. If you say Tier.LOW, you update the config once.
Reach for structured output early. Any time you're thinking "I'll parse the response with regex", use a Pydantic schema instead. It's more reliable, gives you typed data, and works across every provider.
Stream anything long. If a response might take a while — writing, analysis, explanations — use chat.stream(). Users see the words appearing in real time rather than staring at a blank screen.
Use FREE_FAST for bulk work. If you're processing hundreds or thousands of items, local models cost nothing and will never rate-limit you. Save the cloud credits for the tasks that actually need them.
Trust the fallback. When a provider goes down or rate-limits you, resist the urge to add your own retry logic. daz-agent-sdk already handles it — and handles it better than most hand-rolled solutions. Let it do its job.
Fork for creative exploration. Whenever you're working on something open-ended and want to try two different approaches, fork the conversation. You get two independent threads from the same starting point, without losing either.
Putting It All Together
Here's what a real multi-modal pipeline looks like with daz-agent-sdk:
from daz_agent_sdk import agent, Tier
async def create_podcast_episode(topic: str):
# Research and write the script (best quality)
script = await agent.ask(
f"Write a 5-minute podcast script about: {topic}",
tier=Tier.HIGH,
)
# Generate cover art
cover = await agent.image(
f"Podcast cover art for an episode about {topic}",
width=1024,
height=1024,
output=f"episodes/{topic}/cover.png",
)
# Narrate it
audio = await agent.speak(
script.text,
voice="gary",
output=f"episodes/{topic}/episode.mp3",
)
return {"script": script.text, "cover": cover.path, "audio": audio.path}
Script, art, and audio — three lines of meaningful code. That's the idea.
License
This project is licensed under CC BY-NC 4.0 - free to use and modify, but no commercial use without permission.
Project details
Release history Release notifications | RSS feed
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 daz_agent_sdk-0.2.12.tar.gz.
File metadata
- Download URL: daz_agent_sdk-0.2.12.tar.gz
- Upload date:
- Size: 65.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41b45da6955c328affd6fb770202c696e0a8d4989935e3dc0f61bdb6592d467f
|
|
| MD5 |
cc59f45fb7f52652d2da03b1a3a6d556
|
|
| BLAKE2b-256 |
9420bcc215a590786727cb638f57f14504cf08fbceae8087faa3d93f9de08832
|
File details
Details for the file daz_agent_sdk-0.2.12-py3-none-any.whl.
File metadata
- Download URL: daz_agent_sdk-0.2.12-py3-none-any.whl
- Upload date:
- Size: 80.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5bd7ad4530f3a88ac1de34e0b0f15fb076a6f38f3331bc089bf41509813d097
|
|
| MD5 |
d0cd5661db273a475d568940ac6a6e87
|
|
| BLAKE2b-256 |
fa514e5e981abed98f9bf047bb357cd3f369bb828590f759e08bddef84a1b6f1
|