110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
|
|
from opentelemetry.instrumentation.together.utils import dont_throw, should_send_prompts
|
||
|
|
from opentelemetry.semconv._incubating.attributes import (
|
||
|
|
gen_ai_attributes as GenAIAttributes,
|
||
|
|
)
|
||
|
|
from opentelemetry.semconv_ai import (
|
||
|
|
LLMRequestTypeValues,
|
||
|
|
SpanAttributes,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def _set_span_attribute(span, name, value):
|
||
|
|
if value is not None:
|
||
|
|
if value != "":
|
||
|
|
span.set_attribute(name, value)
|
||
|
|
return
|
||
|
|
|
||
|
|
|
||
|
|
@dont_throw
|
||
|
|
def set_prompt_attributes(span, llm_request_type, kwargs):
|
||
|
|
if not span.is_recording():
|
||
|
|
return
|
||
|
|
|
||
|
|
if should_send_prompts():
|
||
|
|
if llm_request_type == LLMRequestTypeValues.CHAT:
|
||
|
|
_set_span_attribute(span, f"{GenAIAttributes.GEN_AI_PROMPT}.0.role", "user")
|
||
|
|
for index, message in enumerate(kwargs.get("messages")):
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
f"{GenAIAttributes.GEN_AI_PROMPT}.{index}.content",
|
||
|
|
message.get("content"),
|
||
|
|
)
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
f"{GenAIAttributes.GEN_AI_PROMPT}.{index}.role",
|
||
|
|
message.get("role"),
|
||
|
|
)
|
||
|
|
elif llm_request_type == LLMRequestTypeValues.COMPLETION:
|
||
|
|
_set_span_attribute(span, f"{GenAIAttributes.GEN_AI_PROMPT}.0.role", "user")
|
||
|
|
_set_span_attribute(
|
||
|
|
span, f"{GenAIAttributes.GEN_AI_PROMPT}.0.content", kwargs.get("prompt")
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@dont_throw
|
||
|
|
def set_model_prompt_attributes(span, kwargs):
|
||
|
|
if not span.is_recording():
|
||
|
|
return
|
||
|
|
|
||
|
|
_set_span_attribute(span, GenAIAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model"))
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
SpanAttributes.LLM_IS_STREAMING,
|
||
|
|
kwargs.get("stream"),
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@dont_throw
|
||
|
|
def set_completion_attributes(span, llm_request_type, response):
|
||
|
|
if not span.is_recording():
|
||
|
|
return
|
||
|
|
|
||
|
|
if should_send_prompts():
|
||
|
|
if llm_request_type == LLMRequestTypeValues.COMPLETION:
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
f"{GenAIAttributes.GEN_AI_COMPLETION}.0.content",
|
||
|
|
response.choices[0].text,
|
||
|
|
)
|
||
|
|
_set_span_attribute(
|
||
|
|
span, f"{GenAIAttributes.GEN_AI_COMPLETION}.0.role", "assistant"
|
||
|
|
)
|
||
|
|
elif llm_request_type == LLMRequestTypeValues.CHAT:
|
||
|
|
index = 0
|
||
|
|
prefix = f"{GenAIAttributes.GEN_AI_COMPLETION}.{index}"
|
||
|
|
_set_span_attribute(
|
||
|
|
span, f"{prefix}.content", response.choices[0].message.content
|
||
|
|
)
|
||
|
|
_set_span_attribute(
|
||
|
|
span, f"{prefix}.role", response.choices[0].message.role
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@dont_throw
|
||
|
|
def set_model_completion_attributes(span, response):
|
||
|
|
if not span.is_recording():
|
||
|
|
return
|
||
|
|
|
||
|
|
_set_span_attribute(span, GenAIAttributes.GEN_AI_RESPONSE_MODEL, response.model)
|
||
|
|
_set_span_attribute(span, GenAIAttributes.GEN_AI_RESPONSE_ID, response.id)
|
||
|
|
|
||
|
|
usage_data = response.usage
|
||
|
|
input_tokens = getattr(usage_data, "prompt_tokens", 0)
|
||
|
|
output_tokens = getattr(usage_data, "completion_tokens", 0)
|
||
|
|
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
SpanAttributes.LLM_USAGE_TOTAL_TOKENS,
|
||
|
|
input_tokens + output_tokens,
|
||
|
|
)
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS,
|
||
|
|
output_tokens,
|
||
|
|
)
|
||
|
|
_set_span_attribute(
|
||
|
|
span,
|
||
|
|
GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS,
|
||
|
|
input_tokens,
|
||
|
|
)
|