How ohadlivay/db-whisperer works
1. What this repo is
- DB Whisperer is a Python + Streamlit application for interactive database exploration.
- Its core idea is an LLM-assisted workflow: the user asks questions in the UI, and the app routes them through query-generation, ambiguity-resolution, and data-loading services.
2. Top-level entry point
- app.py is the deployable entry point used by Streamlit.
- The main runtime boundary is: browser UI → Streamlit app → package code under src/db_whisperer.
3. Presentation layer
- src/db_whisperer/gui/app.py contains the Streamlit UI logic.
- style.css and changelog.json are UI assets, not core business logic.
- This layer is responsible for session interaction, API key collection, and displaying results/errors.
4. Application orchestration layer
- src/db_whisperer/application/service.py is the coordination layer.
- It likely acts as the controller that decides which subsystem to invoke based on user intent: query a dataset, resolve ambiguity, or perform ETL-related preparation.
- This is the main internal boundary between the UI and the domain-specific services.
5. Querying subsystem
- src/db_whisperer/querier/ is the path for “ask a question, get SQL/data back.”
- It includes:
- prompt_builder.py for constructing model prompts,
- openrouter_client.py for LLM calls,
- sql_validator.py for checking generated SQL,
- service.py for orchestration.
- Architecturally, this is the path that turns natural language into validated database queries.
6. Ambiguity-resolution subsystem
- src/db_whisperer/ambiguity/ handles cases where the user’s request is unclear or underspecified.
- It has its own prompt_builder.py, openrouter_client.py, and service.py, which suggests a separate LLM interaction flow focused on clarification rather than query generation.
- This is a distinct guardrail layer before the app commits to an SQL answer.
7. ETL / dataset preparation subsystem
- src/db_whisperer/etler/service.py handles data loading or transformation concerns.
- The repo ships with multiple datasets in data/, including:
- relational CSV tables,
- single CSV files,
- a MIMIC-III clinical database demo.
- This indicates the app supports prepared datasets and likely uses an ETL step to make them queryable.
8. External service boundary
- The only clear external runtime dependency in the architecture is OpenRouter.
- Both the ambiguity and querying flows have dedicated OpenRouter clients, so LLM calls are isolated behind subsystem-specific adapters.
- The README says the API key is sent for the current session and not persisted, which matters for the trust boundary in the UI/session layer.
9. Shared contracts and cross-cutting concerns
- src/db_whisperer/contracts.py likely defines shared data structures/interfaces between services.
- src/db_whisperer/prompt_logging.py is a cross-cutting utility for recording prompts or model interactions, useful for traceability/debugging.
- These pieces sit below the orchestration layer and above the UI/transport layer.
10. Benchmarking and evaluation
- benchmark/run.py and benchmark/cases.json form a separate evaluation path from the interactive app.
- This suggests the repo can run repeatable test cases against the same core logic, independent of the Streamlit UI.
- For an architecture diagram, this is a sibling consumer of the service layer, not part of the main user flow.
11. Testing structure
- tests/ mirrors the package structure: ambiguity, application, etler, gui, and querier.
- There are focused unit tests for prompt builders, OpenRouter clients, services, and UI behavior, plus at least one relational integration test.
- That mirrors the repo’s modular architecture and confirms the subsystem boundaries.
12. How to draw the main flow
- The primary diagram should show:
- User/browser
- Streamlit GUI
- Application service
- branching into Querier, Ambiguity, and ETL
- with OpenRouter as the external LLM service
- and local dataset files as the data source backing the querying/ETL path.
- The benchmark runner should be shown separately as an offline evaluation consumer of the same core services.
Main entry points: application/service.py Application service · querier/service.py Querier service · ambiguity/service.py Ambiguity service · etler/service.py ETL service
Components 18
Interface
User-facing Streamlit entry and UI assets
- Browser · Human interacts with the app through a web browser
- Streamlit entry · Deployable Streamlit entry module
app.py - GUI app · Streamlit UI logic, session handling, and result rendering
src/db_whisperer/gui/app.py
Core
Application orchestration and domain services
- Application service · Coordinates intent routing across querying, ambiguity resolution, and ETL
src/db_whisperer/application/service.py - Contracts · Shared data structures and interfaces between subsystems
src/db_whisperer/contracts.py - Prompt logging · Records prompts or model interactions for traceability
src/db_whisperer/prompt_logging.py - Querier service · Turns natural language requests into validated database queries
src/db_whisperer/querier/service.py - Prompt builder · Builds the query-generation prompts
src/db_whisperer/querier/prompt_builder.py - SQL validator · Checks generated SQL before execution or return
src/db_whisperer/querier/sql_validator.py - Ambiguity service · Handles underspecified requests and drives clarification
src/db_whisperer/ambiguity/service.py - Ambiguity prompts · Builds clarification prompts for ambiguous user requests
src/db_whisperer/ambiguity/prompt_builder.py - ETL service · Prepares or loads datasets for querying
src/db_whisperer/etler/service.py
Evaluation
Offline benchmark runner using the core services
- Benchmark runner · Runs repeatable benchmark cases against core logic
benchmark/run.py - Benchmark cases · Serialized benchmark scenarios and expected interactions
benchmark/cases.json
Data
Prepared datasets and database assets used by ETL and querying
- Relational data · Prepared CSV tables for relational querying and ETL
data/relational csv - Single CSVs · Standalone CSV inputs used as source data
data/single csv - MIMIC demo · Demo clinical database dump and schema files
data/mimic-iii-clinical-database-demo-1.4-20260615T211207Z-3-001/mimic-iii-clinical-database-demo-1.4
External
Third-party runtime boundary
- OpenRouter · External LLM API used by querying and ambiguity flows
Connections 20
- Browser → Streamlit entry: opens · Browser loads the Streamlit entrypoint
- Streamlit entry → GUI app: renders · Entry module hands off to the GUI layer
- GUI app → Application service: submits intent · UI forwards user actions and session context
- Application service → Querier service: query path · Routes question-answering requests to the querier
- Application service → Ambiguity service: clarify path · Routes underspecified requests to ambiguity handling
- Application service → ETL service: prepare data · Invokes ETL/data-loading preparation when needed
- Querier service → Prompt builder: builds prompt · Creates model prompt for SQL generation
- Querier service → SQL validator: validates SQL · Checks generated SQL before use
- Querier service → OpenRouter: calls model · Uses OpenRouter for query generation
- Ambiguity service → Ambiguity prompts: builds prompt · Creates clarification prompt for ambiguous requests
- Ambiguity service → OpenRouter: calls model · Uses OpenRouter for clarification turns
- ETL service → Relational data: loads · Uses prepared relational tables as queryable data
- ETL service → Single CSVs: loads · Uses standalone CSV sources for preparation
- ETL service → MIMIC demo: loads · Can prepare the clinical demo database assets
- GUI app → Prompt logging: logs prompts · UI-adjacent tracing and debugging support
- Querier service → Contracts: shares contracts · Uses common request/response structures
- Ambiguity service → Contracts: shares contracts · Uses common request/response structures
- Application service → Contracts: coordinates via · Orchestration layer relies on shared contracts
- Benchmark runner → Benchmark cases: consumes · Benchmark cases drive repeatable runs
- Benchmark runner → Application service: exercises · Offline runner uses the same core orchestration