Skip to content

Add tools support in langchain#37

Open
wrisa wants to merge 20 commits into
open-telemetry:mainfrom
wrisa:tools-langchain
Open

Add tools support in langchain#37
wrisa wants to merge 20 commits into
open-telemetry:mainfrom
wrisa:tools-langchain

Conversation

@wrisa

@wrisa wrisa commented May 18, 2026

Copy link
Copy Markdown
Contributor

examples/tools/main.py
Tools span:
Screenshot 2026-05-18 at 9 52 10 AM

Inference spans with tool details:
Screenshot 2026-05-18 at 9 52 23 AM
Screenshot 2026-05-18 at 9 52 35 AM

@lmolkova lmolkova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, let's just update langchain to use new InferenceInvocation instead of deprecated LLMInvocation

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 days of this comment.
If you're still working on this, please add a comment or push new commits.

@github-actions github-actions Bot added the Stale Issue or PR has been inactive label Jun 2, 2026
@wrisa wrisa marked this pull request as ready for review June 8, 2026 15:00
@wrisa wrisa requested a review from a team as a code owner June 8, 2026 15:00
Copilot AI review requested due to automatic review settings June 8, 2026 15:00

Copilot AI left a comment

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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds LangChain tool-calling instrumentation support by creating dedicated tool execution spans and capturing tool definitions/tool-call requests in inference spans, along with tests, conformance coverage, and a runnable example.

Changes:

  • Add tool span lifecycle handling (on_tool_start/on_tool_end/on_tool_error) and record tool-call requests on tool_calls finish reason.
  • Capture tool definitions from chat model invocation params (tools / functions) into inference spans.
  • Add extensive unit/integration tests, a new conformance scenario + VCR cassette, and a tool-calling example.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
instrumentation/opentelemetry-instrumentation-genai-langchain/src/opentelemetry/instrumentation/genai/langchain/utils.py Adds helpers to normalize tool definitions into semantic-convention types.
instrumentation/opentelemetry-instrumentation-genai-langchain/src/opentelemetry/instrumentation/genai/langchain/callback_handler.py Implements tool span callbacks and emits tool-call request parts on tool-calling responses.
instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_tools.py Adds unit + callback-handler integration tests for tools and tool-calling outputs.
instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_conformance.py Registers the new tool-calling conformance scenario.
instrumentation/opentelemetry-instrumentation-genai-langchain/tests/conformance/tool_calling.py Adds a tool-calling conformance scenario using ChatOpenAI.bind_tools.
instrumentation/opentelemetry-instrumentation-genai-langchain/tests/cassettes/tool_calling_conformance.yaml Adds recorded OpenAI HTTP interactions for the conformance scenario.
instrumentation/opentelemetry-instrumentation-genai-langchain/examples/tools/main.py Adds a runnable tool-calling example.
instrumentation/opentelemetry-instrumentation-genai-langchain/examples/tools/requirements.txt Adds example dependencies.
instrumentation/opentelemetry-instrumentation-genai-langchain/.changelog/37.added Records the feature in the changelog.

Comment thread instrumentation/opentelemetry-instrumentation-genai-langchain/.changelog/37.added Outdated
@github-actions github-actions Bot removed the Stale Issue or PR has been inactive label Jun 9, 2026
raw_arguments: Any = inputs if inputs is not None else input_str
arguments: str | None
if isinstance(raw_arguments, dict):
arguments = json.dumps(raw_arguments)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is this necessary? can we pass Any ?

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.

Yes, it's necessary. invocation.arguments is typed AttributeValue | None, which doesn't accept dict. The block converts the structured inputs: dict to a JSON string, falling back to the
plain input_str: str. Passing Any directly would be a type violation and would break span attribute setting at runtime when inputs is a dict.

tool_invocation = self._invocation_manager.get_invocation(run_id)
if not isinstance(tool_invocation, ToolInvocation):
return
tool_invocation.tool_call_id = getattr(output, "tool_call_id", None)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is getattr necessary ?

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.

It is defensive pattern here given the output:Any - typed parameter

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants