Skip to content

feat: add Nexus Nemotron claw lane and sync P7 docs - #1104

Merged
POWERFULMOVES merged 1 commit into
mainfrom
codex/nexus-nemotron-claw
Mar 25, 2026
Merged

POWERFULMOVES merged 1 commit into
mainfrom
codex/nexus-nemotron-claw

Conversation

@POWERFULMOVES

@POWERFULMOVES POWERFULMOVES commented Mar 25, 2026

Copy link
Copy Markdown
Owner

feat: add Nexus Nemotron claw lane and sync P7 docs

Summary

  • add Nexus provider-parity config and shared runtime helpers
  • add NVIDIA NIM / Nemotron claw profile and OpenCode/OpenClaw configs
  • document provider-native parity expectations for Nexus
  • sync P7 docs with official Pinokio docs: Pinokio as agent/runtime surface, not mesh control plane
  • update P7 TAC expectations for 7860/fixed HTTPS domains and current remote/mobile status

Validation

  • python -m py_compile pmoves/services/common/model_nexus.py pmoves/services/common/init.py
  • python -m pytest pmoves/services/common/tests/test_model_nexus.py
  • python -c "from pathlib import Path; import yaml; yaml.safe_load(Path(r'C:\Users\russe\Documents\GitHub\PMOVES.AI\pmoves\configs\tac_trees\pinokio-p7.tac.yaml').read_text(encoding='utf-8')); print('yaml ok')"

Notes

  • P7 doc sync is based on the official Pinokio manual, especially Agent Interpreter, Agent Launcher, Localhost Cloud, and instant HTTPS/remote-control behavior.
  • AGNOTE4482 claim history was reviewed but intentionally not rewritten as part of this branch.

Summary by CodeRabbit

Release Notes

  • New Features

    • Nemotron GPU agent support for GPU-accelerated agentic reasoning
    • Local NVIDIA NIM provider for efficient model inference
  • Documentation

    • Enhanced model routing and provider parity framework documentation
    • Updated P7 playground testing status and network validation
    • Improved agent runtime and configuration documentation

@coderabbitai

coderabbitai Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

A new Model Nexus provider parity registry establishes a contract layer for model routing and provider compatibility. The PR adds configuration files for Nemotron Claw GPU node integration, updates P7/TTS test documentation, implements Python utilities for model routing validation, and includes supporting agent profile and TAC tree updates.

Changes

Cohort / File(s) Summary
Model Nexus Contract Layer
pmoves/config/model_nexus.yaml, pmoves/docs/NEXUS_PROVIDER_PARITY.md, pmoves/docs/MODEL_FABRIC_CONTRACT.md
New provider parity registry defining canonical request/response shapes, provider configurations (TensorZero, OpenAI, Anthropic, Gemini, NVIDIA NIM, Ollama, vLLM), lane-level defaults, exemption rules, and parity requirements; updated model fabric contract to reference Nexus as the provider abstraction boundary and extend runtime defaults.
Nemotron Claw GPU Agent Integration
pmoves/configs/agent-profiles/nemotron_claw.yaml, pmoves/configs/claws/opencode-nemotron-claw.json, pmoves/configs/claws/scopes/nemotron-claw.json
New GPU-agentic-claw agent profile targeting 5090/z890 nodes using NVIDIA NIM Nemotron model with TensorZero fallback, NATS connectivity, health checking, and configured MCP servers; defines local service endpoints and execution approvals.
Agent Team & TAC Tree Updates
pmoves/configs/agent-teams.yaml, pmoves/configs/tac_trees/pinokio-p7.tac.yaml
Added nemotron_claw to evolution team agents; reframed P7/TTS tasks to describe PMOVES app launching, recharacterized Pinokio as agent runtime layer (not just transport), changed TTS discovery from requiring SKILL.md to optional additive hints, and updated blocker status for remote TTS and mobile agent flows.
P7/TTS Documentation
pmoves/docs/AGENTS/AGNOTE_P7_PLAYGROUND.md
Updated test status to mark 4090→5090 P7/TTS network path DONE via Pinokio HTTPS proxy, shifted focus from per-app SKILL.md discovery to Pinokio's built-in skills and optional hints, clarified Pinokio localhost-cloud architecture with workspace persistence, and refined remaining validation gaps.
Model Nexus Python Module & Tests
pmoves/services/common/model_nexus.py, pmoves/services/common/tests/test_model_nexus.py, pmoves/services/common/__init__.py
New module providing configuration path resolution, YAML loading with caching, validation logic, and query helpers (get_nexus_provider, get_nexus_lane, provider_allowed_for_lane, provider_requires_nexus_adapter); exports public functions via __init__.py; test suite validates config loading, provider/lane queries, and error handling.

Sequence Diagram

sequenceDiagram
    participant Agent as Agent Code
    participant Nexus as Model Nexus<br/>(Config Loader)
    participant Router as Provider Router
    participant Primary as Primary Provider<br/>(TensorZero/OpenAI/NIM)
    participant Fallback as Fallback<br/>(TensorZero)

    Agent->>Nexus: Load model_nexus.yaml
    Nexus-->>Agent: Config (providers, lanes, rules)
    
    Agent->>Router: Route request for lane
    Router->>Nexus: Check lane default_provider
    Nexus-->>Router: Default provider name
    
    Router->>Nexus: Validate provider allowed for lane
    Nexus-->>Router: Allowed (default or override)
    
    Router->>Nexus: Check if provider requires adapter
    alt Provider requires Nexus adapter
        Nexus-->>Router: true
        Router->>Primary: Call via adapter (with parity checks)
    else Provider is direct (e.g., OpenAI)
        Nexus-->>Router: false
        Router->>Primary: Direct SDK call
    end
    
    alt Response/parity preserves requirements
        Primary-->>Router: Valid response
        Router-->>Agent: Route to primary result
    else Parity cannot be maintained
        Router->>Fallback: Fallback to TensorZero
        Fallback-->>Router: TensorZero result
        Router-->>Agent: Route via fallback
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

configuration, python, model-routing

Poem

🐰 Through the Nexus gate we hop and bound,
Where parity rules and routes are sound,
Nemotron Claw grabs hold with pride,
TensorZero waits with fallback guide,
Config contracts burning bright—
Provider harmony takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description follows the template structure with Summary and Validation sections, but lacks Testing commands/output detail and is missing the required checklist items. Add explicit Testing section with command outputs, complete the Required Checks checklist items, and clarify Reviewer Notes to address contract impact and documentation verification.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding Nexus Nemotron claw lane configuration and synchronizing P7 documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/nexus-nemotron-claw

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72852c9f3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"""

from .telemetry import * # noqa: F401,F403
from .model_nexus import ( # noqa: F401

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid eager Nexus import from services.common

Importing services.common now unconditionally imports model_nexus, which imports yaml at module load time. Many runtime services import services.common.* during startup, but several service requirement sets do not declare PyYAML, so this change can raise ModuleNotFoundError: No module named 'yaml' before the service boots. This should be made optional/lazy (like other optional exports) or accompanied by dependency updates for every affected service environment.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
pmoves/services/common/tests/test_model_nexus.py (1)

7-11: Consider using pytest's conftest.py for import path setup.

The sys.path and sys.modules manipulation works but creates global side-effects. Moving this setup to a conftest.py file in the tests directory would centralize the import configuration and make it reusable across test modules.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/services/common/tests/test_model_nexus.py` around lines 7 - 11, Move
the test import path setup out of the test file and into a tests conftest:
instead of manipulating repo_root, sys.path.append and sys.modules.setdefault
directly in test_model_nexus.py, create a conftest.py that performs the same
setup (e.g. in a pytest_configure or a session-scoped fixture) — compute
repo_root the same way, append it to sys.path if missing, and call
importlib.import_module("pmoves.services") (or set
sys.modules.setdefault("services", ...)) there so all tests reuse the
centralized import-path configuration without per-test global side-effects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pmoves/configs/agent-profiles/nemotron_claw.yaml`:
- Around line 31-32: Remove the embedded credentials from the NATS URL by
replacing the hard-coded value "nats://nats:pmoves@nats:4222" with a
credential-free endpoint (e.g., "nats://nats:4222") in the nats.url setting, and
change any consumer of that profile to obtain username/password from environment
variables or a secret file instead (wire auth into the NATS client
initialization code that reads this profile); ensure the subscribe section and
any code that builds the connection (lookup code using nats.url) uses the
externalized credentials rather than relying on the profile to contain secrets.

In `@pmoves/configs/tac_trees/pinokio-p7.tac.yaml`:
- Line 72: Update the expectation string that currently reads "Claude Code
'speak hello' routes through Pinokio to TTS at :7860 or a fixed HTTPS domain" to
also include the current deployment port :7861 (and keep the optional HTTPS
domain reference) so checks match pmoves defaults; locate the YAML key/value
where expect is set (the expect string on the tac tree for Pinokio, e.g., the
expect entry containing "Claude Code 'speak hello'") and modify that text to
mention ":7861" (for example, "at :7861 or a fixed HTTPS domain" or include both
:7860 and :7861 if you prefer backward compatibility).

In `@pmoves/services/common/model_nexus.py`:
- Around line 49-50: The code uses "data = config or load_model_nexus()" which
treats an explicitly provided empty dict as falsy and reloads disk config;
change this to only call load_model_nexus() when config is None (e.g., use "data
= config if config is not None else load_model_nexus()") so explicit empty
configs are honored. Apply the same change for the similar pattern around lines
referencing the same assignment (the other occurrence at lines 59-60) and keep
references to the variable name "data" and function "load_model_nexus" to locate
and update the logic.
- Around line 24-25: Cached loader functions (_load_model_nexus_cached and the
public load_model_nexus) currently return the same mutable dict instance,
letting callers mutate shared state; update the cache-return path to return a
defensive copy (e.g., use copy.deepcopy on the cached dict) before returning so
callers receive an independent instance, and apply the same change to the other
cached loaders referenced around the other locations (lines 32-33 and 43) to
avoid leaking shared mutable state.

---

Nitpick comments:
In `@pmoves/services/common/tests/test_model_nexus.py`:
- Around line 7-11: Move the test import path setup out of the test file and
into a tests conftest: instead of manipulating repo_root, sys.path.append and
sys.modules.setdefault directly in test_model_nexus.py, create a conftest.py
that performs the same setup (e.g. in a pytest_configure or a session-scoped
fixture) — compute repo_root the same way, append it to sys.path if missing, and
call importlib.import_module("pmoves.services") (or set
sys.modules.setdefault("services", ...)) there so all tests reuse the
centralized import-path configuration without per-test global side-effects.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0e26671d-8c6a-4026-b9db-94552adab8db

📥 Commits

Reviewing files that changed from the base of the PR and between a04f2dc and 72852c9.

📒 Files selected for processing (12)
  • pmoves/config/model_nexus.yaml
  • pmoves/configs/agent-profiles/nemotron_claw.yaml
  • pmoves/configs/agent-teams.yaml
  • pmoves/configs/claws/opencode-nemotron-claw.json
  • pmoves/configs/claws/scopes/nemotron-claw.json
  • pmoves/configs/tac_trees/pinokio-p7.tac.yaml
  • pmoves/docs/AGENTS/AGNOTE_P7_PLAYGROUND.md
  • pmoves/docs/MODEL_FABRIC_CONTRACT.md
  • pmoves/docs/NEXUS_PROVIDER_PARITY.md
  • pmoves/services/common/__init__.py
  • pmoves/services/common/model_nexus.py
  • pmoves/services/common/tests/test_model_nexus.py

Comment on lines +31 to +32
url: nats://nats:pmoves@nats:4222
subscribe:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove embedded NATS credentials from profile config

Line 31 hard-codes Basic Auth in nats.url (nats://nats:pmoves@nats:4222). This leaks credential material into config history and makes rotation harder. Keep URL credential-free and source auth from env/secret-file wiring instead.

🧰 Tools
🪛 Checkov (3.2.508)

[medium] 31-32: Basic Auth Credentials

(CKV_SECRET_4)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/configs/agent-profiles/nemotron_claw.yaml` around lines 31 - 32,
Remove the embedded credentials from the NATS URL by replacing the hard-coded
value "nats://nats:pmoves@nats:4222" with a credential-free endpoint (e.g.,
"nats://nats:4222") in the nats.url setting, and change any consumer of that
profile to obtain username/password from environment variables or a secret file
instead (wire auth into the NATS client initialization code that reads this
profile); ensure the subscribe section and any code that builds the connection
(lookup code using nats.url) uses the externalized credentials rather than
relying on the profile to contain secrets.

action:
type: manual
expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7861"
expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7860 or a fixed HTTPS domain"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update TTS port expectation to match current deployment default

Line 72 expects :7860, but current PMOVES deployment references host/service access on :7861 (see pmoves/docker-compose.yml and TTS_BASE_URL default). This can cause false negatives during manual checks; include :7861 (and optional HTTPS domain) in the expectation text.

Suggested wording update
-            expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7860 or a fixed HTTPS domain"
+            expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7861 (deployment default) or a fixed HTTPS domain"
📝 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.

Suggested change
expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7860 or a fixed HTTPS domain"
expect: "Claude Code 'speak hello' routes through Pinokio to TTS at :7861 (deployment default) or a fixed HTTPS domain"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/configs/tac_trees/pinokio-p7.tac.yaml` at line 72, Update the
expectation string that currently reads "Claude Code 'speak hello' routes
through Pinokio to TTS at :7860 or a fixed HTTPS domain" to also include the
current deployment port :7861 (and keep the optional HTTPS domain reference) so
checks match pmoves defaults; locate the YAML key/value where expect is set (the
expect string on the tac tree for Pinokio, e.g., the expect entry containing
"Claude Code 'speak hello'") and modify that text to mention ":7861" (for
example, "at :7861 or a fixed HTTPS domain" or include both :7860 and :7861 if
you prefer backward compatibility).

Comment on lines +24 to +25
def _load_model_nexus_cached(resolved_path: str) -> dict[str, Any]:
path = Path(resolved_path)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent shared mutable state from leaking out of cache

_load_model_nexus_cached returns a mutable dict, and load_model_nexus returns that same cached object. Any caller mutation will contaminate future reads across the process.

Suggested fix
+from copy import deepcopy
...
 def load_model_nexus(path: str | Path | None = None) -> dict[str, Any]:
@@
     target = Path(path) if path is not None else model_nexus_path()
-    return _load_model_nexus_cached(str(target.resolve()))
+    return deepcopy(_load_model_nexus_cached(str(target.resolve())))

Also applies to: 32-33, 43-43

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/services/common/model_nexus.py` around lines 24 - 25, Cached loader
functions (_load_model_nexus_cached and the public load_model_nexus) currently
return the same mutable dict instance, letting callers mutate shared state;
update the cache-return path to return a defensive copy (e.g., use copy.deepcopy
on the cached dict) before returning so callers receive an independent instance,
and apply the same change to the other cached loaders referenced around the
other locations (lines 32-33 and 43) to avoid leaking shared mutable state.

Comment on lines +49 to +50
data = config or load_model_nexus()
providers = data.get("providers", {})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Don’t ignore explicitly provided empty configs

Using config or load_model_nexus() treats {} as falsy and silently reloads disk config. That breaks explicit test/injected configs and can mask caller intent.

Suggested fix
-    data = config or load_model_nexus()
+    data = config if config is not None else load_model_nexus()
...
-    data = config or load_model_nexus()
+    data = config if config is not None else load_model_nexus()

Also applies to: 59-60

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/services/common/model_nexus.py` around lines 49 - 50, The code uses
"data = config or load_model_nexus()" which treats an explicitly provided empty
dict as falsy and reloads disk config; change this to only call
load_model_nexus() when config is None (e.g., use "data = config if config is
not None else load_model_nexus()") so explicit empty configs are honored. Apply
the same change for the similar pattern around lines referencing the same
assignment (the other occurrence at lines 59-60) and keep references to the
variable name "data" and function "load_model_nexus" to locate and update the
logic.

@POWERFULMOVES
POWERFULMOVES merged commit 5701631 into main Mar 25, 2026
8 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the codex/nexus-nemotron-claw branch April 21, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants