Skip to content

feat(nemo-agents): support nemo agents pacakge for fabric backed agents - #1036

Merged
mmogallapalli merged 13 commits into
mainfrom
mmogallapall/aircore-970-extend-nemo-agents-package-support-for-fabric-backed-agents
Aug 3, 2026
Merged

feat(nemo-agents): support nemo agents pacakge for fabric backed agents#1036
mmogallapalli merged 13 commits into
mainfrom
mmogallapall/aircore-970-extend-nemo-agents-package-support-for-fabric-backed-agents

Conversation

@mmogallapalli

@mmogallapalli mmogallapalli commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR extends nemo agents package to build Docker images for Fabric-backed NeMo Agents as part of AIRCORE-970. It also includes the runtime-only inference-gateway credential binding needed by Fabric adapters from AIRCORE-943.

The package command now detects the agent configuration format and routes to a runtime-specific packaging path while retaining the existing NAT workflow:

nemo agents package
  -> nat-workflow-v1
     -> NAT validation
     -> NAT Dockerfile
     -> NAT image

nemo agents package
  -> nemo-agents-spec-v1
     -> Platform schema validation
     -> Fabric translation and plan
     -> packaged-artifact validation
     -> Fabric Dockerfile
     -> Fabric serving image

The generated Fabric image contains the agent bundle, the release-matched NeMo Agents runtime and supported Fabric adapters, the pinned NeMo Relay CLI, and the Platform-owned Fabric server used by Docker and Kubernetes deployments.

Changes

  • Updated nemo agents package to detect config_format before rendering or building:
    • nemo-agents-spec-v1 routes to Fabric packaging.
    • nat-workflow-v1 and configs without config_format route to NAT packaging.
    • Unknown formats and malformed YAML fail with a CLI error.
  • Split the previous generic image builder into explicit runtime-owned entry points:
    • build_nat_agent_image
    • build_fabric_agent_image
  • Added a Fabric package validation pipeline that:
    • Loads and validates the Platform agent.yaml schema.
    • Translates the selected agent and harness into FabricConfig.
    • Runs Fabric.plan against the agent config directory.
    • Verifies that the config and referenced skills are present inside the Docker build context.
    • Rejects absolute, missing, unreadable, non-directory, or build-context-escaping skill paths.
    • Requires each packaged skill directory to contain SKILL.md.
  • Split Fabric validation into reusable plan and doctor operations:
    • Packaging runs plan-only validation.
    • Existing runtime/deployment validation continues to run both plan and doctor.
  • Added a Fabric-specific Dockerfile renderer that:
    • Copies the complete agent bundle into /workspace so paths remain relative to agent.yaml.
    • Installs the release-matched nemo-platform[nemo-agents-plugin] package.
    • Installs the packaged project in the same dependency resolution when --pyproject is provided.
    • Includes the plugin's supported Fabric adapter dependency set.
    • Installs the pinned NeMo Relay CLI for Codex and Claude Relay execution.
    • Creates and activates /workspace/.venv as the runtime environment.
    • Preserves the existing non-root and sandbox-runtime image options.
    • Exposes port 8000 and starts nemo_agents_plugin.fabric.server.
  • Split shared and runtime-specific render parameters so NAT and Fabric reuse base-image, Python, uv, sandbox, project, and metadata behavior without sharing runtime-only fields.
  • Renamed shared package environment variables from NAT-specific names to runtime-neutral names:
    • NAT_BASE_IMAGE_URL -> NEMO_AGENTS_BASE_IMAGE_URL
    • NAT_BASE_IMAGE_TAG -> NEMO_AGENTS_BASE_IMAGE_TAG
    • NAT_PYTHON_VERSION -> NEMO_AGENTS_PYTHON_VERSION
    • NAT_UV_VERSION -> NEMO_AGENTS_UV_VERSION
  • Retained NAT_VERSION as NAT-only configuration and reject an explicit --nat-version for Fabric agents.
  • Updated the default uv version to 0.9.14, matching the repository's supported uv constraint.
  • Added Fabric image metadata and identity support:
    • Uses the Platform agent name and description when no project metadata overrides them.
    • Sets com.nemo.agent.framework=nemo_platform_agent.
    • Includes the Platform contract version, Relay CLI version, base image, Python, and uv versions in image identity inputs.
    • Uses the installed nemo-platform distribution version as the runtime contract version.
  • Added a runtime-only Platform inference-gateway credential binding:
    • Supplies a placeholder credential only for models routed through the Platform inference gateway.
    • Honors the selected harness model before the shared default model.
    • Leaves direct third-party model endpoints unchanged.
    • Does not mutate or persist the placeholder in the Platform-owned agent config.
    • Passes the binding to subprocess, Docker, and Kubernetes child runtimes.
  • Preserved the existing NAT package flow and added focused coverage for format routing, rendering, validation, metadata, build behavior, generated-file cleanup, credential propagation, and deployment modes.

Design Choices

The CLI owns format routing

nemo agents package detects the configuration format before calling a builder. Each builder therefore receives only the parameters supported by its runtime.

This keeps build_nat_agent_image free of Fabric branches and keeps build_fabric_agent_image free of NAT-only inputs such as nat_version and NAT_CONFIG_FILE.

NAT and Fabric have separate builders and render contracts

The two image types share infrastructure such as Docker invocation, build-context selection, OCI metadata, sandbox setup, and generated-file cleanup. Their runtime dependencies, validation, environment variables, ports, and entrypoints remain separate.

This avoids a compatibility alias for the old internal build_agent_image helper. The CLI was its only production caller, so the call sites and tests were updated directly.

Packaging runs Fabric plan, not doctor

Fabric.plan validates the translated configuration and selected adapter contract without requiring the producer machine to contain the binaries that will be installed in the image.

Fabric.doctor remains part of runtime/deployment validation, where the complete image environment, adapter binaries, and Relay CLI are available. Running doctor during packaging would incorrectly couple image production to the host environment.

The complete build context is the packaged agent bundle

In config-only mode, the directory containing agent.yaml is the Docker build context. In project mode, the directory containing pyproject.toml is the build context, and agent.yaml must be located within it.

The image copies that complete context into /workspace. Referenced skill paths must stay inside the context and remain valid relative to the packaged agent.yaml.

Runtime dependencies follow the Platform release contract

Fabric images install nemo-platform[nemo-agents-plugin] at the same version as the package command that rendered the Dockerfile. The plugin owns the supported Fabric and adapter dependency set, so users do not need to select or version individual adapters while packaging.

The Relay CLI is installed separately because Codex and Claude Relay adapters launch it as an external executable. Its version is pinned independently from the Python dependency graph.

Project mode resolves the runtime and project together

When --pyproject is supplied, the release-matched NeMo Agents runtime and the user's project are installed in one resolution. Conflicting project constraints therefore fail during the image build instead of producing a partially compatible runtime.

Config-only mode installs only the release package and uses the directory containing agent.yaml as the bundle.

Shared environment variables are runtime-neutral

Base image, Python, and uv settings apply to both NAT and Fabric images, so their environment variables now use the NEMO_AGENTS_ prefix. NAT_VERSION remains unchanged because it is meaningful only for NAT packaging.

The CLI distinguishes an explicitly supplied --nat-version from an ambient NAT_VERSION. An explicit NAT-only flag is rejected for Fabric, while an ambient NAT setting does not interfere with Fabric packaging and remains available to the NAT resolver.

Image identity includes the runtime contract

The default image tag remains <agent-name>-<agent-id>:<agent-version>, but Fabric image identity includes the Platform contract, Relay CLI, base image, Python, and uv inputs. Changing a runtime-defining input therefore produces a distinct agent ID rather than silently reusing an incompatible image identity.

Gateway credentials remain runtime-only

Some Fabric model adapters require api_key_env even when requests are routed through the authenticated Platform inference gateway and no upstream API key is needed. Platform supplies a non-secret placeholder to the child runtime for that case.

The binding is derived after deployment gateway resolution, is not persisted in agent.yaml, and is not applied to direct third-party endpoints. This avoids creating a temporary public config convention while keeping the same behavior across subprocess, Docker, and Kubernetes runners.

