feat(agents): allow optimization agents to configure models - #1159
Conversation
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
|
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:
📝 WalkthroughWalkthroughThe PR moves Insights, Experimentalist, and Eval Author to Platform-managed default and fast model pairs. Setup persists and resolves both models. Runtime integrations share routed clients with scoped cleanup. Insights stores model pairs for scheduled analysis. Legacy credential and tier configuration is removed. ChangesPlatform-managed model routing
Insights persistence and execution
Supporting configuration and documentation
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
plugins/nemo-insights/examples/research-agent/README.md (1)
75-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDo not combine
--autowith prompt instructions.
--autouses automatic setup behavior. It does not support “press Enter at the fast prompt.” Remove--autofor interactive selection, or revise the text to describe automatic selection.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/nemo-insights/examples/research-agent/README.md` around lines 75 - 80, Update the setup instructions around the `nemo setup` command so they no longer combine `--auto` with interactive prompt guidance. Either remove `--auto` to preserve the documented Enter-to-reuse behavior, or revise the surrounding text to describe automatic model selection.
🧹 Nitpick comments (2)
packages/nemo_platform_ext/src/nemo_platform_ext/config/config.py (1)
75-78: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueModel resolution logic is duplicated.
resolve()and_create_default_config()now contain the same three-step precedence chain. Extract a small helper so a future precedence change updates one place.Also applies to: 489-492, 501-501, 551-559
🤖 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 `@packages/nemo_platform_ext/src/nemo_platform_ext/config/config.py` around lines 75 - 78, Extract the duplicated three-step model precedence chain from resolve() and _create_default_config() into a shared helper, then reuse that helper at all affected call sites. Preserve the existing precedence and ensure future model-resolution changes only require updating the helper.packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py (1)
2251-2262: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value
NEMO_FAST_MODELis dropped when no default model resolves.If discovery returns nothing and
NEMO_DEFAULT_MODELis unset, theelsebranch runs and neither model is persisted, even when the user exportedNEMO_FAST_MODEL. Persist the fast model in that case, or state in the warning that the fast override is ignored without a default.🤖 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 `@packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py` around lines 2251 - 2262, Update the model persistence flow around ModelPair and the default_model fallback so an explicitly configured NEMO_FAST_MODEL is not discarded when default_model is unavailable. Persist the fast override in the no-default branch using the existing model configuration mechanism, or explicitly warn that it is ignored; preserve the current behavior when a default model resolves.
🤖 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 @.github/workflows/insights-testbed.yml:
- Around line 117-121: Update the NEMO_DEFAULT_MODEL fallback to the
provider-discovered ID default/openai-gpt-5-5, and remove NEMO_FAST_MODEL when
it matches the default so _run_auto_mode supplies the fallback.
In `@docs/get-started/example-agent.mdx`:
- Around line 168-169: Add the clone-mode warning immediately before the
Git-backed command containing NEMO_DEFAULT_MODEL and NEMO_FAST_MODEL, explaining
that clone mode is an integrity boundary rather than a confidentiality boundary.
Keep the existing later local-only warning unchanged.
In `@packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py`:
- Around line 390-414: Update _configure_local_connection so setup never
overwrites an existing context named by _LOCAL_CONTEXT_NAME. Before
Config.write, detect whether that context already exists and reject the
operation or use a distinct dedicated context, preserving the existing context’s
endpoint and credentials while retaining the local no-auth setup behavior.
In `@packages/nemo_platform_plugin/src/nemo_platform_plugin/nooa_model_client.py`:
- Around line 47-51: Update NooaModelClient.aclose to always attempt closing
fast when it is distinct from default, even if default.aclose fails. In the
model-resolution failure path around resolved, close every already-created
client before re-raising the original resolution error. Add failure-path tests
covering both cleanup scenarios in
packages/nemo_platform_plugin/src/nemo_platform_plugin/nooa_model_client.py:47-51
and :159-167.
In `@plugins/nemo-experimentalist/benchmarks/run.py`:
- Around line 345-348: Update the summary aggregation logic around the job field
validation to validate raw payload or stats values before calling int(). Reject
booleans explicitly, along with floats and numeric strings, and preserve the
field name in the TypeError; only convert values after they pass the strict
integer check.
In
`@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/run.py`:
- Around line 106-136: Preserve the selected default and fast model references
returned by resolve_model_clients in the run flow, and expose or pass them to
the benchmark caller alongside the result summary. Update the benchmark
persistence path, including benchmarks/run.py and its summary.json generation,
to record both resolved references in addition to the existing ModelSpec fields.
In `@plugins/nemo-insights/examples/research-agent/tests/test_analyst_e2e.py`:
- Around line 152-154: Update the credential check in the E2E fixture to require
TAVILY_API_KEY and accept either NVIDIA_API_KEY or NEMO_DEFAULT_INFERENCE_KEY as
the model-provider credential. Ensure the missing-key message reports the model
credential requirement without skipping when only the alternate credential is
present.
---
Outside diff comments:
In `@plugins/nemo-insights/examples/research-agent/README.md`:
- Around line 75-80: Update the setup instructions around the `nemo setup`
command so they no longer combine `--auto` with interactive prompt guidance.
Either remove `--auto` to preserve the documented Enter-to-reuse behavior, or
revise the surrounding text to describe automatic model selection.
---
Nitpick comments:
In `@packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py`:
- Around line 2251-2262: Update the model persistence flow around ModelPair and
the default_model fallback so an explicitly configured NEMO_FAST_MODEL is not
discarded when default_model is unavailable. Persist the fast override in the
no-default branch using the existing model configuration mechanism, or
explicitly warn that it is ignored; preserve the current behavior when a default
model resolves.
In `@packages/nemo_platform_ext/src/nemo_platform_ext/config/config.py`:
- Around line 75-78: Extract the duplicated three-step model precedence chain
from resolve() and _create_default_config() into a shared helper, then reuse
that helper at all affected call sites. Preserve the existing precedence and
ensure future model-resolution changes only require updating the helper.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: c5ee37ee-7c42-46bd-9f55-4a7d4633abbd
⛔ Files ignored due to path filters (5)
sdk/python/nemo-platform/src/nemo_platform/cli/commands/manifest_registry.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/config/config.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/config/models.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/vendored/nemo_platform_ext/cli/commands/test_setup.pyis excluded by!sdk/**
📒 Files selected for processing (88)
.github/actions/insights-intake-stack/action.yml.github/workflows/insights-testbed.ymlREADME.mdSETUP.mddocs/agents/insight-driven-optimization.mdxdocs/get-started/example-agent.mdxdocs/get-started/setup.mdxdocs/set-up/config-reference.mdxpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/manifest_registry.pypackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.pypackages/nemo_platform_ext/src/nemo_platform_ext/config/config.pypackages/nemo_platform_ext/src/nemo_platform_ext/config/models.pypackages/nemo_platform_ext/tests/cli/commands/test_setup.pypackages/nemo_platform_plugin/src/nemo_platform_plugin/nooa_model_client.pypackages/nemo_platform_plugin/tests/test_nooa_model_client.pyplugins/nemo-eval-author/.env.exampleplugins/nemo-eval-author/README.mdplugins/nemo-eval-author/src/nemo_eval_author_plugin/cli.pyplugins/nemo-eval-author/src/nemo_eval_author_plugin/eval_author/agent.pyplugins/nemo-eval-author/src/nemo_eval_author_plugin/eval_author/run.pyplugins/nemo-eval-author/src/nemo_eval_author_plugin/model_config.pyplugins/nemo-eval-author/tests/conftest.pyplugins/nemo-eval-author/tests/test_eval_author_repair_e2e.pyplugins/nemo-eval-author/tests/test_eval_author_run.pyplugins/nemo-eval-author/tests/test_model_config.pyplugins/nemo-eval-author/tests/test_plugin_boundary.pyplugins/nemo-experimentalist/AGENTS.mdplugins/nemo-experimentalist/README.mdplugins/nemo-experimentalist/benchmarks/README.mdplugins/nemo-experimentalist/benchmarks/configs/tau3-quality.yamlplugins/nemo-experimentalist/benchmarks/configs/tau3-smoke.yamlplugins/nemo-experimentalist/benchmarks/configs/terminal-bench-quality.yamlplugins/nemo-experimentalist/benchmarks/configs/terminal-bench-smoke.yamlplugins/nemo-experimentalist/benchmarks/run.pyplugins/nemo-experimentalist/examples/tau3-nooa-agent/.env.exampleplugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/cli.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/analyzer.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/cards.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/coder.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/goal_tree.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/loop.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/model_config.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/proposer.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/rationalizer.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/terminator.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/trace_analyzer.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/trace_scorer.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/run.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/preflight.pyplugins/nemo-experimentalist/src/nemo_experimentalist_plugin/settings.pyplugins/nemo-experimentalist/tests/conftest.pyplugins/nemo-experimentalist/tests/experimentalist/test_model_config.pyplugins/nemo-experimentalist/tests/experimentalist/test_terminator.pyplugins/nemo-experimentalist/tests/experimentalist/test_tools.pyplugins/nemo-experimentalist/tests/test_cli_profile.pyplugins/nemo-experimentalist/tests/test_experiment_cli.pyplugins/nemo-experimentalist/tests/test_experimentalist_benchmark.pyplugins/nemo-experimentalist/tests/test_experimentalist_run.pyplugins/nemo-experimentalist/tests/test_preflight.pyplugins/nemo-experimentalist/tests/test_resolve.pyplugins/nemo-insights/README.mdplugins/nemo-insights/examples/research-agent/README.mdplugins/nemo-insights/examples/research-agent/tests/test_analyst_e2e.pyplugins/nemo-insights/src/nemo_insights_plugin/analyst/agent.pyplugins/nemo-insights/src/nemo_insights_plugin/analyst/model_config.pyplugins/nemo-insights/src/nemo_insights_plugin/analyst/run.pyplugins/nemo-insights/src/nemo_insights_plugin/cli.pyplugins/nemo-insights/src/nemo_insights_plugin/config.pyplugins/nemo-insights/src/nemo_insights_plugin/controller.pyplugins/nemo-insights/src/nemo_insights_plugin/entities.pyplugins/nemo-insights/src/nemo_insights_plugin/jobs/analyze.pyplugins/nemo-insights/src/nemo_insights_plugin/preflight.pyplugins/nemo-insights/src/nemo_insights_plugin/schema.pyplugins/nemo-insights/src/nemo_insights_plugin/sdk_resources/analysis_configs.pyplugins/nemo-insights/src/nemo_insights_plugin/service.pyplugins/nemo-insights/testbed/README.mdplugins/nemo-insights/testbed/cli.pyplugins/nemo-insights/testbed/eval/stack.pyplugins/nemo-insights/tests/test_analysis_config_contract.pyplugins/nemo-insights/tests/test_analyst_agent.pyplugins/nemo-insights/tests/test_analyst_run.pyplugins/nemo-insights/tests/test_cli_profile.pyplugins/nemo-insights/tests/test_periodic_analysis.pyplugins/nemo-insights/tests/test_preflight.pyplugins/nemo-insights/tests/testbed/test_cli.pyscript/generate_config_docs.py
💤 Files with no reviewable changes (16)
- docs/set-up/config-reference.mdx
- plugins/nemo-eval-author/src/nemo_eval_author_plugin/model_config.py
- plugins/nemo-insights/src/nemo_insights_plugin/analyst/model_config.py
- plugins/nemo-experimentalist/tests/test_experimentalist_benchmark.py
- plugins/nemo-experimentalist/benchmarks/configs/terminal-bench-quality.yaml
- plugins/nemo-experimentalist/benchmarks/configs/tau3-smoke.yaml
- plugins/nemo-insights/src/nemo_insights_plugin/config.py
- plugins/nemo-insights/testbed/cli.py
- plugins/nemo-experimentalist/tests/experimentalist/test_model_config.py
- plugins/nemo-insights/tests/test_analyst_agent.py
- plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/model_config.py
- plugins/nemo-experimentalist/benchmarks/configs/tau3-quality.yaml
- plugins/nemo-eval-author/tests/test_model_config.py
- plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/settings.py
- script/generate_config_docs.py
- plugins/nemo-experimentalist/benchmarks/configs/terminal-bench-smoke.yaml
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
…newsom Signed-off-by: Brian Newsom <brnewsom@nvidia.com> # Conflicts: # docs/get-started/example-agent.mdx
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
|
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@docs/cli/reference.mdx`:
- Around line 50-51: Move the setup-text changes from the generated
docs/cli/reference.mdx output into its source document, then run the designated
documentation generation command to regenerate the reference page and commit the
updated generated output.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 8770a6e6-6dbb-4903-8374-3d69eec5cc62
📒 Files selected for processing (1)
docs/cli/reference.mdx
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
gaiadilorenzo
left a comment
There was a problem hiding this comment.
Looks good to me but I'm missing a lot of nemo platform context
The Configuration section documented `NEMO_EXPERIMENTALIST_API_BASE`, `_API_KEY`, and the smart/mid/fast tiers. #1159 deletes `settings.py` outright, so every one of those variables goes away: the optimizer now resolves a default/fast pair of Platform Model Entities selected by `nemo setup`, and reads no endpoint, provider key, or provider model name of its own. Rewrites the section against that PR's code rather than its prose, so the tier mapping is accurate -- the trajectory scorer moves from mid to fast, and the architecture doc from mid to default. Updates the sandbox `sbx exec --env` block to the two overrides that replace the six, and the secret-handling caution that assumed keys were among them. Also names the bounded sub-problem optimization loop in the round walkthrough. It was missing, and `implement` runs it before the integration check rather than inside it (coder.py:680-686). Review feedback from @gaiadilorenzo on #1165. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Christian Schüller <cschueller@nvidia.com>
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
…newsom Signed-off-by: Brian Newsom <brnewsom@nvidia.com> # Conflicts: # plugins/nemo-eval-author/src/nemo_eval_author_plugin/eval_author/agent.py # plugins/nemo-eval-author/src/nemo_eval_author_plugin/eval_author/run.py # plugins/nemo-eval-author/tests/test_eval_author_run.py # plugins/nemo-experimentalist/README.md # plugins/nemo-experimentalist/examples/tau3-nooa-agent/.env.example # plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/loop.py # plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/terminator.py # plugins/nemo-experimentalist/tests/experimentalist/test_model_config.py
…newsom Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
…newsom Signed-off-by: Brian Newsom <brnewsom@nvidia.com> # Conflicts: # README.md
Signed-off-by: Brian Newsom <brnewsom@nvidia.com>
Review feedback on #1116. #1159 moves the optimization agents onto the models chosen in `nemo setup` and drops `INFERENCE_API_KEY` as an agent credential, so naming that variable, the gateway, and Claude Opus 4.8 would go stale the day it lands. State the requirement instead — the Analyst needs a model to run on — and let `analyst doctor` be the authority on whether it is satisfied, which is true before and after that change. Also from review: - Frame the skill as analyzing behavior and producing Insights rather than "finding what an agent keeps getting wrong". - Describe `--agent-spec` by what it gives the Analyst: the intent behind the agent, which is not recoverable from code or traces. Per the AGENT-SPEC design doc, that is its whole job. (The proposed ETHOS.md rename has not landed, so the filename stays.) - Drop `--base-url` from the run example; it defaults to `NMP_BASE_URL`. The wider `NMP_*` rename is ASE-815 — 414 files reference those variables, so it is not a skill-PR change. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com>
The previous commit wrote the credential story as #1159 will leave it, but that PR has not landed: the analyst still reads INFERENCE_API_KEY directly today, so "rather than any credential of its own" was false in the world this ships into. Say only that the model configuration is in flux and that pre-flight names what is missing — accurate before and after. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com>
Review feedback on #1116. #1159 moves the optimization agents onto the models chosen in `nemo setup` and drops `INFERENCE_API_KEY` as an agent credential, so naming that variable, the gateway, and Claude Opus 4.8 would go stale the day it lands. State the requirement instead — the Analyst needs a model to run on — and let `analyst doctor` be the authority on whether it is satisfied, which is true before and after that change. Also from review: - Frame the skill as analyzing behavior and producing Insights rather than "finding what an agent keeps getting wrong". - Describe `--agent-spec` by what it gives the Analyst: the intent behind the agent, which is not recoverable from code or traces. Per the AGENT-SPEC design doc, that is its whole job. (The proposed ETHOS.md rename has not landed, so the filename stays.) - Drop `--base-url` from the run example; it defaults to `NMP_BASE_URL`. The wider `NMP_*` rename is ASE-815 — 414 files reference those variables, so it is not a skill-PR change. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com>
The previous commit wrote the credential story as #1159 will leave it, but that PR has not landed: the analyst still reads INFERENCE_API_KEY directly today, so "rather than any credential of its own" was false in the world this ships into. Say only that the model configuration is in flux and that pre-flight names what is missing — accurate before and after. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com>
The README had grown into an operator runbook that duplicated the Experimentalist skill and the docs site while never explaining what the Experimentalist does. Refocus it on the plugin's function and link out for the rest. - Explain the optimization loop, the levers it can change, and the train-diagnoses / validation-selects split, matching the round order the implementation actually runs. - Add a parameter table built from the CLI options, plus smoke-first guidance, run cost and duration, and resume-on-rerun. - Document what ships in the box: the nooa and langchain-framework skills, the two example agents, and the canonical benchmark suites. - Lead with the example-agent walkthrough so readers start from a worked run. - Correct claims that did not hold against the source: the command is `nemo agents experimentalist doctor`; the evaluation container receives whatever each Harbor task's `task.toml` declares rather than a fixed forwarded set, with `AUT_MODEL_NAME` a convention of the example agents; NeMo Experiments receives a structure-only mirror; and the model table read as exhaustive when the fast model also drives sub-steps across most components. Keep the "Recommended laptop isolation" heading, which the Experimentalist skill links to by anchor, and carry forward the objective_function and regression_metrics reference from #1159 under a task-oriented heading. Signed-off-by: Christian Schüller <cschueller@nvidia.com>
* feat(skills): add nemo-analyst workflow Add the platform-bundled nemo-analyst skill so coding agents have a reliable route to `nemo agents analyst run` and the minimum correct operating knowledge to use it. The body stays lean and defers depth to docs/agents/insight-driven-optimization.mdx rather than restating it. It covers the Insight shape, the credential distinction from the Experimentalist (the Analyst reads only INFERENCE_API_KEY), the doctor pre-flight, the run, where Insights are stored, and a verification step. Persistence is documented as it behaves after NVIDIA-NeMo#1054: Insights always go to the platform, and --insights-file-output mirrors what was stored. Routing tests follow the explicit/implicit/negative-control convention already used by nemo-explore. Verified that all six analyst-intent prompts resolve to nemo-analyst, that the skill introduces no new failures elsewhere in the catalog, and that it wins no ties by sort order. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co> Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * feat(skills): tighten nemo-analyst from journey findings Drove the skill end to end in a container against a real LangGraph agent's telemetry. It carried the workflow, so this sharpens what it left the driver to work out rather than adding to it — net zero lines, paid for by cutting redundancy from the storage and verify sections. - `analyst doctor` takes no `--agent` flag, so it always reports a red profile line. Say that passing `--agent` makes that line noise instead of leaving the reader to reason past a red mark, or to write an `optimizer.yaml` it does not need. - `agent_name` is carried on agent-level spans, not on their model and tool children, so the old "matches the `agent_name` on the spans" pointed at a query that undercounts. - Every span came back `status=success` while the agent was badly broken, so state that the Analyst judges behavior rather than status or scores. - Telemetry that captures only the shape of a run is a third cause of an empty result, alongside scoping and volume. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * feat(skills): decouple nemo-analyst from a specific model and credential Review feedback on NVIDIA-NeMo#1116. NVIDIA-NeMo#1159 moves the optimization agents onto the models chosen in `nemo setup` and drops `INFERENCE_API_KEY` as an agent credential, so naming that variable, the gateway, and Claude Opus 4.8 would go stale the day it lands. State the requirement instead — the Analyst needs a model to run on — and let `analyst doctor` be the authority on whether it is satisfied, which is true before and after that change. Also from review: - Frame the skill as analyzing behavior and producing Insights rather than "finding what an agent keeps getting wrong". - Describe `--agent-spec` by what it gives the Analyst: the intent behind the agent, which is not recoverable from code or traces. Per the AGENT-SPEC design doc, that is its whole job. (The proposed ETHOS.md rename has not landed, so the filename stays.) - Drop `--base-url` from the run example; it defaults to `NMP_BASE_URL`. The wider `NMP_*` rename is ASE-815 — 414 files reference those variables, so it is not a skill-PR change. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * fix(skills): don't claim nemo-analyst has no credential of its own The previous commit wrote the credential story as NVIDIA-NeMo#1159 will leave it, but that PR has not landed: the analyst still reads INFERENCE_API_KEY directly today, so "rather than any credential of its own" was false in the world this ships into. Say only that the model configuration is in flux and that pre-flight names what is missing — accurate before and after. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * fix(skills): vendor nemo-analyst into the SDK `lint-sdk-vendored` and `lint-cli` both fail on this branch because every skill is mirrored into `sdk/python/nemo-platform` and this one never was — it was the only skill missing from the vendored tree. Generated with `make vendor`; as with every other skill, `tests.json` is not vendored. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * refactor(skills): ship nemo-analyst with the Insights plugin Follow the pattern NVIDIA-NeMo#1088 settled on. That PR started with the Experimentalist skill in the platform package and deliberately moved it into the plugin; this one was written against the earlier shape. The skill documents `nemo agents analyst`, which only exists when nemo-insights is installed, so the platform package should not ship it. Moving it also removes it from the vendored SDK tree — plugin-owned skills are discovered through the `nemo.skills` entry point instead, which is what made lint-sdk-vendored care about it in the first place. Mirrors the Experimentalist layout: skills.py exposing skills_dir, a skills README, and an entry-point test. `nemo skills list` now reports the skill with source nemo-insights-plugin. Also adds the nemo-analyst row to nemo-skill-selection, as NVIDIA-NeMo#1088 did for the Experimentalist. The catalog already told agents to use the Experimentalist "after `agents analyst` has created an Insight" while having no row that routed there. The description said "Produces the Insight that nemo-experimentalist consumes". Now that both skills are in the catalog together, that literal token made this skill win the Experimentalist's own explicit routing test — scoring treats a hyphenated name as one token. Reworded to "the Experimentalist", which keeps the loop context without the collision. Catalog-wide: 47 failures both before and after, 12 more passes, and nemo-analyst involved in no failure. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * docs(skills): note Analyst telemetry analysis as plugin-owned Completes the NVIDIA-NeMo#1088 parallel: that PR appended the Experimentalist to the plugin-owned skills sentence in both files once its skill moved into the plugin. The Analyst now lives there too. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * fix(skills): verify the analyst run, not the stored Insight set CodeRabbit review on NVIDIA-NeMo#1116. The Verify section contradicted the skill's own premise: it said a successful run leaves at least one Insight, while "What it produces" says filing nothing is a valid outcome. It also verified the wrong thing — listing by `?agent=` returns every Insight for the agent, including earlier runs', so it attests the store rather than this run. Verify against what the run reports instead. `analyst_backend` emits a line per operation (`- created: <title> [<id>]`, `- updated: <id>`, or `- no insights created or updated`), so read those ids back individually via `GET .../insights/<insight-id>`, and treat "no insights created or updated" as the success it is. Two smaller fixes from the same review: - Keep the bearer token out of `curl`'s argv, where any process on the host can read it, by passing it through curl's config on stdin. Verified the header still arrives. - The trigger `my agent keeps getting wrong` was missing its object; now `my agent keeps getting things wrong`. Routing is unchanged against a clean main baseline — 47 failures both sides, and nemo-analyst still fails none and steals none. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> * refactor(skills): drop the Insights skills README and entry-point test Review feedback on NVIDIA-NeMo#1116. Neither file was pulling its weight. skills/README.md is never read — the registry only looks at subdirectories containing a SKILL.md — and with a single skill in the directory it restated that skill's own frontmatter. The Experimentalist's equivalent earns its place by disambiguating a user-facing skill from an internal one; this one had nothing to disambiguate. test_skills_entry_point.py guarded the `nemo.skills` declaration in pyproject.toml. Without that entry the skill simply never appears in `nemo skills list`, so the failure announces itself the first time anyone uses the feature and does not need a regression test of its own. Verified by hand instead: the entry point resolves and `nemo skills list` reports nemo-analyst with source nemo-insights-plugin. Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> --------- Signed-off-by: Aditya Pandey <aditypandey@nvidia.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…IA-NeMo#1165) The README had grown into an operator runbook that duplicated the Experimentalist skill and the docs site while never explaining what the Experimentalist does. Refocus it on the plugin's function and link out for the rest. - Explain the optimization loop, the levers it can change, and the train-diagnoses / validation-selects split, matching the round order the implementation actually runs. - Add a parameter table built from the CLI options, plus smoke-first guidance, run cost and duration, and resume-on-rerun. - Document what ships in the box: the nooa and langchain-framework skills, the two example agents, and the canonical benchmark suites. - Lead with the example-agent walkthrough so readers start from a worked run. - Correct claims that did not hold against the source: the command is `nemo agents experimentalist doctor`; the evaluation container receives whatever each Harbor task's `task.toml` declares rather than a fixed forwarded set, with `AUT_MODEL_NAME` a convention of the example agents; NeMo Experiments receives a structure-only mirror; and the model table read as exhaustive when the fast model also drives sub-steps across most components. Keep the "Recommended laptop isolation" heading, which the Experimentalist skill links to by anchor, and carry forward the objective_function and regression_metrics reference from NVIDIA-NeMo#1159 under a task-oriented heading. Signed-off-by: Christian Schüller <cschueller@nvidia.com>
Summary
This PR makes the Analyst, Eval Author, and Experimentalist use the models selected through
nemo setup. It replaces plugin-specific endpoints, credentials, hardcoded model names, and Experimentalist's three-tier model configuration with one Platform-native pair:default_modelfor quality-oriented work andfast_modelfor latency-oriented work, with fast falling back to default.Before this change, each optimization plugin configured inference independently. Setup-selected models and credentials in Platform Secrets were not reused, so OpenAI-compatible providers required manual plugin configuration and Anthropic could not be selected in setup and consumed through its native Messages contract.
Changes
Platform-native model selection
nemo setupnow stores two workspace-qualified Model Entity references in the active CLI context:Shared logic in
nemo_platform_pluginreads the pair, resolves each entity through the existing Platform SDK, uses its actual served model name/provider route/backend format/Platform headers, constructs the corresponding Nooa/LiteLLM client, and activates those clients for the agent run.Backend selection comes from the Model Entity rather than model-name heuristics:
OPENAI_CHATuses the OpenAI-compatible Chat Completions contract.ANTHROPIC_MESSAGESuses Anthropic's native Messages contract.The plugins do not translate request or response bodies. Provider credentials stay in Platform Secrets and are never passed into the optimization agents.
Consistent agent roles
default_modelis the existing quality-oriented default and replaces the previous smart role.fast_modelis used only for deliberately latency-sensitive or high-volume work, such as summarization and control steps.Experimentalist's checked-in
models.yamlremains separate: it controls model mutations for the agent under test, not the models running the optimizer itself. Application and benchmark credentials such asAUT_MODEL_NAME,OPENAI_API_KEY, andOPENAI_BASE_URLmay therefore still be required by the evaluated workload.Setup and compatibility
Interactive setup asks for a default and fast model. The fast prompt defaults to the chosen default, so users who want one model can press Enter twice without understanding the internal role mapping.
nemo setup --autopreserves main's behavior:NEMO_DEFAULT_MODELwhen set; otherwise select the alphabetically first discovered Model Entity.NEMO_FAST_MODELwhen set; otherwise reuse the effective default.Existing contexts that only contain
default_modelremain compatible because fast automatically falls back to default.For CI, containers, and other environments that cannot read the host CLI context, the pair can be overridden with Model Entity references:
The referenced entities and providers must already exist on the target Platform.
Removed optimizer-specific configuration
The optimization agents no longer consume:
AUTHOR_API_BASE,AUTHOR_API_KEY, orAUTHOR_*_MODEL_NAMENEMO_EXPERIMENTALIST_API_BASEorNEMO_EXPERIMENTALIST_API_KEYNEMO_EXPERIMENTALIST_MODELS_SMART,NEMO_EXPERIMENTALIST_MODELS_MID, orNEMO_EXPERIMENTALIST_MODELS_FASTINFERENCE_API_KEYas an optimization-agent credentialScheduled Analyst runs
nemo insights analysis enablenow persists the effective pair in the server-side analysis config. The controller does not need access to the operator's local~/.config/nmp/config.yaml. Re-runanalysis enableafter changing the pair; previously enabled records must also be re-enabled once to capture it.Anthropic setup's
auth_header_formatfix is intentionally isolated in #1158.Type of Change
Quality Gates
Verification
Signed-off-by:traileruv run pre-commit run -apasses, or any blocked checks are identified belowTargeted validation:
uv run --frozen pytest packages/nemo_platform_ext/tests/cli/commands/test_setup.py -q— 229 passed.uv run --frozen pytest sdk/python/nemo-platform/tests/vendored/nemo_platform_ext/cli/commands/test_setup.py -q— 229 passed.ty: passed.ff047d2a57) — preserved the new SDK/bootstrap/mise documentation and the model-pair setup text; relevant file-level pre-commit hooks passed.uv run pre-commit run -aafter the latest main sync — Ruff, formatting,ty, config docs, Helm docs, copyright, UI, import-boundary, and merge-conflict checks passed.uv-lock-checkis blocked becauseuv lockadds newly published wheel metadata despite no dependency-input change; that generated drift is excluded, and the committed lock resolves successfully withuv run --frozen.make docs-check— passed; 216 MDX files parsed cleanly and no published-to-gated links found.make docs-broken-links— command exited successfully but reported five existing broken links in unchanged pages (telemetry-and-privacy.mdx,using-authentication.mdx, andstudio/index.mdx). None are in this pull request's changed documentation.Live provider validation:
default/openai-openai-gpt-5-5) and created two Insights from 19 observed sessions. Separate Analyst runs completed with native Anthropic models and with an OpenAI default + Anthropic fast pair.default/gpt-5-minifast path.Summary by CodeRabbit
New Features
Documentation
Bug Fixes