Skip to content

feat(api): canonical top-level imports for LLM types and registry functions#1882

Merged
Pouyanpi merged 2 commits into
developfrom
feat/vdr-canonical-import-paths
May 15, 2026
Merged

feat(api): canonical top-level imports for LLM types and registry functions#1882
Pouyanpi merged 2 commits into
developfrom
feat/vdr-canonical-import-paths

Conversation

@Pouyanpi
Copy link
Copy Markdown
Collaborator

@Pouyanpi Pouyanpi commented May 13, 2026

Description

Make from nemoguardrails import ... the canonical user-facing path for the integrator-facing surface of v0.22:

  • LLM types from nemoguardrails.types (ChatMessage, FinishReason, LLMFramework, LLMModel, LLMResponse, LLMResponseChunk, Role, ToolCall, ToolCallFunction, UsageInfo) are re-exported from both nemoguardrails (top-level) and nemoguardrails.llm.

  • Framework registry functions from nemoguardrails.llm.frameworks (register_framework, set_default_framework, get_default_framework) are also re-exported from nemoguardrails.llm. They were already exported from nemoguardrails top-level.

Custom LLM Framework, Custom LLM Model, and testing-your-config doc examples switch their import lines to the top-level form so the "integrator constructs value types and protocol classes" path uses one import statement.

nemoguardrails/types.py gains a module-level docstring documenting it as the stable public LLM interop surface, plus an explicit __all__ listing the public names.

Parametrized exports tests verify each name is exposed on every supported import path and resolves to the same canonical object.

Related Issue(s)

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.

Summary by CodeRabbit

Release Notes

  • New Features

    • Expanded the public API to expose core LLM types and framework utilities directly from the main package, eliminating the need for deep module imports and improving developer experience.
  • Documentation

    • Updated all code examples, guides, and initialization tutorials to reflect the new simplified import patterns for better discoverability.

Review Change Stack

…ctions

Make `from nemoguardrails import ...` the canonical user-facing path for
the integrator-facing surface of v0.22:

- LLM types from `nemoguardrails.types` (ChatMessage, FinishReason,
  LLMFramework, LLMModel, LLMResponse, LLMResponseChunk, Role, ToolCall,
  ToolCallFunction, UsageInfo) are re-exported from both `nemoguardrails`
  (top-level) and `nemoguardrails.llm`.
- Framework registry functions from `nemoguardrails.llm.frameworks`
  (register_framework, set_default_framework, get_default_framework) are
  also re-exported from `nemoguardrails.llm`. They were already exported
  from `nemoguardrails` top-level.

Custom LLM Framework, Custom LLM Model, and testing-your-config doc
examples switch their import lines to the top-level form so the
"integrator constructs value types and protocol classes" path uses one
import statement.

`nemoguardrails/types.py` gains a module-level docstring documenting it
as the stable public LLM interop surface, plus an explicit `__all__`
listing the public names.

Parametrized exports tests verify each name is exposed on every
supported import path and resolves to the same canonical object.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 13, 2026

Greptile Summary

This PR establishes from nemoguardrails import … as the canonical public import path for the v0.22 integrator surface by re-exporting all ten LLM types from nemoguardrails.types and the four registry functions (register_framework, set_default_framework, get_default_framework, register_provider) from both nemoguardrails (top-level) and nemoguardrails.llm. Documentation examples are updated to the new single-import form, and a new parametrized test suite verifies presence in __all__, attribute access, and object identity across all supported import paths.

  • nemoguardrails/types.py gains a module-level docstring and explicit __all__, formalising the stable public LLM interop surface.
  • nemoguardrails/llm/__init__.py is promoted from an empty init to a re-export hub; the import chain is safe because neither llm/frameworks/ nor llm/providers/ import from the top-level nemoguardrails package.
  • Three documentation guides (custom-llm-framework.md, custom-llm-model.md, testing-your-config.md) are updated to the simplified import style.

Confidence Score: 5/5

Safe to merge — the change is purely additive re-exports with no behavioural modifications to existing code paths.

