feat(relay): add typed Relay config - #54
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds first-class NeMo Relay configuration across Rust and Python APIs, JSON Schemas, telemetry planning, adapters, SDK exports, examples, documentation, dependency metadata, and integration fixtures. ChangesNeMo Relay integration
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant SDK as Python SDK
participant Config as FabricConfig
participant Plan as Telemetry planner
participant Adapter as Fabric adapter
participant Relay as Relay plugin config
SDK->>Config: enable_relay(observability, components, policy)
Config->>Plan: provide telemetry providers and relay settings
Plan->>Relay: generate structured relay_config
Plan->>Adapter: pass telemetry_plan and native_config
Adapter->>Relay: configure Relay when relay is selected
Possibly related PRs
Suggested labels: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
python/src/nemo_fabric/types.py (1)
697-724: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
enable_relayreplacesrelaywholesale instead of merging.
self.telemetry.enable_relay(...)merges into the existing telemetry mapping (only overwriting keys that are explicitly passed), but the relay block below it is rebuilt from scratch (relay: dict[str, Any] = {}) and then unconditionally assigned toself["relay"]. A second call toenable_relay()— e.g. to layer inpolicyafter an earlier call setobservability/components— silently drops the previously configured fields. This is inconsistent with the additive semantics used elsewhere in this class (add_mcp_server,add_skill_path).🐛 Proposed fix to merge with existing relay state
- relay: dict[str, Any] = {} + relay: dict[str, Any] = dict(self.get("relay") or {}) if project is not None: relay["project"] = project if output_dir is not None: relay["output_dir"] = str(output_dir)🤖 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 `@python/src/nemo_fabric/types.py` around lines 697 - 724, Update enable_relay to start from the existing self["relay"] mapping when present, then overlay only the explicitly provided project, output_dir, observability, components, and policy values before assigning it back. Preserve previously configured relay fields across repeated calls, matching the additive behavior of add_mcp_server and add_skill_path.
🤖 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 `@crates/fabric-core/src/config.rs`:
- Around line 734-745: Replace the manual Default implementation for
RelayAtofConfig with a Default derive on the struct, preserving the existing
field defaults and removing the redundant impl. Leave the other manual Default
implementations unchanged.
- Around line 1693-1743: Update resolve_telemetry_plan() so relay_project,
relay_output_dir, and relay_config are populated only when relay_enabled is
true; return None/default values for native or disabled telemetry even if
config.relay exists. Add a test covering native telemetry with a relay
configuration and verify telemetry_ref() emits no Relay metadata.
---
Outside diff comments:
In `@python/src/nemo_fabric/types.py`:
- Around line 697-724: Update enable_relay to start from the existing
self["relay"] mapping when present, then overlay only the explicitly provided
project, output_dir, observability, components, and policy values before
assigning it back. Preserve previously configured relay fields across repeated
calls, matching the additive behavior of add_mcp_server and add_skill_path.
🪄 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: ASSERTIVE
Plan: Enterprise
Run ID: c1d2bf15-295f-4f55-af19-e898ac6ebaf9
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (21)
crates/fabric-core/src/config.rsdocs/reference/api/python-library-reference/index.mddocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/sdk/python.mdxexamples/code_review_agent/config.pyexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlpyproject.tomlpython/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.pyschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/profile.schema.jsonschemas/run-plan.schema.jsontests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/integrations/test_harbor_runner.pytests/python/test_sdk_contract.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**
⚙️ CodeRabbit configuration file
**:Contributing to NeMo Fabric
Thank you for your interest in contributing to NeMo Fabric. This guide covers
the development workflow, coding standards, and pull request process.Development Setup
This section collects the setup steps needed before building, testing, or
contributing changes.Package Installation
NeMo Fabric is not currently available on PyPI. To consume the Python packages,
build wheels from a source checkout:just wheels uv pip install --find-links dist "nemo-fabric[runtime]"Adapters are distributed as optional extras. For example, install the Hermes
SDK adapter with:uv pip install --find-links dist "nemo-fabric[adapters-hermes-sdk]"Refer to the installation guide for the
complete list of adapters and installation options.Source Development
Install these tools before you start:
- Rust (stable toolchain) -- install with rustup
- Python >= 3.11
- uv -- follow the uv installation guide
- just >= 1.50.0 --
cargo install just --lockedClone the repository, create a virtual environment, and build the Rust and
Python packages:git clone https://github.com/NVIDIA/NeMo-Fabric.git cd NeMo-Fabric uv venv --seed .venv --python 3.13 source .venv/bin/activate uv sync --all-groups --all-extras just no_uv=true build-allVerify the checkout by running the test suites described in
Testing Requirements.Release Tagging
Versioned release tags must use raw Rust-compatible SemVer without a leading
v.
- Use
0.1.0for stable releases.- Use
0.1.0-rc.1for prereleases.- Do not create tags such as
v0.1.0orv0.1.0-rc.1.This keeps release tags aligned with Cargo package versions and lets...
Files:
tests/fixtures/file-config-agent/profiles/relay-openinference.yamlschemas/profile.schema.jsontests/fixtures/file-config-agent/profiles/relay-otel.yamldocs/reference/api/python-library-reference/index.mdpyproject.tomldocs/sdk/python.mdxexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlpython/src/nemo_fabric/__init__.pytests/fixtures/file-config-agent/profiles/relay.yamlexamples/code_review_agent/config.pyexamples/harbor/README.mdschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/run-plan.schema.jsondocs/reference/api/python-library-reference/nemo_fabric.models.mdtests/integrations/test_harbor_runner.pyschemas/adapter-invocation.schema.jsoncrates/fabric-core/src/config.rstests/python/test_sdk_contract.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
{tests/**,python/tests/**}
⚙️ CodeRabbit configuration file
{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.
Files:
tests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/integrations/test_harbor_runner.pytests/python/test_sdk_contract.py
schemas/**/*
⚙️ CodeRabbit configuration file
schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.
Files:
schemas/profile.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/run-plan.schema.jsonschemas/adapter-invocation.schema.json
{docs/**,README.md,AGENTS.md}
⚙️ CodeRabbit configuration file
{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
Files:
docs/reference/api/python-library-reference/index.mddocs/sdk/python.mdxdocs/reference/api/python-library-reference/nemo_fabric.models.md
{adapters/**,examples/**}
⚙️ CodeRabbit configuration file
{adapters/**,examples/**}: Review adapter and example changes for command correctness, config/schema consistency, artifact handling, and compatibility with the public Fabric contracts.
Files:
examples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/code_review_agent/config.pyexamples/harbor/README.md
python/src/nemo_fabric/**/*
⚙️ CodeRabbit configuration file
python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)
tests/**/*.py: Usepytestto run Python tests.
Do not add@pytest.mark.asyncioto test functions; async tests are detected and run automatically.
Do not add-> Nonereturn type annotations to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, addingspecwhen needed.
Name mocked classes with amockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not duplicate fixtures across test files; if a fixture is needed in multiple test files, define it inconftest.py.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the function as<fixture_name>_fixture() -> <return_type>; only passscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating separate tests for different input types.
If a fixture is needed for a test but does not return a value, or its value is unused, use@pytest.mark.usefixtures.
When modifying environment variables in a test, useos.environ;tests/conftest.pyprovides an autouserestore_environ_fixturethat restores environment variables after each test, somonkeypatch.setenvis unnecessary.
Files:
tests/integrations/test_harbor_runner.pytests/python/test_sdk_contract.py
crates/fabric-core/src/**/*.rs
⚙️ CodeRabbit configuration file
crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.
Files:
crates/fabric-core/src/config.rs
🧠 Learnings (1)
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.
Applied to files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧬 Code graph analysis (4)
examples/code_review_agent/config.py (2)
python/src/nemo_fabric/types.py (2)
telemetry(653-656)telemetry(659-660)adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
agent_name(38-39)
tests/integrations/test_harbor_runner.py (2)
python/src/nemo_fabric/models.py (1)
RunRequest(521-567)python/src/nemo_fabric/integrations/harbor/runner.py (2)
compose_config(27-59)load_config(21-24)
tests/python/test_sdk_contract.py (2)
python/src/nemo_fabric/types.py (2)
enable_relay(487-501)to_mapping(815-822)python/src/nemo_fabric/models.py (2)
enable_relay(354-368)to_mapping(412-418)
python/src/nemo_fabric/types.py (3)
python/src/nemo_fabric/models.py (2)
from_mapping(64-64)enable_relay(354-354)examples/code_review_agent/config.py (1)
enable_relay(196-196)tests/python/test_sdk_contract.py (2)
from_mapping(75-75)enable_relay(139-139)
🪛 ast-grep (0.44.1)
tests/python/test_sdk_contract.py
[info] 575-575: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan()["effective_config"])
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 585-585: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 589-589: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_runtime())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
🪛 Clippy (1.96.0)
crates/fabric-core/src/config.rs
[warning] 734-734: this impl can be derived
(warning)
🪛 markdownlint-cli2 (0.22.1)
docs/reference/api/python-library-reference/nemo_fabric.models.md
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 671-671: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 731-731: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 791-791: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 851-851: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 911-911: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 971-971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1031-1031: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1091-1091: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1151-1151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Ruff (0.15.20)
examples/code_review_agent/config.py
[warning] 243-243: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 245-245: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
tests/python/test_sdk_contract.py
[warning] 592-592: Unused method argument: plan_json
(ARG002)
python/src/nemo_fabric/types.py
[warning] 107-107: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 705-705: Remove quotes from type annotation
Remove quotes
(UP037)
🔇 Additional comments (26)
schemas/agent.schema.json (1)
243-813: Same generated-snapshot parity concern already raised onschemas/adapter-invocation.schema.json; the$defsandrelayproperty here are identical.Also applies to: 987-997
schemas/effective-config.schema.json (1)
131-141: Identical Relay$defs/relayadditions as the other schemas; parity verification already requested onschemas/adapter-invocation.schema.json.Also applies to: 341-911
schemas/adapter-invocation.schema.json (2)
420-430:relayasRelayConfig | nullmatches the RustFabricConfig.relay: Option<RelayConfig>(#[serde(default, skip_serializing_if = "Option::is_none")]). Consistent.
653-1223: 🗄️ Data Integrity & IntegrationNo changes needed for Relay schema snapshots. The Relay
$defsalign with the RustRelay*JsonSchematypes, andschema_snapshots_match_generated_contractlocks the generated schema output againstschemas/adapter-invocation.schema.json.tests/fixtures/file-config-agent/profiles/relay.yaml (1)
13-26: Relay observability is correctly moved under the top-levelrelay:block (nottelemetry.config), matching the new typed contract.tests/integrations/test_harbor_runner.py (2)
22-25: LGTM!Also applies to: 40-43, 159-161, 310-310, 324-324, 346-350
395-407: 🎯 Functional Correctness
hermes-relay.yamlalready usesrelay.observability—openinference,atof, andatifare present there, soconfig["relay"]["observability"]is valid.> Likely an incorrect or invalid review comment.schemas/profile.schema.json (1)
51-58: LGTM!tests/fixtures/file-config-agent/profiles/relay-otel.yaml (1)
13-26: LGTM!schemas/run-plan.schema.json (2)
782-1352: 🩺 Stability & AvailabilityNo change needed — the Relay
$defsare generated fromcrates/fabric-core/src/config.rs, andcrates/fabric-core/src/schema.rsalready snapshotsschemas/run-plan.schema.jsonagainst regenerated output.
1226-1236: 🗄️ Data Integrity & Integration
RelayObservabilityConfig.policyis intentional. It exists in both structs and is serialized in two different places: the top-levelRelayConfig.policygoes into the Relay plugin config, whileRelayObservabilityConfig.policystays inside the nested observability component. There’s no precedence conflict here.> Likely an incorrect or invalid review comment.tests/fixtures/file-config-agent/profiles/relay-openinference.yaml (1)
13-30: 🗄️ Data Integrity & IntegrationNo additional Harbor coverage needed.
tests/e2e/test_cli.pyalready exercisesfile_config_agent_dir, which includestests/fixtures/file-config-agent/profiles/relay-openinference.yaml.> Likely an incorrect or invalid review comment.crates/fabric-core/src/config.rs (1)
632-653: The remaining Relay model definitions, default helpers, and updated telemetry planning tests are internally consistent and match the schema/Python contract.
LGTM!Also applies to: 1035-1066, 2087-2192
python/src/nemo_fabric/models.py (1)
16-27: Relay pydantic models mirror the Rust defaults and shapes (versions, timeouts, mode/transport literals, filename templates), andenable_relaycorrectly normalizes typed/mapping inputs.typing.Selfis valid givenrequires-python = ">=3.11".
LGTM!Also applies to: 234-343, 401-500, 516-516
python/src/nemo_fabric/__init__.py (1)
7-51: All added Relay symbols are both imported and exported; public surface is consistent.
LGTM!Also applies to: 76-85
tests/python/test_sdk_contract.py (1)
11-47: Relay assertions align with the emittedto_mapping()shapes (observability nesting, policy defaults, emptycomponents), and imports resolve against the exported symbols.
LGTM!Also applies to: 140-166, 187-247, 282-286
examples/harbor/demo/task/environment/fabric/configs/hermes-relay.yaml (1)
40-57: Observability config is correctly relocated to the top-levelrelay:block matching the new contract; enable flags, directories, filenames, and endpoint are preserved.
LGTM!pyproject.toml (1)
58-58: 📐 Maintainability & Code Quality | 💤 Low valueNote:
~=0.5.0resolves to>=0.5.0,<0.6.0, which is stricter than the previous~=0.4(>=0.4,<1.0). If minor-level compatibility (<1.0) was intended, use~=0.5; otherwise this pin is fine.python/src/nemo_fabric/types.py (3)
486-500: LGTM!
533-598: LGTM!Also applies to: 625-629
9-16: LGTM!Also applies to: 107-109, 133-133, 264-264, 280-280, 341-341, 385-385, 569-569, 581-585, 812-812, 913-920, 941-941, 997-997, 1067-1067, 1260-1269
examples/code_review_agent/config.py (1)
10-20: LGTM!Also applies to: 145-145, 191-213, 216-236, 239-260
docs/reference/api/python-library-reference/index.md (1)
34-43: LGTM!docs/reference/api/python-library-reference/nemo_fabric.models.md (1)
611-1306: LGTM!Also applies to: 1432-1441
docs/sdk/python.mdx (1)
174-189: 📐 Maintainability & Code Quality | ⚡ Quick winMutates
configdirectly, unlike the surrounding examples.Earlier in this section, variations are built via
config.model_copy(deep=True)before mutation (see thecapability_configandreview_agent_configexamples above). This new snippet instead callsconfig.enable_relay(...)onconfigdirectly, which mutates the shared object used by the earlier examples in this doc. For consistency and to avoid confusing readers who copy snippets sequentially, consider copying first.-config.enable_relay( +relay_config = config.model_copy(deep=True) +relay_config.enable_relay( output_dir="./artifacts/relay", components=[ RelayComponentConfig(kind="switchyard", config={"route": "canary"}), ], )examples/harbor/README.md (1)
62-65: LGTM!Also applies to: 103-133
1dcdf9a to
fedf128
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
python/src/nemo_fabric/models.py (1)
460-490: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
enable_relayoverwritesself.relaywholesale, losing previously configured fields.Every call constructs a brand-new
RelayConfig(...)from only the arguments passed this time —project,output_dir,observability,components,policyall default toNone/[]when omitted, silently wiping any values previously set (either via an earlierenable_relay()call or by directly assigningself.relay). This is confirmed byexamples/code_review_agent/config.py'swith_relay_openinference, which avoids callingenable_relay()a second time and instead mutatesconfig.relayattributes directly — a workaround for this exact reset behavior.🛠️ Suggested fix: merge with existing relay config instead of replacing
if self.telemetry is None: self.telemetry = TelemetryConfig() self.telemetry.enable_relay() + existing = self.relay if isinstance(self.relay, RelayConfig) else ( + RelayConfig.model_validate(self.relay) if self.relay else None + ) relay_observability = ( observability if observability is None or isinstance(observability, RelayObservabilityConfig) else dict(observability) ) relay_components = [ item if isinstance(item, RelayComponentConfig) else dict(item) for item in (components or []) ] relay_policy = policy if policy is None or isinstance(policy, RelayConfigPolicy) else dict(policy) self.relay = RelayConfig( - project=project, - output_dir=output_dir, - observability=relay_observability, - components=relay_components, - policy=relay_policy, + project=project if project is not None else (existing.project if existing else None), + output_dir=output_dir if output_dir is not None else (existing.output_dir if existing else None), + observability=relay_observability if relay_observability is not None else (existing.observability if existing else None), + components=relay_components or (existing.components if existing else []), + policy=relay_policy if relay_policy is not None else (existing.policy if existing else 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 `@python/src/nemo_fabric/models.py` around lines 460 - 490, Update enable_relay to merge provided values into the existing self.relay configuration instead of always constructing a new RelayConfig. Preserve previously configured project, output_dir, observability, components, and policy when their corresponding arguments are omitted, while still applying explicitly supplied values and retaining the existing telemetry enablement behavior.adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
202-235: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHandle the schema-supported
grpctransport. Native telemetry plans can carrygrpchere, but this mapping only acceptshttp_binaryandhttp_json, so a valid plan can fail at runtime. Mapgrpcto the Codex OTLP settings or reject it during validation, and add a regression test.🤖 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 `@adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py` around lines 202 - 235, Update the OpenTelemetry transport mapping in the native telemetry handling flow around the `transport` branch to support the schema-valid `grpc` value by mapping it to the appropriate Codex OTLP exporter and protocol settings. Preserve the existing `http_binary` and `http_json` mappings, and add a regression test covering a plan with `grpc` transport.Source: Path instructions
crates/fabric-core/src/runtime.rs (1)
1273-1304: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMetadata build duplicated across
runtime_telemetry_contextandtelemetry_ref.The
telemetry_providers/relay_project/relay_output_dir/adapter_outputsblock is identical in both functions and had to be edited in both places for this change. Extract a shared helper to keep the two metadata surfaces from drifting.♻️ Sketch
fn base_telemetry_metadata(telemetry: &TelemetryPlan) -> BTreeMap<String, Value> { let mut metadata = BTreeMap::new(); metadata.insert( "telemetry_providers".to_string(), Value::Array( telemetry .providers .iter() .map(|p| Value::String(p.as_str().to_string())) .collect(), ), ); if let Some(project) = &telemetry.relay_project { metadata.insert("relay_project".to_string(), Value::String(project.clone())); } if let Some(output_dir) = &telemetry.relay_output_dir { metadata.insert( "relay_output_dir".to_string(), Value::String(output_dir.to_string_lossy().into_owned()), ); } if !telemetry.adapter_outputs.is_empty() { metadata.insert( "adapter_outputs".to_string(), Value::Array( telemetry .adapter_outputs .iter() .map(|o| Value::String(o.clone())) .collect(), ), ); } metadata }
telemetry_refthen augments the returned map withrelay_config/relay_config_path.🤖 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 `@crates/fabric-core/src/runtime.rs` around lines 1273 - 1304, Extract the shared telemetry metadata construction into a helper such as base_telemetry_metadata(&TelemetryPlan) -> BTreeMap<String, Value>. Update both runtime_telemetry_context and telemetry_ref to call it, preserving the existing telemetry_providers, relay_project, relay_output_dir, and adapter_outputs values; keep telemetry_ref’s relay_config and relay_config_path additions as separate augmentations.
🤖 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 `@adapters/common/src/nemo_fabric_adapters/common/hermes.py`:
- Around line 43-44: Update the provider validation in the Hermes telemetry flow
so any configured provider other than "relay" is rejected, including
combinations such as ["relay", "native"]. Preserve acceptance of an empty or
absent provider list when telemetry is disabled, and use the existing providers
value from common_utils.telemetry_providers(payload).
In `@tests/adapters/test_codex_cli.py`:
- Around line 317-329: Extend the test around codex_cli_config and
with_native_otel with pytest.mark.parametrize to cover both supported native
transports, including grpc and the existing http_binary case. For each
parameter, configure the native transport, generate the Codex profile, and
assert the resulting native_config preserves the selected transport value.
In `@tests/integrations/test_harbor_runner.py`:
- Line 398: Add an assertion near the existing observability lookup in the test
to verify that "relay" is present in config["telemetry"]["providers"], while
preserving the existing relay.observability validation.
---
Outside diff comments:
In `@adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py`:
- Around line 202-235: Update the OpenTelemetry transport mapping in the native
telemetry handling flow around the `transport` branch to support the
schema-valid `grpc` value by mapping it to the appropriate Codex OTLP exporter
and protocol settings. Preserve the existing `http_binary` and `http_json`
mappings, and add a regression test covering a plan with `grpc` transport.
In `@crates/fabric-core/src/runtime.rs`:
- Around line 1273-1304: Extract the shared telemetry metadata construction into
a helper such as base_telemetry_metadata(&TelemetryPlan) -> BTreeMap<String,
Value>. Update both runtime_telemetry_context and telemetry_ref to call it,
preserving the existing telemetry_providers, relay_project, relay_output_dir,
and adapter_outputs values; keep telemetry_ref’s relay_config and
relay_config_path additions as separate augmentations.
In `@python/src/nemo_fabric/models.py`:
- Around line 460-490: Update enable_relay to merge provided values into the
existing self.relay configuration instead of always constructing a new
RelayConfig. Preserve previously configured project, output_dir, observability,
components, and policy when their corresponding arguments are omitted, while
still applying explicitly supplied values and retaining the existing telemetry
enablement behavior.
🪄 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: ASSERTIVE
Plan: Enterprise
Run ID: 41c708d4-e02d-4f13-908a-2e0883cec07e
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (94)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pycrates/fabric-core/src/config.rscrates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rsdocs/reference/api/python-library-reference/index.mddocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/sdk/python.mdxexamples/code_review_agent/config.pyexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamlpyproject.tomlpython/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.pyschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/profile.schema.jsonschemas/run-plan.schema.jsontests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/adapters/test_hermes_cli.pytests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/python/test_sdk_contract.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**
⚙️ CodeRabbit configuration file
**:Contributing to NeMo Fabric
Thank you for your interest in contributing to NeMo Fabric. This guide covers
the development workflow, coding standards, and pull request process.Development Setup
This section collects the setup steps needed before building, testing, or
contributing changes.Package Installation
NeMo Fabric is not currently available on PyPI. To consume the Python packages,
build wheels from a source checkout:just wheels uv pip install --find-links dist "nemo-fabric[runtime]"Adapters are distributed as optional extras. For example, install the Hermes
SDK adapter with:uv pip install --find-links dist "nemo-fabric[adapters-hermes-sdk]"Refer to the installation guide for the
complete list of adapters and installation options.Source Development
Install these tools before you start:
- Rust (stable toolchain) -- install with rustup
- Python >= 3.11
- uv -- follow the uv installation guide
- just >= 1.50.0 --
cargo install just --lockedClone the repository, create a virtual environment, and build the Rust and
Python packages:git clone https://github.com/NVIDIA/NeMo-Fabric.git cd NeMo-Fabric uv venv --seed .venv --python 3.13 source .venv/bin/activate uv sync --all-groups --all-extras just no_uv=true build-allVerify the checkout by running the test suites described in
Testing Requirements.Release Tagging
Versioned release tags must use raw Rust-compatible SemVer without a leading
v.
- Use
0.1.0for stable releases.- Use
0.1.0-rc.1for prereleases.- Do not create tags such as
v0.1.0orv0.1.0-rc.1.This keeps release tags aligned with Cargo package versions and lets...
Files:
tests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxexamples/harbor/demo/task/environment/fabric/configs/hermes.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxtests/fixtures/file-config-agent/profiles/relay-otel.yamlexamples/harbor/demo/task/environment/fabric/configs/codex.yamldocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxtests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxexamples/harbor/demo/task/environment/fabric/configs/smoke.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxpyproject.tomldocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxtests/fixtures/file-config-agent/profiles/relay.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxcrates/fabric-core/src/lib.rsdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxtests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxtests/fixtures/file-config-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pydocs/reference/api/rust-library-reference/fabric-core/index.mdxtests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamladapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pydocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxtests/fixtures/hermes-shim-agent/profiles/mcp-github.yamlexamples/harbor/README.mdtests/fixtures/file-config-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxschemas/profile.schema.jsonadapters/common/src/nemo_fabric_adapters/common/hermes.pydocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxtests/fixtures/file-config-agent/profiles/relay-openinference.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxtests/python/test_code_review_example.pydocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxtests/adapters/test_hermes_cli.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxpython/src/nemo_fabric/__init__.pydocs/reference/api/python-library-reference/index.mdschemas/run-plan.schema.jsontests/adapters/test_adapaters_common_hermes.pycrates/fabric-core/src/runtime.rsschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonexamples/code_review_agent/config.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pytests/adapters/test_codex_cli.pydocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxtests/integrations/test_harbor_runner.pypython/src/nemo_fabric/models.pyschemas/effective-config.schema.jsondocs/reference/api/python-library-reference/nemo_fabric.models.mdtests/python/test_sdk_contract.pypython/src/nemo_fabric/types.pycrates/fabric-core/src/config.rs
{tests/**,python/tests/**}
⚙️ CodeRabbit configuration file
{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.
Files:
tests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/python/test_code_review_example.pytests/adapters/test_hermes_cli.pytests/fixtures/file-config-agent/profiles/mcp-github.yamltests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/integrations/test_harbor_runner.pytests/python/test_sdk_contract.py
{docs/**,README.md,AGENTS.md}
⚙️ CodeRabbit configuration file
{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/python-library-reference/index.mddocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/python-library-reference/nemo_fabric.models.md
{adapters/**,examples/**}
⚙️ CodeRabbit configuration file
{adapters/**,examples/**}: Review adapter and example changes for command correctness, config/schema consistency, artifact handling, and compatibility with the public Fabric contracts.
Files:
examples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamladapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyexamples/harbor/README.mdadapters/common/src/nemo_fabric_adapters/common/hermes.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/code_review_agent/config.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
crates/fabric-core/src/**/*.rs
⚙️ CodeRabbit configuration file
crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.
Files:
crates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rscrates/fabric-core/src/config.rs
schemas/**/*
⚙️ CodeRabbit configuration file
schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.
Files:
schemas/profile.schema.jsonschemas/run-plan.schema.jsonschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.json
tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)
tests/**/*.py: Usepytestto run Python tests.
Do not add@pytest.mark.asyncioto test functions; async tests are detected and run automatically.
Do not add-> Nonereturn type annotations to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, addingspecwhen needed.
Name mocked classes with amockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not duplicate fixtures across test files; if a fixture is needed in multiple test files, define it inconftest.py.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the function as<fixture_name>_fixture() -> <return_type>; only passscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating separate tests for different input types.
If a fixture is needed for a test but does not return a value, or its value is unused, use@pytest.mark.usefixtures.
When modifying environment variables in a test, useos.environ;tests/conftest.pyprovides an autouserestore_environ_fixturethat restores environment variables after each test, somonkeypatch.setenvis unnecessary.
Files:
tests/python/test_code_review_example.pytests/adapters/test_hermes_cli.pytests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/integrations/test_harbor_runner.pytests/python/test_sdk_contract.py
python/src/nemo_fabric/**/*
⚙️ CodeRabbit configuration file
python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧠 Learnings (2)
📚 Learning: 2026-07-09T22:28:51.689Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 43
File: adapters/claude-sdk/src/nemo_fabric_adapters/claude_sdk/adapter.py:164-168
Timestamp: 2026-07-09T22:28:51.689Z
Learning: In the NeMo-Fabric adapters, treat path values used in Fabric adapter configuration (including logic like `_resolve_path` in adapter.py) as config-root-relative. Do not apply `Path.expanduser()` (or otherwise apply `~`/home or shell-style expansion), because it will make the resolved paths normalize inconsistently across adapters. Also, do not rely on or add any resolution behavior that uses `harness.settings.cwd` as an override point for these adapter paths—`harness.settings.cwd` is explicitly unsupported in this adapter context.
Applied to files:
adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.
Applied to files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧬 Code graph analysis (8)
adapters/common/src/nemo_fabric_adapters/common/hermes.py (1)
adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py (1)
validate_hermes_telemetry_provider(69-69)
examples/code_review_agent/config.py (1)
python/src/nemo_fabric/types.py (2)
telemetry(648-651)telemetry(654-655)
adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
adapters/common/src/nemo_fabric_adapters/common/hermes.py (2)
relay_enabled(49-49)dump_yaml(113-113)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
adapters/common/src/nemo_fabric_adapters/common/utils.py (3)
settings_payload(73-75)collect_relay_artifacts(338-356)runtime_id(54-60)
tests/integrations/test_harbor_runner.py (2)
python/src/nemo_fabric/models.py (1)
RunRequest(511-557)python/src/nemo_fabric/integrations/harbor/runner.py (2)
compose_config(27-59)load_config(21-24)
python/src/nemo_fabric/models.py (3)
python/src/nemo_fabric/types.py (2)
telemetry(648-651)telemetry(654-655)examples/code_review_agent/config.py (1)
enable_relay(196-196)tests/python/test_sdk_contract.py (3)
FabricProfileConfig(1037-1037)FabricProfileConfig(1027-1027)TelemetryConfig(147-147)
tests/python/test_sdk_contract.py (1)
python/src/nemo_fabric/types.py (1)
to_mapping(807-814)
python/src/nemo_fabric/types.py (2)
examples/code_review_agent/config.py (1)
enable_relay(196-196)tests/python/test_sdk_contract.py (2)
EffectiveConfig(354-354)enable_relay(140-140)
🪛 ast-grep (0.44.1)
tests/python/test_sdk_contract.py
[info] 587-587: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan()["effective_config"])
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 597-597: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 601-601: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_runtime())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
🪛 LanguageTool
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> Endpoint headers. ### timeout_millis: u64 Re...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdx
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> OTLP headers. ### `resource_attributes: BTr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~35-~35: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..._attributes: BTreeMap<String, String> OTLP resource attributes. ###service_name...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~39-~39: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ttributes. ### service_name: String OTLP service name. ### `service_namespace: ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## service_namespace: Option<String> OTLP service namespace. ### `service_versio...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~47-~47: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... ### service_version: Option<String> OTLP service version. ### `instrumentation_...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...instrumentation_scope: Option OTLP instrumentation scope. ###timeout_mi...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...orted_value: RelayUnsupportedBehavior` Policy for unsupported values. ## Trait Imple...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
docs/reference/api/python-library-reference/nemo_fabric.models.md
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 671-671: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 731-731: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 791-791: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 851-851: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 911-911: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 971-971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1031-1031: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1091-1091: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1151-1151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1211-1211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1271-1271: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Ruff (0.15.20)
examples/code_review_agent/config.py
[warning] 243-243: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 245-245: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
[warning] 161-161: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 235-235: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 259-259: Prefer TypeError exception for invalid type
(TRY004)
[warning] 259-259: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 321-321: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 384-384: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 411-411: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 503-503: Avoid specifying long messages outside the exception class
(TRY003)
tests/python/test_sdk_contract.py
[warning] 604-604: Unused method argument: plan_json
(ARG002)
python/src/nemo_fabric/types.py
[warning] 107-107: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 469-469: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 475-475: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 483-483: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 494-494: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 507-507: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 700-700: Remove quotes from type annotation
Remove quotes
(UP037)
fedf128 to
6d5c25c
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
python/src/nemo_fabric/models.py (1)
460-490: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMerge into the existing relay block instead of replacing it.
enable_relay()rebuildsself.relayfrom scratch, so a second call drops earlierobservability/components/policyvalues. It also emitscomponents: []here while the resolved config omits the field when unused, so the two SDK layers drift.🤖 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 `@python/src/nemo_fabric/models.py` around lines 460 - 490, Update Config.enable_relay to merge supplied values into the existing self.relay instead of recreating it, preserving previously configured observability, components, and policy across repeated calls. Treat omitted components as unchanged and preserve the resolved-config behavior that omits unused components rather than storing an empty list.Sources: Path instructions, Learnings
🤖 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 `@adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py`:
- Around line 445-454: Update the environment setup around
virtualenv_subprocess_env so Codex starts from an explicit minimal allowlist
rather than the complete parent environment. Preserve overlaying validated
configured variables from settings_payload, and add a regression assertion
confirming FABRIC_UNRELATED_SECRET is not passed to the subprocess.
In `@adapters/common/src/nemo_fabric_adapters/common/utils.py`:
- Around line 111-129: Update run_deepagents and resolve_observability to stop
calling the removed common_utils.telemetry_provider and
common_utils.telemetry_payload helpers. Use telemetry_providers for provider
selection, relay_enabled for relay status, and native_telemetry_config for
native configuration, preserving the existing telemetry behavior without
AttributeError.
In `@adapters/deepagents/pyproject.toml`:
- Line 26: Update the nemo-relay dependency in the project requirements to
include the deepagents extra, changing the existing nemo-relay~=0.5.0
specification to enable the integration imported by the deepagents adapter while
preserving the same version constraint.
In `@adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py`:
- Around line 358-379: Replace the manual context-manager handling in
open_checkpointer and close_checkpointer with an AsyncExitStack owned by
run_deepagents. Enter AsyncSqliteSaver through the stack, pass the resulting
saver to the agent, and let the stack close it when the invocation scope exits;
remove the _fabric_cm assignment, type-ignore, and explicit close_checkpointer
call.
- Around line 455-456: Replace the legacy common_utils.telemetry_provider and
telemetry_payload calls in the surrounding adapter flow with the shared
telemetry_plan fields and helpers: use telemetry_plan.relay_enabled,
telemetry_plan.providers, and telemetry_plan.native_config to configure Relay
and native observability without relying on undefined utility symbols.
In `@adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py`:
- Line 84: Update the relay gate in the deepagents adapter’s relevant flow to
call common_utils.relay_enabled(payload) instead of reading FABRIC_RELAY_ENABLED
directly. Preserve the existing payload and downstream relay behavior so gating
consistently follows telemetry_plan.relay_enabled.
In `@crates/fabric-core/src/runtime.rs`:
- Around line 1343-1353: Update validate_python_command to collapse the nested
adapter_python_value and path.is_file checks into a single let-chain, preserving
the existing InvalidAdapterPython error and Ok behavior.
In `@docs/reference/api/python-library-reference/nemo_fabric.models.md`:
- Around line 611-612: Add blank lines immediately after each inserted class
heading in the generated API reference, including RelayConfigPolicy and the
other listed class headings, so each heading is separated from its description
and satisfies markdownlint MD022.
In `@examples/code_review_agent/config.py`:
- Around line 269-284: Split the composite assertions in the relay configuration
setup into separate assertions for each condition. Update the assertions
guarding config.telemetry, config.relay, and relay.observability so each failure
identifies one missing or invalid value, while preserving the existing type and
non-None checks.
In `@tests/adapters/test_codex_cli.py`:
- Around line 546-547: Update the test around the seeded FABRIC_UNRELATED_SECRET
and codex_payload environment settings to assert that child_env does not contain
FABRIC_UNRELATED_SECRET, while preserving the existing assertion that
CODEX_EXPLICIT is forwarded.
---
Outside diff comments:
In `@python/src/nemo_fabric/models.py`:
- Around line 460-490: Update Config.enable_relay to merge supplied values into
the existing self.relay instead of recreating it, preserving previously
configured observability, components, and policy across repeated calls. Treat
omitted components as unchanged and preserve the resolved-config behavior that
omits unused components rather than storing an empty list.
🪄 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: ASSERTIVE
Plan: Enterprise
Run ID: 93bf105e-ebb5-447f-883c-be46bb9d7dd8
⛔ Files ignored due to path filters (2)
adapters/deepagents/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (96)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/deepagents/pyproject.tomladapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pycrates/fabric-core/src/config.rscrates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rsdocs/reference/api/python-library-reference/index.mddocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/sdk/python.mdxexamples/code_review_agent/config.pyexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamlpyproject.tomlpython/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.pyschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/profile.schema.jsonschemas/run-plan.schema.jsontests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/adapters/test_hermes_cli.pytests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/python/test_sdk_contract.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Test (arm64)
- GitHub Check: Test (x86_64)
⚠️ CI failures not shown inline (3)
GitHub Actions: Check / Pre-commit: feat(relay): add typed Relay config
Conclusion: failure
##[group]Run bail() {
�[36;1mbail() {�[0m
�[36;1m printf '::error::install-action: %s\n' "$*"�[0m
GitHub Actions: Check / 0_Pre-commit.txt: feat(relay): add typed Relay config
Conclusion: failure
##[group]Run bail() {
�[36;1mbail() {�[0m
�[36;1m printf '::error::install-action: %s\n' "$*"�[0m
GitHub Actions: Check / Pre-commit: feat(relay): add typed Relay config
Conclusion: failure
##[group]Run uv run --no-sync pre-commit run --all-files --show-diff-on-failure
�[36;1muv run --no-sync pre-commit run --all-files --show-diff-on-failure�[0m
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
env:
UV_PYTHON_INSTALL_DIR: /home/runner/work/_temp/uv-python-dir
UV_CACHE_DIR: /home/runner/work/_temp/setup-uv-cache
GOTOOLCHAIN: local
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 0
CARGO_TERM_COLOR: always
RUST_BACKTRACE: short
RUSTFLAGS: -D warnings
CARGO_UNSTABLE_SPARSE_REGISTRY: true
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
##[endgroup]
[INFO] Initializing environment for https://github.com/rhysd/actionlint.
[INFO] Installing environment for https://github.com/rhysd/actionlint.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
copyright header.........................................................Passed
Lint GitHub Actions workflow files.......................................Passed
Cargo.lock is up to date.................................................Passed
uv lockfiles are up to date..............................................Passed
ATTRIBUTIONS-Rust.md (Cargo.lock)........................................Passed
ATTRIBUTIONS-Python.md (uv.lock).........................................Failed
- hook id: attributions-python
- files were modified by this hook
Wrote ATTRIBUTIONS-Python.md
pre-commit hook(s) made changes.
If you are seeing this message in CI, reproduce locally with: `pre-commit run --all-files`.
To run `pre-commit` as part of git workflow, use `pre-commit install`.
All changes made by hooks:
diff --git a/ATTRIBUTIONS-Python.md b/ATTRIBUTIONS-Python.md
index fdb91e1..5c75ab2 100644
--- a/ATTRIBUTIONS-Python.md
+++ b/ATTRIBUTIONS-Python.md
@@ -5725,7 +5725,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
-## nemo-relay (0.4.0)
+## nemo-relay (0.5.0...
🧰 Additional context used
📓 Path-based instructions (8)
**
⚙️ CodeRabbit configuration file
**:Contributing to NeMo Fabric
Thank you for your interest in contributing to NeMo Fabric. This guide covers
the development workflow, coding standards, and pull request process.Development Setup
This section collects the setup steps needed before building, testing, or
contributing changes.Package Installation
NeMo Fabric is not currently available on PyPI. To consume the Python packages,
build wheels from a source checkout:just wheels uv pip install --find-links dist "nemo-fabric[runtime]"Adapters are distributed as optional extras. For example, install the Hermes
SDK adapter with:uv pip install --find-links dist "nemo-fabric[adapters-hermes-sdk]"Refer to the installation guide for the
complete list of adapters and installation options.Source Development
Install these tools before you start:
- Rust (stable toolchain) -- install with rustup
- Python >= 3.11
- uv -- follow the uv installation guide
- just >= 1.50.0 --
cargo install just --lockedClone the repository, create a virtual environment, and build the Rust and
Python packages:git clone https://github.com/NVIDIA/NeMo-Fabric.git cd NeMo-Fabric uv venv --seed .venv --python 3.13 source .venv/bin/activate uv sync --all-groups --all-extras just no_uv=true build-allVerify the checkout by running the test suites described in
Testing Requirements.Release Tagging
Versioned release tags must use raw Rust-compatible SemVer without a leading
v.
- Use
0.1.0for stable releases.- Use
0.1.0-rc.1for prereleases.- Do not create tags such as
v0.1.0orv0.1.0-rc.1.This keeps release tags aligned with Cargo package versions and lets...
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxtests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxtests/fixtures/hermes-cli-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxexamples/harbor/demo/task/environment/fabric/configs/codex.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/hermes-shim-agent/agent.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlpyproject.tomlcrates/fabric-core/src/lib.rsdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxtests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/file-config-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/error/index.mdxexamples/harbor/demo/task/environment/fabric/configs/smoke.yamladapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pytests/fixtures/file-config-agent/profiles/relay.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxtests/fixtures/file-config-agent/profiles/env-local.yamlschemas/profile.schema.jsondocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/python-library-reference/index.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxtests/fixtures/hermes-shim-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxtests/fixtures/file-config-agent/profiles/relay-otel.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamldocs/sdk/python.mdxtests/fixtures/file-config-agent/profiles/relay-openinference.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxtests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/adapters/test_hermes_cli.pytests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamladapters/deepagents/pyproject.tomldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxtests/fixtures/file-config-agent/profiles/mcp-github.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxtests/fixtures/file-config-agent/profiles/hermes-cli.yamlpython/src/nemo_fabric/__init__.pytests/fixtures/hermes-shim-agent/profiles/mcp-github.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxcrates/fabric-core/src/runtime.rsdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyexamples/harbor/README.mdadapters/common/src/nemo_fabric_adapters/common/hermes.pydocs/reference/api/python-library-reference/nemo_fabric.models.mdtests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pyschemas/agent.schema.jsondocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxschemas/adapter-invocation.schema.jsonadapters/common/src/nemo_fabric_adapters/common/utils.pyschemas/effective-config.schema.jsontests/adapters/test_codex_cli.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyexamples/code_review_agent/config.pypython/src/nemo_fabric/types.pytests/adapters/test_adapaters_common_hermes.pypython/src/nemo_fabric/models.pytests/python/test_sdk_contract.pyschemas/run-plan.schema.jsoncrates/fabric-core/src/config.rs
{docs/**,README.md,AGENTS.md}
⚙️ CodeRabbit configuration file
{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/python-library-reference/index.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdx
{tests/**,python/tests/**}
⚙️ CodeRabbit configuration file
{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.
Files:
tests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/adapters/test_hermes_cli.pytests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/adapters/test_codex_cli.pytests/adapters/test_adapaters_common_hermes.pytests/python/test_sdk_contract.py
{adapters/**,examples/**}
⚙️ CodeRabbit configuration file
{adapters/**,examples/**}: Review adapter and example changes for command correctness, config/schema consistency, artifact handling, and compatibility with the public Fabric contracts.
Files:
examples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamladapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamladapters/deepagents/pyproject.tomladapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyexamples/harbor/README.mdadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyexamples/code_review_agent/config.py
crates/fabric-core/src/**/*.rs
⚙️ CodeRabbit configuration file
crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.
Files:
crates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rscrates/fabric-core/src/config.rs
schemas/**/*
⚙️ CodeRabbit configuration file
schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.
Files:
schemas/profile.schema.jsonschemas/agent.schema.jsonschemas/adapter-invocation.schema.jsonschemas/effective-config.schema.jsonschemas/run-plan.schema.json
tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)
tests/**/*.py: Usepytestto run Python tests.
Do not add@pytest.mark.asyncioto test functions; async tests are detected and run automatically.
Do not add-> Nonereturn type annotations to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, addingspecwhen needed.
Name mocked classes with amockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not duplicate fixtures across test files; if a fixture is needed in multiple test files, define it inconftest.py.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the function as<fixture_name>_fixture() -> <return_type>; only passscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating separate tests for different input types.
If a fixture is needed for a test but does not return a value, or its value is unused, use@pytest.mark.usefixtures.
When modifying environment variables in a test, useos.environ;tests/conftest.pyprovides an autouserestore_environ_fixturethat restores environment variables after each test, somonkeypatch.setenvis unnecessary.
Files:
tests/adapters/test_hermes_cli.pytests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/adapters/test_codex_cli.pytests/adapters/test_adapaters_common_hermes.pytests/python/test_sdk_contract.py
python/src/nemo_fabric/**/*
⚙️ CodeRabbit configuration file
python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/types.pypython/src/nemo_fabric/models.py
🧠 Learnings (2)
📚 Learning: 2026-07-09T22:28:51.689Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 43
File: adapters/claude-sdk/src/nemo_fabric_adapters/claude_sdk/adapter.py:164-168
Timestamp: 2026-07-09T22:28:51.689Z
Learning: In the NeMo-Fabric adapters, treat path values used in Fabric adapter configuration (including logic like `_resolve_path` in adapter.py) as config-root-relative. Do not apply `Path.expanduser()` (or otherwise apply `~`/home or shell-style expansion), because it will make the resolved paths normalize inconsistently across adapters. Also, do not rely on or add any resolution behavior that uses `harness.settings.cwd` as an override point for these adapter paths—`harness.settings.cwd` is explicitly unsupported in this adapter context.
Applied to files:
adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.
Applied to files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/types.pypython/src/nemo_fabric/models.py
🧬 Code graph analysis (6)
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py (1)
adapters/common/src/nemo_fabric_adapters/common/utils.py (6)
load_relay_plugin_config(156-180)load_payload(71-77)settings_payload(103-105)environment_payload(99-100)models_payload(108-109)fabric_config(59-60)
tests/integrations/test_harbor_runner.py (1)
python/src/nemo_fabric/integrations/harbor/runner.py (2)
compose_config(27-59)load_config(21-24)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
settings_payload(103-105)
examples/code_review_agent/config.py (2)
python/src/nemo_fabric/types.py (2)
telemetry(648-651)telemetry(654-655)python/src/nemo_fabric/models.py (2)
remove_skill_path(452-459)remove_mcp_server(435-442)
python/src/nemo_fabric/models.py (1)
python/src/nemo_fabric/types.py (2)
telemetry(648-651)telemetry(654-655)
tests/python/test_sdk_contract.py (2)
python/src/nemo_fabric/types.py (1)
to_mapping(807-814)python/src/nemo_fabric/models.py (1)
extra_fields(70-73)
🪛 ast-grep (0.44.1)
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py
[info] 81-81: use jsonify instead of json.dumps for JSON output
Context: json.dumps(output, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 352-352: use jsonify instead of json.dumps for JSON output
Context: json.dumps({"runtime_id": runtime_id, "thread_id": thread_id}, indent=2)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 459-459: use jsonify instead of json.dumps for JSON output
Context: json.dumps(user_message, sort_keys=True)
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
tests/python/test_sdk_contract.py
[info] 588-588: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan()["effective_config"])
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 598-598: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 602-602: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_runtime())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
🪛 Clippy (1.96.0)
crates/fabric-core/src/runtime.rs
[warning] 1344-1344: this if statement can be collapsed
(warning)
🪛 LanguageTool
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> Endpoint headers. ### timeout_millis: u64 Re...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdx
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> OTLP headers. ### `resource_attributes: BTr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~35-~35: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..._attributes: BTreeMap<String, String> OTLP resource attributes. ###service_name...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~39-~39: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ttributes. ### service_name: String OTLP service name. ### `service_namespace: ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## service_namespace: Option<String> OTLP service namespace. ### `service_versio...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~47-~47: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... ### service_version: Option<String> OTLP service version. ### `instrumentation_...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...instrumentation_scope: Option OTLP instrumentation scope. ###timeout_mi...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...orted_value: RelayUnsupportedBehavior` Policy for unsupported values. ## Trait Imple...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
docs/reference/api/python-library-reference/nemo_fabric.models.md
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 671-671: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 731-731: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 791-791: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 851-851: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 911-911: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 971-971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1031-1031: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1091-1091: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1151-1151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1211-1211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1271-1271: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Ruff (0.15.20)
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py
[warning] 72-74: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 107-110: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 116-120: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 158-158: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 163-163: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 190-190: Dynamically typed expressions (typing.Any) are disallowed in resolve_backend
(ANN401)
[warning] 223-226: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 230-230: Dynamically typed expressions (typing.Any) are disallowed in allowed_tools_middleware
(ANN401)
[warning] 242-242: Dynamically typed expressions (typing.Any) are disallowed in request
(ANN401)
[warning] 242-242: Dynamically typed expressions (typing.Any) are disallowed in _blocked
(ANN401)
[warning] 251-251: Dynamically typed expressions (typing.Any) are disallowed in request
(ANN401)
[warning] 251-251: Dynamically typed expressions (typing.Any) are disallowed in handler
(ANN401)
[warning] 251-251: Dynamically typed expressions (typing.Any) are disallowed in awrap_tool_call
(ANN401)
[warning] 256-256: Dynamically typed expressions (typing.Any) are disallowed in request
(ANN401)
[warning] 256-256: Dynamically typed expressions (typing.Any) are disallowed in handler
(ANN401)
[warning] 256-256: Dynamically typed expressions (typing.Any) are disallowed in wrap_tool_call
(ANN401)
[warning] 287-287: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 292-292: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 296-296: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 301-303: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 343-343: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 358-358: Dynamically typed expressions (typing.Any) are disallowed in open_checkpointer
(ANN401)
[warning] 375-375: Dynamically typed expressions (typing.Any) are disallowed in checkpointer
(ANN401)
[warning] 385-385: Dynamically typed expressions (typing.Any) are disallowed in model
(ANN401)
[warning] 415-415: Dynamically typed expressions (typing.Any) are disallowed in extra
(ANN401)
[warning] 425-428: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 431-434: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 437-440: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 444-444: Dynamically typed expressions (typing.Any) are disallowed in subagent
(ANN401)
[warning] 444-444: Dynamically typed expressions (typing.Any) are disallowed in _gate_subagent
(ANN401)
[warning] 452-452: Too many statements (52 > 50)
(PLR0915)
[warning] 505-505: Do not catch blind exception: Exception
(BLE001)
[warning] 593-593: Boolean-typed positional argument in function definition
(FBT001)
[warning] 607-607: Boolean positional value in function call
(FBT003)
[warning] 613-613: Boolean positional value in function call
(FBT003)
[warning] 627-627: Dynamically typed expressions (typing.Any) are disallowed in result_state
(ANN401)
[warning] 666-666: Dynamically typed expressions (typing.Any) are disallowed in result_state
(ANN401)
[warning] 672-672: Dynamically typed expressions (typing.Any) are disallowed in raw
(ANN401)
[warning] 698-698: Dynamically typed expressions (typing.Any) are disallowed in message
(ANN401)
[warning] 717-717: Dynamically typed expressions (typing.Any) are disallowed in _final_response
(ANN401)
[warning] 759-759: Dynamically typed expressions (typing.Any) are disallowed in callable_obj
(ANN401)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
[warning] 131-131: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 205-205: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 229-229: Prefer TypeError exception for invalid type
(TRY004)
[warning] 229-229: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 291-291: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 354-354: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 381-381: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 452-452: Prefer TypeError exception for invalid type
(TRY004)
[warning] 452-452: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 478-478: Avoid specifying long messages outside the exception class
(TRY003)
examples/code_review_agent/config.py
[warning] 269-269: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 271-271: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
python/src/nemo_fabric/types.py
[warning] 107-107: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 469-469: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 475-475: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 483-483: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 494-494: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 507-507: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 700-700: Remove quotes from type annotation
Remove quotes
(UP037)
tests/python/test_sdk_contract.py
[warning] 605-605: Unused method argument: plan_json
(ARG002)
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
🛑 Comments failed to post (10)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
445-454: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Do not pass the complete parent environment to Codex.
virtualenv_subprocess_env()returnsos.environ.copy(), so this subprocess receives unrelated host/CI secrets. Start from an explicit minimal environment allowlist, then overlay configured variables; keep a regression assertion forFABRIC_UNRELATED_SECRET.🧰 Tools
🪛 Ruff (0.15.20)
[warning] 452-452: Prefer
TypeErrorexception for invalid type(TRY004)
[warning] 452-452: Avoid specifying long messages outside the exception class
(TRY003)
🤖 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 `@adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py` around lines 445 - 454, Update the environment setup around virtualenv_subprocess_env so Codex starts from an explicit minimal allowlist rather than the complete parent environment. Preserve overlaying validated configured variables from settings_payload, and add a regression assertion confirming FABRIC_UNRELATED_SECRET is not passed to the subprocess.adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
111-129: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== utils.py ==\n' nl -ba adapters/common/src/nemo_fabric_adapters/common/utils.py | sed -n '1,220p' printf '\n== deepagents/adapter.py ==\n' nl -ba adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py | sed -n '1,260p' printf '\n== telemetry symbol search ==\n' rg -n "telemetry_payload|telemetry_provider|telemetry_plan|native_telemetry_config|relay_enabled" adapters -SRepository: NVIDIA/NeMo-Fabric
Length of output: 212
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== utils.py ==\n' sed -n '1,220p' adapters/common/src/nemo_fabric_adapters/common/utils.py | cat -n printf '\n== deepagents/adapter.py ==\n' sed -n '1,260p' adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py | cat -n printf '\n== telemetry symbol search ==\n' rg -n "telemetry_payload|telemetry_provider|telemetry_plan|native_telemetry_config|relay_enabled" adapters -SRepository: NVIDIA/NeMo-Fabric
Length of output: 27503
🏁 Script executed:
#!/bin/bash set -euo pipefail sed -n '440,620p' adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py | cat -nRepository: NVIDIA/NeMo-Fabric
Length of output: 9043
Restore the deepagents telemetry helper calls
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pystill callscommon_utils.telemetry_provider(payload)inrun_deepagentsandcommon_utils.telemetry_payload(payload)inresolve_observability. Both helpers were removed, so deepagents now hitsAttributeErroron the telemetry path; usetelemetry_providers,relay_enabled, andnative_telemetry_confighere.🤖 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 `@adapters/common/src/nemo_fabric_adapters/common/utils.py` around lines 111 - 129, Update run_deepagents and resolve_observability to stop calling the removed common_utils.telemetry_provider and common_utils.telemetry_payload helpers. Use telemetry_providers for provider selection, relay_enabled for relay status, and native_telemetry_config for native configuration, preserving the existing telemetry behavior without AttributeError.adapters/deepagents/pyproject.toml (1)
26-26: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Check whether the deepagents adapter imports Relay's deepagents integration module. rg -n "nemo_relay" adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyRepository: NVIDIA/NeMo-Fabric
Length of output: 507
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== adapter import usage ==\n' sed -n '470,520p' adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py printf '\n== nemo-relay references in repo ==\n' rg -n "nemo-relay|nemo_relay\\.integrations\\.deepagents|deepagents\\]" -S . printf '\n== deepagents pyproject ==\n' sed -n '1,120p' adapters/deepagents/pyproject.tomlRepository: NVIDIA/NeMo-Fabric
Length of output: 8167
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== adapters/deepagents uv.lock excerpt ==\n' sed -n '840,890p' adapters/deepagents/uv.lock printf '\n== top-level pyproject relay dependency ==\n' sed -n '50,85p' pyproject.toml printf '\n== deepagents README install guidance ==\n' sed -n '1,40p' adapters/deepagents/README.md sed -n '130,155p' adapters/deepagents/README.mdRepository: NVIDIA/NeMo-Fabric
Length of output: 6532
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n== any repo metadata about nemo-relay extras ==\n' rg -n "deepagents.*extra|extra.*deepagents|nemo-relay\\[|integrations\\.deepagents" -S adapters pyproject.toml uv.lock README.md docs tests printf '\n== lockfile source for nemo-relay ==\n' python3 - <<'PY' from pathlib import Path text = Path('adapters/deepagents/uv.lock').read_text() for needle in ['name = "nemo-relay"', 'dependencies = [', 'requires-dist = [']: print(f"\n-- {needle} occurrences --") idx = 0 while True: idx = text.find(needle, idx) if idx < 0: break start = text.rfind('\n', 0, idx-200) end = text.find('\n\n', idx) print(text[idx-80:end+1][:1000]) idx += len(needle) break PYRepository: NVIDIA/NeMo-Fabric
Length of output: 3354
🌐 Web query:
nemo-relay 0.5.0 deepagents extra package metadata integrations.deepagents💡 Result:
In NeMo Relay 0.5.0, the deepagents extra provides integration for adding NeMo Relay observability to applications built with Deep Agents [1][2]. This extra is designed to build upon and include the langchain and langgraph extras, which are required dependencies for the integration [2][3]. You can install it using the following commands: # With uv uv add "nemo-relay[deepagents]" # With pip pip install "nemo-relay[deepagents]" The nemo_relay.integrations.deepagents package enables this observability by composing existing LangChain and LangGraph hooks while emitting specific marks for Deep Agents features such as configured skills, subagents, and human-in-the-loop lifecycle events [4][5]. Key components include: - NemoRelayDeepAgentsCallbackHandler: Bridges Deep Agents LangGraph lifecycle events to NeMo Relay marks [6][7]. - NemoRelayDeepAgentsMiddleware: Routes Deep Agents model and tool calls through NeMo Relay to emit semantic events [8]. These tools allow developers to track model and tool calls, run scopes, and agent-specific lifecycle events within their Deep Agents applications [4].
Citations:
- 1: https://docs.nvidia.com/nemo/relay/v0.5.0/supported-integrations/deepagents
- 2: https://pypi.org/project/nemo-relay/0.5.0/
- 3: https://github.com/NVIDIA/NeMo-Relay/blob/main/python/nemo_relay/README.md
- 4: https://docs.nvidia.com/nemo/relay/v0.4.0/supported-integrations/deepagents
- 5: https://docs.nvidia.com/nemo/relay/supported-integrations/deepagents
- 6: https://docs.nvidia.com/nemo/relay/dev/reference/api/python-library-reference/integrations/deepagents
- 7: https://docs.nvidia.com/nemo/relay/dev/reference/api/python-library-reference/nemo-relay/integrations/deepagents/callbacks
- 8: https://docs.nvidia.com/nemo/relay/dev/reference/api/python-library-reference/nemo-relay/integrations/deepagents/middleware
Add the
deepagentsextra tonemo-relay.adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyimportsnemo_relay.integrations.deepagents, and NeMo-Relay exposes that integration via thedeepagentsextra.nemo-relay~=0.5.0alone can leave the relay path broken at runtime; usenemo-relay[deepagents]~=0.5.0here.🤖 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 `@adapters/deepagents/pyproject.toml` at line 26, Update the nemo-relay dependency in the project requirements to include the deepagents extra, changing the existing nemo-relay~=0.5.0 specification to enable the integration imported by the deepagents adapter while preserving the same version constraint.adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py (2)
358-379: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Consider
contextlib.AsyncExitStackinstead of manual__aenter__/stashed private attribute.
open_checkpointer/close_checkpointermanually driveAsyncSqliteSaver's async context manager and stash it on a private-looking_fabric_cmattribute of a third-party object. It works today (guarded by the caller's try/finally), but is fragile if the library's internals change, and the# type: ignore[attr-defined]is a sign this bypasses the intended API. AnAsyncExitStackowned by the caller would be more idiomatic and avoid monkey-patching the saver object.♻️ Sketch using AsyncExitStack
-async def open_checkpointer(state_sqlite: Path) -> Any: - from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver - - state_sqlite.parent.mkdir(parents=True, exist_ok=True) - saver_cm = AsyncSqliteSaver.from_conn_string(str(state_sqlite)) - saver = await saver_cm.__aenter__() - saver._fabric_cm = saver_cm # type: ignore[attr-defined] - return saver - - -async def close_checkpointer(checkpointer: Any) -> None: - saver_cm = getattr(checkpointer, "_fabric_cm", None) - if saver_cm is not None: - await saver_cm.__aexit__(None, None, None) +async def open_checkpointer(stack: AsyncExitStack, state_sqlite: Path) -> Any: + from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver + + state_sqlite.parent.mkdir(parents=True, exist_ok=True) + return await stack.enter_async_context(AsyncSqliteSaver.from_conn_string(str(state_sqlite)))Then wrap the body of
run_deepagentsinasync with AsyncExitStack() as stack:and drop the manualclose_checkpointercall.🧰 Tools
🪛 Ruff (0.15.20)
[warning] 358-358: Dynamically typed expressions (typing.Any) are disallowed in
open_checkpointer(ANN401)
[warning] 375-375: Dynamically typed expressions (typing.Any) are disallowed in
checkpointer(ANN401)
🤖 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 `@adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py` around lines 358 - 379, Replace the manual context-manager handling in open_checkpointer and close_checkpointer with an AsyncExitStack owned by run_deepagents. Enter AsyncSqliteSaver through the stack, pass the resulting saver to the agent, and let the stack close it when the invocation scope exits; remove the _fabric_cm assignment, type-ignore, and explicit close_checkpointer call.
455-456: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Inspect the telemetry helper implementations and schema field names to # confirm whether the "enabled"/"config" keys and FABRIC_RELAY_ENABLED env var # still match the current contract. ast-grep run --pattern 'def telemetry_payload($$$): $$$' --lang python adapters/common/src/nemo_fabric_adapters/common/utils.py ast-grep run --pattern 'def telemetry_provider($$$): $$$' --lang python adapters/common/src/nemo_fabric_adapters/common/utils.py rg -n 'relay_enabled|FABRIC_RELAY_ENABLED' adapters/common/src/nemo_fabric_adapters/common/utils.py schemas/adapter-invocation.schema.json crates/fabric-core/src/runtime.rs rg -n '"native_config"|"providers"|"enabled"' schemas/run-plan.schema.jsonRepository: NVIDIA/NeMo-Fabric
Length of output: 1488
🏁 Script executed:
#!/bin/bash set -euo pipefail # Show the relevant adapter section. sed -n '430,630p' adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py # Show the shared telemetry helpers. sed -n '1,220p' adapters/common/src/nemo_fabric_adapters/common/utils.py # Show the schema areas that define the current telemetry contract. sed -n '1360,1565p' schemas/adapter-invocation.schema.jsonRepository: NVIDIA/NeMo-Fabric
Length of output: 21024
🏁 Script executed:
#!/bin/bash set -euo pipefail # Find every telemetry helper and its call sites. rg -n 'def telemetry_(payload|provider|plan|providers|relay_enabled|native_telemetry_config)|telemetry_payload\(|telemetry_provider\(' adapters/common/src/nemo_fabric_adapters/common/utils.py adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py # Show the rest of the common telemetry helpers if they exist. sed -n '220,360p' adapters/common/src/nemo_fabric_adapters/common/utils.py # Show the exact adapter lines around the legacy branch. sed -n '600,620p' adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyRepository: NVIDIA/NeMo-Fabric
Length of output: 7194
🏁 Script executed:
#!/bin/bash set -euo pipefail rg -n 'def telemetry_payload\(|def telemetry_provider\(|telemetry_payload\(|telemetry_provider\(' adapters crates schemasRepository: NVIDIA/NeMo-Fabric
Length of output: 818
Replace the legacy telemetry helper calls here.
common_utils.telemetry_provider()andcommon_utils.telemetry_payload()are not defined inadapters/common/src/nemo_fabric_adapters/common/utils.py, so this path will raiseAttributeErrorand skip both Relay and native observability. Use thetelemetry_planfields (relay_enabled,providers,native_config) via the shared helpers instead.🤖 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 `@adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py` around lines 455 - 456, Replace the legacy common_utils.telemetry_provider and telemetry_payload calls in the surrounding adapter flow with the shared telemetry_plan fields and helpers: use telemetry_plan.relay_enabled, telemetry_plan.providers, and telemetry_plan.native_config to configure Relay and native observability without relying on undefined utility symbols.adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py (1)
84-84: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Verify other adapters use the same telemetry-plan-based relay_enabled helper. rg -n 'FABRIC_RELAY_ENABLED|relay_enabled\(' adapters --type=py -C2Repository: NVIDIA/NeMo-Fabric
Length of output: 3357
Update deepagents to use the shared relay gate.
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py:456still readsFABRIC_RELAY_ENABLEDdirectly; switch it tocommon_utils.relay_enabled(payload)so relay gating followstelemetry_plan.relay_enabledacross the adapter surface.🤖 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 `@adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py` at line 84, Update the relay gate in the deepagents adapter’s relevant flow to call common_utils.relay_enabled(payload) instead of reading FABRIC_RELAY_ENABLED directly. Preserve the existing payload and downstream relay behavior so gating consistently follows telemetry_plan.relay_enabled.Source: Path instructions
crates/fabric-core/src/runtime.rs (1)
1343-1353: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Collapse the nested
ifwith a let-chain.Clippy flags this as collapsible. Let-chains are already used in this crate (
config.rsresolve_relay_plugin_config), so the edition supports it — collapsing avoids a potential failure under-D warnings.♻️ Collapse
fn validate_python_command(command: PythonCommand) -> Result<()> { - if let Some(value) = command.adapter_python_value { - if !command.path.is_file() { - return Err(FabricError::InvalidAdapterPython { - value, - path: command.path, - }); - } - } + if let Some(value) = command.adapter_python_value + && !command.path.is_file() + { + return Err(FabricError::InvalidAdapterPython { + value, + path: command.path, + }); + } Ok(()) }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.fn validate_python_command(command: PythonCommand) -> Result<()> { if let Some(value) = command.adapter_python_value && !command.path.is_file() { return Err(FabricError::InvalidAdapterPython { value, path: command.path, }); } Ok(()) }🧰 Tools
🪛 Clippy (1.96.0)
[warning] 1344-1344: this
ifstatement can be collapsed(warning)
🤖 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 `@crates/fabric-core/src/runtime.rs` around lines 1343 - 1353, Update validate_python_command to collapse the nested adapter_python_value and path.is_file checks into a single let-chain, preserving the existing InvalidAdapterPython error and Ok behavior.Source: Linters/SAST tools
docs/reference/api/python-library-reference/nemo_fabric.models.md (1)
611-612: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add blank lines around the inserted class headings.
markdownlintreports MD022 because each new heading is immediately followed by its description. Add the required blank line after each heading so documentation checks pass.Also applies to: 671-672, 731-732, 791-792, 851-852, 911-912, 971-972, 1031-1032, 1091-1092, 1151-1152, 1211-1212
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below(MD022, blanks-around-headings)
🤖 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 `@docs/reference/api/python-library-reference/nemo_fabric.models.md` around lines 611 - 612, Add blank lines immediately after each inserted class heading in the generated API reference, including RelayConfigPolicy and the other listed class headings, so each heading is separated from its description and satisfies markdownlint MD022.Source: Linters/SAST tools
examples/code_review_agent/config.py (1)
269-284: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Split composite asserts flagged by Ruff (PT018).
Lines 269 and 271 combine two conditions per
assert, which Ruff flags because a failure won't indicate which half failed.🔧 Proposed fix
- assert config.telemetry is not None and config.relay is not None + assert config.telemetry is not None + assert config.relay is not None relay = config.relay - assert not isinstance(relay, dict) and relay.observability is not None + assert not isinstance(relay, dict) + assert relay.observability is not None observability = relay.observability assert not isinstance(observability, dict)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.assert config.telemetry is not None assert config.relay is not None relay = config.relay assert not isinstance(relay, dict) assert relay.observability is not None observability = relay.observability assert not isinstance(observability, dict) relay.output_dir = "./artifacts/relay-openinference" observability.openinference = RelayOtlpConfig( enabled=True, transport="http_binary", endpoint="http://localhost:6006/v1/traces", ) if isinstance(observability.atif, RelayAtifConfig): observability.atif.output_directory = "./artifacts/relay-openinference" if isinstance(observability.atof, RelayAtofConfig): observability.atof.output_directory = "./artifacts/relay-openinference"🧰 Tools
🪛 Ruff (0.15.20)
[warning] 269-269: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 271-271: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
🤖 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 `@examples/code_review_agent/config.py` around lines 269 - 284, Split the composite assertions in the relay configuration setup into separate assertions for each condition. Update the assertions guarding config.telemetry, config.relay, and relay.observability so each failure identifies one missing or invalid value, while preserving the existing type and non-None checks.Source: Linters/SAST tools
tests/adapters/test_codex_cli.py (1)
546-547: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
Assert that unrelated secrets are not forwarded.
The test seeds
FABRIC_UNRELATED_SECRETbut never checks that it is absent fromchild_env. Add that assertion so environment-leak regressions are detected.🧰 Tools
🪛 Ruff (0.15.20)
[error] 546-546: Possible hardcoded password assigned to: "FABRIC_UNRELATED_SECRET"
(S105)
🤖 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 `@tests/adapters/test_codex_cli.py` around lines 546 - 547, Update the test around the seeded FABRIC_UNRELATED_SECRET and codex_payload environment settings to assert that child_env does not contain FABRIC_UNRELATED_SECRET, while preserving the existing assertion that CODEX_EXPLICIT is forwarded.
6d5c25c to
ff56843
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py (1)
599-614: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftDo not route native telemetry through the Relay plugin path.
resolve_observabilitynow returns a non-Nonevalue for native plans, butrun_deepagentssends every non-Noneresult throughrelay_api_plugin_config(...),plugin.plugin(...), andadd_nemo_relay_integration(...)at Lines 492-500. Native configuration can therefore be rejected as Relay config or silently use the wrong integration. Split the execution paths so only Relay uses the Relay plugin, and pass native configuration through its native observability setup. Also avoid requiringnative_config["components"]unless that requirement is part of the public schema.🤖 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 `@adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py` around lines 599 - 614, The native observability result from resolve_observability must not enter the Relay execution path in run_deepagents. Branch on the selected telemetry provider so relay uses relay_api_plugin_config, plugin.plugin, and add_nemo_relay_integration, while native configuration uses the native observability setup directly; do not require native_config["components"] unless mandated by the public schema.Source: Path instructions
🤖 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 `@examples/code_review_agent/config.py`:
- Around line 269-271: Split the combined assertions in the configuration setup
around config.telemetry and config.relay into separate assert statements,
ensuring each assert checks only one condition. Preserve the existing validation
and relay assignment behavior.
In `@python/src/nemo_fabric/models.py`:
- Around line 234-343: Update RelayAtifConfig.storage to use a Pydantic
discriminated union keyed by the existing type field, with RelayS3StorageConfig
selected for "s3" and RelayHttpStorageConfig for "http". Preserve support for
dictionary inputs while removing reliance on untagged smart-union matching.
In `@python/src/nemo_fabric/types.py`:
- Around line 483-492: Update _TelemetryConfig.enable_native() to start from the
existing providers["native"] mapping, preserving its configured "config" when
called again without config; when a new config is supplied, continue validating
it with _mapping and update the native provider configuration. Keep the method’s
fluent return and typed mapping behavior consistent with
_ResolvedFabricConfig.enable_relay().
---
Outside diff comments:
In `@adapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.py`:
- Around line 599-614: The native observability result from
resolve_observability must not enter the Relay execution path in run_deepagents.
Branch on the selected telemetry provider so relay uses relay_api_plugin_config,
plugin.plugin, and add_nemo_relay_integration, while native configuration uses
the native observability setup directly; do not require
native_config["components"] unless mandated by the public schema.
🪄 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: ASSERTIVE
Plan: Enterprise
Run ID: c7cf827a-4d0a-49ca-8de5-61d69eee02f1
⛔ Files ignored due to path filters (2)
adapters/deepagents/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (104)
ATTRIBUTIONS-Python.mdadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/deepagents/README.mdadapters/deepagents/pyproject.tomladapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pycrates/fabric-core/src/config.rscrates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rsdocs/reference/api/python-library-reference/index.mddocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/sdk/python.mdxexamples/code_review_agent/config.pyexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamlpyproject.tomlpython/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.pyschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/profile.schema.jsonschemas/run-plan.schema.jsontests/_utils/utils.pytests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/adapters/test_deepagents.pytests/adapters/test_hermes_cli.pytests/adapters/test_hermes_sdk_adapter.pytests/e2e/test_cli.pytests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/python/test_native_sdk.pytests/python/test_sdk_contract.pytests/python/test_typed_config.py
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: Test (arm64)
- GitHub Check: Test (x86_64)
- GitHub Check: Pre-commit
🧰 Additional context used
📓 Path-based instructions (8)
**
⚙️ CodeRabbit configuration file
**:Contributing to NeMo Fabric
Thank you for your interest in contributing to NeMo Fabric. This guide covers
the development workflow, coding standards, and pull request process.Development Setup
This section collects the setup steps needed before building, testing, or
contributing changes.Package Installation
NeMo Fabric is not currently available on PyPI. To consume the Python packages,
build wheels from a source checkout:just wheels uv pip install --find-links dist "nemo-fabric[runtime]"Adapters are distributed as optional extras. For example, install the Hermes
SDK adapter with:uv pip install --find-links dist "nemo-fabric[adapters-hermes-sdk]"Refer to the installation guide for the
complete list of adapters and installation options.Source Development
Install these tools before you start:
- Rust (stable toolchain) -- install with rustup
- Python >= 3.11
- uv -- follow the uv installation guide
- just >= 1.50.0 --
cargo install just --lockedClone the repository, create a virtual environment, and build the Rust and
Python packages:git clone https://github.com/NVIDIA/NeMo-Fabric.git cd NeMo-Fabric uv venv --seed .venv --python 3.13 source .venv/bin/activate uv sync --all-groups --all-extras just no_uv=true build-allVerify the checkout by running the test suites described in
Testing Requirements.Release Tagging
Versioned release tags must use raw Rust-compatible SemVer without a leading
v.
- Use
0.1.0for stable releases.- Use
0.1.0-rc.1for prereleases.- Do not create tags such as
v0.1.0orv0.1.0-rc.1.This keeps release tags aligned with Cargo package versions and lets...
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxpyproject.tomldocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxadapters/deepagents/pyproject.tomldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxtests/fixtures/hermes-cli-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxtests/fixtures/hermes-shim-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxtests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamldocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxexamples/harbor/demo/task/environment/fabric/configs/smoke.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxtests/fixtures/file-config-agent/profiles/relay.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pytests/fixtures/file-config-agent/profiles/hermes-sdk.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxtests/_utils/utils.pydocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxtests/fixtures/file-config-agent/profiles/native-otel.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamltests/fixtures/file-config-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxtests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/hermes-cli-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxtests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxschemas/profile.schema.jsontests/fixtures/file-config-agent/profiles/relay-otel.yamladapters/deepagents/README.mdtests/fixtures/file-config-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxpython/src/nemo_fabric/__init__.pytests/adapters/test_hermes_sdk_adapter.pyATTRIBUTIONS-Python.mdtests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/python/test_native_sdk.pytests/fixtures/file-config-agent/profiles/hermes-cli.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxexamples/harbor/README.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxexamples/harbor/demo/task/environment/fabric/configs/codex.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxtests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/e2e/test_cli.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pytests/fixtures/file-config-agent/profiles/env-opensandbox.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxtests/adapters/test_hermes_cli.pydocs/reference/api/python-library-reference/index.mdtests/python/test_code_review_example.pydocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxadapters/common/src/nemo_fabric_adapters/common/hermes.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxcrates/fabric-core/src/runtime.rsdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/sdk/python.mdxtests/adapters/test_deepagents.pydocs/reference/api/rust-library-reference/fabric-core/config/index.mdxtests/python/test_typed_config.pyexamples/code_review_agent/config.pycrates/fabric-core/src/lib.rsschemas/run-plan.schema.jsontests/integrations/test_harbor_runner.pydocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxschemas/adapter-invocation.schema.jsonadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pypython/src/nemo_fabric/models.pydocs/reference/api/python-library-reference/nemo_fabric.models.mdtests/adapters/test_adapaters_common_hermes.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyschemas/effective-config.schema.jsonschemas/agent.schema.jsontests/adapters/test_codex_cli.pytests/python/test_sdk_contract.pycrates/fabric-core/src/config.rspython/src/nemo_fabric/types.py
{docs/**,README.md,AGENTS.md}
⚙️ CodeRabbit configuration file
{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/python-library-reference/index.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/python-library-reference/nemo_fabric.models.md
{adapters/**,examples/**}
⚙️ CodeRabbit configuration file
{adapters/**,examples/**}: Review adapter and example changes for command correctness, config/schema consistency, artifact handling, and compatibility with the public Fabric contracts.
Files:
adapters/deepagents/pyproject.tomlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamladapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyexamples/harbor/demo/task/environment/fabric/configs/hermes.yamladapters/deepagents/README.mdexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/codex.yamladapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/code_review_agent/config.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
{tests/**,python/tests/**}
⚙️ CodeRabbit configuration file
{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.
Files:
tests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/_utils/utils.pytests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/agent.yamltests/adapters/test_hermes_sdk_adapter.pytests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/python/test_native_sdk.pytests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/e2e/test_cli.pytests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/adapters/test_hermes_cli.pytests/python/test_code_review_example.pytests/adapters/test_deepagents.pytests/python/test_typed_config.pytests/integrations/test_harbor_runner.pytests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/python/test_sdk_contract.py
tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)
tests/**/*.py: Usepytestto run Python tests.
Do not add@pytest.mark.asyncioto test functions; async tests are detected and run automatically.
Do not add-> Nonereturn type annotations to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, addingspecwhen needed.
Name mocked classes with amockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not duplicate fixtures across test files; if a fixture is needed in multiple test files, define it inconftest.py.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the function as<fixture_name>_fixture() -> <return_type>; only passscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating separate tests for different input types.
If a fixture is needed for a test but does not return a value, or its value is unused, use@pytest.mark.usefixtures.
When modifying environment variables in a test, useos.environ;tests/conftest.pyprovides an autouserestore_environ_fixturethat restores environment variables after each test, somonkeypatch.setenvis unnecessary.
Files:
tests/_utils/utils.pytests/adapters/test_hermes_sdk_adapter.pytests/python/test_native_sdk.pytests/e2e/test_cli.pytests/adapters/test_hermes_cli.pytests/python/test_code_review_example.pytests/adapters/test_deepagents.pytests/python/test_typed_config.pytests/integrations/test_harbor_runner.pytests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/python/test_sdk_contract.py
schemas/**/*
⚙️ CodeRabbit configuration file
schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.
Files:
schemas/profile.schema.jsonschemas/run-plan.schema.jsonschemas/adapter-invocation.schema.jsonschemas/effective-config.schema.jsonschemas/agent.schema.json
python/src/nemo_fabric/**/*
⚙️ CodeRabbit configuration file
python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
crates/fabric-core/src/**/*.rs
⚙️ CodeRabbit configuration file
crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.
Files:
crates/fabric-core/src/runtime.rscrates/fabric-core/src/lib.rscrates/fabric-core/src/config.rs
🧠 Learnings (2)
📚 Learning: 2026-07-09T22:28:51.689Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 43
File: adapters/claude-sdk/src/nemo_fabric_adapters/claude_sdk/adapter.py:164-168
Timestamp: 2026-07-09T22:28:51.689Z
Learning: In the NeMo-Fabric adapters, treat path values used in Fabric adapter configuration (including logic like `_resolve_path` in adapter.py) as config-root-relative. Do not apply `Path.expanduser()` (or otherwise apply `~`/home or shell-style expansion), because it will make the resolved paths normalize inconsistently across adapters. Also, do not rely on or add any resolution behavior that uses `harness.settings.cwd` as an override point for these adapter paths—`harness.settings.cwd` is explicitly unsupported in this adapter context.
Applied to files:
adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.
Applied to files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧬 Code graph analysis (7)
adapters/common/src/nemo_fabric_adapters/common/hermes.py (3)
adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py (1)
validate_hermes_telemetry_provider(69-69)adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.py (2)
validate_hermes_telemetry_provider(45-45)configure_hermes_relay(54-54)tests/adapters/test_adapaters_common_hermes.py (1)
build_hermes_config(151-151)
tests/integrations/test_harbor_runner.py (1)
python/src/nemo_fabric/integrations/harbor/runner.py (2)
compose_config(27-59)load_config(21-24)
adapters/common/src/nemo_fabric_adapters/common/utils.py (4)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
relay_enabled(55-55)adapters/common/src/nemo_fabric_adapters/common/hermes.py (1)
relay_enabled(49-49)tests/adapters/test_codex_cli.py (1)
relay_enabled(368-368)tests/adapters/test_adapaters_common_hermes.py (1)
relay_enabled(151-151)
python/src/nemo_fabric/models.py (1)
tests/python/test_sdk_contract.py (2)
FabricProfileConfig(1114-1114)TelemetryConfig(148-148)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
settings_payload(103-105)
tests/python/test_sdk_contract.py (1)
python/src/nemo_fabric/types.py (1)
to_mapping(807-814)
python/src/nemo_fabric/types.py (1)
tests/python/test_sdk_contract.py (1)
enable_relay(141-141)
🪛 ast-grep (0.44.1)
tests/python/test_sdk_contract.py
[info] 588-588: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan()["effective_config"])
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 598-598: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 602-602: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_runtime())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
🪛 LanguageTool
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> Endpoint headers. ### timeout_millis: u64 Re...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdx
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> OTLP headers. ### `resource_attributes: BTr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~35-~35: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..._attributes: BTreeMap<String, String> OTLP resource attributes. ###service_name...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~39-~39: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ttributes. ### service_name: String OTLP service name. ### `service_namespace: ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## service_namespace: Option<String> OTLP service namespace. ### `service_versio...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~47-~47: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... ### service_version: Option<String> OTLP service version. ### `instrumentation_...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...instrumentation_scope: Option OTLP instrumentation scope. ###timeout_mi...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...orted_value: RelayUnsupportedBehavior` Policy for unsupported values. ## Trait Imple...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
docs/reference/api/python-library-reference/nemo_fabric.models.md
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 671-671: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 731-731: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 791-791: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 851-851: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 911-911: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 971-971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1031-1031: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1091-1091: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1151-1151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1211-1211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1271-1271: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Ruff (0.15.20)
examples/code_review_agent/config.py
[warning] 269-269: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
[warning] 271-271: Assertion should be broken down into multiple parts
Break down assertion into multiple parts
(PT018)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
[warning] 131-131: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 205-205: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 229-229: Prefer TypeError exception for invalid type
(TRY004)
[warning] 229-229: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 291-291: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 354-354: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 381-381: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 478-478: Avoid specifying long messages outside the exception class
(TRY003)
tests/adapters/test_codex_cli.py
[error] 546-546: Possible hardcoded password assigned to: "FABRIC_UNRELATED_SECRET"
(S105)
tests/python/test_sdk_contract.py
[warning] 605-605: Unused method argument: plan_json
(ARG002)
python/src/nemo_fabric/types.py
[warning] 107-107: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 469-469: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 475-475: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 483-483: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 494-494: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 507-507: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 700-700: Remove quotes from type annotation
Remove quotes
(UP037)
Signed-off-by: Anuradha Karuppiah <26330987+AnuradhaKaruppiah@users.noreply.github.com>
ff56843 to
fb40311
Compare
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
tests/adapters/test_codex_cli.py (1)
316-364: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnused
tmp_pathfixture parameter.Ruff (ARG001) flags
tmp_pathas unused intest_native_otel_profile_writes_codex_telemetry_config; nothing in the body references it.♻️ Remove the unused parameter
def test_native_otel_profile_writes_codex_telemetry_config( codex_payload, - tmp_path, transport, expected_exporter, expected_protocol, ):Good coverage otherwise — this parametrization now exercises both
http_binaryandgrpc, closing the gap flagged in an earlier review.🤖 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 `@tests/adapters/test_codex_cli.py` around lines 316 - 364, Remove the unused tmp_path fixture parameter from test_native_otel_profile_writes_codex_telemetry_config while preserving the existing parametrization and test behavior.Source: Linters/SAST tools
python/src/nemo_fabric/models.py (1)
475-505: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve existing Relay fields in
FabricConfig.enable_relay()
This helper currently replacesself.relayon every call, so a later call likeenable_relay(policy=...)clears earlierproject,output_dir,observability, orcomponentsvalues. Start from the existing relay config and overlay only the fields passed in, matching_ResolvedFabricConfig.enable_relay().🤖 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 `@python/src/nemo_fabric/models.py` around lines 475 - 505, The enable_relay method currently replaces self.relay and loses values from earlier calls. Update FabricConfig.enable_relay to start from the existing relay configuration and overlay only explicitly provided project, output_dir, observability, components, and policy values, matching _ResolvedFabricConfig.enable_relay behavior while preserving existing fields for omitted arguments.
🤖 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 `@adapters/deepagents/README.md`:
- Around line 142-144: Update the Native bullet in the adapter documentation to
remove the dangling “the provider config” phrasing and make the sentence
grammatically describe applying the OpenTelemetry/OpenInference exporter from
the configured provider settings, while preserving the existing direct-export
behavior.
In `@examples/code_review_agent/config.py`:
- Around line 223-237: Update the RelayAtifConfig construction in the
observability configuration to set model_name from the active default model,
using base.models["default"].model instead of relying on the "unknown" default;
leave the remaining ATIF and ATOF settings unchanged.
In `@python/src/nemo_fabric/types.py`:
- Line 475: Remove the quotes from the self-referencing "_TelemetryConfig"
return type annotations in the affected signatures, including the corresponding
annotations near lines 483, 494, and 700. Keep the return types unchanged
semantically and rely on the module’s future annotations support.
In `@schemas/agent.schema.json`:
- Around line 896-905: Update TelemetryConfig.providers to constrain property
names to the TelemetryProvider enum while retaining the existing
TelemetryProviderConfig value reference. Add the enum-aware key constraint, such
as propertyNames with the TelemetryProvider schema reference, so unknown
provider names are rejected.
In `@tests/_utils/utils.py`:
- Around line 47-49: Update the telemetry assertion in the relevant test helper
to explicitly validate the allowed shape: telemetry may be absent, but when
present it must have relay_enabled set to False. Add or update
request_verification ownership coverage so each adapter’s expected telemetry
presence or absence is checked, preserving SDK/native parity.
In `@tests/adapters/test_codex_cli.py`:
- Around line 560-561: Update the assertions in the Codex subprocess environment
test to verify that child_env does not contain FABRIC_UNRELATED_SECRET, while
retaining the existing assertion that CODEX_EXPLICIT is forwarded.
---
Outside diff comments:
In `@python/src/nemo_fabric/models.py`:
- Around line 475-505: The enable_relay method currently replaces self.relay and
loses values from earlier calls. Update FabricConfig.enable_relay to start from
the existing relay configuration and overlay only explicitly provided project,
output_dir, observability, components, and policy values, matching
_ResolvedFabricConfig.enable_relay behavior while preserving existing fields for
omitted arguments.
In `@tests/adapters/test_codex_cli.py`:
- Around line 316-364: Remove the unused tmp_path fixture parameter from
test_native_otel_profile_writes_codex_telemetry_config while preserving the
existing parametrization and test behavior.
🪄 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: ASSERTIVE
Plan: Enterprise
Run ID: 7ea44b59-8f47-465a-aa5b-8aed1fec0e01
⛔ Files ignored due to path filters (2)
adapters/deepagents/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (104)
ATTRIBUTIONS-Python.mdadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/deepagents/README.mdadapters/deepagents/pyproject.tomladapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pycrates/fabric-core/src/config.rscrates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rsdocs/reference/api/python-library-reference/index.mddocs/reference/api/python-library-reference/nemo_fabric.models.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/sdk/python.mdxexamples/code_review_agent/config.pyexamples/harbor/README.mdexamples/harbor/demo/task/environment/fabric/configs/codex.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamlexamples/harbor/demo/task/environment/fabric/configs/hermes.yamlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamlpyproject.tomlpython/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.pyschemas/adapter-invocation.schema.jsonschemas/agent.schema.jsonschemas/effective-config.schema.jsonschemas/profile.schema.jsonschemas/run-plan.schema.jsontests/_utils/utils.pytests/adapters/test_adapaters_common_hermes.pytests/adapters/test_codex_cli.pytests/adapters/test_deepagents.pytests/adapters/test_hermes_cli.pytests/adapters/test_hermes_sdk_adapter.pytests/e2e/test_cli.pytests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/relay.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/integrations/test_harbor_runner.pytests/python/test_code_review_example.pytests/python/test_native_sdk.pytests/python/test_sdk_contract.pytests/python/test_typed_config.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Test (x86_64)
- GitHub Check: Test (arm64)
🧰 Additional context used
📓 Path-based instructions (8)
**
⚙️ CodeRabbit configuration file
**:Contributing to NeMo Fabric
Thank you for your interest in contributing to NeMo Fabric. This guide covers
the development workflow, coding standards, and pull request process.Development Setup
This section collects the setup steps needed before building, testing, or
contributing changes.Package Installation
NeMo Fabric is not currently available on PyPI. To consume the Python packages,
build wheels from a source checkout:just wheels uv pip install --find-links dist "nemo-fabric[runtime]"Adapters are distributed as optional extras. For example, install the Hermes
SDK adapter with:uv pip install --find-links dist "nemo-fabric[adapters-hermes-sdk]"Refer to the installation guide for the
complete list of adapters and installation options.Source Development
Install these tools before you start:
- Rust (stable toolchain) -- install with rustup
- Python >= 3.11
- uv -- follow the uv installation guide
- just >= 1.50.0 --
cargo install just --lockedClone the repository, create a virtual environment, and build the Rust and
Python packages:git clone https://github.com/NVIDIA/NeMo-Fabric.git cd NeMo-Fabric uv venv --seed .venv --python 3.13 source .venv/bin/activate uv sync --all-groups --all-extras just no_uv=true build-allVerify the checkout by running the test suites described in
Testing Requirements.Release Tagging
Versioned release tags must use raw Rust-compatible SemVer without a leading
v.
- Use
0.1.0for stable releases.- Use
0.1.0-rc.1for prereleases.- Do not create tags such as
v0.1.0orv0.1.0-rc.1.This keeps release tags aligned with Cargo package versions and lets...
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxpyproject.tomltests/fixtures/hermes-shim-agent/agent.yamldocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxadapters/deepagents/pyproject.tomldocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxtests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/file-config-agent/profiles/env-local.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxexamples/harbor/demo/task/environment/fabric/configs/smoke.yamldocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxtests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamldocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxexamples/harbor/demo/task/environment/fabric/configs/codex.yamldocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxtests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxtests/fixtures/hermes-cli-agent/profiles/env-local.yamlcrates/fabric-core/src/lib.rsadapters/deepagents/README.mdtests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxtests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxexamples/harbor/demo/task/environment/fabric/configs/hermes.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxadapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pytests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/adapters/test_hermes_cli.pytests/_utils/utils.pytests/adapters/test_hermes_sdk_adapter.pydocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxschemas/profile.schema.jsontests/e2e/test_cli.pyATTRIBUTIONS-Python.mdexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamldocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxtests/python/test_native_sdk.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pytests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamldocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxexamples/harbor/README.mddocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxtests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamldocs/reference/api/python-library-reference/index.mdpython/src/nemo_fabric/__init__.pyexamples/code_review_agent/config.pydocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pytests/python/test_typed_config.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pydocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxtests/fixtures/file-config-agent/profiles/relay.yamltests/adapters/test_adapaters_common_hermes.pytests/python/test_code_review_example.pyschemas/agent.schema.jsoncrates/fabric-core/src/runtime.rsdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxtests/integrations/test_harbor_runner.pytests/adapters/test_deepagents.pyschemas/run-plan.schema.jsondocs/reference/api/python-library-reference/nemo_fabric.models.mdadapters/common/src/nemo_fabric_adapters/common/utils.pyschemas/effective-config.schema.jsontests/python/test_sdk_contract.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.pyschemas/adapter-invocation.schema.jsonpython/src/nemo_fabric/models.pytests/adapters/test_codex_cli.pycrates/fabric-core/src/config.rspython/src/nemo_fabric/types.py
{docs/**,README.md,AGENTS.md}
⚙️ CodeRabbit configuration file
{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
Files:
docs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/fn-version.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorreport.mdxdocs/reference/api/rust-library-reference/fabric-core/error/index.mdxdocs/reference/api/rust-library-reference/fabric-core/error/type-result.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-from-config.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-adapter-descriptor.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-from-effective-config.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/fn-doctor-plan.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-load-fabric-document.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-effective-config-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/index.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/struct-doctorcheck.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitykind.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-resolve-run-plan-with-profiles.mdxdocs/reference/api/rust-library-reference/fabric-core/error/enum-fabricerror.mdxdocs/reference/api/rust-library-reference/fabric-core/doctor/enum-doctorstatus.mdxdocs/reference/api/rust-library-reference/fabric-core/runtime/index.mdxdocs/reference/api/rust-library-reference/fabric-core/schema/index.mdxdocs/reference/api/rust-library-reference/fabric-core/config/fn-validate-agent-directory.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relaycomponentconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryplan.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatifstorageconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-telemetryproviderconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointfieldnamepolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofendpointtransport.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayobservabilityconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-telemetryprovider.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayunsupportedbehavior.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-fabricconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/index.mdxdocs/sdk/python.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdxdocs/reference/api/rust-library-reference/fabric-core/config/struct-relayatifconfig.mdxdocs/reference/api/python-library-reference/index.mddocs/reference/api/rust-library-reference/fabric-core/config/enum-capabilitytarget.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayatofmode.mdxdocs/reference/api/rust-library-reference/fabric-core/config/enum-relayotlptransport.mdxdocs/reference/api/python-library-reference/nemo_fabric.models.md
{tests/**,python/tests/**}
⚙️ CodeRabbit configuration file
{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.
Files:
tests/fixtures/hermes-shim-agent/agent.yamltests/fixtures/hermes-cli-agent/agent.yamltests/fixtures/file-config-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/swebench-shim.yamltests/fixtures/file-config-agent/profiles/hermes-sdk.yamltests/fixtures/hermes-shim-agent/profiles/env-local.yamltests/fixtures/hermes-shim-agent/profiles/mcp-github.yamltests/fixtures/hermes-cli-agent/profiles/env-local.yamltests/fixtures/file-config-agent/agent.yamltests/fixtures/file-config-agent/profiles/codex-cli.yamltests/fixtures/file-config-agent/profiles/relay-openinference.yamltests/fixtures/file-config-agent/profiles/relay-otel.yamltests/fixtures/file-config-agent/profiles/native-otel.yamltests/fixtures/file-config-agent/profiles/env-opensandbox.yamltests/adapters/test_hermes_cli.pytests/_utils/utils.pytests/adapters/test_hermes_sdk_adapter.pytests/e2e/test_cli.pytests/python/test_native_sdk.pytests/fixtures/file-config-agent/profiles/hermes-cli.yamltests/fixtures/file-config-agent/profiles/mcp-github.yamltests/fixtures/hermes-shim-agent/profiles/harbor-swebench-django-13741.yamltests/python/test_typed_config.pytests/fixtures/file-config-agent/profiles/relay.yamltests/adapters/test_adapaters_common_hermes.pytests/python/test_code_review_example.pytests/integrations/test_harbor_runner.pytests/adapters/test_deepagents.pytests/python/test_sdk_contract.pytests/adapters/test_codex_cli.py
{adapters/**,examples/**}
⚙️ CodeRabbit configuration file
{adapters/**,examples/**}: Review adapter and example changes for command correctness, config/schema consistency, artifact handling, and compatibility with the public Fabric contracts.
Files:
adapters/deepagents/pyproject.tomlexamples/harbor/demo/task/environment/fabric/configs/smoke.yamlexamples/harbor/demo/task/environment/fabric/configs/codex.yamladapters/deepagents/README.mdexamples/harbor/demo/task/environment/fabric/configs/hermes.yamladapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyexamples/harbor/demo/task/environment/fabric/configs/hermes-relay.yamladapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyexamples/harbor/README.mdexamples/code_review_agent/config.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/common/src/nemo_fabric_adapters/common/hermes.pyadapters/common/src/nemo_fabric_adapters/common/utils.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
crates/fabric-core/src/**/*.rs
⚙️ CodeRabbit configuration file
crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.
Files:
crates/fabric-core/src/lib.rscrates/fabric-core/src/runtime.rscrates/fabric-core/src/config.rs
tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)
tests/**/*.py: Usepytestto run Python tests.
Do not add@pytest.mark.asyncioto test functions; async tests are detected and run automatically.
Do not add-> Nonereturn type annotations to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, addingspecwhen needed.
Name mocked classes with amockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not duplicate fixtures across test files; if a fixture is needed in multiple test files, define it inconftest.py.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the function as<fixture_name>_fixture() -> <return_type>; only passscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating separate tests for different input types.
If a fixture is needed for a test but does not return a value, or its value is unused, use@pytest.mark.usefixtures.
When modifying environment variables in a test, useos.environ;tests/conftest.pyprovides an autouserestore_environ_fixturethat restores environment variables after each test, somonkeypatch.setenvis unnecessary.
Files:
tests/adapters/test_hermes_cli.pytests/_utils/utils.pytests/adapters/test_hermes_sdk_adapter.pytests/e2e/test_cli.pytests/python/test_native_sdk.pytests/python/test_typed_config.pytests/adapters/test_adapaters_common_hermes.pytests/python/test_code_review_example.pytests/integrations/test_harbor_runner.pytests/adapters/test_deepagents.pytests/python/test_sdk_contract.pytests/adapters/test_codex_cli.py
schemas/**/*
⚙️ CodeRabbit configuration file
schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.
Files:
schemas/profile.schema.jsonschemas/agent.schema.jsonschemas/run-plan.schema.jsonschemas/effective-config.schema.jsonschemas/adapter-invocation.schema.json
python/src/nemo_fabric/**/*
⚙️ CodeRabbit configuration file
python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧠 Learnings (2)
📚 Learning: 2026-07-09T22:28:51.689Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 43
File: adapters/claude-sdk/src/nemo_fabric_adapters/claude_sdk/adapter.py:164-168
Timestamp: 2026-07-09T22:28:51.689Z
Learning: In the NeMo-Fabric adapters, treat path values used in Fabric adapter configuration (including logic like `_resolve_path` in adapter.py) as config-root-relative. Do not apply `Path.expanduser()` (or otherwise apply `~`/home or shell-style expansion), because it will make the resolved paths normalize inconsistently across adapters. Also, do not rely on or add any resolution behavior that uses `harness.settings.cwd` as an override point for these adapter paths—`harness.settings.cwd` is explicitly unsupported in this adapter context.
Applied to files:
adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.pyadapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.pyadapters/deepagents/src/nemo_fabric_adapters/deepagents/adapter.pyadapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.
Applied to files:
python/src/nemo_fabric/__init__.pypython/src/nemo_fabric/models.pypython/src/nemo_fabric/types.py
🧬 Code graph analysis (7)
adapters/common/src/nemo_fabric_adapters/common/hermes.py (2)
adapters/hermes-sdk/src/nemo_fabric_adapters/hermes_sdk/adapter.py (1)
validate_hermes_telemetry_provider(69-69)adapters/hermes-cli/src/nemo_fabric_adapters/hermes_cli/adapter.py (2)
validate_hermes_telemetry_provider(45-45)configure_hermes_relay(54-54)
tests/integrations/test_harbor_runner.py (1)
python/src/nemo_fabric/integrations/harbor/runner.py (2)
compose_config(27-59)load_config(21-24)
adapters/common/src/nemo_fabric_adapters/common/utils.py (2)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
relay_enabled(55-55)adapters/common/src/nemo_fabric_adapters/common/hermes.py (2)
relay_enabled(49-49)dump_yaml(113-113)
tests/python/test_sdk_contract.py (1)
python/src/nemo_fabric/types.py (3)
to_mapping(807-814)telemetry(648-651)telemetry(654-655)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py (1)
adapters/common/src/nemo_fabric_adapters/common/utils.py (2)
settings_payload(103-105)collect_relay_artifacts(368-386)
python/src/nemo_fabric/models.py (2)
adapters/common/src/nemo_fabric_adapters/common/utils.py (1)
agent_name(67-68)tests/python/test_sdk_contract.py (1)
FabricProfileConfig(1136-1136)
python/src/nemo_fabric/types.py (1)
tests/python/test_sdk_contract.py (5)
EffectiveConfig(366-366)from_mapping(77-77)extra_fields(85-85)enable_relay(141-141)DoctorReport(426-426)
🪛 ast-grep (0.44.1)
tests/python/test_sdk_contract.py
[info] 610-610: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan()["effective_config"])
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 620-620: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_plan())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
[info] 624-624: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_runtime())
Note: [CWE-116] Improper Encoding or Escaping of Output.
(use-jsonify)
🪛 LanguageTool
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayatofendpointconfig.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> Endpoint headers. ### timeout_millis: u64 Re...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayotlpconfig.mdx
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## headers: BTreeMap<String, String> OTLP headers. ### `resource_attributes: BTr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~35-~35: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..._attributes: BTreeMap<String, String> OTLP resource attributes. ###service_name...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~39-~39: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ttributes. ### service_name: String OTLP service name. ### `service_namespace: ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...## service_namespace: Option<String> OTLP service namespace. ### `service_versio...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~47-~47: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... ### service_version: Option<String> OTLP service version. ### `instrumentation_...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~51-~51: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...instrumentation_scope: Option OTLP instrumentation scope. ###timeout_mi...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
docs/reference/api/rust-library-reference/fabric-core/config/struct-relayconfigpolicy.mdx
[style] ~27-~27: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...orted_value: RelayUnsupportedBehavior` Policy for unsupported values. ## Trait Imple...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
docs/reference/api/python-library-reference/nemo_fabric.models.md
[warning] 611-611: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 671-671: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 731-731: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 791-791: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 851-851: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 911-911: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 971-971: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1031-1031: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1091-1091: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1151-1151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1211-1211: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 1271-1271: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🪛 Ruff (0.15.20)
tests/python/test_sdk_contract.py
[warning] 627-627: Unused method argument: plan_json
(ARG002)
adapters/codex-cli/src/nemo_fabric_adapters/codex_cli/adapter.py
[warning] 131-131: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 208-208: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 232-232: Prefer TypeError exception for invalid type
(TRY004)
[warning] 232-232: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 294-294: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 357-357: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 384-384: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 481-481: Avoid specifying long messages outside the exception class
(TRY003)
tests/adapters/test_codex_cli.py
[warning] 325-325: Unused function argument: tmp_path
(ARG001)
[error] 560-560: Possible hardcoded password assigned to: "FABRIC_UNRELATED_SECRET"
(S105)
python/src/nemo_fabric/types.py
[warning] 107-107: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 469-469: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 475-475: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 483-483: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 494-494: Remove quotes from type annotation
Remove quotes
(UP037)
[warning] 507-507: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 700-700: Remove quotes from type annotation
Remove quotes
(UP037)
Salonijain27
left a comment
There was a problem hiding this comment.
Approved from a dependency point of view
Signed-off-by: Anuradha Karuppiah <26330987+AnuradhaKaruppiah@users.noreply.github.com>
6e37567 to
4270bd0
Compare
Signed-off-by: Anuradha Karuppiah <26330987+AnuradhaKaruppiah@users.noreply.github.com>
|
/merge |
#### Overview
Adds first-class blocked tool policy across Fabric config, SDK authoring, run-plan routing, and adapters that can enforce it.
Canonical config shape:
```yaml
tools:
blocked:
- browser
- shell
```
#### Configuration note
The adapter-level `harness.settings.disallowed_tools` setting has been dropped. Configure the deny-list only through the typed, normalized `tools.blocked` field; the Claude adapter maps it internally to the Claude SDK's `disallowed_tools` option.
Adapter mappings:
- Hermes maps blocked names to disabled toolsets.
- Claude maps blocked names to `disallowed_tools`.
- DeepAgents enforces blocked names through middleware for the main agent and subagents.
- Adapters without tools support route the policy as unsupported.
#### Unsupported harness handling
An adapter that cannot enforce blocked tools must omit `tools` from its descriptor's `config.accepts`. Core preserves the configured policy and routes the tools capability to `capability_plan.unsupported` so the mismatch is explicit.
Blocked-tool policy must be handled fail-closed: planning and doctor diagnostics should identify the unsupported adapter capability, and invocation must not silently ignore the deny-list. The user must remove `tools.blocked` or select an adapter that declares and implements tools support.
This PR is stacked on #54.
#### Where should the reviewer start?
- `crates/fabric-core/src/config.rs`
- `python/src/nemo_fabric/models.py`
- `adapters/common/src/nemo_fabric_adapters/common/utils.py`
- Adapter tests for Hermes, Claude, and DeepAgents
#### Validation
- `cargo test -p fabric-core`
- Focused Python adapter/SDK tests for blocked tools
- `ruff check` on touched Python files
- `cargo fmt --check`
- `git diff --check`
#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
- Closes FABRIC-74
- [x] I confirm this contribution is my own work, or I have the right to submit it under this project's license.
- [x] I searched existing issues and open pull requests, and this does not duplicate existing work.
## Summary by CodeRabbit
* **New Features**
* Added a portable `tools.blocked` configuration for disabling named tools and toolsets.
* Claude, Deep Agents, and Hermes now enforce blocked-tool settings consistently, including delegated agents where supported.
* Added typed configuration support for NeMo Relay, telemetry providers, and tool policies.
* Added `FabricConfig.block_tools()` for programmatically blocking tools.
* Unsupported tool policies now produce clear validation errors before runtime execution.
* **Documentation**
* Updated configuration guides and API references for tools, Relay, telemetry, and related schemas.
Authors:
- Anuradha Karuppiah (https://github.com/AnuradhaKaruppiah)
Approvers:
- Ajay Thorve (https://github.com/AjayThorve)
URL: #56
Overview
Adds first-class Relay config as a top-level
relayblock and changes telemetry selection to a provider map:Configured providers are enabled providers. Relay-specific project, output, observability, components, and policy live under the top-level
relayblock.Relay sample
Where should the reviewer start?
Start with
crates/fabric-core/src/config.rsfor the source-of-truth config and telemetry plan, thenpython/src/nemo_fabric/models.py/python/src/nemo_fabric/types.pyfor SDK authoring, andadapters/common/src/nemo_fabric_adapters/common/utils.pyfor adapter-facing helpers.Adapter guidance
telemetry_planas the adapter contract; do not infer telemetry intent fromeffective_config.config.telemetry.telemetry_plan.relay_enabledistrue.telemetry_plan.native_config.FABRIC_RELAY_CONFIG_PATHand related Relay env vars as runtime state, not as enablement signals.Follow-up
nemo_fabric.__init__exports in a separate PR: keep SDK entrypoints/errors at the package root, and import config/result types fromnemo_fabric.modelsandnemo_fabric.types.Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
CLOSES FABRIC-76
I confirm this contribution is my own work, or I have the right to submit it under this project license.
I searched existing issues and open pull requests, and this does not duplicate existing work.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation