From ed5b6b2365220600565b6b14cf279f6389486a40 Mon Sep 17 00:00:00 2001 From: Alvin Tang Date: Wed, 18 Mar 2026 22:14:30 +0800 Subject: [PATCH] fix: populate usage_metadata with response_cost in LangsmithLogger LangSmith reads cost from outputs.usage_metadata.total_cost but LangsmithLogger never wrote to that key, so the Cost column in LangSmith was always empty. Inject usage_metadata (token counts + cost) into data['outputs'] inside _prepare_log_data so the cost is surfaced in the LangSmith UI. Fixes #24001 --- litellm/integrations/langsmith.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/litellm/integrations/langsmith.py b/litellm/integrations/langsmith.py index 03845af521d..a9243e7fe1b 100644 --- a/litellm/integrations/langsmith.py +++ b/litellm/integrations/langsmith.py @@ -165,6 +165,23 @@ class LangsmithLogger(CustomBatchLogger): "extra": extra_metadata, } + # Populate usage_metadata so LangSmith can display cost in + # the project overview. LangSmith reads cost exclusively from + # outputs.usage_metadata.total_cost (the same structure that the + # official LangSmith OpenAI/Gemini wrappers produce). + if isinstance(data.get("outputs"), dict): + response_cost = payload.get("response_cost") or 0.0 + data["outputs"]["usage_metadata"] = { + "input_tokens": payload.get("prompt_tokens", 0), + "output_tokens": payload.get("completion_tokens", 0), + "total_tokens": payload.get("total_tokens", 0), + "input_token_details": {}, + "output_token_details": {}, + "input_cost": response_cost, + "output_cost": 0.0, + "total_cost": response_cost, + } + if payload["error_str"] is not None and payload["status"] == "failure": data["error"] = payload["error_str"]