Skip to content

Conversation

divya-garak
Copy link

Summary

Fixes #472: This PR resolves the issue where Langfuse tracing integration was broken when using NeMo-Guardrails with LangChain chains.

The problem was that the RunnableConfig containing callbacks wasn't being properly passed through to the underlying LLM runnable in the passthrough function.

Changes Made

  • Store config and kwargs: Modified RunnableRails.invoke() to store the RunnableConfig and kwargs for later use in the passthrough function
  • Pass config to underlying runnable: Updated _init_passthrough_fn() to use the stored config when invoking the passthrough runnable
  • Added comprehensive test: Created test_runnable_config_callback_passthrough() to verify that callbacks are properly propagated

Technical Details

The issue occurred because:

  1. RunnableRails.invoke() received a config parameter with callbacks
  2. The passthrough_fn was called asynchronously through the Rails system
  3. The original config wasn't available in the passthrough function scope
  4. Callbacks (like Langfuse tracing) weren't being called

Testing

  • ✅ All existing tests continue to pass
  • ✅ New test verifies callback passthrough functionality
  • ✅ Tested with passthrough mode scenarios

This ensures that tracing libraries like Langfuse work correctly when using RunnableRails in LangChain chains.

Fixes NVIDIA-NeMo#472: The langchain runnable was not called with the runnable
config that defines callbacks, breaking Langfuse tracing integration.

Changes:
- Store RunnableConfig and kwargs from invoke() for use in passthrough function
- Pass stored config to underlying runnable to preserve callbacks
- Add test to verify callback passthrough functionality

This ensures that callbacks (like Langfuse tracing) are properly
propagated to the underlying LLM runnable wrapped in RunnableRails.
@Pouyanpi Pouyanpi requested a review from Copilot September 18, 2025 14:40
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes Langfuse callback passthrough in RunnableRails when integrated with LangChain chains by ensuring the RunnableConfig containing callbacks is properly propagated to the underlying runnable.

  • Modified RunnableRails to store config and kwargs from invoke() method for later use in passthrough function
  • Updated passthrough function to use stored config when invoking the underlying runnable
  • Added comprehensive test to verify callback propagation functionality

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
nemoguardrails/integrations/langchain/runnable_rails.py Added instance variables to store current config/kwargs and modified passthrough function to use them
tests/test_runnable_rails.py Added test case to verify RunnableConfig callbacks are properly passed through to underlying runnable

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 198 to 199
self.config = config
self.kwargs = kwargs
Copy link
Preview

Copilot AI Sep 18, 2025

Choose a reason for hiding this comment

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

There's duplicate assignment here. Both self.config and self._current_config are assigned the same value, as are self.kwargs and self._current_kwargs. Consider removing the redundant assignments to self.config and self.kwargs since they appear to be legacy variables that are now replaced by the _current_* variants.

Suggested change
self.config = config
self.kwargs = kwargs

Copilot uses AI. Check for mistakes.

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.

NeMo-Guardrails breaks Langfuse integration / Runnable config is ignored in LLM call
1 participant