From cf5a22a9d566eebf75e92b064070b3ac712cd1be Mon Sep 17 00:00:00 2001 From: Asaf Vertman Date: Thu, 16 Apr 2026 10:25:18 +0300 Subject: [PATCH] fix(langfuse_otel): tighten responses observation payload --- .../langfuse/langfuse_otel_attributes.py | 11 +++++++-- .../integrations/test_langfuse_otel.py | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/litellm/integrations/langfuse/langfuse_otel_attributes.py b/litellm/integrations/langfuse/langfuse_otel_attributes.py index a8b1de17973..15c8525f75e 100644 --- a/litellm/integrations/langfuse/langfuse_otel_attributes.py +++ b/litellm/integrations/langfuse/langfuse_otel_attributes.py @@ -15,7 +15,10 @@ from litellm.integrations.opentelemetry_utils.base_otel_llm_obs_attributes impor safe_set_attribute, ) from litellm.litellm_core_utils.safe_json_dumps import safe_dumps -from litellm.types.llms.openai import HttpxBinaryResponseContent, ResponsesAPIResponse +from litellm.types.llms.openai import ( + HttpxBinaryResponseContent, + ResponsesAPIResponse, +) from litellm.types.utils import ( EmbeddingResponse, ImageResponse, @@ -102,18 +105,22 @@ def get_langfuse_observation_input_by_type( response_input = kwargs.get("input") if response_input is not None: prompt: dict[str, Any] = {"input": response_input} + # Keep the Responses observation focused on request fields that affect + # model context, tool behavior, or response shape. for key in ( "instructions", - "functions", "tools", "tool_choice", "reasoning", "max_output_tokens", + "max_tool_calls", "text", "parallel_tool_calls", "truncation", "temperature", "top_p", + "previous_response_id", + "prompt", ): value = optional_params.get(key) if value is not None: diff --git a/tests/test_litellm/integrations/test_langfuse_otel.py b/tests/test_litellm/integrations/test_langfuse_otel.py index 661fa1c6155..8c487085c4d 100644 --- a/tests/test_litellm/integrations/test_langfuse_otel.py +++ b/tests/test_litellm/integrations/test_langfuse_otel.py @@ -499,6 +499,14 @@ class TestLangfuseOtelResponsesAPI: ], "tool_choice": "auto", "reasoning": {"effort": "low"}, + "previous_response_id": "resp_prev_123", + "prompt": { + "id": "pmpt_123", + "variables": {"tenant": "acme"}, + }, + "max_tool_calls": 3, + "functions": [{"name": "legacy_chat_only"}], + "metadata": {"request_id": "req_123"}, "stream": False, }, "litellm_params": {"custom_llm_provider": "openai", "metadata": {}}, @@ -510,6 +518,12 @@ class TestLangfuseOtelResponsesAPI: "tools": [{"type": "function", "name": "list_applications"}], "tool_choice": "auto", "reasoning": {"effort": "low"}, + "previous_response_id": "resp_prev_123", + "prompt": { + "id": "pmpt_123", + "variables": {"tenant": "acme"}, + }, + "max_tool_calls": 3, "stream": False, }, }, @@ -544,6 +558,15 @@ class TestLangfuseOtelResponsesAPI: assert observation_input["tool_choice"] == "auto" assert observation_input["reasoning"] == {"effort": "low"} assert observation_input["tools"][0]["name"] == "list_applications" + assert observation_input["previous_response_id"] == "resp_prev_123" + assert observation_input["prompt"] == { + "id": "pmpt_123", + "variables": {"tenant": "acme"}, + } + assert observation_input["max_tool_calls"] == 3 + assert "functions" not in observation_input + assert "metadata" not in observation_input + assert "stream" not in observation_input assert ( "show me connected applications with high risk" in actual_attributes["langfuse.observation.input"]