DataOps Incident Copilot is a local AI-assisted incident investigation application for analyzing KPI anomalies. It combines deterministic data diagnostics with an LLM-based investigator, then applies rule-based classification so the final incident type is grounded in collected evidence.
The project runs locally with DuckDB, Ollama, Qwen3, FastAPI, and Streamlit.
Given a question such as:
Why did completed orders decrease yesterday?
the application:
- Compares completed-order metrics.
- Checks data freshness and required-field completeness.
- Passes deterministic evidence to the investigator Agent.
- Produces a structured root-cause report.
- Applies deterministic classification precedence.
- Stores the investigation lifecycle and result history.
- Displays the result through the API or Streamlit dashboard.
Supported incident classifications include:
business_declineincomplete_datadata_quality_issuestale_datapipeline_failureunknown
- Local LLM execution through Ollama and Qwen3
- OpenAI Agents SDK orchestration
- Deterministic metric and data-quality diagnostics
- Structured Pydantic root-cause reports
- Rule-based incident classification
- Read-only SQL validation with
sqlglot - Single-statement SQL enforcement
- SQL result limiting and truncation metadata
- Investigation history persisted in DuckDB
- FastAPI service with generated API documentation
- Streamlit dashboard with report history and JSON export
- Unit and integration test coverage
- Standard Python logging for investigation and SQL lifecycles
flowchart TD
U[User Question] --> API[FastAPI or Streamlit]
API --> S[Investigation Service]
S --> M[Metric Diagnostics]
S --> Q[Data Quality Diagnostics]
M --> C[Investigation Context]
Q --> C
C --> A[Investigator Agent]
A --> L[Ollama / Qwen3]
A --> R[Structured RootCauseReport]
R --> D[Deterministic Classifier]
D --> H[Investigation History]
D --> O[API or Dashboard Response]
M --> DB[(DuckDB)]
Q --> DB
H --> HDB[(History DuckDB)]
The LLM creates the explanatory report, while deterministic diagnostics retain priority when classifying known data conditions.
Classification precedence:
- Required-field data-quality issue
- Stale or missing data
- Incomplete current-period data
- Confirmed business decline
- Unknown
- Python
- FastAPI
- Streamlit
- DuckDB
- OpenAI Agents SDK
- Ollama
- Qwen3
- Pydantic
- sqlglot
- pytest
app/
├── agents/ # Investigator Agent configuration
├── api/ # API schemas and routes
├── models/ # Pydantic domain models
├── prompts/ # Investigator system prompt
├── repositories/ # Investigation-history persistence
├── services/ # Investigation orchestration and classification
├── tools/ # SQL, metric, schema, and quality diagnostics
├── ui/ # Streamlit application
├── config.py # Environment-based settings
└── main.py # FastAPI application
data/ # DuckDB and local analytical datasets
docs/ # Supporting documentation
scripts/ # Data generation and local utility scripts
sql/ # Investigation SQL examples
tests/ # Unit, API, UI, and integration tests
- Python 3.12 or newer
- Ollama
- A local Qwen3 model
- PowerShell, Bash, or another terminal
The project has been tested with Python 3.14.
PowerShell:
python -m venv .ai
.ai\Scripts\Activate.ps1macOS or Linux:
python -m venv .ai
source .ai/bin/activateInstall the packages used by the application:
python -m pip install fastapi uvicorn streamlit duckdb openai-agents sqlglot pydantic pytest pytest-asyncioCopy the example configuration:
PowerShell:
Copy-Item .env.example .envmacOS or Linux:
cp .env.example .envDefault configuration:
DATAOPS_DATABASE_PATH=data/dataops.duckdb
DATAOPS_HISTORY_DATABASE_PATH=data/investigation_history.duckdb
OLLAMA_BASE_URL=http://localhost:11434/v1
OLLAMA_MODEL=qwen3
AGENT_TIMEOUT_SECONDS=120
AGENT_MAX_RETRIES=2
AGENT_TEMPERATURE=0
RECENT_INVESTIGATION_LIMIT=20
DATA_FRESHNESS_THRESHOLD_HOURS=24ollama pull qwen3Confirm that Ollama is running before starting an investigation.
The repository includes data generation and database initialization scripts:
python scripts/generate_data.py
python scripts/initialize_database.pypython -m uvicorn app.main:app --reloadOpen:
- Health check:
http://127.0.0.1:8000/health - Swagger UI:
http://127.0.0.1:8000/docs - OpenAPI schema:
http://127.0.0.1:8000/openapi.json
Example health response:
{
"status": "ok",
"service": "dataops-incident-copilot"
}Investigation requests use a natural-language question between 5 and 500 characters. The generated Swagger UI shows the available investigation endpoint and its complete request and response schemas.
python -m streamlit run app/ui/streamlit_app.pyThe dashboard provides:
- Natural-language investigation input
- Incident type, confidence, and human-review status
- Root-cause summary
- Evidence and recommendations
- Raw structured report
- JSON report download
- Latest-report session state
Run the full suite:
python -m pytest -vRun only tests that do not require the local model:
python -m pytest -m "not integration" -vRun integration tests after Ollama and Qwen3 are available:
python -m pytest -m integration -vFocused regression suites:
python -m pytest tests/test_sql_tool.py -v
python -m pytest tests/test_incident_classifier.py -v
python -m pytest tests/test_investigation_service.py -v
python -m pytest tests/test_data_quality_tool.py -vAgent-generated SQL is handled as read-only analytical SQL.
Current safeguards include:
- DuckDB parsing through
sqlglot - Exactly one SQL statement
- SELECT-style query enforcement
- Explicit blocking of write and command expressions
- Validation before opening a database connection
- A maximum of 1,000 returned rows
- Truncation metadata for larger result sets
- Read-only database connections
This is an AST-validated read-only execution layer, not a complete operating-system-level SQL sandbox.
Investigations return a structured report containing:
{
"summary": "Concise investigation summary",
"incident_type": "incomplete_data",
"root_cause": "Evidence-supported root cause",
"confidence": 0.85,
"evidence": [
{
"source": "diagnostic source",
"finding": "Specific factual finding"
}
],
"recommendations": [
"Recommended next action"
],
"requires_human_review": false
}Metric and quality diagnostics run before the LLM. Their results are added to InvestigationContext, giving the Agent concrete evidence instead of relying only on the user question.
The Agent provides a structured report, but the incident classifier can override the incident type when deterministic evidence identifies stale data, incomplete data, or a required-field issue.
The analytical database and language model run locally. This keeps the demonstration self-contained and avoids external API cost.
Integration tests patch changing diagnostic inputs where necessary while retaining the real Agent execution. This prevents test outcomes from changing solely because the local dataset has aged.
- The analytical scope is currently centered on the included order and pipeline datasets.
- Ollama must be running for Agent-backed investigations.
- Results depend on the selected local model and available evidence.
- SQL validation does not provide a complete file-system or process sandbox.
- The application does not include authentication or multi-user authorization.
Add the license that matches how you want others to use this portfolio project.