Skip to content

feat(nemo-agents): add NAT Fabric adapter#888

Draft
AjayThorve wants to merge 10 commits into
NVIDIA-NeMo:mainfrom
AjayThorve:nat-fabric-adapter/athorve
Draft

feat(nemo-agents): add NAT Fabric adapter#888
AjayThorve wants to merge 10 commits into
NVIDIA-NeMo:mainfrom
AjayThorve:nat-fabric-adapter/athorve

Conversation

@AjayThorve

@AjayThorve AjayThorve commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Overview

Add a Platform-owned, third-party NeMo Agent Toolkit adapter for NeMo Fabric.
agent.yaml is the only agent configuration source: Platform translates it
into a normalized FabricConfig, and the adapter translates that config into a
typed in-memory NAT Config.

This replaces #885, which GitHub closed automatically when its stacked base
#865 merged. The branch is based directly on main and incorporates the shared
agent.yaml capability translation introduced by #890.

The change:

  • installs nvidia.nemo.platform.nat metadata in the wheel data directory
    discovered by NeMo Fabric after fix: discover installed adapter descriptors NVIDIA/NeMo-Fabric#108;
  • removes workflow.yml, harness.settings.config_file, llm_map, and the
    file-resolution/containment path;
  • defines a small Platform-owned NAT harness contract for react and
    current_timezone workflows;
  • maps the supported calculator, current_datetime, and
    email_phishing_analyzer tool names to NAT functions/function groups inside
    the adapter rather than exposing native NAT configuration in agent.yaml;
  • translates the selected Platform model into NAT's typed default LLM,
    including provider, model name, temperature, credential environment variable,
    and explicit provider settings;
  • builds the typed NAT config during start_runtime, launches it with
    WorkflowBuilder.from_config() and SessionManager.create(), invokes it
    through NAT's session runner, and shuts it down during stop;
  • maps harness_native MCP servers to NAT mcp_client function groups and
    enforces tools.blocked before building the workflow;
  • explicitly rejects unsupported workflow/tool names and non-empty
    skills.paths rather than silently ignoring them;
  • provides a shared agent.yaml that selects Codex, Hermes, or NAT through
    default_harness, plus self-contained calculator and email-phishing
    agent.yaml examples.

NAT serve, streaming, durable Platform sessions, Platform telemetry
normalization, Fabric-managed MCP exposure, runtime skills, arbitrary NAT
component configuration, and multi-LLM NAT workflows remain out of scope.

sequenceDiagram
    participant Platform
    participant Fabric
    participant Adapter as "NAT adapter host"
    participant NAT

    Platform->>Fabric: translated agent.yaml + input
    Fabric->>Adapter: start(runtime context, FabricConfig)
    Adapter->>Adapter: map workflow, tools, model, MCP, blocked tools
    Adapter->>NAT: validate typed Config
    Adapter->>NAT: WorkflowBuilder.from_config() + SessionManager.create()

    Fabric->>Adapter: invoke(request)
    Adapter->>NAT: session.run(input, RUN_OR_SERVE)
    NAT-->>Adapter: workflow result
    Adapter-->>Fabric: normalized result

    Fabric->>Adapter: stop(runtime_id)
    Adapter->>NAT: shutdown sessions, builder, components
Loading

Where should the reviewer start?

Start with
plugins/nemo-agents/src/nemo_agents_plugin/agent_config.py for the narrow
Platform NAT settings contract, then review
plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py and
plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/adapter.py for
the Platform -> Fabric -> typed NAT translation. The calculator and phishing
examples under plugins/nemo-agents/examples/nemo-agent-config/ show the
complete one-file authoring contract.

Validation

  • 86 focused agent-config and Fabric unit tests passed
  • installed-discovery integration passed through the real Platform -> Fabric
    -> installed NAT subprocess boundary without a workflow file
  • calculator and email-phishing React workflows both completed real
    WorkflowBuilder / SessionManager start-stop with their installed NAT
    components
  • uv lock --check, ruff check, ruff format --check, git diff --check,
    and all pre-commit hooks passed
  • published PyPI nemo-fabric[runtime]==0.1.0a20260724 loaded the installed
    Platform descriptor

Live calculator/phishing inference was not run because this shell did not expose
an NVIDIA API credential. Runtime construction used a non-secret placeholder
credential and did not make an external model request.

Related Issues

@github-actions github-actions Bot added the feat label Jul 24, 2026
@AjayThorve
AjayThorve marked this pull request as ready for review July 24, 2026 17:20
@AjayThorve
AjayThorve requested review from a team as code owners July 24, 2026 17:20
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a NeMo Fabric NAT adapter with configuration translation, lifecycle execution, model and capability mapping, packaged discovery, NAT workflow examples, and unit/integration coverage.

Changes

NAT Fabric adapter

Layer / File(s) Summary
NAT configuration translation and validation
plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py, plugins/nemo-agents/tests/unit/test_fabric_translator.py
Adds NAT adapter mapping, llm_map translation, NAT-specific validation, telemetry handling, and shared capability conversion.
NAT lifecycle runtime
plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/adapter.py, plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py
Loads confined workflow files, applies model/MCP/tool transformations, manages sessions, normalizes invocation results, and handles lifecycle cleanup.
Adapter packaging and discovery
plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/fabric-adapter.json, plugins/nemo-agents/pyproject.toml, plugins/nemo-agents/tests/unit/test_fabric_nat_adapter_packaging.py, plugins/nemo-agents/tests/integration/test_fabric_nat_adapter.py
Defines and installs the NAT adapter descriptor, adds NAT dependencies, and validates installed adapter discovery.
NAT examples and documentation
plugins/nemo-agents/examples/nemo-agent-config/README.md, plugins/nemo-agents/examples/nemo-agent-config/agent.yaml, plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/*, plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/*
Adds calculator and email-phishing NAT workflows, model mappings, blocked-tool configuration, and setup documentation.

Sequence Diagram(s)

sequenceDiagram
  participant Platform
  participant translate_agent_config
  participant NatRuntime
  participant NATWorkflow
  Platform->>translate_agent_config: translate NAT agent.yaml
  translate_agent_config-->>Platform: return FabricConfig
  Platform->>NatRuntime: start runtime
  NatRuntime->>NATWorkflow: load workflow and create session
  Platform->>NatRuntime: invoke request
  NatRuntime->>NATWorkflow: run workflow
  NATWorkflow-->>NatRuntime: return result
  NatRuntime-->>Platform: return normalized response
Loading

Possibly related PRs

Suggested reviewers: mmogallapalli, arpitsardhana, ngoncharenko

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a NAT Fabric adapter to nemo-agents.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
plugins/nemo-agents/examples/nemo-agent-config/README.md (1)

1-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Complete the README’s required usage structure.

Add a top-level prerequisites section, pair CLI examples with Python SDK examples in tab-sets, and add a Next Steps section with cross-links.

As per coding guidelines, documentation pages must list prerequisites first, provide Python SDK and CLI examples in tab-sets, and include a Next Steps section.

Also applies to: 14-48, 68-72

🤖 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 `@plugins/nemo-agents/examples/nemo-agent-config/README.md` around lines 1 -
12, Update the README’s documentation structure by adding a top-level
Prerequisites section first, then organize each CLI example with its
corresponding Python SDK example in tab-sets. Add a Next Steps section with
links to relevant follow-up documentation, while preserving the existing Fabric
installation and example content.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@plugins/nemo-agents/examples/nemo-agent-config/README.md`:
- Around line 1-12: Update the README’s documentation structure by adding a
top-level Prerequisites section first, then organize each CLI example with its
corresponding Python SDK example in tab-sets. Add a Next Steps section with
links to relevant follow-up documentation, while preserving the existing Fabric
installation and example content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7516a4d7-1ce5-4b00-aed4-bb32872db075

📥 Commits

Reviewing files that changed from the base of the PR and between 009588a and cbeb415.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • plugins/nemo-agents/examples/nemo-agent-config/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/workflow.yml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/workflow.yml
  • plugins/nemo-agents/pyproject.toml
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/adapter.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/fabric-adapter.json
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py
  • plugins/nemo-agents/tests/integration/test_fabric_nat_adapter.py
  • plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py
  • plugins/nemo-agents/tests/unit/test_fabric_nat_adapter_packaging.py
  • plugins/nemo-agents/tests/unit/test_fabric_translator.py

@AjayThorve
AjayThorve force-pushed the nat-fabric-adapter/athorve branch from da5f87b to ad55914 Compare July 24, 2026 18:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py (2)

17-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Drop redundant string-quoted forward refs.

from __future__ import annotations already defers annotation evaluation; quoting "_FakeRunner" (line 22) and "_FakeSessions" (line 40) is unnecessary.

As per coding guidelines, "prefer concrete type hints over string-based type hints... import them normally when possible."

♻️ Proposed fix
-    async def __aenter__(self) -> "_FakeRunner":
+    async def __aenter__(self) -> _FakeRunner:
-    def __init__(self, sessions: "_FakeSessions") -> None:
+    def __init__(self, sessions: _FakeSessions) -> 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 `@plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py` around lines 17 -
56, Remove the redundant string quotes from the _FakeRunner return annotation on
_FakeSession.__aenter__ and the _FakeSessions parameter annotation in
_FakeSession.__init__, relying on the module’s postponed annotation evaluation
while preserving the existing types.

Source: Coding guidelines


197-238: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test for already-started guard.

NatRuntime.start raises nat_runtime_already_started when called on an already-running instance (per adapter.py's start), but no test here exercises calling start() twice.

🤖 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 `@plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py` around lines 197 -
238, Add a unit test covering the already-started guard in NatRuntime.start:
successfully start one runtime instance, call start again with the same payload,
and assert LifecycleError code nat_runtime_already_started. Ensure cleanup with
runtime.stop() so the test remains safe and isolated.
🤖 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.

Nitpick comments:
In `@plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py`:
- Around line 17-56: Remove the redundant string quotes from the _FakeRunner
return annotation on _FakeSession.__aenter__ and the _FakeSessions parameter
annotation in _FakeSession.__init__, relying on the module’s postponed
annotation evaluation while preserving the existing types.
- Around line 197-238: Add a unit test covering the already-started guard in
NatRuntime.start: successfully start one runtime instance, call start again with
the same payload, and assert LifecycleError code nat_runtime_already_started.
Ensure cleanup with runtime.stop() so the test remains safe and isolated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c72500f0-7be9-4c67-9142-4ba9a9454a3c

📥 Commits

Reviewing files that changed from the base of the PR and between da5f87b and ad55914.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • plugins/nemo-agents/examples/nemo-agent-config/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/workflow.yml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/workflow.yml
  • plugins/nemo-agents/pyproject.toml
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/adapter.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/fabric-adapter.json
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py
  • plugins/nemo-agents/tests/integration/test_fabric_nat_adapter.py
  • plugins/nemo-agents/tests/unit/test_fabric_nat_adapter.py
  • plugins/nemo-agents/tests/unit/test_fabric_nat_adapter_packaging.py
  • plugins/nemo-agents/tests/unit/test_fabric_translator.py
🚧 Files skipped from review as they are similar to previous changes (11)
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/agent.yaml
  • plugins/nemo-agents/tests/integration/test_fabric_nat_adapter.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/fabric-adapter.json
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-email-phishing/workflow.yml
  • plugins/nemo-agents/examples/nemo-agent-config/nat-calculator/workflow.yml
  • plugins/nemo-agents/pyproject.toml
  • plugins/nemo-agents/tests/unit/test_fabric_nat_adapter_packaging.py
  • plugins/nemo-agents/examples/nemo-agent-config/README.md
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/adapters/nat/adapter.py

@@ -0,0 +1,26 @@
function_groups:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we drop the separate workflow.yml requirement and make the NAT configuration part of agent.yaml?


runtime_id = _runtime_id(payload)
validate_supported_fabric_config(payload)
config_file = resolve_config_file(payload)

@AnuradhaKaruppiah AnuradhaKaruppiah Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don’t think workflow.yml or harness.settings.config_file should be part of the NAT adapter contract.

  • agent.yaml is the public Platform agent schema and is already translated into a normalized FabricConfig.
  • The NAT adapter should consume that FabricConfig, translate its models, harness settings, MCP servers, tools, prompts, environment, and other supported capabilities into a typed NAT Config, and then launch it with WorkflowBuilder.from_config() and SessionManager.create().

Requiring a native NAT workflow file creates a second source of truth and makes FabricConfig an overlay rather than the adapter’s authoritative input. It also introduces llm_map solely to reconcile aliases between the two configurations.
I recommend removing - harness.settings.config_file,harness.settings.llm_map,the example workflow.yml files
the file-resolution and containment machinery

The adapter should instead implement an explicit FabricConfig => NAT Config translation. If information required to construct the NAT workflow is missing from the public agent.yaml/FabricConfig contract, we address that in the public schema or barf (rather than passing native NAT configuration through harness.settings).
This may mean the initial adapter supports only the normalized subset expressible by the public schema. That is preferable to establishing a parallel, NAT-specific configuration contract.

@AjayThorve
AjayThorve marked this pull request as draft July 24, 2026 18:59
AjayThorve and others added 10 commits July 24, 2026 12:14
Build on the shared Platform-to-Fabric config translation from NVIDIA-NeMo#890 and apply NAT-native MCP and blocked-tool mappings before the workflow runtime starts.

Co-authored-by: Manjesh Mogallapalli <[email protected]>
Signed-off-by: Ajay Thorve <[email protected]>
@AjayThorve
AjayThorve force-pushed the nat-fabric-adapter/athorve branch from ad55914 to ab817e0 Compare July 24, 2026 19:15
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