Tool calls should be instrumented as well. There can be multiple tool calls, so we treat this like we treat input_messages above. This example uses OpenAi tool call type but can be easily adapted to any tool call with a function name and arguments (as JSON).
Copy from typing import List
from openai . types . chat . chat_completion_chunk import ChoiceDeltaToolCall
from openinference . semconv . trace import (
MessageAttributes ,
OpenInferenceSpanKindValues ,
SpanAttributes ,
ToolCallAttributes ,
)
from opentelemetry . trace import Span
def set_tool_call_attrs ( tool_span : Span , tool_calls : List [ ChoiceDeltaToolCall ] ) -> None :
tool_span . set_attribute (
SpanAttributes.OPENINFERENCE_SPAN_KIND,
OpenInferenceSpanKindValues.TOOL.value,
)
for idx , tool_call in enumerate (tool_calls):
function = tool_call . function
if not function :
continue
tool_span . set_attribute (
f " { MessageAttributes.MESSAGE_TOOL_CALLS } . { idx } ."
f " { ToolCallAttributes.TOOL_CALL_FUNCTION_NAME } " ,
function.name or "" ,
)
tool_span . set_attribute (
f " { MessageAttributes.MESSAGE_TOOL_CALLS } . { idx } ."
f " { ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON } " ,
function.arguments or "" ,
)