fix(router): satisfy calibration lint and schema checks

This commit is contained in:
Tin Chi Lo 2026-09-11 14:26:43 -07:00
parent 82937d9969
commit 2ac98ab4ca
4 changed files with 20 additions and 16 deletions

View file

@ -18914,7 +18914,7 @@
}
}
},
"description": "\n Unified rate-limit error.\n\n Every rate-limit condition surfaced by litellm \u2014 whether it originated from\n an upstream LLM provider, a vendor batch endpoint, or one of litellm's own\n proxy-side limiters (parallel-requests, dynamic-rate, batch-rate, budget,\n max-iterations, etc.) \u2014 is raised as an instance of this class.\n\n The :attr:`category` attribute lets callers distinguish the source. See\n :class:`RateLimitErrorCategory` for the available values.\n "
"description": "\nUnified rate-limit error.\n\nEvery rate-limit condition surfaced by litellm \u2014 whether it originated from\nan upstream LLM provider, a vendor batch endpoint, or one of litellm's own\nproxy-side limiters (parallel-requests, dynamic-rate, batch-rate, budget,\nmax-iterations, etc.) \u2014 is raised as an instance of this class.\n\nThe :attr:`category` attribute lets callers distinguish the source. See\n:class:`RateLimitErrorCategory` for the available values.\n"
},
"500": {
"content": {

View file

@ -185,7 +185,7 @@ def capability_classifier_response_format(
) -> Mapping[str, object]:
"""Fresh copy of Switchyard's packaged strict JSON Schema wrapper."""
return (
{"type": "json_object"}
_RESPONSE_FORMAT_ADAPTER.validate_json('{"type": "json_object"}')
if mode == "json_object"
else _RESPONSE_FORMAT_ADAPTER.validate_json(_CAPABILITY_CLASSIFIER_RESPONSE_FORMAT_JSON)
)

View file

@ -1032,11 +1032,12 @@ def _with_capability_forecast(
}
if forecast.calibration_version is None:
return enriched
return {
calibrated: Final[StandardLoggingRoutingDecision] = {
**enriched,
"classifier_calibrated_p_solve": forecast.p_solve,
"classifier_calibration_version": forecast.calibration_version,
}
return calibrated
class _ClassifierCircuitBreaker:
@ -2265,7 +2266,9 @@ class ComplexityRouter(CustomLogger):
INTERNAL_CALL_ORIGIN_METADATA_KEY: AUTOROUTER_CLASSIFIER_CALL_ORIGIN,
}
classifier_call_params: Final = (
{"reasoning_effort": llm_config.reasoning_effort} if llm_config.reasoning_effort is not None else {}
MappingProxyType({"reasoning_effort": llm_config.reasoning_effort})
if llm_config.reasoning_effort is not None
else EMPTY_MAPPING
)
classifier_payload: Final = (
self._native_classifier_payload(messages_for_call, response_format, encrypted_task)
@ -2274,14 +2277,18 @@ class ComplexityRouter(CustomLogger):
{"messages": messages_for_call, "response_format": response_format, **classifier_call_params}
)
)
payload: Final = {
**classifier_payload,
**(
{"max_output_tokens" if encrypted_task is not None else "max_tokens": max_output_tokens}
if max_output_tokens is not None
else {}
),
}
payload: Final = MappingProxyType(
{
**classifier_payload,
**(
MappingProxyType(
{"max_output_tokens" if encrypted_task is not None else "max_tokens": max_output_tokens}
)
if max_output_tokens is not None
else EMPTY_MAPPING
),
}
)
proxy_server_request: Final = {
"originating_request_masked": masked_originating_request(request_kwargs),
"body": {"model": llm_config.model, **payload},

View file

@ -151,10 +151,7 @@ export type ClassifierType = "heuristic" | "heuristic_v2" | "llm" | "heuristic_f
* control and payload key, so a new chaining type cannot strip knobs the operator set.
*/
export const usesLlmClassifier = (classifierType: ClassifierType): boolean =>
classifierType === "llm" ||
classifierType === "heuristic_first" ||
classifierType === "hybrid" ||
classifierType === "capability";
(["llm", "heuristic_first", "hybrid", "capability"] as const).some((type) => type === classifierType);
export type ClassifierFallback = "heuristic" | "default_model";