mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-13 03:59:12 +00:00
Merge 36a226cda9 into a9b9700790
This commit is contained in:
commit
59441699b9
2 changed files with 68 additions and 9 deletions
|
|
@ -196,19 +196,25 @@ class LangfuseOtelLogger(OpenTelemetry):
|
|||
"content": getattr(getattr(item, "content", [{}])[0], "text", ""),
|
||||
}
|
||||
)
|
||||
elif item_type == "function_call":
|
||||
arguments_str = getattr(item, "arguments", "{}")
|
||||
arguments_obj = (
|
||||
safe_json_loads(arguments_str, default={})
|
||||
if isinstance(arguments_str, str)
|
||||
else arguments_str
|
||||
)
|
||||
elif item_type in ("function_call", "custom_tool_call"):
|
||||
# A custom (freeform) tool carries its payload as a raw string under `input`,
|
||||
# where a function call carries a JSON string under `arguments`.
|
||||
if item_type == "custom_tool_call":
|
||||
payload_key, payload_value = "input", getattr(item, "input", "")
|
||||
else:
|
||||
arguments_str = getattr(item, "arguments", "{}")
|
||||
payload_key = "arguments"
|
||||
payload_value = (
|
||||
safe_json_loads(arguments_str, default={})
|
||||
if isinstance(arguments_str, str)
|
||||
else arguments_str
|
||||
)
|
||||
langfuse_tool_call = {
|
||||
"id": getattr(item, "id", ""),
|
||||
"name": getattr(item, "name", ""),
|
||||
"call_id": getattr(item, "call_id", ""),
|
||||
"type": "function_call",
|
||||
"arguments": arguments_obj,
|
||||
"type": item_type,
|
||||
payload_key: payload_value,
|
||||
}
|
||||
output_items_data.append(langfuse_tool_call)
|
||||
if output_items_data:
|
||||
|
|
|
|||
|
|
@ -1005,6 +1005,59 @@ class TestLangfuseOtelResponsesAPI:
|
|||
assert output_data[0]["name"] == "get_weather"
|
||||
assert output_data[0]["arguments"] == {}
|
||||
|
||||
def test_responses_api_with_custom_tool_calls(self):
|
||||
"""Test Langfuse OTEL logger with Responses API custom_tool_call output."""
|
||||
from litellm.types.integrations.langfuse_otel import LangfuseSpanAttributes
|
||||
from litellm.types.responses.main import CustomToolCallOutputItem
|
||||
|
||||
# Create Responses API response with a custom (freeform) tool call
|
||||
response_obj = ResponsesAPIResponse(
|
||||
id="response-790",
|
||||
created_at=1625247700,
|
||||
output=[
|
||||
CustomToolCallOutputItem(
|
||||
id="ctc-123",
|
||||
type="custom_tool_call",
|
||||
name="exec",
|
||||
call_id="call-def",
|
||||
input="console.log('hello')",
|
||||
status="completed",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
kwargs = {
|
||||
"call_type": "responses",
|
||||
"messages": [{"role": "user", "content": "Print hello"}],
|
||||
"model": "gpt-4o",
|
||||
"optional_params": {},
|
||||
}
|
||||
|
||||
mock_span = MagicMock()
|
||||
|
||||
with patch(
|
||||
"litellm.integrations.arize._utils.safe_set_attribute"
|
||||
) as mock_safe_set_attribute:
|
||||
LangfuseOtelLogger._set_langfuse_specific_attributes(
|
||||
mock_span, kwargs, response_obj
|
||||
)
|
||||
|
||||
output_calls = [
|
||||
call
|
||||
for call in mock_safe_set_attribute.call_args_list
|
||||
if call.args[1] == LangfuseSpanAttributes.OBSERVATION_OUTPUT.value
|
||||
]
|
||||
|
||||
assert len(output_calls) > 0, "observation.output should be set"
|
||||
output_data = json.loads(output_calls[0].args[2])
|
||||
assert isinstance(output_data, list)
|
||||
assert len(output_data) == 1
|
||||
assert output_data[0]["type"] == "custom_tool_call"
|
||||
assert output_data[0]["id"] == "ctc-123"
|
||||
assert output_data[0]["name"] == "exec"
|
||||
assert output_data[0]["call_id"] == "call-def"
|
||||
assert output_data[0]["input"] == "console.log('hello')"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue