Skip to content

feat(skills): add nemo-analyst workflow - #1116

Merged
callingmedic911 merged 9 commits into
mainfrom
aditya/ase-745-analyst-skill-b080
Aug 7, 2026
Merged

feat(skills): add nemo-analyst workflow#1116
callingmedic911 merged 9 commits into
mainfrom
aditya/ase-745-analyst-skill-b080

Conversation

@callingmedic911

@callingmedic911 callingmedic911 commented Aug 5, 2026

Copy link
Copy Markdown
Member

Adds the platform-bundled nemo-analyst skill (ASE-745), so coding agents have a reliable route to nemo agents analyst run plus the minimum correct operating knowledge to use it.

Closes ASE-745.

Summary by CodeRabbit

  • New Features

    • Added the NeMo Analyst skill for analyzing agent telemetry and recording evidence-based Insights.
    • Added plugin skill discovery and installation support for NeMo Insights.
    • Documented Analyst prerequisites, execution options, verification, and handoff workflows.
  • Tests

    • Added coverage for relevant Analyst requests and unrelated-task exclusions.
    • Added validation for skill discovery and availability.

@github-actions github-actions Bot added the feat label Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 31628/40251 78.6% 63.2%
Integration Tests 18379/38186 48.1% 20.8%

@callingmedic911
callingmedic911 force-pushed the aditya/ase-745-analyst-skill-b080 branch from 519f9f1 to e463b0b Compare August 6, 2026 22:06
callingmedic911 added a commit that referenced this pull request Aug 7, 2026
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>
cursoragent and others added 6 commits August 7, 2026 13:47
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 #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>
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>
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>
`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>
Follow the pattern #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 #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>
@callingmedic911
callingmedic911 force-pushed the aditya/ase-745-analyst-skill-b080 branch from e133e68 to e9e96ef Compare August 7, 2026 19:56
Completes the #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>
@callingmedic911

Copy link
Copy Markdown
Member Author

/nvskills-ci

@callingmedic911
callingmedic911 marked this pull request as ready for review August 7, 2026 20:13
@callingmedic911
callingmedic911 requested review from a team as code owners August 7, 2026 20:13
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d4a2eea8-27fc-4c4b-9fd2-b4ca2163345a

📥 Commits

Reviewing files that changed from the base of the PR and between 6740cbf and 8cea8c5.

📒 Files selected for processing (1)
  • plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md

📝 Walkthrough

Walkthrough

Adds the nemo-analyst skill for telemetry analysis and Insight generation. Registers the Insights plugin skill directory through nemo.skills, updates routing documentation, and adds routing and entry-point tests.

Changes

Analyst skill integration

Layer / File(s) Summary
Analyst skill behavior and validation
plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/*
Defines Analyst metadata, prerequisites, execution, Insight storage, verification, handoff, and routing tests.
Plugin skill discovery
plugins/nemo-insights/pyproject.toml, plugins/nemo-insights/src/nemo_insights_plugin/skills.py, plugins/nemo-insights/src/nemo_insights_plugin/skills/README.md, plugins/nemo-insights/tests/test_skills_entry_point.py
Registers the nemo.skills entry point, returns the packaged skills directory, documents installation, and validates discovery.
Shared routing updates
packages/nemo_platform_ext/src/nemo_platform_ext/skills/nemo-skill-selection/SKILL.md, AGENTS.md, CLAUDE.md
Routes recurring failures and telemetry analysis to nemo-analyst and lists the skill among plugin-owned skills.

Sequence Diagram(s)

sequenceDiagram
  participant NemoSkillSelection
  participant InsightsEntryPoint
  participant SkillsDirectory
  participant NemoAnalystSkill
  NemoSkillSelection->>InsightsEntryPoint: Discover the insights nemo.skills entry point
  InsightsEntryPoint->>SkillsDirectory: Call skills_dir()
  SkillsDirectory-->>NemoSkillSelection: Return the packaged skills Path
  NemoSkillSelection->>NemoAnalystSkill: Load nemo-analyst/SKILL.md
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding the nemo-analyst skill workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch aditya/ase-745-analyst-skill-b080

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
plugins/nemo-insights/tests/test_skills_entry_point.py (1)

20-30: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert the loaded entry point's target.

The test only proves that insights loads a callable that returns some directory. It does not prove that the callable is nemo_insights_plugin.skills.skills_dir or that the loaded directory contains the new skill. Compare loaded and result with skills_dir() and assert that SKILL.md exists.

Suggested assertion
     from importlib.metadata import entry_points
+    from nemo_insights_plugin.skills import skills_dir

     eps = [ep for ep in entry_points(group="nemo.skills") if ep.name == "insights"]
     assert len(eps) == 1, f"Expected exactly one 'insights' entry-point, got {eps}"
     loaded = eps[0].load()
+    assert loaded is skills_dir
     assert callable(loaded), f"Entry-point did not resolve to a callable: {loaded!r}"
     result = loaded()
+    assert result == skills_dir()
     assert isinstance(result, Path), f"skills_dir() returned {result!r} (not Path)"
     assert result.is_dir(), f"skills_dir() returned {result!r} which is not a directory"
+    assert (result / "nemo-analyst" / "SKILL.md").is_file()
🤖 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/tests/test_skills_entry_point.py` around lines 20 - 30,
Strengthen test_entry_point_loads_skills_dir by importing the canonical
skills_dir symbol, asserting the loaded entry-point callable matches it, and
comparing the returned result with skills_dir(). Also assert that the returned
directory contains the new skill’s SKILL.md file while preserving the existing
entry-point and directory validations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md`:
- Line 18: Update the routing trigger in SKILL.md by replacing the incomplete
phrase “my agent keeps getting wrong” with “my agent keeps getting things
wrong,” or remove the trigger entirely if it is not needed.
- Around line 127-129: Update the curl example in the nemo analyst skill to
avoid expanding the bearer token in command arguments: obtain authentication
through a protected header file or stdin-based mechanism, and keep the
unauthenticated request command separate from token handling while preserving
the existing insights endpoint and query parameters.
- Around line 132-136: Update the analyst-run validation to inspect the current
AnalystResult or its operation-specific create/update marker, rather than
relying on the stored ?agent=... Insight listing. Treat “no insights created or
updated” as a valid successful run, while still validating any newly created or
updated Insights for clear titles, actionable descriptions, non-empty
trace_refs, and Studio optimizer visibility.

---

Nitpick comments:
In `@plugins/nemo-insights/tests/test_skills_entry_point.py`:
- Around line 20-30: Strengthen test_entry_point_loads_skills_dir by importing
the canonical skills_dir symbol, asserting the loaded entry-point callable
matches it, and comparing the returned result with skills_dir(). Also assert
that the returned directory contains the new skill’s SKILL.md file while
preserving the existing entry-point and directory validations.
🪄 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: 3ec17f55-a813-44fc-bacb-5925e763f5a9

📥 Commits

Reviewing files that changed from the base of the PR and between 6811a4e and 6740cbf.

⛔ Files ignored due to path filters (1)
  • sdk/python/nemo-platform/src/nemo_platform/skills/nemo-skill-selection/SKILL.md is excluded by !sdk/**
📒 Files selected for processing (9)
  • AGENTS.md
  • CLAUDE.md
  • packages/nemo_platform_ext/src/nemo_platform_ext/skills/nemo-skill-selection/SKILL.md
  • plugins/nemo-insights/pyproject.toml
  • plugins/nemo-insights/src/nemo_insights_plugin/skills.py
  • plugins/nemo-insights/src/nemo_insights_plugin/skills/README.md
  • plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md
  • plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/tests.json
  • plugins/nemo-insights/tests/test_skills_entry_point.py

Comment thread plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md Outdated
Comment thread plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md Outdated
Comment thread plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md Outdated
CodeRabbit review on #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>

@aleckhoury aleckhoury 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.

Just a couple questions, not blocking

Comment thread plugins/nemo-insights/src/nemo_insights_plugin/skills/nemo-analyst/SKILL.md Outdated
Comment thread plugins/nemo-insights/src/nemo_insights_plugin/skills/README.md Outdated
Comment thread plugins/nemo-insights/tests/test_skills_entry_point.py Outdated
Review feedback on #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>
@callingmedic911

Copy link
Copy Markdown
Member Author

/nvskills-ci

@callingmedic911
callingmedic911 added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit edf66b9 Aug 7, 2026
60 of 61 checks passed
@callingmedic911
callingmedic911 deleted the aditya/ase-745-analyst-skill-b080 branch August 7, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants