All endpoints are served under the /api prefix by
../backend/app/api/routes.py. Request and
response bodies are defined in
../backend/app/models/schemas.py.
Base URL:
- Dev backend:
http://localhost:8000 - Standalone binary / single-process:
http://127.0.0.1:8000(or the next free port, printed at startup)
Interactive Swagger UI is available at http://localhost:8000/docs while the
backend is running.
These string values must be used exactly.
- Vendor:
amd-epyc,intel-xeon,unknown - Tool (
tool_hint/detected_tool):perf-stat,perf-c2c,uprof,vtune,generic,unknown - Tier:
primary,secondary
Using amd or intel instead of amd-epyc / intel-xeon returns
422 Unprocessable Entity.
Liveness and LLM status.
{ "status": "ok", "version": "0.1.0", "llm_enabled": false }The core endpoint. Parses the paste, routes to ranked skills, optionally refines with the LLM, and records a session step.
Request (AnalyzeRequest):
| Field | Type | Default | Notes |
|---|---|---|---|
problem |
string | "" |
Free-text symptom description |
pasted_output |
string | "" |
Raw profiler output |
tool_hint |
Tool | unknown |
Force a parser; otherwise auto-detected |
context |
SystemContext | {} |
vendor, microarch, numa_config, numa_nodes, kernel |
session_id |
string | null | Continue an existing investigation |
use_llm |
bool | true |
Refine only runs if a key is configured |
Response (AnalyzeResponse): session_id, detected_tool, detected_vendor,
parsed (metrics + matched line numbers), recommendations (ranked, each with
skill_id, score, confidence, evidence, run_next, fix, verify, and
optional root_cause / llm_notes), llm_used, and fallback_reason.
Errors: 413 Payload Too Large if pasted_output exceeds MAX_INPUT_BYTES.
curl -s http://localhost:8000/api/analyze \
-H "Content-Type: application/json" \
-d '{
"problem": "low IPC under load, suspect remote memory",
"pasted_output": "Performance counter stats:\n 60000000 node-loads\n 18000000 node-load-misses\n",
"context": { "vendor": "amd-epyc", "microarch": "Zen4" },
"use_llm": false
}'Return the timeline for a session (Session with a list of TimelineStep).
404 if the session id is unknown.
curl -s http://localhost:8000/api/session/<session_id>List skill summaries. Optional query parameters:
| Param | Type | Effect |
|---|---|---|
vendor |
Vendor | Only skills supporting that vendor |
theme |
string | Only skills in that theme |
q |
string | Substring match over id, name, signal, keywords |
curl -s "http://localhost:8000/api/skills?vendor=amd-epyc&q=numa"Full skill detail (Skill), including thresholds, detect commands, fix, verify,
sources, themes, tier, and platforms. 404 if not found.
Signal-to-skill routing table grouped by subsystem. Each entry has id,
signal, tier, platforms, and themes.
List all themes or fetch one (Theme with id, name, description, and a
per-vendor ladder of ordered skill ids). 404 for an unknown theme id.
Return the predefined uProf collect/view configs and the known PMU/IBS events from the uProf database.
Build a grounded AMDuProfCLI command from a symptom or metric.
Request (UProfCommandRequest): symptom, metric, cpu_family (for example
Zen4), pid, duration_s — all optional.
Response (UProfCommand): entry_id, description, collect, report,
events, supported_families, notes. 404 if nothing matches.
curl -s http://localhost:8000/api/uprof/command \
-H "Content-Type: application/json" \
-d '{ "symptom": "l3 miss cache", "cpu_family": "Zen4", "duration_s": 10 }'Render a Markdown diagnosis report from an analyze response. Returns
text/plain Markdown.
Request (ReportRequest): problem, response (a prior AnalyzeResponse),
session_id.
curl -s http://localhost:8000/api/report \
-H "Content-Type: application/json" \
-d '{ "problem": "low IPC", "response": { ... }, "session_id": "<session_id>" }'- The rule engine is deterministic;
use_llmhas no effect unlessOPENAI_API_KEYis set (see the configuration table). - CORS origins for the dev frontend are controlled by
CORS_ORIGINS. The single-process build serves the UI and API from the same origin, so CORS does not apply there.