AI-powered incident-response dashboard built with CopilotKit + OpenAI. Triage cybersecurity incidents conversationally, fill report forms via human-in-the-loop chat, drill into per-incident analysis and cross-incident timelines, and view charts over a decade of global cybersecurity threats (2015β2024).
- Frontend: React + TypeScript + Vite, CopilotKit (
@copilotkit/react-core,@copilotkit/react-ui), Recharts - Backend: Node + Express +
@copilotkit/runtimewith the OpenAI adapter - LLM: OpenAI via
OpenAIAdapter - Data: Global Cybersecurity Threats (2015β2024) (see
README_DATASET.md) - Tests: Vitest + Testing Library
- Node.js 20.19+ or 22.12+
- pnpm β install
- An OpenAI API key
git clone https://github.com/NathanTarbert/incident-copilot.git
cd incident-copilot
pnpm install
cp .env.example .env # then paste your OPENAI_API_KEYpnpm dev:all- Frontend: http://localhost:5173 (Vite)
- Backend: http://localhost:4000/copilotkit (CopilotKit runtime)
pnpm dev:server # one terminal β Express + runtime
pnpm dev # another β Vitepnpm test # one-shot
pnpm test:watch # watch mode- Incidents list & detail β severities P0βP4, statuses Open / Investigating / Mitigated / Resolved, with sorting and filtering.
- AI sidebar β
CopilotSidebarchat that can read app state and trigger frontend tools. - Conversational incident reporting β the AI fills a structured
ChatIncidentFormin-chat, the user reviews and submits (classic HITL pattern). - Tool calls visualized β runbook execution cards, analysis panels, and cross-incident timelines render inline from tool results.
- Charts β Recharts-powered incident charts over the cybersecurity-threats dataset.
The frontend wraps the app in <CopilotKit runtimeUrl="http://localhost:4000/copilotkit"> and a <CopilotSidebar>. Three integration points carry the work:
useCopilotReadableβ shares the live incidents list and selection state with the agent.useFrontendToolβ registers ~9 tools the agent can call (report/resolve/clear incidents, fill the chat form, navigate to a detail view, run a runbook, etc.).useRenderToolCallβ renders custom React UI for specific tool calls (runbook cards, analysis panels) directly inside the chat thread.
The backend (server.js) mounts copilotRuntimeNodeHttpEndpoint on /copilotkit with the OpenAIAdapter so each request reaches OpenAI with the latest app context attached.
incident-copilot/
βββ server.js # Express + CopilotKit runtime + OpenAI adapter
βββ src/
β βββ App.tsx # CopilotKit provider, sidebar, frontend tools
β βββ components/
β β βββ IncidentsList.tsx # Sort + filter incidents
β β βββ IncidentDetail.tsx # Per-incident detail view
β β βββ ChatIncidentForm.tsx # HITL form rendered inside the sidebar
β β βββ CrossIncidentTimeline.tsx
β β βββ AnalysisPanel.tsx
β β βββ RunbookExecutionCard.tsx
β β βββ charts/IncidentCharts.tsx
β βββ services/
β β βββ incidentDatabase.ts # In-memory store
β β βββ mockApi.ts # Async wrapper
β βββ data/ # Cybersecurity threats dataset
β βββ types/incident.ts
βββ README_DATASET.md # How the dataset is wired in
βββ package.json
| Variable | Description | Required |
|---|---|---|
OPENAI_API_KEY |
Used by the runtime's OpenAI adapter. | Yes |
The backend port (4000) and the frontend's runtimeUrl are matched in server.js and src/App.tsx β change both if you need a different port.
Deploys as a single Node service. In production server.js binds to process.env.PORT, serves the Vite build from dist/, and mounts the runtime at /copilotkit on the same origin β no CORS, no second service.
- Build:
pnpm install --frozen-lockfile && pnpm build - Start:
pnpm start - Env:
NODE_ENV=production,OPENAI_API_KEY,VITE_COPILOTKIT_RUNTIME_URL=/copilotkit
Run the production bundle locally to sanity-check:
pnpm build
OPENAI_API_KEY=sk-... pnpm start # http://localhost:4000Agent 'default' not foundβ make surepnpm dev:serveris running and theruntimeUrlinApp.tsxmatches.OPENAI_API_KEY is not setβ populate.envand restart the server.- Port 4000 already in use β
lsof -ti:4000 | xargs kill -9.