1. Provision a working Agent (control-plane, one-time setup)
The canonical provisioning flow: Provider → Skill → Knowledge → Agent (with attachments) → verify. All control-plane calls (noexternal_user_id).
2. RAG pipeline: Knowledge base with search
Create a Knowledge base, embed a document, then run the same similarity search an attached Agent would use internally.upload_documents() is synchronous — it returns only once embedding finishes (expect it to
take longer for larger/more files; up to 10 files × 20MB, PDF/TXT/MD/JSON/CSV).
3. OAuth connection flow for an MCP server
For anauthType: "oauth" MCP: register it, then drive the owner- or user-mode browser flow. This
is the two-step pattern your backend and frontend cooperate on.
test_connection() populates the MCP’s tool/resource inventory:
4. Human-in-the-loop tool approval flow
An Agent configured with a sensitive tool pauses for approval. Drive the full approve/reject round-trip on the same Thread.thread_id must match the run that paused; resume’s shape must match the
interrupt’s kind (hitl → {"decisions": [...]}, clarification → {"answers": [...], "text": ...}).
5. Per-user conversation history with files
The runtime-plane pattern: one client per request, threads persisted explicitly, files attached to a conversation.threads.list() then shows each user’s Threads most-recently-active-first, with the Agent
populated as an object.
6. Error handling: resilient provisioning
Retry with an idempotency key after ambiguous failures, and handle the typed errors distinctly:7. Connection pooling at high request volume
Constructing a client is cheap — no connection happens at construction time — so build a fresh, per-request instance scoped to whoever is making the request (every recipe above does exactly that). But if you don’t share anything, each instance opens its ownhttpx connection pool, so no
TCP/TLS connection is ever reused across requests. At high volume, build one
httpx.Client/httpx.AsyncClient at app startup and pass it to every per-request client via
http_client=:
async with on their own client — closing one of
those never closes a client you passed in via http_client=; only a client the SDK created for
you gets closed. Close shared_http_client yourself, once, at app shutdown.
8. Flask
No special handling — construct the client once at module scope and use it in your view functions.9. FastAPI
Construct the client per-request via aDepends() provider so it plugs into FastAPI’s own
dependency-injection system — the SDK itself needs no FastAPI-specific support, and this uses the
async client since FastAPI route handlers are async def. Shares one httpx.AsyncClient across
every request (see Connection pooling above) since
a real API is likely to see meaningful request volume.
10. Django
Wire a module-level singleton, same idea as Flask — Django views are sync by default, so the syncPersonaClient is the natural fit.
PERSONA_CREDENTIAL in your environment / secrets manager and read it into settings.py
(os.environ["PERSONA_CREDENTIAL"]) — never commit it, and never expose it via a template context
processor a browser can read.