Skip to content

feat(studio): replace the NAT with the Fabric in Create-Example - #1223

Merged
marcusds merged 3 commits into
mainfrom
astd-407-studio-sample-entry/nwalston
Aug 11, 2026
Merged

feat(studio): replace the NAT with the Fabric in Create-Example#1223
marcusds merged 3 commits into
mainfrom
astd-407-studio-sample-entry/nwalston

Conversation

@walston

@walston walston commented Aug 10, 2026

Copy link
Copy Markdown
Contributor
Screen.Recording.2026-08-10.at.15.04.20.mov

Summary

Replaces the NAT email-security-analyst sample with the Fabric (nemo-agents-spec-v1) email-phishing agent in Studio's Create Example Agent dropdown. NAT is being deprecated; this makes the modern Fabric example the one users land on. The Fabric example itself shipped via #1117.

No new plumbing — the create flow already supports Fabric samples: loadSampleAgentConfig branches on config_format and injects the model at models.default.model, and CreateExampleAgentModal enumerates SAMPLE_AGENTS and forwards config_format.

Changes

Add the Fabric example:

  • public/sample-agents/email-phishing-agent/agent.yml — static asset, an independent (byte-identical) copy of the plugin example's agent.yaml with a Studio-sample header.
  • SAMPLE_AGENTS entry (email_phishing_agent, configFormat: 'nemo-agents-spec-v1').
  • INVARIANT comment reworked to document the Fabric console-script dependency (email-phishing-iocs on PATH).

Remove the NAT example (dropdown only):

  • Delete the email_security_analyst SAMPLE_AGENTS entry + its agent.yml.
  • DEFAULT_SAMPLE_AGENT_KEY now resolves to email_phishing_agent.
  • Kept the eval-config assets (eval-config.*.json, dataset.jsonl, READMEs): EVAL_CONFIG_SAMPLES is a separate registry and, per its own contract, configs aren't owned by an agent — so the eval-config picker keeps working unchanged. Only agent.yml was removed from that directory.

Scope

Studio dropdown only. The NAT plugin example plugins/nemo-agents/examples/email-security-analyst/ (Octavian's code) is intentionally left in place — removing it is a broader NAT-deprecation decision (there are other NAT examples too) and warrants its own cross-team ticket, not a silent fold into this one.

Verification

  • loadSampleAgentConfig tests 7/7; dropdown now lists only the Fabric agent; eval-config picker assets all still resolve on disk.

Notes for review

Tickets

Resolves ASTD-407 (expanded from "add" to "replace" per the NAT-deprecation direction).

Adds the Fabric (nemo-agents-spec-v1) email-phishing agent as a canned example in
Studio's Create Example Agent modal, alongside the NAT email-security-analyst.

- New static asset public/sample-agents/email-phishing-agent/agent.yml: an
  independent copy of the plugin example's agent.yaml (source of truth) with a
  Studio-sample header. Body byte-identical, so the two stay diffable.
- New SAMPLE_AGENTS entry with configFormat: nemo-agents-spec-v1, so the create
  API validates it as Fabric and loadSampleAgentConfig injects the selected model
  at models.default.model (the existing Fabric branch — no loader change needed).
- Reworked the INVARIANT comment: it previously only covered NAT _type -> Python
  package deps; added the Fabric shape (mcp.servers.<n>.url console script must be
  on PATH — here email-phishing-iocs) and the hand-sync note for the copies.

Verified: loadSampleAgentConfig tests 7/7; the asset parses with config_format,
models.default.model, and the console-script MCP url the loader/deploy path need.

NOTE: the asset is a hand-maintained copy. #1222 (specialist sub-agents) changes
the plugin agent.yaml; this sample will need a one-line re-sync once that lands.

Pre-existing (NOT from this change): studio typecheck fails on
src/api/evaluation/agent-evaluations.ts (missing AggregateScalarScore in the
generated web SDK) — reproduces on pristine main; needs make update-web-sdk.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston
walston requested review from a team as code owners August 10, 2026 21:43
@github-actions github-actions Bot added the feat label Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a Studio Fabric sample agent for email-phishing analysis. The configuration defines DeepAgents delegation, IOC extraction through MCP, model and telemetry settings, and deployment metadata.

Changes

Email phishing agent

Layer / File(s) Summary
Agent workflow and verdict contract
web/packages/studio/public/sample-agents/email-phishing-agent/agent.yml
Defines the DeepAgents orchestrator, phishing-analysis subagent, phishing indicators, and YAML verdict schema.
Runtime and telemetry configuration
web/packages/studio/public/sample-agents/email-phishing-agent/agent.yml
Adds model defaults, the email-phishing-iocs MCP server, workspace and artifact paths, and relay telemetry exports.
Studio deployment registration
web/packages/studio/src/constants/sampleAgents.ts
Documents NAT and Fabric MCP requirements and registers the email_phishing_agent sample with its configuration path and format.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DeepAgentsOrchestrator
  participant PhishingAnalyzer
  participant EmailPhishingIOCs
  User->>DeepAgentsOrchestrator: Submit complete email
  DeepAgentsOrchestrator->>PhishingAnalyzer: Delegate phishing analysis
  PhishingAnalyzer->>EmailPhishingIOCs: Extract indicators when needed
  EmailPhishingIOCs-->>PhishingAnalyzer: Return extracted IOCs
  PhishingAnalyzer-->>DeepAgentsOrchestrator: Return YAML verdict
  DeepAgentsOrchestrator-->>User: Return subagent verdict
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: replacing the NAT sample agent with the Fabric agent in Studio's Create Example flow.
✨ 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 astd-407-studio-sample-entry/nwalston

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

NAT is being deprecated, so remove the NAT email-security-analyst sample from
Studio's Create Example Agent dropdown, leaving the Fabric email-phishing agent
(added in this PR) as the example.

- Remove the email_security_analyst SAMPLE_AGENTS entry + its INVARIANT _type lines.
- Delete its static agent.yml.
- KEEP the eval-config assets (eval-config.*.json, dataset.jsonl, READMEs): the
  eval-config picker (EVAL_CONFIG_SAMPLES) is a separate registry and, per its own
  contract, configs are not owned by an agent, so the picker keeps working. Only
  agent.yml is removed from that directory.

DEFAULT_SAMPLE_AGENT_KEY now resolves to email_phishing_agent (only entry).

Scope: Studio dropdown only. The NAT plugin example
(plugins/nemo-agents/examples/email-security-analyst/) is intentionally left in
place; removing it is a broader NAT-deprecation call for a separate, cross-team
ticket. loadSampleAgentConfig tests 7/7.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston walston changed the title feat(studio): add Fabric email-phishing agent to the Create-Example dropdown feat(studio): replace the NAT Email Security Analyst with the Fabric email-phishing agent in Create-Example Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 31999/40616 78.8% 63.5%
Integration Tests 18559/38542 48.1% 20.8%

@marcusds marcusds changed the title feat(studio): replace the NAT Email Security Analyst with the Fabric email-phishing agent in Create-Example feat(studio): replace the NAT with the Fabric in Create-Example Aug 11, 2026
@marcusds
marcusds enabled auto-merge August 11, 2026 04:53
@marcusds
marcusds added this pull request to the merge queue Aug 11, 2026
Merged via the queue into main with commit 4cfa993 Aug 11, 2026
55 of 56 checks passed
@marcusds
marcusds deleted the astd-407-studio-sample-entry/nwalston branch August 11, 2026 05:19
marcusds added a commit that referenced this pull request Aug 11, 2026
Every evaluation Studio submitted targeted the agent proxy's /generate, which
only NAT's FastAPI front end serves. A `nemo-agents-spec-v1` agent is served by
the Platform-owned Fabric server, which exposes /health, /v1/chat/completions
and DELETE /v1/sessions/{id} and nothing else, so the request 404s and the run
fails with nothing to show for it.

That is the format `nemo-build-agent` produces by default, and since #1223 it is
also what Studio's Create Example Agent produces — SAMPLE_AGENTS now holds a
single Fabric entry — so the documented way to build an agent yields one that
cannot be evaluated.

The target now posts OpenAI chat completions for every agent rather than
branching on config_format. Both formats serve that path: Fabric natively, and
NAT through its FastAPI front end, whose default workflow endpoint sets
openai_api_v1_path to /v1/chat/completions. No agent config in this repo
overrides general.front_end, and both launchers (`nat start fastapi` in the
subprocess and container backends) take those defaults. Studio's own chat
playground already relies on this, posting chat completions to every deployment
without regard to format.

Branching on the agent entity would have meant resolving it before submit, and
an unresolved or failed lookup would have to pick a wire format anyway —
defaulting to the one that 404s for the agents this fixes. One shape for both
formats removes the lookup, the fallback, and the race between them.

The generic agent target needed no evaluator or SDK change: it already takes a
URL, a Jinja body template and a JSONPath. render_template recurses through
dicts and lists, so `{{ instruction }}` substitutes inside the nested messages
entry, and _extract_jsonpath returns matches[0].value, so
$.choices[0].message.content resolves to the text.

DatasetEvalRowResultsPanel read the rendered prompt out of the request body at
`input_message`, a key the new body does not have; it would have silently fallen
back to dumping the raw dataset row. It now reads the last chat message and
keeps `input_message` as a fallback so jobs submitted before this still render.

Also drops AgentEvaluationsRoute/components/submitEvaluationSpec.ts, an
unreferenced second copy of the submission logic still building the /generate
target, and updates the route's AGENTS.md, which prescribed /generate as the
eval target.

ASTD-410

Signed-off-by: mschwab <mschwab@nvidia.com>
marcusds added a commit that referenced this pull request Aug 11, 2026
Every evaluation Studio submitted targeted the agent proxy's /generate, which
only NAT's FastAPI front end serves. A `nemo-agents-spec-v1` agent is served by
the Platform-owned Fabric server, which exposes /health, /v1/chat/completions
and DELETE /v1/sessions/{id} and nothing else, so the request 404s and the run
fails with nothing to show for it.

That is the format `nemo-build-agent` produces by default, and since #1223 it is
also what Studio's Create Example Agent produces — SAMPLE_AGENTS now holds a
single Fabric entry — so the documented way to build an agent yields one that
cannot be evaluated.

The target now posts OpenAI chat completions for every agent rather than
branching on config_format. Both formats serve that path: Fabric natively, and
NAT through its FastAPI front end, whose default workflow endpoint sets
openai_api_v1_path to /v1/chat/completions. No agent config in this repo
overrides general.front_end, and both launchers (`nat start fastapi` in the
subprocess and container backends) take those defaults. Studio's own chat
playground already relies on this, posting chat completions to every deployment
without regard to format.

Branching on the agent entity would have meant resolving it before submit, and
an unresolved or failed lookup would have to pick a wire format anyway —
defaulting to the one that 404s for the agents this fixes. One shape for both
formats removes the lookup, the fallback, and the race between them.

The generic agent target needed no evaluator or SDK change: it already takes a
URL, a Jinja body template and a JSONPath. render_template recurses through
dicts and lists, so `{{ instruction }}` substitutes inside the nested messages
entry, and _extract_jsonpath returns matches[0].value, so
$.choices[0].message.content resolves to the text.

DatasetEvalRowResultsPanel read the rendered prompt out of the request body at
`input_message`, a key the new body does not have; it would have silently fallen
back to dumping the raw dataset row. It now reads the last chat message and
keeps `input_message` as a fallback so jobs submitted before this still render.

Also drops AgentEvaluationsRoute/components/submitEvaluationSpec.ts, an
unreferenced second copy of the submission logic still building the /generate
target, and updates the route's AGENTS.md, which prescribed /generate as the
eval target.

ASTD-410

Signed-off-by: mschwab <mschwab@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants