Skip to main content
Glama
Praharsh-Projects

mobility-operations-agent-platform

README.md
# Mobility Operations Agent Platform

Mobility Operations Agent Platform is a Python service for grounded analysis over synthetic electric-taxi operations data. It combines an LLM tool-calling loop, policy retrieval, structured warehouse tools, workflow guardrails, evaluation gates, MCP exposure, and a local Spark SQL data pipeline.

The repository focuses on engineering boundaries that matter when an AI feature can influence operations: models do not receive arbitrary database access, retrieved policy text is cited, personal-data requests are blocked, tool calls are traced, and workflow writes require explicit human approval.

No DRIVR affiliation, real taxi data, production deployment, or autonomous operational action is claimed.

## What the project demonstrates

- a multi-step agent loop with function calling and an Ollama adapter tested against `qwen2.5:7b-instruct`
- retrieval-augmented generation using a versioned mobility-policy corpus and BM25 ranking
- allowlisted tools for aggregated trip metrics, charging risk, policy retrieval, and draft case creation
- input, output, SQL, personal-data, prompt-injection, and side-effect guardrails
- FastAPI endpoints and an official MCP Python SDK server over the same service functions
- a DuckDB analytical warehouse seeded with deterministic synthetic trips and charging sessions
- a local PySpark pipeline that validates trip data and writes silver and gold Parquet datasets
- deterministic regression evaluations for tool choice, retrieval, approval boundaries, and refusals
- unit, integration, API, MCP, Spark, lint, Docker, and GitHub Actions checks

## Architecture

```mermaid
flowchart LR
  U[Operations question] --> G[Input guardrails]
  G --> R[BM25 policy retrieval]
  R --> A[Agent loop]
  A --> L[Ollama or deterministic model]
  L --> T{Allowlisted tool call}
  T --> W[DuckDB warehouse]
  T --> P[Policy index]
  T --> C[Human-approved draft case]
  W --> A
  P --> A
  C --> A
  A --> O[Grounded answer and tool trace]
  M[MCP clients] --> T
  F[FastAPI clients] --> A
  S[Spark SQL pipeline] --> D[Silver and gold Parquet]
```

The agent never executes model-generated SQL. Tool arguments are validated with Pydantic and compiled into fixed, parameterised analytical queries. See [docs/architecture.md](docs/architecture.md) for the request and data flows.

## Quick start

Prerequisites:

- Python 3.11 or 3.12
- `uv`
- Java 17 for the optional local Spark pipeline
- Ollama with `qwen2.5:7b-instruct` for the live LLM path

Install and seed the deterministic local profile:

```bash
uv sync --extra dev --extra spark
uv run mobility-ai seed --rows 10000
uv run mobility-ai profile
```

Ask through the reproducible deterministic orchestration model:

```bash
uv run mobility-ai ask "What is the average pickup wait by city?"
```

Run the same agent loop with a local LLM:

```bash
ollama pull qwen2.5:7b-instruct
uv run mobility-ai ask --provider ollama "Which depot-day has the highest charging failure rate?"
```

The deterministic provider exists for repeatable tests and CI. It is not presented as an LLM. The live smoke report is produced separately with the Ollama provider.

## FastAPI

Start the API:

```bash
uv run uvicorn mobility_ai.api:app --host 0.0.0.0 --port 8000
```

Then inspect the service and ask a question:

```bash
curl http://127.0.0.1:8000/health
curl -X POST http://127.0.0.1:8000/v1/chat \
  -H 'content-type: application/json' \
  -d '{"question":"What threshold applies to accessible-trip pickup waits?"}'
```

API details are documented in [docs/api.md](docs/api.md).

## MCP server

The MCP server uses `mcp.server.fastmcp.FastMCP` from the official Python SDK and exposes aggregated metric, charging-risk, and policy-retrieval tools:

```bash
uv run mobility-ai-mcp
```

It defaults to stdio so an MCP client controls the transport lifecycle. The MCP tools call the same warehouse and retrieval functions used by the FastAPI agent.

## Spark SQL pipeline

Export the seeded warehouse and build local silver/gold Parquet tables:

```bash
uv run mobility-ai export-spark-source --destination data/runtime/trips.csv
uv run mobility-ai spark-pipeline \
  --source data/runtime/trips.csv \
  --output data/runtime/lakehouse
```

The pipeline runs Spark locally, not on Databricks or a production cluster. It validates required fields and non-negative measures, partitions the silver table by city, and writes daily city metrics to the gold layer.

## Evaluation and tests

Run the reproducible quality gates:

```bash
uv run ruff check .
uv run pytest -m "not spark and not live_llm" \
  --cov=mobility_ai --cov-report=term-missing --cov-fail-under=85
uv run pytest -m spark
uv run mobility-ai eval --cases evals/cases.json --report-dir reports
```

Run the live local-model smoke scenarios:

```bash
uv run python scripts/live_ollama_smoke.py
```

The deterministic evaluation set covers metric tools, policy retrieval, tool chaining, human approval, prompt injection, personal-data requests, direct side effects, and arbitrary-SQL requests. See [docs/evaluation.md](docs/evaluation.md) and the generated reports under `reports/`.

## Repository layout

```text
src/mobility_ai/
  agent.py           bounded tool-calling loop and RAG context
  api.py             FastAPI surface
  evaluation.py      regression evaluation runner and reports
  guardrails.py      prompt, personal-data, and side-effect policies
  llm.py             deterministic and Ollama providers
  mcp_server.py      official MCP SDK tools
  retrieval.py       BM25 policy index
  spark_pipeline.py  local silver/gold Spark SQL pipeline
  tools.py           schemas, validation, and tool allowlist
  warehouse.py       DuckDB schema, seed data, and analytical queries
data/policies/       versioned synthetic operating policies
evals/               regression cases
tests/               unit and integration tests
```

## Limitations

- All trip, charging, policy, and workflow data are synthetic.
- The repository has no connection to DRIVR systems and does not model their internal architecture.
- Ollama verification is a local model smoke test, not a hosted production LLM deployment.
- Spark runs in local mode and writes Parquet; no Databricks workspace or distributed cluster is claimed.
- DuckDB is appropriate for this reproducible portfolio scope, not a substitute for a production warehouse governance model.
- Draft operations cases are the only write workflow and require explicit human approval.

See [docs/limitations.md](docs/limitations.md) for the complete evidence boundary.

TDQS

B3.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct domain area: charging risk, mobility metrics, and policy retrieval. No overlap or ambiguity exists between their purposes.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: 'query_' or 'retrieve_' followed by a specific noun. No mixing of conventions.

Tool Count5/5

Three tools is appropriate for a focused mobility operations domain. Each tool provides essential, non-redundant functionality without overwhelming the agent.

Completeness4/5

The tool set covers key informational needs (charging risk, metrics, policy) but lacks any action-oriented tools (e.g., update, create). This is acceptable for a query-focused agent, but operations may require more than just retrieval.

Maintenance

ActivityStale
ResponsivenessNo issues