Skip to content

style(langchain): format codebase and verify ToolNode agent creation …#4368

Open
ManyaS-Git wants to merge 1 commit into
traceloop:mainfrom
ManyaS-Git:fix/langgraph-toolnode-iterable
Open

style(langchain): format codebase and verify ToolNode agent creation …#4368
ManyaS-Git wants to merge 1 commit into
traceloop:mainfrom
ManyaS-Git:fix/langgraph-toolnode-iterable

Conversation

@ManyaS-Git

@ManyaS-Git ManyaS-Git commented Jul 18, 2026

Copy link
Copy Markdown

…patch

  • I have added tests that cover my changes.
  • If adding a new instrumentation or changing an existing one, I've added screenshots from some observability platform showing the change.
  • PR name follows conventional commits format: feat(instrumentation): ... or fix(instrumentation): ....
  • (If applicable) I have updated the documentation accordingly.

Summary by CodeRabbit

  • Refactor
    • Improved internal code consistency and readability across LangChain and LangGraph instrumentation.
    • Preserved existing tracing, event emission, vendor detection, prompt handling, and token-usage behavior.
  • Tests
    • Standardized test formatting and assertions while maintaining existing coverage and expected results.

@CLAassistant

CLAassistant commented Jul 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR reformats LangChain instrumentation, LangGraph patching, span utilities, event emission, vendor rules, fixtures, and extensive tests. Existing wrapper targets, tracing behavior, metric expectations, event payloads, and test logic are preserved.

Changes

LangChain instrumentation

Layer / File(s) Summary
Instrumentation and callback wiring
opentelemetry/instrumentation/langchain/__init__.py, callback_handler.py, event_emitter.py
Reformats wrapper registration, callback span handling, token usage, event emission, and tracing context operations.
LangGraph patching and agent spans
opentelemetry/instrumentation/langchain/patch.py
Adds lazy context-var lookup and reformats graph naming, invocation, routing, middleware, and agent tool-definition handling without changing documented behavior.
Span data and request helpers
opentelemetry/instrumentation/langchain/span_utils.py, utils.py, vendor_detection.py
Reformats message-part construction, request/response usage handling, prompt/event gating, and vendor rule declarations.
Fixtures and metric validation
tests/conftest.py, tests/metrics/test_langchain_metrics.py
Reformats fixtures and metric assertions while retaining provider, token, duration, and generation-choice expectations.
Instrumentation regression tests
tests/test_*.py
Compacts setup, span selection, event assertions, lifecycle checks, tool-call tests, and trace-propagation tests without changing their expected behavior.

Estimated code review effort: 2 (Simple) | ~15 minutes

Suggested reviewers: doronkopit5

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main themes: broad formatting cleanup plus LangChain/LangGraph agent-creation verification changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (defensive_cruft, description_diff_mismatch). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py`:
- Around line 745-749: Update the token-count initialization in the callback
handling flow around total_tokens so missing prompt and completion values
default to 0 for arithmetic and comparisons, while preserving None when setting
semantic span attributes so absent token data remains omitted. Ensure the
total-token calculation and the later prompt_tokens/completion_tokens checks
cannot receive None.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 441ae3c1-2a99-480f-a99b-52e713957e06

📥 Commits

Reviewing files that changed from the base of the PR and between 93429cf and f915b51.

⛔ Files ignored due to path filters (1)
  • packages/opentelemetry-instrumentation-langchain/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/__init__.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/event_emitter.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/patch.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/utils.py
  • packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/vendor_detection.py
  • packages/opentelemetry-instrumentation-langchain/tests/conftest.py
  • packages/opentelemetry-instrumentation-langchain/tests/metrics/test_langchain_metrics.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_agents.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_batch_metadata.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_chains.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_context_token_lifecycle.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_documents_chains.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_finish_reasons.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_generation_role_extraction.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_langgraph.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_lcel.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_llms.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_non_ascii_content.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_structured_output.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_tool_call_content.py
  • packages/opentelemetry-instrumentation-langchain/tests/test_tool_calls.py

Comment on lines +745 to +749
total_tokens = token_usage.get("total_tokens") or (prompt_tokens + completion_tokens)

_set_span_attribute(
span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens
)
_set_span_attribute(
span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
_set_span_attribute(
span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens
)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens)
_set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent TypeError when token counts are missing.

If the token_usage dictionary is empty or lacks explicit prompt/completion token keys, both prompt_tokens and completion_tokens will evaluate to None. This causes a TypeError when computing prompt_tokens + completion_tokens, and another TypeError later when evaluating if prompt_tokens > 0: (around line 753). Defaulting them to 0 prevents both crashes while retaining the exact semantic attribute omission via None.

🔧 Proposed fix
-            total_tokens = token_usage.get("total_tokens") or (prompt_tokens + completion_tokens)
-
-            _set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens)
-            _set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens)
-            _set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens)
+            prompt_tokens = prompt_tokens or 0
+            completion_tokens = completion_tokens or 0
+            total_tokens = token_usage.get("total_tokens") or (prompt_tokens + completion_tokens)
+
+            _set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens if prompt_tokens > 0 else None)
+            _set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens if completion_tokens > 0 else None)
+            _set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens if total_tokens > 0 else None)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
total_tokens = token_usage.get("total_tokens") or (prompt_tokens + completion_tokens)
_set_span_attribute(
span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens
)
_set_span_attribute(
span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
_set_span_attribute(
span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens
)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens)
_set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens)
prompt_tokens = prompt_tokens or 0
completion_tokens = completion_tokens or 0
total_tokens = token_usage.get("total_tokens") or (prompt_tokens + completion_tokens)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens if prompt_tokens > 0 else None)
_set_span_attribute(span, GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens if completion_tokens > 0 else None)
_set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens if total_tokens > 0 else None)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py`
around lines 745 - 749, Update the token-count initialization in the callback
handling flow around total_tokens so missing prompt and completion values
default to 0 for arithmetic and comparisons, while preserving None when setting
semantic span attributes so absent token data remains omitted. Ensure the
total-token calculation and the later prompt_tokens/completion_tokens checks
cannot receive None.

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.

2 participants