mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(langsmith): populate usage_metadata in outputs for Cost column
LangSmith reads the Cost column from outputs.usage_metadata.total_cost, but LangsmithLogger._prepare_log_data never wrote to that key. The response_cost was already computed in StandardLoggingPayload but was not forwarded to the outputs dict. Inject usage_metadata with input_tokens, output_tokens, total_tokens, and total_cost into the outputs dict so LangSmith can display cost. Fixes #24001 Made-with: Cursor
This commit is contained in:
parent
244bdffd1b
commit
fcea560682
2 changed files with 67 additions and 1 deletions
|
|
@ -153,11 +153,23 @@ class LangsmithLogger(CustomBatchLogger):
|
|||
if key in requester_metadata and key not in extra_metadata:
|
||||
extra_metadata[key] = requester_metadata[key]
|
||||
|
||||
outputs = payload["response"]
|
||||
if isinstance(outputs, dict):
|
||||
outputs = {**outputs}
|
||||
else:
|
||||
outputs = {"output": outputs}
|
||||
outputs["usage_metadata"] = {
|
||||
"input_tokens": payload.get("prompt_tokens", 0),
|
||||
"output_tokens": payload.get("completion_tokens", 0),
|
||||
"total_tokens": payload.get("total_tokens", 0),
|
||||
"total_cost": payload.get("response_cost", 0),
|
||||
}
|
||||
|
||||
data = {
|
||||
"name": run_name,
|
||||
"run_type": "llm", # this should always be llm, since litellm always logs llm calls. Langsmith allow us to log "chain"
|
||||
"inputs": payload,
|
||||
"outputs": payload["response"],
|
||||
"outputs": outputs,
|
||||
"session_name": project_name,
|
||||
"start_time": payload["startTime"],
|
||||
"end_time": payload["endTime"],
|
||||
|
|
|
|||
|
|
@ -132,3 +132,57 @@ class TestLangsmithLoggerInit:
|
|||
assert (
|
||||
logger.sampling_rate >= 0.0
|
||||
), f"sampling_rate should be non-negative, got {logger.sampling_rate}"
|
||||
|
||||
|
||||
class TestLangsmithPrepareLogData:
|
||||
"""Regression test for #24001: _prepare_log_data must inject
|
||||
usage_metadata into outputs so LangSmith's Cost column is populated."""
|
||||
|
||||
@patch("asyncio.create_task")
|
||||
@patch.dict(os.environ, {"LANGSMITH_SAMPLING_RATE": "1"}, clear=False)
|
||||
def test_outputs_contain_usage_metadata(self, mock_create_task):
|
||||
logger = LangsmithLogger(
|
||||
langsmith_api_key="test-key",
|
||||
langsmith_project="test-project",
|
||||
)
|
||||
|
||||
payload = {
|
||||
"id": "test-id",
|
||||
"response": {"choices": [{"message": {"content": "hi"}}]},
|
||||
"metadata": {},
|
||||
"startTime": 1.0,
|
||||
"endTime": 2.0,
|
||||
"request_tags": [],
|
||||
"error_str": None,
|
||||
"status": "success",
|
||||
"response_cost": 0.0042,
|
||||
"prompt_tokens": 100,
|
||||
"completion_tokens": 50,
|
||||
"total_tokens": 150,
|
||||
}
|
||||
|
||||
kwargs = {
|
||||
"litellm_params": {"metadata": {}},
|
||||
"standard_logging_object": payload,
|
||||
}
|
||||
|
||||
credentials = {
|
||||
"LANGSMITH_API_KEY": "test-key",
|
||||
"LANGSMITH_PROJECT": "test-project",
|
||||
"LANGSMITH_BASE_URL": "https://api.smith.langchain.com",
|
||||
}
|
||||
|
||||
data = logger._prepare_log_data(
|
||||
kwargs=kwargs,
|
||||
response_obj=None,
|
||||
start_time=1.0,
|
||||
end_time=2.0,
|
||||
credentials=credentials,
|
||||
)
|
||||
|
||||
assert "usage_metadata" in data["outputs"]
|
||||
um = data["outputs"]["usage_metadata"]
|
||||
assert um["total_cost"] == 0.0042
|
||||
assert um["input_tokens"] == 100
|
||||
assert um["output_tokens"] == 50
|
||||
assert um["total_tokens"] == 150
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue