litellm/tests/test_litellm/integrations/datadog
tin-berri 81277252e1
fix(datadog_llm_obs): send tool calls, tool results and cache tokens in DD's own fields (#39222)
The LLM Obs callback copied litellm's OpenAI-shaped objects into the span
verbatim, so every field Datadog names differently landed somewhere it does
not read: tool calls kept their nested `function` wrapper instead of DD's
name/arguments/tool_id, tool messages carried no result linking them to their
call, the request's tools were never sent, and prompt-cache counts sat inside
meta.metadata rather than the span metrics its cache dashboards chart.

One rule governs the message mapper: add the fields Datadog declares, and never
destroy content it did not understand. Content collapses to its text only when
it has text, so a content list carrying tool or image blocks rides along
unchanged, and absent messages map to an empty input rather than a fabricated
turn. Tool calls and results are read from both dialects, the OpenAI
`tool_calls` / `role: tool` shape and the Anthropic `tool_use` / `tool_result`
content blocks, so /v1/messages sessions gain tool linking they never had.

Cache counts come from the same owners the savings dashboard uses, so every
provider spelling resolves through one place rather than a second local guess.
The three cache metrics partition the input count: litellm's normalized prompt
total includes both cache categories, as the cost calculator's pricing helper
documents, so the non-cached residual subtracts reads AND writes. Counting a
primed prefix as ordinary input had inflated non-cached usage by exactly the
cache-write count on every priming request.

Correlating a result to its call reads ids and names structurally and parses no
arguments, so a tool call's arguments are decoded once per span rather than
once per pass, and arguments past a size bound ship as the raw string instead
of paying a decode that multiplies memory on hostile compact JSON.

The flat `output_tool_calls.*` metadata copies go away with this: they were a
second representation of a fact that now has its own field on the same span.
2026-09-01 18:01:13 -07:00
..
test_datadog_cost_management.py test(datadog): restore an empty DD_API_KEY instead of unsetting it (#37832) 2026-08-21 20:39:07 -07:00
test_datadog_llm_obs.py fix(datadog_llm_obs): send tool calls, tool results and cache tokens in DD's own fields (#39222) 2026-09-01 18:01:13 -07:00
test_datadog_llm_obs_agent.py feat(datadog): add agent support for LLM Observability (#19574) 2026-01-22 19:49:22 -08:00
test_datadog_logger_batching.py fix(datadog): split log batches proactively under intake payload limits (#32860) 2026-07-10 20:54:42 -07:00
test_datadog_metrics.py test(datadog): restore an empty DD_API_KEY instead of unsetting it (#37832) 2026-08-21 20:39:07 -07:00
test_datadog_tags_regression.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_datadog_team_handler.py fix(datadog): read team callback dd_* params from kwargs instead of blocked dynamic params (#35115) (#35687) 2026-08-03 16:19:56 -07:00