py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
cd frontend
npm install
cd ..
python scripts/run_local.py
This starts all five services concurrently:
Press Ctrl+C in the terminal to cleanly terminate all 5 processes.
Run each command in its own terminal tab with the virtual environment activated:
# Terminal 1: Helpdesk Service
uvicorn services.helpdesk.app:app --port 8001 --reload
# Terminal 2: Operations Portal Service
uvicorn services.portal.app:app --port 8002 --reload
# Terminal 3: Agent API Service
uvicorn services.agent.app:app --port 8003 --reload
# Terminal 4: Autonomous Background Polling Loop
python -m services.agent.agent
# Terminal 5: Operations Web Console (Vite)
cd frontend
npm run dev
The Operations Web UI is designed specifically for technical support engineers and Network Operations Center (NOC) operators.
@vitejs/plugin-reactlucide-reactBrowserRouter, Routes, Route, Navigate)@testing-library/react + jsdomfrontend/
├── src/
│ ├── api/ # Typed API clients for each backend service
│ │ ├── client.ts # Generic fetch wrapper & ApiError
│ │ ├── helpdesk.ts # Tickets, search, comments, notes
│ │ ├── portal.ts # Assets, health, faults, actions, sites
│ │ ├── agent.ts # State, policy, knowledge, run-once, investigate
│ │ └── types.ts # TypeScript interfaces matching backend models
│ ├── components/ # Reusable UI & diagnostic components
│ │ ├── chat/ # AI Assistant chat components
│ │ │ ├── ChatContainer.tsx
│ │ │ ├── ChatSidebar.tsx
│ │ │ ├── ChatMessageItem.tsx
│ │ │ └── ChatToolStep.tsx
│ │ ├── common/ # Atomic badges, cards, skeletons, empty states
│ │ │ ├── Badge.tsx
│ │ │ ├── PolicyBadge.tsx
│ │ │ ├── Card.tsx
│ │ │ ├── Skeleton.tsx
│ │ │ └── EmptyState.tsx
│ │ ├── layout/ # Global chrome layout
│ │ │ ├── Header.tsx
│ │ │ ├── Sidebar.tsx
│ │ │ ├── AppLayout.tsx
│ │ │ └── LabControlsModal.tsx
│ │ ├── timeline/ # Diagnostic evidence timeline
│ │ │ └── InvestigationTimeline.tsx
│ │ └── topology/ # Network dependency & outage graph
│ │ └── TopologyGraph.tsx
│ ├── context/
│ │ └── LabContext.tsx # Global telemetry, polling (6s), notification state
│ ├── pages/ # 10 dedicated operations views
│ │ ├── DashboardPage.tsx
│ │ ├── IncidentsPage.tsx
│ │ ├── IncidentDetailPage.tsx
│ │ ├── DevicesPage.tsx
│ │ ├── DeviceDetailPage.tsx
│ │ ├── SitesPage.tsx
│ │ ├── SiteDetailPage.tsx
│ │ ├── AssistantPage.tsx
│ │ ├── KnowledgePage.tsx
│ │ └── AuditPage.tsx
│ ├── test/ # Component and unit test suites
│ ├── App.tsx # Route definitions
│ ├── index.css # Design tokens and custom scrollbars
│ └── main.tsx # Application entry point
├── package.json
├── tailwind.config.js
├── tsconfig.json
└── vite.config.ts
The frontend connects directly to backend services using configurable environment variables (defaulting to localhost):
VITE_HELPDESK_URL → http://localhost:8001VITE_PORTAL_URL → http://localhost:8002VITE_AGENT_URL → http://localhost:8003Each service enables CORSMiddleware allowlisting all origins in development mode.
LabContext)injectFault, clearFault, clearAllFaults) for interactive testing.The conversational assistant console (/assistant) allows technicians to query state and trigger targeted autonomous investigations.
/investigate <ASSET_ID>
POST /investigate/{asset_id}.SAFE_REVERSIBLE, executes recovery and verifies outcome.HUMAN_ONLY or APPROVAL_REQUIRED, safely halts and flags for technician review./status <ASSET_ID>
/site <SITE_ID>
/history <QUERY>
/help
/clear
When executing commands, the UI renders interactive status pills:
Running (Blue pulsing spinner)Success (Green checkmark)Failure (Red warning indicator)Blocked by Policy (Purple shield indicator)Technicians can click any tool pill to inspect the exact input arguments and JSON output received from the backend simulator.
Every diagnostic finding and proposed remediation displays its assigned safety class:
SAFE_REVERSIBLE: Automatically executed if auto-recoverable (e.g. reconnect_stream, restart_service).APPROVAL_REQUIRED: Proposes remediation but prompts the user for explicit confirmation (e.g. reboot_host, update_config).HUMAN_ONLY: Prohibits autonomous execution; highlights required physical inspection or credential update (e.g. hardware_repair, credential_rotation).READ: Diagnostic check without state modification (e.g. ping_check, rtsp_check).Architectural Invariant: Policy is enforced strictly on the backend (
services/agent/policy.py). The frontend reflects policy states visually but has zero ability to bypass safety rules.
frontend/src/pages/MyNewPage.tsx.frontend/src/App.tsx:
<Route path="my-page" element={<MyNewPage />} />
frontend/src/components/layout/Sidebar.tsx with a Lucide icon.frontend/src/components/common/.bg-slate-900, border-slate-800, text-cyan-400, text-slate-100).frontend/src/test/ to verify rendering and user interactions.services/agent/agent.py:
check_audio_stream(asset)).investigate_single_asset() or diagnose().services/agent/policy.py:
READ, SAFE_REVERSIBLE, APPROVAL_REQUIRED, or HUMAN_ONLY.frontend/src/components/chat/ChatContainer.tsx:
toolSteps during command execution so operators can see it running live.# 60 automated unit, API, recovery, and regression tests
python -m pytest -q
python -m ruff check .
cd frontend
npm test
Vitest executes tests across:
BadgeAndPolicy.test.tsx: Policy color-coding and safety class labelsChatCommands.test.tsx: Command parser, slash command execution, and /clear isolationInvestigationTimeline.test.tsx: Expandable diagnostic steps and JSON evidenceTopologyGraph.test.tsx: Topology hierarchy and correlated multi-device outagesSafetyEnforcement.test.tsx: Human-in-the-loop alerts for non-reversible faultsAppViews.test.tsx: Navigation, page routing, and empty/error statescd frontend
npm run build
Build output is generated under frontend/dist/ with full type validation and bundle optimization.
To reset all tickets, faults, device status overrides, and agent state back to the seed baseline:
python scripts/reset_lab.py
On the next cycle or page refresh, all demo assets return to a healthy state and default sample tickets are restored.