One shared service layer is exposed 3 ways: FastAPI, a Streamlit UI, and a terminal client, supporting PDF, TXT, and Markdown ingestion with local sentence-transformer embeddings. Retrieval, ingestion, chart, and memory tests run without any LLM call; the full agent-loop test skips gracefully when no provider is configured.