gateway: instrument the audio per-request helper (speech still bills $0)
Speech billed $0.000000 across three deploys while transcription billed $0.010000 exactly, so the patch works for one audio call type and not the other. Three hypotheses have now been retired (hidden-params early return; missing character price; lookup miss) — the remaining question is WHERE the speech cost is lost, and guessing is more expensive than measuring. The helper now prints, for TTS/STT models only, whether it ran at all, what it could see (custom_pricing keys, shared cost-map hits) and what it resolved, into the app log. If those lines never appear for a speech call, the request never reaches the model cost calculator and the loss is upstream of this patch. Also fixes a real defect in the previous revision: the addition was wrapped in a bare except, so a TypeError from a None base cost would have been swallowed silently — which is exactly the sort of silence that made this take three deploys. It now coerces a None base to 0.0 and reports any failure.
This commit is contained in:
1 parent
a6098741d0
commit
a3acce2107
1 file changed
+55
-13
+55
-13
@@ -56,18 +56,26 @@ HELPER = '''def _coop_per_request_cost(
|
|||||||
logging layer builds from our config.yaml model_info, then the shared cost
|
logging layer builds from our config.yaml model_info, then the shared cost
|
||||||
map, then the call metadata. Inert unless a model declares the field.
|
map, then the call metadata. Inert unless a model declares the field.
|
||||||
"""
|
"""
|
||||||
|
def _is_audio(name: Any) -> bool:
|
||||||
|
text = str(name or "").lower()
|
||||||
|
return "tts" in text or "whisper" in text
|
||||||
|
|
||||||
|
cost_map = {}
|
||||||
|
try:
|
||||||
|
import litellm as _litellm # local import: not every caller binds it globally
|
||||||
|
cost_map = getattr(_litellm, "model_cost", {}) or {}
|
||||||
|
except Exception:
|
||||||
|
cost_map = {}
|
||||||
|
|
||||||
candidates = []
|
candidates = []
|
||||||
if isinstance(custom_pricing, dict):
|
if isinstance(custom_pricing, dict):
|
||||||
candidates.append(custom_pricing)
|
candidates.append(custom_pricing)
|
||||||
try:
|
map_hits = []
|
||||||
import litellm as _litellm # local import: not every caller binds it globally
|
for key in (litellm_model_name, model):
|
||||||
cost_map = _litellm.model_cost
|
entry = cost_map.get(key) if key else None
|
||||||
for key in (litellm_model_name, model):
|
if isinstance(entry, dict):
|
||||||
entry = cost_map.get(key) if key else None
|
candidates.append(entry)
|
||||||
if isinstance(entry, dict):
|
map_hits.append((key, entry.get("input_cost_per_request")))
|
||||||
candidates.append(entry)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
try:
|
try:
|
||||||
details = getattr(litellm_logging_obj, "model_call_details", None) or {}
|
details = getattr(litellm_logging_obj, "model_call_details", None) or {}
|
||||||
info = (details.get("metadata") or {}).get("model_info")
|
info = (details.get("metadata") or {}).get("model_info")
|
||||||
@@ -75,6 +83,22 @@ HELPER = '''def _coop_per_request_cost(
|
|||||||
candidates.append(info)
|
candidates.append(info)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Diagnostic (audio models only): did this run at all, and what could it see?
|
||||||
|
# If this line never appears for a speech call, the request never reaches the
|
||||||
|
# model cost calculator and the loss is upstream of this patch.
|
||||||
|
if _is_audio(model) or _is_audio(litellm_model_name):
|
||||||
|
try:
|
||||||
|
print(
|
||||||
|
"[coop-audio] probe"
|
||||||
|
f" model={model!r} litellm={litellm_model_name!r}"
|
||||||
|
f" custom_pricing={sorted(custom_pricing) if isinstance(custom_pricing, dict) else type(custom_pricing).__name__}"
|
||||||
|
f" map_hits={map_hits!r} candidates={len(candidates)}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
for candidate in candidates:
|
for candidate in candidates:
|
||||||
try:
|
try:
|
||||||
value = candidate.get("input_cost_per_request")
|
value = candidate.get("input_cost_per_request")
|
||||||
@@ -82,9 +106,20 @@ HELPER = '''def _coop_per_request_cost(
|
|||||||
continue
|
continue
|
||||||
if value:
|
if value:
|
||||||
try:
|
try:
|
||||||
return float(value)
|
resolved = float(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
continue
|
continue
|
||||||
|
if _is_audio(model) or _is_audio(litellm_model_name):
|
||||||
|
try:
|
||||||
|
print(f"[coop-audio] resolved per_request={resolved}", flush=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return resolved
|
||||||
|
if _is_audio(model) or _is_audio(litellm_model_name):
|
||||||
|
try:
|
||||||
|
print("[coop-audio] resolved per_request=0.0 (nothing declared)", flush=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
@@ -107,14 +142,21 @@ PATCHED_RETURN = """ region_name=region_name,
|
|||||||
# declares nothing; the early "provider reported the cost" return above
|
# declares nothing; the early "provider reported the cost" return above
|
||||||
# is unaffected.
|
# is unaffected.
|
||||||
try:
|
try:
|
||||||
response_cost = response_cost + _coop_per_request_cost(
|
_coop_pr = _coop_per_request_cost(
|
||||||
model=model,
|
model=model,
|
||||||
litellm_model_name=litellm_model_name,
|
litellm_model_name=litellm_model_name,
|
||||||
custom_pricing=custom_pricing,
|
custom_pricing=custom_pricing,
|
||||||
litellm_logging_obj=litellm_logging_obj,
|
litellm_logging_obj=litellm_logging_obj,
|
||||||
)
|
)
|
||||||
except Exception:
|
response_cost = (response_cost or 0.0) + _coop_pr
|
||||||
pass
|
_coop_name = str(model or "") + str(litellm_model_name or "")
|
||||||
|
if "tts" in _coop_name.lower() or "whisper" in _coop_name.lower():
|
||||||
|
print(
|
||||||
|
f"[coop-audio] add per_request={_coop_pr!r} -> response_cost={response_cost!r}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
except Exception as _coop_exc:
|
||||||
|
print(f"[coop-audio] add failed: {type(_coop_exc).__name__}: {_coop_exc}", flush=True)
|
||||||
|
|
||||||
return response_cost
|
return response_cost
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in new issue
Block a user