mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(langfuse_otel_attributes.py): log tools and other optional params
This commit is contained in:
parent
75bee1f274
commit
b2da4bdac2
3 changed files with 91 additions and 16 deletions
|
|
@ -20,12 +20,14 @@ class ArizeOTELAttributes(BaseLLMObsOTELAttributes):
|
|||
|
||||
@staticmethod
|
||||
@override
|
||||
def set_messages(span: "Span", messages: List[Dict[str, Any]]):
|
||||
def set_messages(span: "Span", kwargs: Dict[str, Any]):
|
||||
from litellm.integrations._types.open_inference import (
|
||||
MessageAttributes,
|
||||
SpanAttributes,
|
||||
)
|
||||
|
||||
messages = kwargs.get("messages")
|
||||
|
||||
# for /chat/completions
|
||||
# https://docs.arize.com/arize/large-language-models/tracing/semantic-conventions
|
||||
if messages:
|
||||
|
|
@ -205,9 +207,7 @@ def set_attributes(
|
|||
SpanAttributes.OPENINFERENCE_SPAN_KIND,
|
||||
OpenInferenceSpanKindValues.LLM.value,
|
||||
)
|
||||
messages = kwargs.get("messages")
|
||||
|
||||
attributes.set_messages(span, messages)
|
||||
attributes.set_messages(span, kwargs)
|
||||
|
||||
# Capture tools (function definitions) used in the LLM call.
|
||||
tools = optional_params.get("tools")
|
||||
|
|
|
|||
|
|
@ -1,25 +1,104 @@
|
|||
import json
|
||||
from typing import TYPE_CHECKING, Any, Dict, List
|
||||
"""
|
||||
If the LLM Obs has any specific attributes to log request or response, we can add them here.
|
||||
|
||||
Relevant Issue: https://github.com/BerriAI/litellm/issues/13764
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
||||
|
||||
from numpy import isin
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import override
|
||||
|
||||
import litellm
|
||||
from litellm.integrations.opentelemetry_utils.base_otel_llm_obs_attributes import (
|
||||
BaseLLMObsOTELAttributes,
|
||||
safe_set_attribute,
|
||||
)
|
||||
from litellm.types.llms.openai import HttpxBinaryResponseContent, ResponsesAPIResponse
|
||||
from litellm.types.utils import (
|
||||
EmbeddingResponse,
|
||||
ImageResponse,
|
||||
ModelResponse,
|
||||
RerankResponse,
|
||||
TextCompletionResponse,
|
||||
TranscriptionResponse,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from opentelemetry.trace import Span
|
||||
|
||||
|
||||
def get_output_content_by_type(
|
||||
response_obj: Union[
|
||||
None,
|
||||
dict,
|
||||
EmbeddingResponse,
|
||||
ModelResponse,
|
||||
TextCompletionResponse,
|
||||
ImageResponse,
|
||||
TranscriptionResponse,
|
||||
RerankResponse,
|
||||
HttpxBinaryResponseContent,
|
||||
ResponsesAPIResponse,
|
||||
list,
|
||||
],
|
||||
kwargs: Optional[Dict[str, Any]] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Extract output content from response objects based on their type.
|
||||
|
||||
This utility function handles the type-specific logic for converting
|
||||
various response objects into appropriate output formats for Langfuse logging.
|
||||
|
||||
Args:
|
||||
response_obj: The response object returned by the function
|
||||
kwargs: Optional keyword arguments containing call_type and other metadata
|
||||
|
||||
Returns:
|
||||
The formatted output content suitable for Langfuse logging, or None
|
||||
"""
|
||||
if response_obj is None:
|
||||
return ""
|
||||
|
||||
kwargs = kwargs or {}
|
||||
call_type = kwargs.get("call_type", None)
|
||||
|
||||
# Embedding responses - no output content
|
||||
if call_type == "embedding" or isinstance(response_obj, EmbeddingResponse):
|
||||
return "embedding-output"
|
||||
|
||||
# Binary/Speech responses
|
||||
if isinstance(response_obj, HttpxBinaryResponseContent):
|
||||
return "speech-output"
|
||||
|
||||
if isinstance(response_obj, BaseModel):
|
||||
return response_obj.model_dump_json()
|
||||
|
||||
if response_obj and (
|
||||
isinstance(response_obj, dict) or isinstance(response_obj, list)
|
||||
):
|
||||
return json.dumps(response_obj)
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
class LangfuseLLMObsOTELAttributes(BaseLLMObsOTELAttributes):
|
||||
@staticmethod
|
||||
@override
|
||||
def set_messages(span: "Span", messages: List[Dict[str, Any]]):
|
||||
safe_set_attribute(
|
||||
span, "langfuse.observation.input", json.dumps({"messages": messages})
|
||||
)
|
||||
def set_messages(span: "Span", kwargs: Dict[str, Any]):
|
||||
prompt = {"messages": kwargs.get("messages")}
|
||||
optional_params = kwargs.get("optional_params", {})
|
||||
functions = optional_params.get("functions")
|
||||
tools = optional_params.get("tools")
|
||||
if functions is not None:
|
||||
prompt["functions"] = functions
|
||||
if tools is not None:
|
||||
prompt["tools"] = tools
|
||||
|
||||
input = prompt
|
||||
safe_set_attribute(span, "langfuse.observation.input", json.dumps(input))
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
|
|
@ -27,9 +106,5 @@ class LangfuseLLMObsOTELAttributes(BaseLLMObsOTELAttributes):
|
|||
safe_set_attribute(
|
||||
span,
|
||||
"langfuse.observation.output",
|
||||
(
|
||||
response_obj.model_dump_json()
|
||||
if isinstance(response_obj, BaseModel)
|
||||
else response_obj
|
||||
),
|
||||
get_output_content_by_type(response_obj),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class BaseLLMObsOTELAttributes(ABC):
|
||||
@staticmethod
|
||||
def set_messages(span: "Span", messages: List[Dict[str, Any]]):
|
||||
def set_messages(span: "Span", kwargs: Dict[str, Any]):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue