Skip to content

Conversation

@saksharthakkar
Copy link
Contributor

Summary

  • Thread RunnableConfig from BaseTool through tool_fn to llm.ainvoke() in the Analyze Files tool
  • Fixes LLM call span not being linked to parent tool span (LLMOPS-2067)
  • LangChain auto-injects child config with correct parent_run_id when tool_fn declares a config: RunnableConfig param

Test plan

  • Run agent with Analyze Files tool and verify LLM span nests under tool span in trace UI
  • Verify no regression in Analyze Files tool functionality
  • Confirm ruff + mypy pass

🤖 Generated with Claude Code

saksharthakkar and others added 3 commits February 10, 2026 21:02
…parenting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@saksharthakkar saksharthakkar changed the title (wip) fix: thread RunnableConfig to analyze_files LLM call for proper span parenting fix: thread RunnableConfig to analyze_files LLM call for proper span parenting Feb 11, 2026
@cristian-groza cristian-groza marked this pull request as ready for review February 11, 2026 13:12
@cristian-groza cristian-groza self-requested a review February 11, 2026 14:09
saksharthakkar and others added 6 commits February 11, 2026 16:10
…hierarchy

Thread RunnableConfig from LangGraph node through wrapper chain to tool.ainvoke()
so inner LLM calls (e.g. Analyze_Files) produce correctly nested spans instead
of orphaned siblings.

- tool_node.py: accept config param, pass to tool.invoke() or set contextvar
- job_attachment_wrapper.py: read config from contextvar, pass to tool.ainvoke()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines 89 to 90
config = var_child_runnable_config.get(None)
tool_result = await tool.ainvoke(call, config=config)
Copy link
Contributor

Choose a reason for hiding this comment

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

since we have this system in place? why even pass it through the structured tool? We could retrieve it like this right before the LLM invoke. Is there any reason why we need to pass it through structured tool? Does it affect the way the Tool spans integrate with the LLM span?

I have certain opinions on Langchain's system with RunnableConfig being passed everywhere (though it's nowhere near as an offender as ToolRuntime in that regard), so i'm reluctant to mix it in with our node.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call! Now we just read var_child_runnable_config.get(None) directly in analyze_files_tool.py right before llm.ainvoke(). No RunnableConfig in the node/wrapper layer at all.

@cristian-groza cristian-groza self-requested a review February 12, 2026 12:06
saksharthakkar and others added 2 commits February 12, 2026 11:31
…les_tool

Instead of threading RunnableConfig through tool_node.py and wrappers,
read it from the LangGraph-managed context variable where it's needed.
This simplifies the code and avoids mixing config into the tool node layer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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