1414limitations under the License.
1515"""
1616
17- import json
18-
19- from langtrace .trace_attributes import Event , LLMSpanAttributes
17+ from typing import Any , Callable , Dict , List , Optional , Iterator , TypedDict , Union
18+ from langtrace .trace_attributes import Event , SpanAttributes , LLMSpanAttributes
2019from langtrace_python_sdk .utils import set_span_attribute
2120from langtrace_python_sdk .utils .silently_fail import silently_fail
2221
2726 get_llm_request_attributes ,
2827 get_llm_url ,
2928 get_span_name ,
30- is_streaming ,
3129 set_event_completion ,
3230 set_usage_attributes ,
31+ set_span_attribute ,
3332)
34- from opentelemetry .trace import SpanKind
35- from opentelemetry .trace .status import Status , StatusCode
36- from langtrace .trace_attributes import SpanAttributes
37-
33+ from opentelemetry .trace import Span , Tracer , SpanKind
34+ from opentelemetry .trace .status import StatusCode
3835from langtrace_python_sdk .constants .instrumentation .anthropic import APIS
39- from langtrace_python_sdk .constants .instrumentation .common import (
40- SERVICE_PROVIDERS ,
36+ from langtrace_python_sdk .constants .instrumentation .common import SERVICE_PROVIDERS
37+ from langtrace_python_sdk .instrumentation .anthropic .types import (
38+ StreamingResult ,
39+ ResultType ,
40+ MessagesCreateKwargs ,
41+ ContentItem ,
42+ Usage ,
4143)
4244
4345
44- def messages_create (original_method , version , tracer ) :
46+ def messages_create (version : str , tracer : Tracer ) -> Callable [..., Any ] :
4547 """Wrap the `messages_create` method."""
4648
47- def traced_method (wrapped , instance , args , kwargs ):
49+ def traced_method (
50+ wrapped : Callable [..., Any ],
51+ instance : Any ,
52+ args : List [Any ],
53+ kwargs : MessagesCreateKwargs ,
54+ ) -> Any :
4855 service_provider = SERVICE_PROVIDERS ["ANTHROPIC" ]
4956
50- # extract system from kwargs and attach as a role to the prompts
51- # we do this to keep it consistent with the openai
57+ # Extract system from kwargs and attach as a role to the prompts
5258 prompts = kwargs .get ("messages" , [])
5359 system = kwargs .get ("system" )
5460 if system :
5561 prompts = [{"role" : "system" , "content" : system }] + kwargs .get (
5662 "messages" , []
5763 )
58-
64+ extraAttributes = get_extra_attributes ()
5965 span_attributes = {
6066 ** get_langtrace_attributes (version , service_provider ),
6167 ** get_llm_request_attributes (kwargs , prompts = prompts ),
6268 ** get_llm_url (instance ),
6369 SpanAttributes .LLM_PATH : APIS ["MESSAGES_CREATE" ]["ENDPOINT" ],
64- ** get_extra_attributes (),
70+ ** extraAttributes , # type: ignore
6571 }
6672
6773 attributes = LLMSpanAttributes (** span_attributes )
@@ -74,37 +80,35 @@ def traced_method(wrapped, instance, args, kwargs):
7480 try :
7581 # Attempt to call the original method
7682 result = wrapped (* args , ** kwargs )
77- return set_response_attributes (result , span , kwargs )
83+ return set_response_attributes (result , span )
7884
7985 except Exception as err :
8086 # Record the exception in the span
8187 span .record_exception (err )
8288 # Set the span status to indicate an error
83- span .set_status (Status ( StatusCode .ERROR , str (err ) ))
89+ span .set_status (StatusCode .ERROR , str (err ))
8490 # Reraise the exception to ensure it's not swallowed
8591 span .end ()
8692 raise
8793
88- @silently_fail
89- def set_response_attributes (result , span , kwargs ):
90- if not is_streaming (kwargs ):
94+ def set_response_attributes (
95+ result : Union [ResultType , StreamingResult ], span : Span
96+ ) -> Any :
97+ if not isinstance (result , Iterator ):
9198 if hasattr (result , "content" ) and result .content is not None :
9299 set_span_attribute (
93100 span , SpanAttributes .LLM_RESPONSE_MODEL , result .model
94101 )
102+ content_item = result .content [0 ]
95103 completion = [
96104 {
97- "role" : result .role if result . role else "assistant" ,
98- "content" : result . content [ 0 ] .text ,
99- "type" : result . content [ 0 ] .type ,
105+ "role" : result .role or "assistant" ,
106+ "content" : content_item .text ,
107+ "type" : content_item .type ,
100108 }
101109 ]
102110 set_event_completion (span , completion )
103111
104- else :
105- responses = []
106- set_event_completion (span , responses )
107-
108112 if (
109113 hasattr (result , "system_fingerprint" )
110114 and result .system_fingerprint is not None
@@ -116,7 +120,7 @@ def set_response_attributes(result, span, kwargs):
116120 # Get the usage
117121 if hasattr (result , "usage" ) and result .usage is not None :
118122 usage = result .usage
119- set_usage_attributes (span , dict (usage ))
123+ set_usage_attributes (span , vars (usage ))
120124
121125 span .set_status (StatusCode .OK )
122126 span .end ()
0 commit comments