All modifications are additive: new names are re-exported, all lists are extended, and docs are updated to match. No existing import paths are removed, no logic is altered, and the import chain in the newly populated nemoguardrails/llm/init.py is acyclic because neither llm/frameworks/ nor llm/providers/ imports from the top-level nemoguardrails package. The new test suite covers attribute presence, all membership, and object identity across all three import paths.

No files require special attention.

Important Files Changed

Filename Overview
nemoguardrails/init.py Adds re-exports of all public LLM types from nemoguardrails.types and register_provider from nemoguardrails.llm.providers; updates all accordingly. No circular-import risk since types.py has no nemoguardrails-internal imports.
nemoguardrails/llm/init.py Transforms a previously empty init into a re-export hub for types and registry functions. Import chain is safe: frameworks/init.py and providers/init.py only import from sibling submodules, not from the top-level nemoguardrails package.
nemoguardrails/types.py Adds module docstring promising stability across minor versions and an explicit all. The listed names match the actual class/type definitions in the file.
tests/test_types_exports.py New parametrized test suite verifying presence in all, attribute access, and object identity across all three import paths for both type names and registry functions.
docs/configure-rails/custom-initialization/custom-llm-framework.md Updates code examples to use the new top-level import path; changes are cosmetic and consistent with the new public API.
docs/configure-rails/custom-initialization/custom-llm-model.md Consolidates previously separate imports of types and register_provider into a single from nemoguardrails import block, consistent with the new API surface.
docs/user-guides/testing-your-config.md Updates LLMResponse import to use the new top-level path. Correct and consistent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["from nemoguardrails import …\n(top-level __init__.py)"] --> B["nemoguardrails.types\nChatMessage, FinishReason,\nLLMFramework, LLMModel,\nLLMResponse, LLMResponseChunk,\nRole, ToolCall,\nToolCallFunction, UsageInfo"]
    A --> C["nemoguardrails.llm.frameworks\nregister_framework,\nset_default_framework,\nget_default_framework"]
    A --> D["nemoguardrails.llm.providers\nregister_provider"]

    E["from nemoguardrails.llm import …\n(llm __init__.py)"] --> B
    E --> C
    E --> D

    B --> F["nemoguardrails.llm.frameworks.registry\n(canonical implementation)"]
    C --> F
    D --> G["nemoguardrails.llm.frameworks\n(delegates to active framework)"]
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
tests/test_types_exports.py:74-89
The suite has `test_direct_from_imports_top_level` and `test_direct_from_imports_llm_subpackage` that exercise direct star-import style for all type names, but there is no equivalent direct-import smoke test for the four registry functions. A `SyntaxError`-style import failure (e.g. a typo in a future refactor) would only be caught by the parametrized attribute/identity tests, not by a `from nemoguardrails import register_provider, …` style check. Adding a parallel block for the registry names keeps the coverage symmetrical.

```suggestion
def test_direct_from_imports_llm_subpackage():
    from nemoguardrails.llm import (  # noqa: F401
        ChatMessage,
        FinishReason,
        LLMFramework,
        LLMModel,
        LLMResponse,
        LLMResponseChunk,
        Role,
        ToolCall,
        ToolCallFunction,
        UsageInfo,
    )

def test_direct_from_imports_registry_top_level():
    from nemoguardrails import (  # noqa: F401
        get_default_framework,
        register_framework,
        register_provider,
        set_default_framework,
    )

def test_direct_from_imports_registry_llm_subpackage():
    from nemoguardrails.llm import (  # noqa: F401
        get_default_framework,
        register_framework,
        register_provider,
        set_default_framework,
    )

# Registry functions and the submodule that owns each one.
```

Reviews (2): Last reviewed commit: "feat(api): also re-export register_provi..." | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown
Contributor

Documentation preview

https://nvidia-nemo.github.io/Guardrails/review/pr-1882

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 52a80bd4-adc8-4be9-b13f-10406364f13c

📥 Commits

Reviewing files that changed from the base of the PR and between ef69220 and 5489a71.

📒 Files selected for processing (7)
  • docs/configure-rails/custom-initialization/custom-llm-framework.md
  • docs/configure-rails/custom-initialization/custom-llm-model.md
  • docs/user-guides/testing-your-config.md
  • nemoguardrails/__init__.py
  • nemoguardrails/llm/__init__.py
  • nemoguardrails/types.py
  • tests/test_types_exports.py

