Skip to content

feat(nemo-agents): add specialist subagents + rename to Email Security Triage - #1222

Merged
walston merged 4 commits into
mainfrom
astd-408-specialist-subagents/nwalston
Aug 11, 2026
Merged

feat(nemo-agents): add specialist subagents + rename to Email Security Triage#1222
walston merged 4 commits into
mainfrom
astd-408-specialist-subagents/nwalston

Conversation

@walston

@walston walston commented Aug 10, 2026

Copy link
Copy Markdown
Contributor
1222-stitched.mov

Summary

Two coherent changes to the Fabric email example (the second motivates the first):

  1. Specialist sub-agents — the orchestrator fans out to specialists before the verdict, so the analysis is a traced, tunable chain instead of one opaque classification.
  2. Rename email-phishing-agentemail-security-triage ("Email Security Triage") — with the specialists the example is broader than "phishing"; it's an email-security triage orchestrator.

1. Specialist sub-agents

Sub-agent Signal Notes
url-brand-analyst brand impersonation judges the domains extract_iocs harvested — tool → sub-agent composition in one trace
attack-attributor attack category (bec/credential/malware/spam/benign) every email
header-auth-analyst SPF/DKIM/DMARC gated on the email carrying Authentication-Results:/Received: headers

phishing-analyzer stays the verdict owner and folds the findings in (advisory — it can override or supply them); the verdict gains attack_type and impersonated_brand.