Error Behavior

  • Malformed YAML or unsupported config_format: package command exits before rendering.
  • Explicit --nat-version with a Fabric agent: package command exits with a NAT-only flag error.
  • Invalid Platform schema, Fabric translation, or Fabric plan: package command exits before Docker build.
  • Missing, invalid, unreadable, or context-escaping skill artifact: package command reports all discovered artifact errors.
  • Agent config outside the selected project build context: rendering and validation fail before build.
  • Existing user-owned generated files are preserved according to the existing package ownership rules.
  • Docker build failures still clean up transient Dockerfile.generated and generated .dockerignore files.

Out of Scope

  • Documentation updates and migration guidance for renamed environment variables; tracked in AIRCORE-957.
  • Platform fileset creation and remote artifact staging for Docker/Kubernetes deployments; tracked in AIRCORE-966.

Validation

Affected NeMo Agents unit suites:

294 passed

This includes NAT and Fabric package routing, Dockerfile rendering, metadata and image identity, Fabric package validation, gateway credential binding, Fabric server startup, translation and validation, and subprocess/Docker/Kubernetes runner configuration.

Repository Python style and formatting:

All checks passed
2954 files already formatted

Manual Docker end-to-end validation:

  1. Rendered a Fabric Dockerfile from a nemo-agents-spec-v1 agent.yaml.
  2. Built a local image from the monorepo workspace.
  3. Verified the packaged Platform and Fabric modules imported inside the image.
  4. Registered the Fabric agent with a local Platform.
  5. Deployed the image in Docker mode and observed pending -> starting -> running.
  6. Retrieved the running deployment through the CLI.
  7. Invoked the Codex-backed agent through the Platform gateway and received the expected response.

Local CLI flow

The branch version is not available from the package index, so local validation rendered the release Dockerfile and replaced its published-package install with a frozen workspace sync. Released builds use the generated Dockerfile directly and do not need the perl substitution.

cd /Users/mmogallapall/nemo-platform

export NMP_BASE_URL="http://127.0.0.1:8080"
export AGENT_CONFIG="$PWD/plugins/nemo-agents/examples/nemo-agent-config/agent.yaml"

export SUFFIX="$(date +%s)"
export AGENT_NAME="fabric-docker-${SUFFIX}"
export DEPLOYMENT_NAME="fabric-docker-deployment-${SUFFIX}"
export IMAGE="fabric-docker-${SUFFIX}:local"
export LOCAL_DOCKERFILE="/tmp/Dockerfile.fabric-local-${SUFFIX}"

uv run nemo agents package \
  --agent "$AGENT_CONFIG" \
  --pyproject "$PWD/pyproject.toml" \
  --uv-version 0.9.18 \
  --no-build \
  --no-ignore \
  --output "$LOCAL_DOCKERFILE"

perl -0pi -e \
  's#uv pip install "nemo-platform\[nemo-agents-plugin\]==[^"]+" \.#uv sync --frozen --package nemo-agents-plugin --no-dev --no-editable#' \
  "$LOCAL_DOCKERFILE"

uv run nemo agents package \
  --agent "$AGENT_CONFIG" \
  --pyproject "$PWD/pyproject.toml" \
  --dockerfile "$LOCAL_DOCKERFILE" \
  --tag "$IMAGE" \
  --skip-validation

docker image inspect "$IMAGE" >/dev/null && echo "Built $IMAGE"

docker run --rm \
  --entrypoint python \
  "$IMAGE" \
  -c 'import nemo_agents_plugin, nemo_fabric; print("Fabric runtime imports passed")'

uv run nemo agents create \
  --name "$AGENT_NAME" \
  --agent-config "$AGENT_CONFIG"

uv run nemo agents deploy \
  --agent "$AGENT_NAME" \
  --name "$DEPLOYMENT_NAME" \
  --mode docker \
  --image "$IMAGE" \
  --timeout 300

uv run nemo agents deployments get "$DEPLOYMENT_NAME"

uv run nemo agents invoke \
  --agent-deployment "$DEPLOYMENT_NAME" \
  --input "Reply with exactly: Fabric Docker deployment works" \
  --timeout 300

Optional cleanup:

uv run nemo agents deployments delete "$DEPLOYMENT_NAME" --yes
uv run nemo agents delete "$AGENT_NAME" --yes

Summary by CodeRabbit

  • New Features

    • Added support for packaging and building Fabric and NAT agent configurations.
    • Added automatic configuration-format detection and format-specific validation, rendering, and image creation.
    • Added Fabric package validation, skill-path and build-context checks, Dockerfile rendering, and image metadata.
    • Added secure runtime credentials for Platform inference gateway deployments.
    • Added separate configuration planning and diagnostic validation flows.
    • Added support for NEMO_AGENTS_* packaging environment variables.
  • Bug Fixes

    • Improved cleanup of generated Dockerfiles and Docker ignore files after builds.
    • Prevented platform credentials from modifying source model configurations or affecting unrelated endpoints.

Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@github-actions github-actions Bot added the feat label Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 30032/38046 78.9% 63.5%
Integration Tests 17781/36715 48.4% 20.8%

Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@mmogallapalli
mmogallapalli marked this pull request as ready for review August 2, 2026 04:34
@mmogallapalli
mmogallapalli requested review from a team as code owners August 2, 2026 04:34
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 30043e30-6f18-4ca1-a9a8-048c43e7c000

📥 Commits

Reviewing files that changed from the base of the PR and between b5438b3 and 19dde21.

📒 Files selected for processing (1)
  • plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py

📝 Walkthrough

Walkthrough

Packaging detects NAT and Fabric configurations and routes them through separate validation, rendering, and image-building paths. Fabric support adds artifact checks, dedicated Dockerfiles, Platform gateway credential handling, deployment environment propagation, and regression coverage.

Changes

Agent packaging and Fabric runtime

