23 lines
1.6 KiB
JSON
23 lines
1.6 KiB
JSON
{
|
|
"task": 7,
|
|
"title": "Make telemetry optional per-provider and replace global account-refusal tracking with per-provider tracking",
|
|
"file": "src/dispatcher.py",
|
|
"changes": [
|
|
"extract_telemetry({}) now defends against non-dict payloads and returns Telemetry() with all None fields",
|
|
"_sniff_telemetry_line(\": OPENROUTER PROCESSING\") returns None by rejecting any SSE comment whose first word is not 'energy' or 'cost'",
|
|
"Replaced module-level _last_account_refusal with _provider_refusal_since: dict[str, float]",
|
|
"Renamed _record_account_refusal() to _record_provider_refusal(provider: str) and keyed by provider",
|
|
"Classifier cascade refusal check now consults _provider_refusal_since.get(cfg.dispatch_settings.default_provider) with cfg.classifier.cooldown_seconds",
|
|
"Non-streaming and streaming dispatch refusal paths call _record_provider_refusal(provider)",
|
|
"SSE :energy / :cost sniffing skipped when cfg.dispatch_providers[provider].has_energy_telemetry is false",
|
|
"Added module _self_check() verifying extract_telemetry({}) and _sniff_telemetry_line behavior at import time"
|
|
],
|
|
"verification": {
|
|
"py_compile": "passed",
|
|
"extract_telemetry_empty": "passed",
|
|
"sniff_openrouter_keepalive": "passed",
|
|
"targeted_tests": "expected failure: tests/test_classifier_cascade.py and tests/test_local_dispatch_fallback.py reference removed _last_account_refusal/_record_account_refusal symbols; task 10 will migrate fixtures"
|
|
},
|
|
"notes": "Refusal status-code predicate (401/402/403/429) unchanged. Cross-provider runner-up failover not implemented. SSE response contract to clients unchanged."
|
|
}
|