How it fits together
Three separately installable packages with a strict, one-way dependency graph. Each one has a single job, and none of them blur into the next.
The dependency graph
PyWrapAI imports nothing from the other two. Adding a dependency in the other direction would force every user of the simple LLM-calling library to install the full stack.
What each library owns
PyWrapAI
Knows: LLM providers, tokens, cost, caching, retries, tool wire format, embeddings.
Doesn't know: Conversation structure, history, system prompts, databases, RAG.
PyWrapAI-Graph
Knows: Message order, prompt files, history injection, tool execution, RAG, the agent loop.
Doesn't know: Databases, user identities, session IDs, analytics.
PyWrapAI-Monitor
Knows: User identities, session IDs, databases, analytics queries.
Doesn't know: LLM provider details, API keys, token pricing calculations.
Runtime message flow
Every call assembles the same shape, regardless of which layers are involved:
Only the original user text is ever persisted to history — injected RAG context is dropped before saving, so follow-up turns always retrieve fresh context instead of stale chunks.
Infrastructure — one file, then three backends
SQLite
Zero external infrastructure. One file. Strong enough to demo end-to-end and run a real single-server deployment.
PostgreSQL / MySQL
Built in, not planned. Same BaseStore interface, connection pooling, portable SQL — swap the connection string, nothing else changes.
Design philosophy
One library, one job
No feature ever belongs to two libraries. The boundaries never blur.
No magic
Every behavior is explicit and visible in the calling code.
Lazy imports
Provider SDKs load only when used. Importing PyWrapAI with none installed never fails.
Portable SQL
ON CONFLICT ... DO UPDATE SET everywhere — a connection-string change moves SQLite to Postgres.
Production first
Built for thousands of concurrent users — pooling, async writes, isolated errors from day one.
Structured logging
A logging.getLogger per library — pywrapai.llm, .agent, .monitor — wired into your own log pipeline.