Layer / File(s) Summary
Format detection and image rendering
plugins/nemo-agents/src/nemo_agents_plugin/cli.py, plugins/nemo-agents/src/nemo_agents_plugin/container/*, plugins/nemo-agents/tests/unit/test_container.py
Packaging detects NAT or Fabric formats and routes each format to dedicated builders, renderers, templates, metadata handling, and environment variables.
Fabric package validation and build context
plugins/nemo-agents/src/nemo_agents_plugin/container/fabric_validator.py, plugins/nemo-agents/src/nemo_agents_plugin/fabric/validation.py, plugins/nemo-agents/tests/unit/test_fabric_package_validation.py, plugins/nemo-agents/tests/unit/test_fabric_validation.py, plugins/nemo-agents/tests/unit/test_fabric_server.py
Fabric packages are translated, planned, and checked for valid in-context skill directories and readable SKILL.md manifests. Planning and doctor operations use separate public helpers.
Platform gateway credentials in Fabric runtime
plugins/nemo-agents/src/nemo_agents_plugin/fabric/*, plugins/nemo-agents/src/nemo_agents_plugin/runner/*, plugins/nemo-agents/tests/unit/test_fabric_gateway_credentials.py, plugins/nemo-agents/tests/unit/test_fabric_translator.py, plugins/nemo-agents/tests/unit/test_runner_*.py
Platform gateway models receive placeholder API-key bindings. Deployment configurations and Fabric subprocesses receive derived credential environments without changing the controller environment.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant FormatDetector
  participant FabricBuilder
  participant FabricValidator
  participant Docker
  CLI->>FormatDetector: detect configuration format
  FormatDetector-->>CLI: Fabric format
  CLI->>FabricBuilder: build_fabric_agent_image
  FabricBuilder->>FabricValidator: validate and plan package
  FabricValidator-->>FabricBuilder: validation result
  FabricBuilder->>Docker: render and build image
Loading

Possibly related PRs

Suggested labels: breaking

Suggested reviewers: tylersbray, stefan-kickoff, mikeknep, ajaythorve

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.78% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding Fabric-backed agent support to the NeMo Agents package command.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mmogallapall/aircore-970-extend-nemo-agents-package-support-for-fabric-backed-agents

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.

Actionable comments posted: 3

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

381-395: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix the stale docstring and render through _render_context.

Line 382 states the renderer is not wired yet. TestRenderFabricDockerfile below wires it in this same PR. Also, asdict(params) bypasses _render_context, so the flattening path the production renderers use is not exercised here.

♻️ Proposed change
 class TestFabricDockerfileTemplate:
-    """Direct contract tests for the Fabric template before its renderer is wired."""
+    """Direct contract tests for the Fabric Dockerfile template."""
 
     `@staticmethod`
     def _render(**overrides: object) -> str:
-        from dataclasses import asdict
-
         from nemo_agents_plugin.container.template import (
             FABRIC_DOCKERFILE_TEMPLATE,
             FabricRenderParams,
             _jinja_env,
+            _render_context,
         )
 
         params = FabricRenderParams(contract_version="1.2.3", **overrides)
-        return _jinja_env().from_string(FABRIC_DOCKERFILE_TEMPLATE).render(**asdict(params))
+        return _jinja_env().from_string(FABRIC_DOCKERFILE_TEMPLATE).render(**_render_context(params))
🤖 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_container.py` around lines 381 - 395,
Update TestFabricDockerfileTemplate’s docstring to reflect that the Fabric
renderer is wired, and change its _render helper to render using _render_context
with the FabricRenderParams instance instead of converting params via asdict.
Preserve the existing overrides and template rendering behavior while exercising
the production flattening path.

535-554: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add Fabric non-root hardening coverage.

Every Fabric test either sets allow_root=True or does not assert the user block. TestRenderNatDockerfile.test_non_root_user_by_default locks the uid-1000 reclaim guards for NAT. The Fabric template carries the same block at template lines 275-281 with no equivalent test. A regression there ships a root-running agent image.

Add a test that renders Fabric with default allow_root and asserts USER agent, getent passwd 1000, and chown -R agent:agent /workspace.

🤖 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_container.py` around lines 535 - 554, Add
a Fabric Dockerfile test alongside test_allow_root_and_sandbox_profile that
calls render_fabric_dockerfile with the default allow_root setting, then asserts
the rendered output contains USER agent, getent passwd 1000, and chown -R
agent:agent /workspace. Keep the existing root-enabled test unchanged.
plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py (1)

354-378: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared render-build-cleanup block.

Lines 354-378 duplicate lines 208-248 of build_nat_agent_image exactly. The safety comments that explain the .dockerignore pre-existence guard exist only in the NAT copy. A future fix to one copy will miss the other.

Extract a helper such as _build_with_generated_dockerfile(context_dir, content, tag, build_args, generate_ignore, platforms, push) and call it from both builders.

🤖 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/src/nemo_agents_plugin/container/builder.py` around lines
354 - 378, Extract the duplicated generated-Dockerfile render/build/cleanup flow
from build_nat_agent_image and the corresponding builder block into a shared
helper such as _build_with_generated_dockerfile. Move the Dockerfile refusal
check and .dockerignore pre-existence cleanup guard into that helper, then
update both builders to call it while preserving their existing arguments and
return behavior.
plugins/nemo-agents/src/nemo_agents_plugin/container/fabric_validator.py (1)

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

Import FabricConfig normally instead of under TYPE_CHECKING.

nemo_fabric is already a runtime dependency of this package (nemo_agents_plugin.fabric.translator imports it at module level). The guarded import gives no benefit here and blocks runtime introspection of FabricPackageValidationResult.

♻️ Proposed change
-from typing import TYPE_CHECKING, Any
+from typing import Any
 
+from nemo_fabric import FabricConfig
 from nemo_agents_plugin.agent_config import AgentConfig, AgentConfigLoadError, load_agent_config
 from nemo_agents_plugin.fabric.translator import FabricTranslationError, translate_agent_config
 from nemo_agents_plugin.fabric.validation import FabricValidationError, plan_fabric_config
-
-if TYPE_CHECKING:
-    from nemo_fabric import FabricConfig

As per coding guidelines: "In Python code, prefer concrete type hints over string-based type hints, and do not import those types only under TYPE_CHECKING; import them normally when possible."

🤖 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/src/nemo_agents_plugin/container/fabric_validator.py`
around lines 10 - 17, Import FabricConfig directly from nemo_fabric in
fabric_validator.py instead of guarding it with TYPE_CHECKING, and remove the
now-unused TYPE_CHECKING import. Preserve the existing FabricConfig annotations
and runtime introspection of FabricPackageValidationResult.

Source: Coding guidelines

plugins/nemo-agents/src/nemo_agents_plugin/fabric/validation.py (1)

91-108: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider matching doctor_fabric_config error handling in plan_fabric_config.

plan_fabric_config catches only FabricConfigError and applies no timeout. doctor_fabric_config catches all exceptions and bounds runtime with FABRIC_VALIDATION_TIMEOUT_SECONDS. The packaging path in container/fabric_validator.py wraps only FabricValidationError, so any other Fabric failure escapes as a raw traceback during nemo agents package. A blocking plan call in a worker thread also cannot be cancelled.

♻️ Proposed change
     try:
-        return await asyncio.to_thread(fabric_client.plan, fabric_config, base_dir=base_dir)
+        return await asyncio.wait_for(
+            asyncio.to_thread(fabric_client.plan, fabric_config, base_dir=base_dir),
+            timeout=FABRIC_VALIDATION_TIMEOUT_SECONDS,
+        )
+    except asyncio.TimeoutError as error:
+        raise FabricValidationError(f"Fabric plan timed out after {FABRIC_VALIDATION_TIMEOUT_SECONDS:g}s.") from error
     except FabricConfigError as error:
         raise FabricValidationError(f"Fabric plan failed: {error}") from error
🤖 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/src/nemo_agents_plugin/fabric/validation.py` around lines
91 - 108, Update plan_fabric_config to mirror doctor_fabric_config: run
fabric_client.plan through the existing FABRIC_VALIDATION_TIMEOUT_SECONDS
timeout mechanism and catch all exceptions, converting them into
FabricValidationError with the original exception chained. Preserve the current
planning arguments and injected fabric client behavior.
plugins/nemo-agents/tests/unit/test_fabric_gateway_credentials.py (1)

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

Add coverage for the legacy settings.base_url branch.

_is_platform_gateway_model also matches the gateway marker inside model["settings"]["base_url"]. No test exercises that path.

💚 Proposed test
+def test_legacy_settings_base_url_receives_runtime_only_binding() -> None:
+    config = {"models": {"default": {"provider": "nvidia", "model": "m", "settings": {"base_url": _IGW_URL}}}}
+
+    assert platform_gateway_credential_env(config) == {PLATFORM_IGW_API_KEY_ENV: PLATFORM_IGW_API_KEY_PLACEHOLDER}
🤖 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_gateway_credentials.py` around
lines 56 - 87, Add a unit test alongside
test_translated_igw_model_receives_runtime_only_key_reference that builds a
model with the platform gateway URL under model["settings"]["base_url"], invokes
bind_platform_gateway_model_credential, and verifies it receives
PLATFORM_IGW_API_KEY_ENV while the original model remains without api_key_env.
This should cover the legacy settings.base_url branch of
_is_platform_gateway_model.
🤖 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.

Inline comments:
In `@plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py`:
- Around line 381-393: Update detect_agent_config_format to catch OSError and
UnicodeDecodeError from agent_config.read_text, converting them into ValueError
messages consistent with validate_agent_config so the CLI’s existing ValueError
handling reports structured errors without a traceback. Preserve the existing
YAML parsing and format validation behavior.

In `@plugins/nemo-agents/src/nemo_agents_plugin/container/template.py`:
- Around line 232-247: The Fabric install flow must not pin nemo-platform to the
unresolved "0.0.0" fallback from get_contract_version(). Validate the resolved
contract version before rendering the install commands in the template, and fail
with an explicit message when it is unavailable; otherwise preserve the
exact-version pin for valid versions in both has_pyproject branches.
- Around line 216-222: Update the Nemo Relay installer block to fetch the script
from an immutable tag or commit matching PINNED_NEMO_RELAY_CLI_VERSION, verify
the downloaded script against a pinned checksum before execution, and only then
run it as root; keep the cleanup and version validation steps intact and correct
the adjacent comment if its guarantee is not fully accurate.

---

Nitpick comments:
In `@plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py`:
- Around line 354-378: Extract the duplicated generated-Dockerfile
render/build/cleanup flow from build_nat_agent_image and the corresponding
builder block into a shared helper such as _build_with_generated_dockerfile.
Move the Dockerfile refusal check and .dockerignore pre-existence cleanup guard
into that helper, then update both builders to call it while preserving their
existing arguments and return behavior.

In `@plugins/nemo-agents/src/nemo_agents_plugin/container/fabric_validator.py`:
- Around line 10-17: Import FabricConfig directly from nemo_fabric in
fabric_validator.py instead of guarding it with TYPE_CHECKING, and remove the
now-unused TYPE_CHECKING import. Preserve the existing FabricConfig annotations
and runtime introspection of FabricPackageValidationResult.

In `@plugins/nemo-agents/src/nemo_agents_plugin/fabric/validation.py`:
- Around line 91-108: Update plan_fabric_config to mirror doctor_fabric_config:
run fabric_client.plan through the existing FABRIC_VALIDATION_TIMEOUT_SECONDS
timeout mechanism and catch all exceptions, converting them into
FabricValidationError with the original exception chained. Preserve the current
planning arguments and injected fabric client behavior.

In `@plugins/nemo-agents/tests/unit/test_container.py`:
- Around line 381-395: Update TestFabricDockerfileTemplate’s docstring to
reflect that the Fabric renderer is wired, and change its _render helper to
render using _render_context with the FabricRenderParams instance instead of
converting params via asdict. Preserve the existing overrides and template
rendering behavior while exercising the production flattening path.
- Around line 535-554: Add a Fabric Dockerfile test alongside
test_allow_root_and_sandbox_profile that calls render_fabric_dockerfile with the
default allow_root setting, then asserts the rendered output contains USER
agent, getent passwd 1000, and chown -R agent:agent /workspace. Keep the
existing root-enabled test unchanged.

In `@plugins/nemo-agents/tests/unit/test_fabric_gateway_credentials.py`:
- Around line 56-87: Add a unit test alongside
test_translated_igw_model_receives_runtime_only_key_reference that builds a
model with the platform gateway URL under model["settings"]["base_url"], invokes
bind_platform_gateway_model_credential, and verifies it receives
PLATFORM_IGW_API_KEY_ENV while the original model remains without api_key_env.
This should cover the legacy settings.base_url branch of
_is_platform_gateway_model.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c82940fe-eadf-42de-99ec-57ef1cc8fc4a

📥 Commits

Reviewing files that changed from the base of the PR and between 58a02de and ba674a8.

📒 Files selected for processing (18)
  • plugins/nemo-agents/src/nemo_agents_plugin/cli.py
  • plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py
  • plugins/nemo-agents/src/nemo_agents_plugin/container/fabric_validator.py
  • plugins/nemo-agents/src/nemo_agents_plugin/container/metadata.py
  • plugins/nemo-agents/src/nemo_agents_plugin/container/template.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/gateway_credentials.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/translator.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/validation.py
  • plugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.py
  • plugins/nemo-agents/src/nemo_agents_plugin/runner/in_memory.py
  • plugins/nemo-agents/tests/unit/test_container.py
  • plugins/nemo-agents/tests/unit/test_fabric_gateway_credentials.py
  • plugins/nemo-agents/tests/unit/test_fabric_package_validation.py
  • plugins/nemo-agents/tests/unit/test_fabric_server.py
  • plugins/nemo-agents/tests/unit/test_fabric_translator.py
  • plugins/nemo-agents/tests/unit/test_fabric_validation.py
  • plugins/nemo-agents/tests/unit/test_runner_deployments.py
  • plugins/nemo-agents/tests/unit/test_runner_in_memory.py

Comment thread plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/container/template.py Outdated
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/container/template.py
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@mmogallapalli mmogallapalli self-assigned this Aug 2, 2026
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/container/builder.py Outdated
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/cli.py
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/cli.py
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/cli.py
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@mmogallapalli
mmogallapalli added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 2cb9a08 Aug 3, 2026
54 checks passed
@mmogallapalli
mmogallapalli deleted the mmogallapall/aircore-970-extend-nemo-agents-package-support-for-fabric-backed-agents branch August 3, 2026 16:14
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