📝 Walkthrough

Walkthrough

This PR expands the public API surface of the nemoguardrails package, exposing LLM-related types and framework registry functions at both the top level and the nemoguardrails.llm subpackage. The changes include updating type module exports, re-exporting from package entry points, adding comprehensive validation tests, and updating documentation examples to use the new import paths.

Changes

LLM Type API Expansion

Layer / File(s) Summary
Define public type exports in types module
nemoguardrails/types.py
Module docstring and __all__ added to explicitly define the public export surface for LLM interop types (ChatMessage, FinishReason, LLMFramework, LLMModel, LLMResponse, LLMResponseChunk, Role, ToolCall, ToolCallFunction, UsageInfo).
Re-export types at top-level nemoguardrails package
nemoguardrails/__init__.py
Top-level package now imports and re-exports all LLM types from nemoguardrails.types and adds them to __all__, expanding the public API alongside existing LLMRails and RailsConfig exports.
Re-export types and registry functions via nemoguardrails.llm subpackage
nemoguardrails/llm/__init__.py
Subpackage re-exports LLM types and framework registry helpers (get_default_framework, register_framework, set_default_framework) with an explicit __all__ list defining the public import surface from nemoguardrails.llm.
Test export contract and object identity
tests/test_types_exports.py
New test module validates that PUBLIC_TYPE_NAMES and REGISTRY_FUNCTION_NAMES are exported at both package levels, direct imports succeed, and exports resolve to the same canonical object identity across nemoguardrails and nemoguardrails.llm paths.
Update documentation to reflect new import paths
docs/configure-rails/custom-initialization/custom-llm-framework.md, docs/configure-rails/custom-initialization/custom-llm-model.md, docs/user-guides/testing-your-config.md
Documentation examples updated to import LLMModel, ChatMessage, LLMResponse, LLMResponseChunk, UsageInfo, and registry functions from the nemoguardrails top-level package instead of nemoguardrails.types and nemoguardrails.llm.frameworks.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Results For Major Changes ⚠️ Warning PR contains major API changes (expanding public export surface), but PR description lacks test execution results showing the new parametrized tests pass. Add test execution results or CI workflow output demonstrating that the new test_types_exports.py tests pass, confirming the API exports work correctly.
✅ 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 clearly and concisely describes the main objective of the PR: establishing canonical top-level imports for LLM types and registry functions.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/vdr-canonical-import-paths

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

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Pouyanpi Pouyanpi added the VDR label May 13, 2026
@Pouyanpi Pouyanpi added this to the v0.22.0 milestone May 13, 2026
@Pouyanpi Pouyanpi self-assigned this May 13, 2026
Copy link
Copy Markdown
Collaborator

@tgasser-nv tgasser-nv left a comment

Choose a reason for hiding this comment

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

Looks good, just need to add register_provider to the init() so we can import from nemoguards rather than nemoguards.llm.providers

Comment thread docs/configure-rails/custom-initialization/custom-llm-model.md Outdated
Apply reviewer suggestion to extend the canonical-import-path work:
register_provider was the one integrator-facing function that still
required reaching into nemoguardrails.llm.providers, while its
framework-level peers (register_framework, set_default_framework,
get_default_framework) were already at top-level.

Now an integrator writing a custom LLMModel reaches every symbol they
need from `from nemoguardrails import ...`: the value types, the
protocol, and the registration function.

Collapses the two-line import in custom-llm-model.md to one. The
existing nemoguardrails.llm.providers module remains the authoritative
implementation site; the variants (register_chat_provider,
register_llm_provider, get_provider_names, get_chat_provider_names,
get_llm_provider_names) are not re-exported - register_provider is the
canonical one, the others are either aliases or deprecated.

Tests: extend REGISTRY_FUNCTIONS to a (name, canonical_module) tuple
list so each function's same-object check resolves to its real owning
module. 45 tests pass.
@Pouyanpi Pouyanpi merged commit 12369ae into develop May 15, 2026
9 checks passed
@Pouyanpi Pouyanpi deleted the feat/vdr-canonical-import-paths branch May 15, 2026 09:07
@miyoungc miyoungc mentioned this pull request May 20, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants