fix(status): parse actual Tavily API response structure

The Tavily /usage endpoint returns a nested "account" object with
plan_usage/plan_limit/search_usage/etc fields, not the flat structure
with used/limit/breakdown that was assumed. This caused all usage
values to be None.
This commit is contained in:
yanghan-cyber 2026-04-06 18:56:28 +08:00 committed by Xubin Ren
parent 84f0571e0d
commit e528e6dd96

View File

@ -129,43 +129,40 @@ def _parse_tavily_usage(data: dict[str, Any]) -> SearchUsageInfo:
""" """
Parse Tavily /usage response. Parse Tavily /usage response.
Expected shape (may vary by plan): Actual API response shape:
{ {
"used": 142, "account": {
"limit": 1000, "current_plan": "Researcher",
"remaining": 858, "plan_usage": 20,
"reset_date": "2026-05-01", "plan_limit": 1000,
"breakdown": { "search_usage": 20,
"search": 120, "crawl_usage": 0,
"extract": 15, "extract_usage": 0,
"crawl": 7 "map_usage": 0,
"research_usage": 0,
"paygo_usage": 0,
"paygo_limit": null
} }
} }
""" """
used = data.get("used") account = data.get("account") or {}
limit = data.get("limit") used = account.get("plan_usage")
remaining = data.get("remaining") limit = account.get("plan_limit")
reset_date = data.get("reset_date") or data.get("resetDate")
# Compute remaining if not provided # Compute remaining
if remaining is None and used is not None and limit is not None: remaining = None
if used is not None and limit is not None:
remaining = max(0, limit - used) remaining = max(0, limit - used)
breakdown = data.get("breakdown") or {}
search_used = breakdown.get("search")
extract_used = breakdown.get("extract")
crawl_used = breakdown.get("crawl")
return SearchUsageInfo( return SearchUsageInfo(
provider="tavily", provider="tavily",
supported=True, supported=True,
used=used, used=used,
limit=limit, limit=limit,
remaining=remaining, remaining=remaining,
reset_date=str(reset_date) if reset_date else None, search_used=account.get("search_usage"),
search_used=search_used, extract_used=account.get("extract_usage"),
extract_used=extract_used, crawl_used=account.get("crawl_usage"),
crawl_used=crawl_used,
) )