# API Contract

Base URL: `http://localhost:8787`

## POST `/api/normalize`

Core request fields:
- `promptVersion` (e.g. `normalizer_v2_0_2`)
- `schemaVersion` (e.g. `v2_0_2`)
- `userQuestion`
- model transport fields (`apiKey`, `model`, `baseUrl`, `temperature`, `maxOutputTokens`)

For v2.0.2, backend returns:
- `schema_version: "v2_0_2"`
- normalized payload with `normalized_query_v2_0_2`
- deterministic `route_hint_summary`

Schema selection:
- `promptVersion=normalizer_v2_0_2` or `schemaVersion=v2_0_2` -> `normalized_query_v2_0_2`
- `promptVersion=normalizer_v2_0_1` or `schemaVersion=v2_0_1` -> `normalized_query_v2_0_1`
- `promptVersion=normalizer_v2` or `schemaVersion=v2` -> `normalized_query_v2`
- otherwise -> `normalized_query_v1`

## POST `/api/eval/run`

Supports v2 family (`v2`, `v2_0_1`, `v2_0_2`) with inline batch via `rawQuestions`.

Assistant Stage 1 eval target is additive and enabled only when `eval_target=assistant_stage1`.
Legacy normalizer eval remains default when `eval_target` is omitted.

Example:
```json
{
  "mode": "single-pass-strict",
  "rawQuestions": "вопрос 1; вопрос 2; вопрос 3",
  "useMock": false,
  "normalizeConfig": {
    "promptVersion": "normalizer_v2_0_2",
    "schemaVersion": "v2_0_2",
    "model": "gpt-4o-mini",
    "temperature": 0,
    "maxOutputTokens": 900
  }
}
```

Assistant Stage 1 example:
```json
{
  "eval_target": "assistant_stage1",
  "mode": "single-pass-strict",
  "useMock": true,
  "caseSetFile": "assistant_stage1_canonical_v0_1.json",
  "compare_with_report_file": "assistant-stage1-baseline.json",
  "normalizeConfig": {
    "promptVersion": "normalizer_v2_0_2"
  }
}
```

v2.0.2 eval metrics include:
- `schema_validation_pass_rate`
- `scope_detection_accuracy`
- `route_resolution_accuracy`
- `no_route_precision`
- `false_no_route_rate`
- `execution_state_consistency_rate`
- `clarification_precision`
- `clarification_recall`

## Presets and History
- `GET /api/presets`
- `POST /api/presets/save`
- `GET /api/history`
- `GET /api/history/:trace_id`