Prompts are ported from the email-security-analyst NAT example — co-authored with @nv-odrulea (they were removed from it in #1135 as more protocol than that sample needed). Here each is a declarative_subagent, so its reasoning gets its own trace span and its prompt is tunable in agent.yaml. Octavian's prompt-injection guardrails are ported with them.

analyze_headers is demo-only, on purpose: the scored dataset has no SMTP headers, and synthesizing them per row would leak the phishing/benign label into the input and inflate the eval. So the specialist is gated, the dataset stays header-free, and the README ships a header-bearing email to exercise it by hand.

2. Rename → Email Security Triage

Full identifier sweep, collision-checked against the still-present NAT email-security-analyst and email-phishing-analyzer:

  • example dir, agent name, telemetry project → email-security-triage
  • package nemo-agent-config-example-email-phishing…-email-security-triage
  • console script / MCP url email-phishing-iocsemail-security-triage-iocs (MCP key stays iocs; module stays mcps/iocs.py)
  • eval config → email-security-triage-eval.yml; default deployment name in the README
  • Studio registry key/namePrefix/displayName/agentConfigPath + sample dir; re-synced the Studio sample copy to this branch's (specialist) agent.yaml

Unchanged on purpose: the is_likely_phishing verdict schema, the phishing-analyzer sub-agent (it is the phishing specialist), and domain references to phishing.

Resolves ASTD-411 (rename); the earlier plan to do it as a post-merge capstone is superseded — folding it here avoids a rename that would conflict with this very PR.

Verification

  • Live, --mode subprocess, real key: createdeployinvoke under the new slug returns the correct schema (phishing true, incl. attack_type/impersonated_brand); the renamed console script resolves on PATH. 3/3 clean runs (phishing plain + header-bearing true, benign false) confirmed earlier; runtime checkpointer shows all four sub-agent tasks + the extract_iocs call.
  • AgentConfig validate + Fabric translate_agent_config; ruff; 8/8 tool tests; Studio loadSampleAgentConfig tests; zero rename stragglers.
  • Live-testing caught + fixed two prompt bugs (verdict paraphrasing; delegating without inlining the email → retry loop), and four CodeRabbit nits (brand casing, verdict-ownership wording, a self-contradictory synthetic header example, conditional-specialist trace claim).

Tickets

Resolves ASTD-408 (specialists) and ASTD-411 (rename). Docs updated: README gains the header-specialist step; CUSTOMIZE.md gains an "Adding or removing a specialist" section.

Summary by CodeRabbit

  • New Features

    • Added an Email Security Triage agent sample for phishing and authentication-threat analysis.
    • Supports IOC extraction and specialist analysis for brand impersonation, attack categories, SMTP authentication, and final verdicts.
    • Added Studio configuration and dataset evaluation support.
  • Documentation

    • Added deployment, invocation, tracing, evaluation, and customization guides.
    • Documented specialist outputs, security safeguards, and conditional header analysis.
  • Tests

    • Added coverage for URL, host, sender-domain, normalization, deduplication, and clean-input IOC extraction behavior.

@walston
walston requested review from a team as code owners August 10, 2026 21:30
@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

The email-phishing example is replaced by an email-security-triage agent. The configuration adds specialist subagents, strict verdict output, IOC dataset tooling, MCP wiring, evaluation support, telemetry, documentation, and Studio registration.

Changes

Email security triage

Layer / File(s) Summary
Orchestration and verdict contracts
plugins/nemo-agents/examples/nemo-agent-config/.../agent.yaml, web/packages/studio/public/sample-agents/email-security-triage/agent.yml
The orchestrator extracts IOCs, delegates specialist analysis, forwards full email context, and requires a six-key YAML verdict.
Specialist analysis subagents
plugins/nemo-agents/examples/nemo-agent-config/.../agent.yaml, web/packages/studio/public/sample-agents/email-security-triage/agent.yml
Brand, attack-category, and conditional SMTP-authentication specialists return constrained findings while treating email content as untrusted data.
Runtime wiring and evaluation
plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/..., pyproject.toml, web/packages/studio/src/constants/sampleAgents.ts
The workspace, MCP server, console script, model, telemetry, evaluation paths, dataset builder, IOC tests, and Studio registry use email-security-triage.
Deployment and customization guidance
plugins/nemo-agents/examples/nemo-agent-config/.../README.md, plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md, web/packages/studio/public/sample-agents/email-security-triage/agent.yml
Documentation covers deployment, specialist behavior, conditional header analysis, traces, evaluation, and customization.

Sequence Diagram(s)

sequenceDiagram
  participant Analyst as Email analyst
  participant Triage as Triage orchestrator
  participant MCP as IOC MCP server
  participant Specialists as Specialist subagents
  participant Verdict as phishing-analyzer

  Analyst->>Triage: Submit email
  Triage->>MCP: Extract URLs and domains
  MCP-->>Triage: Return IOCs
  Triage->>Specialists: Analyze brand, category, and eligible headers
  Specialists-->>Triage: Return specialist findings
  Triage->>Verdict: Submit email, IOCs, and findings
  Verdict-->>Triage: Return YAML verdict
Loading

Possibly related PRs

Suggested labels: docs, test

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes do not address the linked issue's required documentation links, installation guidance, log location, troubleshooting, or PyPI link fixes. Implement the five documentation fixes listed in issue #39, or link the PR to issues that cover the specialist-agent and example-renaming work.
Out of Scope Changes check ⚠️ Warning Most changes add specialist agents and rename the example, which are unrelated to the documentation fixes required by linked issue #39. Remove unrelated implementation and rename changes, or update the linked issues to explicitly cover the Email Security Triage scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the two main changes: adding specialist subagents and renaming the example to Email Security Triage.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch astd-408-specialist-subagents/nwalston

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: 4

🤖 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-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml`:
- Around line 99-105: Update the output schema in the phishing-analyzer prompt
to require a lowercase impersonated_brand value, changing the placeholder under
the existing YAML keys while preserving the “or none” option.

In
`@plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md`:
- Around line 38-41: Update the README description of the YAML verdict to
identify phishing-analyzer as the verdict owner. Describe attack_type and
impersonated_brand as specialist-informed fields that phishing-analyzer may
override or fill, rather than fields emitted directly by attack-attributor or
url-brand-analyst.
- Around line 53-54: Update the authentication-results example in the
email-phishing-agent README so the SPF interpretation is accurate: either make
the reported SPF, DKIM, and DMARC results consistent with a spoofed From domain,
or explicitly describe spf=fail smtp.mailfrom=evil.example as an envelope-sender
failure without claiming it proves From: paypal.com was spoofed.
- Around line 66-70: Update the trace description near the deployment artifact
and NeMo Studio Intake examples to state that tasks are recorded only for
applicable specialists; clarify that header-auth-analyst appears for emails
containing Authentication-Results: or Received: headers and is absent for the
Step 2 email.
🪄 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: 12ed3c03-3180-4465-9b66-a5754b271d1b

📥 Commits

Reviewing files that changed from the base of the PR and between 33cecaf and 5dbe0ee.

📒 Files selected for processing (3)
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/CUSTOMIZE.md
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml

Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml Outdated
Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md Outdated
Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md Outdated
Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md Outdated
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 32000/40622 78.8% 63.5%
Integration Tests 18552/38548 48.1% 20.8%

@walston

walston commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Naming note (not blocking this PR): with these specialist sub-agents (brand impersonation, attack attribution, SMTP header auth) the example reads as broader than "phishing" now — I'd like to rename it to "Email Security Triage" (email-phishing-agentemail-security-triage).

Deferring it deliberately as a post-merge capstone rather than folding it in here: a full identifier rename touches the merged base example (#1117), this PR, and the Studio PR (#1223) all at once, so it's cleanest as one sweep on main after #1222 + #1223 land — not as a scope-expanding churn on a focused, co-authored PR mid-review.

Locked manifest for whoever runs it later (slug email-security-triage — collision-checked against the existing email-security-analyst and email-phishing-analyzer):

  • dir email-phishing-agent/email-security-triage/
  • agent name + telemetry project → email-security-triage
  • package nemo-agent-config-example-email-phishing…-email-security-triage
  • console script email-phishing-iocsemail-security-triage-iocs (MCP key stays iocs; module stays mcps/iocs.py)
  • eval email-phishing-eval.ymlemail-security-triage-eval.yml
  • default deployment name → email-security-triage-deployment
  • Studio registry key/namePrefix/sample-dir → email_security_triage / email-security-triage
    • docs, tests, root pyproject member

@walston walston changed the title feat(nemo-agents): add specialist subagents to the email-phishing example feat(nemo-agents): add specialist subagents + rename to Email Security Triage Aug 11, 2026

@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: 1

🧹 Nitpick comments (1)
plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md (1)

16-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Keep CUSTOMIZE.md in one Diataxis quadrant.

This page mixes a customization HOW-TO with an architecture diagram, a configuration reference table, and contract rules. Move the reference material to a linked reference page, or keep this page procedural.

As per coding guidelines, each documentation page should fit one Diataxis quadrant and should not mix how-tos with architecture explanations or reference tables.

Also applies to: 36-61

🤖 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-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`
around lines 16 - 24, Refocus CUSTOMIZE.md as a procedural customization how-to
by removing the architecture explanations, configuration/reference table, and
contract rules. Move that material into an appropriate linked reference page,
then add links from CUSTOMIZE.md while preserving only the ordered steps needed
to customize the example. Apply this consistently to the sections covered by the
“Parts & what to change” table and the later referenced content.

Source: Coding guidelines

🤖 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-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`:
- Around line 3-4: Update the goal statement in CUSTOMIZE.md to explicitly name
both delegated roles: the verdict sub-agent and the specialist sub-agents.
Preserve the existing description of the DeepAgents orchestrator and its tool
usage while replacing the generic “a sub-agent” wording.

---

Nitpick comments:
In
`@plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`:
- Around line 16-24: Refocus CUSTOMIZE.md as a procedural customization how-to
by removing the architecture explanations, configuration/reference table, and
contract rules. Move that material into an appropriate linked reference page,
then add links from CUSTOMIZE.md while preserving only the ordered steps needed
to customize the example. Apply this consistently to the sections covered by the
“Parts & what to change” table and the later referenced content.
🪄 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: f640b104-3ae1-44a8-bb4d-620c002a3ff5

📥 Commits

Reviewing files that changed from the base of the PR and between 5dba780 and 463d214.

⛔ Files ignored due to path filters (2)
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/data/smaller_test.csv is excluded by !**/*.csv
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/data/build_dataset.py
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/email-security-triage-eval.yml
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/mcps/iocs.py
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/pyproject.toml
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/tests/test_extract_iocs.py
  • pyproject.toml
  • web/packages/studio/public/sample-agents/email-security-triage/agent.yml
  • web/packages/studio/src/constants/sampleAgents.ts

Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md Outdated
walston and others added 3 commits August 11, 2026 11:15
…mple

The orchestrator now fans out to specialist subagents before the verdict, so the
analysis is a traced, tunable chain instead of one opaque classification:

- url-brand-analyst   - lookalike / brand-impersonation judgement on the domains
                        extract_iocs harvested (tool -> subagent composition)
- attack-attributor   - names the attack category (bec/credential/malware/spam/benign)
- header-auth-analyst - SPF/DKIM/DMARC reading, gated on the email actually
                        carrying Authentication-Results:/Received: headers

phishing-analyzer stays the verdict owner and folds the findings in, adding
`attack_type` and `impersonated_brand` to the YAML verdict.

Prompts are ported from the email-security-analyst NAT example (they were removed
from it in #1135 as more protocol than that sample needed). There they were LLM
capability tools behind a router; here each is a declarative subagent, so its
reasoning gets its own trace span and its prompt is tunable in agent.yaml. The
prompt-injection guardrails are ported with them.

analyze_headers is demo-only: the scored dataset has no SMTP headers, and
synthesizing them per row would leak the phishing/benign label into the input and
inflate the eval. README shows a header-bearing email to exercise it by hand.

Verified live (--mode subprocess, real NVIDIA_API_KEY): 3/3 invocations return the
correct schema - phishing (plain + header-bearing) true, benign false - with
attack_type and impersonated_brand populated. The runtime checkpointer shows all
four subagent tasks plus the extract_iocs tool call. AgentConfig validate +
Fabric translate OK; ruff clean; 8/8 tool tests.

Co-authored-by: Octavian Drulea <odrulea@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
- agent.yaml: require lowercase impersonated_brand in the phishing-analyzer
  verdict schema too (the orchestrator copy was already lowercase; the sub-agent
  copy wasn't - that mismatch is why live output flip-flopped PayPal vs paypal).
- README Step 2: phishing-analyzer owns the verdict and emits every field; the
  attack_type/impersonated_brand values are specialist-informed (advisory), not
  produced by the specialists instead of the classifier.
- README Step 3: fix a self-contradictory synthetic header example - it had
  spf=fail but dkim=pass/dmarc=pass, which actually authenticates From: paypal.com.
  Make all three fail and lead the explanation with dmarc=fail on header.from,
  the check tied to the visible From: domain.
- README Step 4: traces carry a task per *applicable* specialist; header-auth-analyst
  appears only for header-bearing input (the Step 2 email has none).

Co-authored-by: Octavian Drulea <odrulea@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…ecurity-triage

With the specialist sub-agents this example is broader than "phishing" — it's an
email-security triage orchestrator — so rename it to match (display name
"Email Security Triage", slug `email-security-triage`). Folded into this PR because
the specialists are the reason for the rename.

Full identifier sweep (collision-checked vs the still-present NAT
`email-security-analyst` and `email-phishing-analyzer`):
- example dir, agent `name`, telemetry project
- package `nemo-agent-config-example-email-phishing` -> `...-email-security-triage`
- console script / MCP url `email-phishing-iocs` -> `email-security-triage-iocs`
  (MCP server key stays `iocs`; module stays `mcps/iocs.py`)
- eval config `email-phishing-eval.yml` -> `email-security-triage-eval.yml`
- default deployment name in the README
- Studio registry key/namePrefix/displayName/agentConfigPath + sample dir
- README/CUSTOMIZE branding; re-synced the Studio sample copy to this branch's
  (specialist) agent.yaml

Unchanged on purpose: the `is_likely_phishing` verdict schema, the
`phishing-analyzer` sub-agent (it IS the phishing specialist), and domain
references to phishing.

Verified: AgentConfig validate + Fabric translate; ruff; 8/8 tool tests; Studio
loader tests; zero stragglers; and live create -> deploy -> invoke under the new
slug returns is_likely_phishing: true (renamed console script resolves).

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston
walston force-pushed the astd-408-specialist-subagents/nwalston branch from 463d214 to 875ec7a Compare August 11, 2026 19:54

@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: 1

🧹 Nitpick comments (1)
plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md (1)

11-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep CUSTOMIZE.md as a HOW-TO.

This section mixes an architecture explanation with a path reference table. Move that content to linked EXPLANATION or REFERENCE pages, or rewrite it as steps for the customization task.

As per coding guidelines, each documentation page must use one Diátaxis quadrant.

🤖 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-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`
around lines 11 - 25, Rewrite the “Parts & what to change” section in
CUSTOMIZE.md as task-oriented customization steps, removing the architecture
overview and path-reference table from this HOW-TO page. Link to separate
explanation or reference documentation for those details if it exists, while
keeping the page focused on the sequence of changes needed to customize the
example.

Source: Coding guidelines

🤖 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-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`:
- Line 7: Expand the prerequisites section in CUSTOMIZE.md to list the concrete
setup, deployment, invocation, and required access requirements for the
email-security-triage example. Add tested usage examples for both the Python SDK
and CLI, presented in the repository’s standard tab-set format, while preserving
the existing README reference.

---

Nitpick comments:
In
`@plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md`:
- Around line 11-25: Rewrite the “Parts & what to change” section in
CUSTOMIZE.md as task-oriented customization steps, removing the architecture
overview and path-reference table from this HOW-TO page. Link to separate
explanation or reference documentation for those details if it exists, while
keeping the page focused on the sequence of changes needed to customize the
example.
🪄 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: fbf7381e-5635-47f5-8bd2-08a5645b80eb

📥 Commits

Reviewing files that changed from the base of the PR and between 463d214 and 875ec7a.

📒 Files selected for processing (1)
  • plugins/nemo-agents/examples/nemo-agent-config/email-security-triage/CUSTOMIZE.md

@walston
walston added this pull request to the merge queue Aug 11, 2026
Merged via the queue into main with commit 2ad0f9b Aug 11, 2026
59 checks passed
@walston
walston deleted the astd-408-specialist-subagents/nwalston branch August 11, 2026 20:59
ryana pushed a commit to ryana/nemo-platform that referenced this pull request Aug 12, 2026
…IA-NeMo#1223)

* feat(studio): add Fabric email-phishing agent to Create-Example dropdown

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. NVIDIA-NeMo#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>

* feat(studio): drop the NAT email-security-analyst from Create-Example

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>

---------

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Co-authored-by: Marcus <marcusds@users.noreply.github.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.

3 participants