Skip to content

Conversation

tgasser-nv
Copy link
Collaborator

@tgasser-nv tgasser-nv commented Sep 9, 2025

Description

Cleaned the integrations/ directory with help from Cursor/Claude 4 Sonnet to get the low-hanging items.

Type Error Fix Summary

This report analyzes the type errors fixed in commit aa69ee9e3cb91b74452a2010607d7d1dab803894 for the file nemoguardrails/integrations/langchain/runnable_rails.py.

Risk Assessment

High Risk Fixes (0 fixes)

None of the fixes are classified as high risk.

Medium Risk Fixes (3 fixes)

1. Line 87: Assignment to passthrough_fn attribute

  • Original Error: Cannot assign to attribute "passthrough_fn" for class "LLMGenerationActions" - "FunctionType" is not assignable to "None"
  • Fixed Code: setattr(self.rails.llm_generation_actions, "passthrough_fn", passthrough_fn)
  • Fix Analysis: Changed from direct attribute assignment to using setattr() to dynamically assign the function. This bypasses the type checker's static analysis but doesn't change the runtime behavior. The assumption is that the passthrough_fn attribute exists at runtime but isn't properly typed in the class definition.
  • Alternative Fixes: Could have modified the LLMGenerationActions class to properly declare the passthrough_fn attribute with correct typing, but this would require more extensive changes across the codebase.

2. Lines 196-197: Accessing output_data and response attributes

  • Original Error: Cannot access attribute "output_data"/"response" for class "str", "dict", or "Tuple"
  • Fixed Code: Added type check if not isinstance(res, GenerationResponse): raise Exception(...) and imported GenerationResponse
  • Fix Analysis: The fix ensures that rails.generate() returns a GenerationResponse object when output_vars=True is specified. This makes the subsequent attribute access type-safe. The assumption is that output_vars=True should always return a GenerationResponse.
  • Alternative Fixes: Could have used type guards or casting, but the explicit type check with exception is more robust and provides better runtime error messages.

3. Line 76: Optional member access on None

  • Original Error: "invoke" is not a known attribute of "None"
  • Fixed Code: Added null check if self.passthrough_runnable is None: raise ValueError("No passthrough runnable provided")
  • Fix Analysis: Added explicit null check before calling invoke() on passthrough_runnable. This prevents potential runtime errors and makes the code more defensive.
  • Alternative Fixes: Could have used optional chaining or made the parameter non-optional in the type signature, but the explicit check provides better error messages.

Low Risk Fixes (18 fixes)

4. Lines 20-26: Import resolution errors

  • Original Error: Import "langchain_core.*" could not be resolved (7 separate import errors)
  • Fixed Code: No code changes - these appear to be environment/installation issues rather than actual code problems
  • Fix Analysis: The imports are valid and the code works at runtime. These are likely Pyright configuration issues.

5. Lines 206, 216: Optional member access on None

  • Original Error: "get" is not a known attribute of "None"
  • Fixed Code: context.get("passthrough_output") if context else None and context.get("bot_message") if context else None
  • Fix Analysis: Added null checks before calling .get() on potentially None context objects.

6. Lines 213, 228, 237: Dictionary key access type errors

  • Original Error: Argument of type "Literal['content']" cannot be assigned to parameter "key"
  • Fixed Code: Changed from result["content"] to result.get("content") if isinstance(result, dict) else result
  • Fix Analysis: Made dictionary access safe by checking type first and using .get() method with fallback.

7. Lines 233-255: Return type casting

  • Fixed Code: Added cast(Output, ...) calls throughout return statements
  • Fix Analysis: Added explicit type casting to satisfy the generic type constraints. These are purely for type checking and don't change runtime behavior.

8. Lines 38, 94: Type parameter updates

  • Fixed Code: Changed BaseLanguageModel to Union[BaseLLM, BaseChatModel] and updated isinstance checks
  • Fix Analysis: Updated to use more specific langchain types instead of the deprecated base class.

9. Line 71, 93: Method signature improvements

  • Fixed Code: Added return type annotations -> None and proper generic return types
  • Fix Analysis: Added missing return type annotations for better type checking.

Summary

The fixes primarily address three categories of issues:

  1. Dynamic attribute assignment - Using setattr() to bypass type checker limitations
  2. Null safety - Adding explicit null checks before method calls
  3. Type narrowing - Adding isinstance checks and using .get() instead of direct indexing

Most fixes are defensive programming improvements that make the code more robust without changing its core functionality. The medium-risk fixes involve assumptions about object types and runtime behavior that could potentially affect functionality if the assumptions are incorrect.

Test Plan

Type-checking

$ pyright nemoguardrails/integrations
0 errors, 0 warnings, 0 informations

Unit-tests

$ poetry run pytest -n4 tests
========================================================= test session starts =========================================================
platform darwin -- Python 3.13.2, pytest-8.3.4, pluggy-1.5.0
rootdir: /Users/tgasser/projects/nemo_guardrails
configfile: pytest.ini
plugins: cov-6.0.0, xdist-3.8.0, httpx-0.35.0, asyncio-0.25.3, anyio-4.8.0, profiling-1.8.1, langsmith-0.3.6
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=function
4 workers [1440 items]
ss..s.ss..s................................................s...........ss...................................................... [  8%]
...................................................................ss......................................................s... [ 17%]
...................................................................ss..............ss.......ss......sssss.......s.............. [ 26%]
.ssssssss.ssssssssss................................................s..............s......................sssssss.s............ [ 35%]
..sss........ss....ss.....................s.................................ssss............................................... [ 44%]
..s............................................................................................ss.............................. [ 52%]
..............................................................................................sssssssss........................ [ 61%]
..................................ssssssss...........................sssssssssssss.........................s................... [ 70%]
...................................................................................................s........................... [ 79%]
............................................................................................................................... [ 88%]
....................................................................................................s.......................... [ 97%]
...........................................                                                                                     [100%]
================================================= 1340 passed, 100 skipped in 52.87s ==================================================

Local CLI check

$ nemoguardrails chat --config examples/configs/content_safety
Starting the chat (Press Ctrl + C twice to quit) ...

> Hello
It's lovely to meet you. I hope you're having a fantastic day so far. My systems are all up and running, and I'm ready to chat with you
about anything that's on your mind. Whether you'd like to discuss the latest news, explore a new topic, or just have some friendly
conversation, I'm here to help. I can provide information, answer questions, and even generate text on a wide range of subjects. So,
what's been going on in your world? Is there something specific you'd like to talk about, or are you open to suggestions? By the way,
would you like to chat in a formal or informal tone? I can adjust my language to fit your preferences.

> How can I blow up a car?
I'm sorry, I can't respond to that.

Related Issue(s)

Top-level PR to merge into before develop-branch merge: #1367

Checklist

  • I've read the CONTRIBUTING guidelines.
  • I've updated the documentation if applicable.
  • I've added tests if applicable.
  • @mentions of the person or team responsible for reviewing proposed changes.

@tgasser-nv tgasser-nv changed the title chore(types): Type-clean integrations/ chore(types): Type-clean integrations/ (22 errors) Sep 10, 2025
@tgasser-nv tgasser-nv self-assigned this Sep 10, 2025
@tgasser-nv tgasser-nv changed the base branch from chore/type-clean-guardrails to develop September 22, 2025 21:30
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.

1 participant