{
  "markdown": "# OpsFlow\n\n**AI-verified operations console for IT application maintenance.**\n\nA supervised team of AI agents that turns patching, performance tuning, and incident resolution\ninto one repeatable, auditable workflow — from \"an alert (or voice note, or screenshot) came in\"\nto \"ticket closed, CMDB updated, and a verified fix, not just an assumed one.\"\n\nBuilt for **TCS AI Fridays Season 2 — Regional Round**\n(*Problem statement: AI-Powered Multi-Agent Workflow Automation for IT Application Maintenance*).\n\n**🔗 Live demo:** [opsflowapp.onrender.com](https://opsflowapp.onrender.com)\n\nNo API key needed to try it — the login screen opens with an **Instant Demo** mode using\npre-generated output, plus options to bring your own key or use a shared free key. See\n[§8 Try it live](#8-try-it-live--testing-modes) below.\n\n> New to this repo? Read this file top to bottom once — it gets you from a fresh clone to a\n> running app. Everything else you might want is linked from [§7 Learn more](#7-learn-more) below.\n\n---\n\n## 1. What this actually is\n\n- A **FastAPI backend** running a 9-step supervised agent chain (Correlate → Enrich → Diagnose →\n  Plan → Gate → Approve → Execute → Verify → Sync → Knowledge) over three workflow types\n  (incident / patch / performance).\n- A **Next.js frontend** (\"the OpsFlow cockpit\") — a role-based ops console with a live alert\n  feed, an incident workspace, a full agent-trace viewer, and a floating chat assistant that\n  accepts text, voice, and screenshot uploads.\n- **No real third-party systems.** \"ServiceNow\" and \"Jira\" panels you'll see are FastAPI\n  simulators this project wrote itself.\n- **Multi-provider LLM architecture** (`backend/providers.py`): Google Gemini by default, OpenRouter\n  as a fallback, and the original TCS GenAI Lab gateway kept as a legacy/gated provider (only\n  reachable from the TCS network) — plus a local Ollama model for the PII/secrets scrubber and as\n  an offline fallback if the active provider fails mid-request. Which provider backs a given\n  session depends on the testing mode chosen at login (§8) — never a mix of vendors within one\n  session, and a visitor's own Bring-Your-Own-Key never touches the server.\n- **100% synthetic data** — generated with a fixed seed, provenance-tracked in `data/PROVENANCE.md`.\n\nFull architecture, data flow, demo script, and folder-by-folder guide: see [§7](#7-learn-more).\n\n---\n\n## 2. Prerequisites — exact versions that are known to work\n\n| Tool | Version | Notes |\n|---|---|---|\n| **Python** | 3.12.x (this project was built/tested on 3.12.8) | 3.11 likely works too; avoid 3.13 until you've confirmed `chromadb`/`langchain` compatibility yourself |\n| **Node.js** | **20.9 or newer** (20.x LTS or 22.x LTS recommended) | Next.js 16 refuses to install below this — you'll get an `EBADENGINE` error otherwise |\n| **npm** | ships with Node | On Windows PowerShell, use `npm.cmd`, not `npm` (see [Troubleshooting](#troubleshooting)) |\n| **Ollama** | any recent version | Must already have `llama-3.2-3b-it` and `gte-large` pulled — used for the PII scrubber and the offline fallback. Run `ollama list` to check; **do not download new models on an event/restricted network** |\n| **Git** | any recent version | Only needed if you're cloning rather than copying the folder |\n| **A TCS GenAI Lab gateway API key** | — | Issued per-event; without it the app still runs, but every LLM step will fall back to local Ollama (slower, and the scrubber-only model isn't a substitute for the reasoning/planning models) |\n\n**OS note:** this project was built and is documented for **Windows** (PowerShell). Mac/Linux\nshould work with the equivalent shell commands, but the corporate-proxy SSL workarounds baked\ninto `backend/config.py` are a no-op (not harmful) if you don't need them.\n\n---\n\n## 3. Get the code\n\n```powershell\ngit clone <this-repo-url> my-hackathon-app\ncd my-hackathon-app\n```\n(If you already have the folder — e.g. it was shared as a zip — just `cd` into it; skip cloning.)\n\n---\n\n## 4. Backend setup\n\n```powershell\ncd backend\n\n# 1. Create and activate a virtual environment\npython -m venv venv\nvenv\\Scripts\\activate\n\n# 2. Install dependencies (pinned versions — see backend/requirements.txt)\npip install -r requirements.txt\n\n# 3. Configure environment variables\ncopy .env.example .env\n# now open backend\\.env and fill in BASE_URL / API_KEY (your gateway credentials) —\n# see backend/.env.example for what every key means and a working default shape\n\n# 4. Build the SQLite database (only needed once, or after data/app.db is deleted)\npython db\\init_db.py\n\n# 5. Build the Chroma vector store (runbooks/postmortems/tickets — needs a working gateway\n#    connection, since it calls the real embedding model)\npython db\\load_chroma.py\n\n# 6. (Optional but recommended first time) confirm the gateway + Ollama + models all actually work\npython smoke_test.py\n\n# 7. Run the API server\nuvicorn main:app --reload --host 0.0.0.0 --port 8765\n```\n\nLeave this terminal running. You should see `Application startup complete.` and no errors.\nVerify it's alive: open **http://localhost:8765/health** in a browser — expect a `200 OK` JSON\nresponse.\n\n> **Port 8765, not 8000/8001.** Windows silently blocks binds to those ports on some machines\n> (Hyper-V/WSL reserved ranges) — see [Troubleshooting](#troubleshooting).\n\n### If steps 4/5 are already done for you\nIf `data/app.db` and `data/chroma_db/` already exist and look populated (e.g. you received this\nproject pre-built, not a fresh clone), you can skip steps 4-5 and go straight to step 7. Re-run\n`db/init_db.py`/`db/load_chroma.py` any time you want a clean, from-scratch database.\n\n---\n\n## 5. Frontend setup\n\nOpen a **second** terminal (leave the backend running in the first one):\n\n```powershell\ncd frontend\n\n# 1. Install dependencies\nnpm.cmd install\n\n# 2. Configure environment variables\ncopy .env.local.example .env.local\n# defaults to http://localhost:8765 — only change this if your backend runs on a different port\n\n# 3. Run the dev server\nnpm.cmd run dev\n```\n\nOpen **http://localhost:3000** — you should land on the OpsFlow login screen.\n\n---\n\n## 6. Log in and confirm it works\n\nThree demo accounts are seeded automatically by `db/init_db.py` (one per role):\n\n| Username | Password | Role |\n|---|---|---|\n| `alex.chen` | `OpsEngineer!123` | Ops Engineer |\n| `priya.sharma` | `Approver!123` | Approver |\n| `admin` | `Admin!123` | Admin |\n\nLog in as `admin` first — it can see every panel (Users, Config, Scenarios, Audit Log, Knowledge\nBase) in the sidebar, useful for verifying the whole stack came up correctly. You should see:\n- The **Overview** tab with real (non-zero, if any runs have happened) or zero-but-not-erroring\n  metric tiles.\n- The **Ops Board** tab showing a live-updating connection indicator (SSE feed from the backend).\n- The **Autonomy Ladder** tab listing runbooks (confirms both the DB and the seed data loaded).\n\nIf all three render without errors, the full stack is working end to end.\n\n### Try one real workflow run\nSidebar → **Scenarios** panel (Admin/Approver) → launch `SCEN-01` (a clean, auto-approved incident\nresolution). It should reach `verified_resolved` within roughly the time it takes DeepSeek R1 to\nrespond (can be 10-40+ seconds on a busy gateway — this is expected, not a hang). See the Scenario\nLauncher panel itself, or `.okf/demo-modes/pregenerate-script.md`, for the full scenario list and\nwhat each one demonstrates.\n\n---\n\n## 7. Learn more\n\nThis README gets you running. For everything else:\n\n| Doc | What's in it |\n|---|---|\n| [`.knowledge/PRD_INITIAL.md`](.knowledge/reference/PRD_INITIAL.md) | The frozen original product requirements this build satisfies (long — reference, not required reading) |\n| [`.knowledge/`](.knowledge/) | The build's own engineering log (architecture-as-built detail, decisions, phase-by-phase history) — useful if you're extending the code, not needed to just run it |\n| [`.okf/`](.okf/) | Portable Open Knowledge Format bundle — the same system knowledge as `.knowledge/`, distilled into one-concept-per-file markdown for readers without this repo's session history. Start at `.okf/index.md`. |\n\n---\n\n## 8. Try it live / testing modes\n\nThe login screen offers three ways to try OpsFlow — no account or key required just to look\naround:\n\n| Mode | What it needs | What it does |\n|---|---|---|\n| **Instant Demo** | Nothing | Replays 6 pre-generated scenario runs (`data/demo_outputs.json`, built by `scripts/pregenerate_demo_outputs.py`) plus a real, unmodified-pipeline PII-scrubbing sample — zero live model calls, always works. Ad-hoc chat, voice, and image intake are disabled with an inline explanation; the full agent-chain UI (Agent Trace, evidence, blast radius, approval flow) still renders from real (pre-captured) data. |\n| **Bring Your Own Key** | Your own key for Google Gemini, OpenAI, OpenRouter, xAI Grok, the legacy TCS gateway, or any custom OpenAI-compatible endpoint | Sent as request headers (`X-LLM-Provider`/`X-LLM-Api-Key`/`X-LLM-Model`), used only for that browser session, never written to disk or logged. The login screen validates the key/model against the real provider before letting you into the cockpit — a bad key surfaces the provider's real error inline instead of failing later. Voice intake is only available if the chosen provider supports transcription (OpenAI, TCS; for a custom endpoint this is actually checked live rather than guessed — see `providers.py`'s `probe_transcription_support()`). |\n| **Free Demo Key** | Nothing (uses a key the deployer configured) | Live diagnosis backed by a Gemini key set as a platform secret, with the same offline-Ollama-fallback resilience the app already has for gateway outages. |\n\nReal login still happens either way — role quick-fill buttons on the login screen fill in one of\nthe seeded demo accounts (§6 above) so you can prove sign-in works without hunting for credentials.\n\n**A note on free-tier limits** (found live-testing this): Gemini's free tier caps some models at a\nliteral 20 requests/day (`gemini-flash-latest`'s \"thinking\" alias) — `providers.py` deliberately\nroutes every Gemini role through `gemini-flash-lite-latest` instead, which doesn't hit that wall\nand doesn't truncate structured JSON output under a capped token budget the way the reasoning\nalias does. Embeddings have a separate, more generous per-minute quota; `orchestrator/retrieval.py`\nretries with a full-minute backoff on a 429 rather than failing the request.\n\n---\n\n## 9. Deploying your own copy\n\nOne platform, two free service types on [Render](https://render.com) — a Web Service for the\nbackend (needs a long-running process: SQLite + Chroma opened once and held across requests, plus\nan SSE stream) and a Static Site for the frontend (zero server-side routes, so it gets a strictly\nbetter free tier: always-warm, CDN-backed, no idle-sleep). `render.yaml` at the repo root defines\nboth as a Render Blueprint.\n\n1. Push this repo to your own GitHub account (public or private — Render's free tier works with\n   either).\n2. On Render: **New +** → **Blueprint**, connect the repo. Render reads `render.yaml` and proposes\n   both services (`opsflowapp-backend`, `opsflowapp`) — rename them in `render.yaml` first if you\n   want different names; Render silently appends a random suffix to whichever ones are already\n   taken by another account, which is exactly what happened on the first deploy of this project\n   (fixed 2026-08-15 by recreating both services directly via Render's API under names that turned\n   out to be free).\n3. Fill in the secrets it asks for before creating: `GEMINI_API_KEY` (required — backs both\n   embeddings and Free Demo Key mode; get one free at aistudio.google.com/apikey) and\n   `OPENROUTER_API_KEY` (optional — only needed if you want that as a working Free/BYOK fallback\n   option). `JWT_SECRET`/`A2A_SECRET` auto-generate; leave `FRONTEND_ORIGIN` and\n   `NEXT_PUBLIC_API_BASE_URL` blank for now — their real values aren't known until both services\n   exist.\n4. Once both are created, note their actual `*.onrender.com` URLs (Render appends a suffix if your\n   chosen name is taken by someone else). Set:\n   - The backend's `FRONTEND_ORIGIN` → the frontend's URL, then trigger a manual restart (no\n     rebuild needed — read from the environment at request time).\n   - The frontend's `NEXT_PUBLIC_API_BASE_URL` → the backend's URL, then trigger a manual\n     **deploy** (rebuild needed — Next.js bakes `NEXT_PUBLIC_*` values into the static bundle at\n     build time, per `output: \"export\"` in `next.config.mjs`).\n5. Visit the frontend's URL, confirm `/health` on the backend responds, and run one Instant Demo\n   scenario end to end before calling it done.\n\nThe backend's free tier sleeps after 15 minutes idle (~1 min cold-start on the next request) and\nhas no persistent disk — SQLite/Chroma rebuild fresh from the committed synthetic seed data on\nevery boot, so this is expected, not a bug (see `render.yaml`'s comments). The frontend never\nsleeps.\n\n---\n\n## Troubleshooting\n\nThe most common first-run issues, and their fixes:\n\n- **`pip install` fails with a `ResolutionImpossible` / numpy conflict** — you're likely on a\n  Python version where `langchain==0.3.7` and a newer `numpy` can't co-exist. Use Python 3.12 and\n  the exact `requirements.txt` as pinned; don't upgrade individual packages by hand.\n- **Backend won't bind / silently exits, no errors** — something is already listening on port\n  8765 from a previous run. Find and stop it (`netstat -ano | findstr :8765` on Windows, then\n  `taskkill /PID <pid> /F`), then restart `uvicorn`.\n- **`npm install` / `npm run dev` fails with a PowerShell script-execution error** — use `npm.cmd`\n  instead of `npm` in PowerShell.\n- **Frontend loads but every API call fails / CORS errors in the console** — check that\n  `frontend/.env.local`'s `NEXT_PUBLIC_API_BASE_URL` and `backend/.env`'s `FRONTEND_ORIGIN`\n  actually point at each other's real host/port.\n- **`uvicorn` crashes on `python-multipart`** — already pinned in `requirements.txt`; if you edited\n  it, this is why login and file-upload routes break.\n- **Diagnose/Plan steps take a long time or seem to hang** — DeepSeek R1 genuinely takes tens of\n  seconds on a busy gateway; this is expected latency on one step, not a bug. If the gateway is\n  fully unreachable, the app should still complete via the local Ollama fallback (slower).\n- **`ollama` fallback errors** — run `ollama list` and confirm `llama-3.2-3b-it` and `gte-large`\n  are present; if not, get them from whoever manages the lab machine rather than pulling new\n  models on a restricted network.\n\nFor anything not listed here, `.knowledge/errors-solved.md` has a longer, more detailed log of\nevery real error hit while building this project and exactly how it was fixed.\n\n---\n\n## A note on data & privacy\n\nEvery dataset in `data/` (alerts, tickets, CMDB, runbooks, postmortems) is synthetic — generated\nby this project's own scripts, never scraped or copied from a real system. Where the demo shows\n\"planted\" personal data or secrets (names, phone numbers, connection strings, API keys), it exists\nspecifically to prove the PII/secret scrubber works, and is tracked in\n`data/pii_ground_truth.json` for that purpose. See `.knowledge/domain-privacy.md` for the full\nrationale.\n",
  "bytes": 15279,
  "sha": "70ce55024fc7a5066fbcd027bcf592ddd9e177b445bf3783be47e9648cb3ca53",
  "repo_slug": "desairaj414/opsflow",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_desairaj414_opsflow_okf_index_md_e5cd2d94/readme"
}