A declined answer left one number behind and it was in a log line, so confidence_min could not be tuned from data. route_decisions.confidence cannot say it either: the chat path re-routes through the override branch, which hard-codes 1.0, and 43,804 of 43,856 live rows hold exactly that. Measured on 2026-10-04 under local_decision (qwen3.5:4b): 769 of 2,557 turns (30%) had no fresh classification, against 0% for local_llm and local_encoder. The cause was recorded in only 4 of them. - classifier_confidence, classifier_coverage and classifier_reject on route_decisions, filled from a ClassifierAttempt carried on Classification. Both accepted and declined answers carry one, so the two distributions can be compared around the floor. Reason codes are listed in docs/data-model.md. - ClassifierRejected (a RuntimeError subclass, messages unchanged) replaces the plain RuntimeErrors at the six floor-miss sites and the two local_decision refusals, so the number and reason travel out of the raise site. - The chat path captures the classifier's verdict before the re-route and passes it to persist_route_decision (attempt_of), like it already does for source. - Admin decisions page: the source badge's tooltip shows the attempt, and session_history / session_stale get an amber badge instead of neutral grey. TUI detail popup and the live event carry the same three keys. - The /metrics degraded-share warning lists the recorded reasons instead of claiming the classifier "has been failing", which was wrong for a classifier that answers and is declined. - degraded_warn_threshold must be in (0, 1] and degraded_warn_min at least 1, refused at load: a value above 1 could never fire. The three columns arrive by ALTER and are NULL on every earlier row; metrics selects them only when present, so the live DB reads NULL until its restart. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkCGRantZsSwmcFpet6FTa
38 lines
1.0 KiB
JSON
38 lines
1.0 KiB
JSON
{
|
|
"agent": null,
|
|
"candidates_considered": 2,
|
|
"classification_source": "classifier",
|
|
"classifier_confidence": null,
|
|
"classifier_coverage": null,
|
|
"classifier_reject": null,
|
|
"confidence": 0.9,
|
|
"est_cost_usd": 0.00016,
|
|
"est_proficiency": 0.5,
|
|
"exploration": 0,
|
|
"flex_forced": 0,
|
|
"flex_preference": "auto",
|
|
"flex_swapped": 0,
|
|
"images": 0,
|
|
"json_mode": 0,
|
|
"kind": "chat",
|
|
"latency_tolerance": "interactive",
|
|
"parent_key": null,
|
|
"pinch_final_tokens": 5,
|
|
"pinch_original_tokens": 5,
|
|
"prefix_divergence_index": null,
|
|
"prefix_prev_message_count": null,
|
|
"prefix_tokens_after_divergence": null,
|
|
"profile": "default",
|
|
"rejected_reason": null,
|
|
"request_id": "chatcmpl-test",
|
|
"required_context_tokens": 100,
|
|
"runner_up_models": "[{\"model_id\": \"dear-model\", \"provider\": \"neuralwatt\"}]",
|
|
"selected_model": "cheap-model",
|
|
"selected_provider": "neuralwatt",
|
|
"session_key": "be41d1308beb018d",
|
|
"streamed": 0,
|
|
"task_category": "coding_general",
|
|
"task_tier": 2,
|
|
"tools": 0
|
|
}
|