Skip to content

GenAI Utils | Add support for ToolCall Invocations#4356

Open
keith-decker wants to merge 51 commits intoopen-telemetry:mainfrom
keith-decker:toolcall-handler-and-spans
Open

GenAI Utils | Add support for ToolCall Invocations#4356
keith-decker wants to merge 51 commits intoopen-telemetry:mainfrom
keith-decker:toolcall-handler-and-spans

Conversation

@keith-decker
Copy link
Copy Markdown
Contributor

@keith-decker keith-decker commented Mar 24, 2026

Description

Implementing the ToolCall handler methods. Check out the example app here

Some output from the example app:

Trace ID: 9db02aa0f3f04e3280383277aeb8daa1
└── Span ID: a6aac8039683ad5f (Parent: none) - Name: agent_workflow [op:invoke_agent] (Type: span)
    ├── Span ID: f225d302435ccab6 (Parent: a6aac8039683ad5f) - Name: chat gpt-4o-mini [op:chat] (Type: span)
    │   ├── Metric: gen_ai.client.operation.duration [op:chat] (Type: metric)
    │   ├── Metric: gen_ai.client.token.usage (input) [op:chat] (Type: metric)
    │   └── Metric: gen_ai.client.token.usage (output) [op:chat] (Type: metric)
    └── Span ID: a56510b4b1a902c5 (Parent: a6aac8039683ad5f) - Name: execute_tool get_weather [op:execute_tool] (Type: span)
Span #1
    Trace ID       : 9db02aa0f3f04e3280383277aeb8daa1
    Parent ID      : a6aac8039683ad5f
    ID             : a56510b4b1a902c5
    Name           : execute_tool get_weather
    Kind           : Internal
    Start time     : 2026-03-24 21:12:59.832384 +0000 UTC
    End time       : 2026-03-24 21:12:59.833126 +0000 UTC
    Status code    : Ok
    Status message : 
Attributes:
     -> gen_ai.operation.name: Str(execute_tool)
     -> gen_ai.tool.name: Str(get_weather)
     -> gen_ai.tool.call.id: Str(019d21b1-96b8-7f00-961c-e2e9c1a0baa1)
     -> gen_ai.tool.type: Str(function)
     -> gen_ai.tool.description: Str(Get current weather for a location.

    Args:
        location: The city name to get weather for.

    Returns:
        Weather information as a string.)

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Test A

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

keith-decker and others added 30 commits February 19, 2026 15:55
…pentelemetry-python-contrib into pr1-enhance-toolcall-type
@keith-decker keith-decker force-pushed the toolcall-handler-and-spans branch from 3b05b19 to a9f9eef Compare March 30, 2026 16:13
@keith-decker keith-decker marked this pull request as ready for review March 30, 2026 17:11
@keith-decker keith-decker requested a review from a team as a code owner March 30, 2026 17:11
@tammy-baylis-swi tammy-baylis-swi moved this to Ready for review in Python PR digest Apr 2, 2026
"""Fail an LLM invocation and end its span with error status."""
return self._fail(invocation, error)

@contextmanager
Copy link
Copy Markdown
Contributor

@DylanRussell DylanRussell Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the google gen AI instrumentation we monkey patch the actual function call: https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/tool_call_wrapper.py#L164

IDK if it makes sense to do something like that here or not (accept the actual Callable object)?

Either way I'll try to update that instrumentation to use this once we submit

Copy link
Copy Markdown
Contributor

@eternalcuriouslearner eternalcuriouslearner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM!! I left few questions to understand the design better.

# Metric-related fields (for gen_ai.client.operation.duration)
provider: str | None = None # gen_ai.provider.name (Required for metrics)
server_address: str | None = None # server.address (Recommended)
server_port: int | None = None # server.port (Conditionally Required)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why are we ignoring attributes: dict[str, Any] = field(default_factory=_new_str_any_dict) attribute here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are properties used by the metrics. the attributes you mentioned is used for custom attributes the user might want to use on the span.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh dumb question are we ignoring custom attributes for ToolCall?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

6 participants