Skip to content

feat(nemo-agents): add Fabric (spec-v1) email-phishing example - #1117

Merged
walston merged 9 commits into
mainfrom
astd-370-372-fabric-phishing-example/nwalston
Aug 10, 2026
Merged

feat(nemo-agents): add Fabric (spec-v1) email-phishing example#1117
walston merged 9 commits into
mainfrom
astd-370-372-fabric-phishing-example/nwalston

Conversation

@walston

@walston walston commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
demo.mov

Summary

Ports the email-phishing analyzer to a Platform-native nemo-agents-spec-v1 example at
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/ (alongside the
calculator-agent sibling — that directory is where spec-v1 / Fabric examples live; the
top level holds NAT examples).

The NAT example proxy-passes classification to an opaque MCP server — beyond the reach of
trace views, prompt/hyperparameter tuning, and evaluation. This example restructures it as a
deepagents orchestrator that delegates the verdict to a phishing sub-agent and calls a
deterministic extract_iocs MCP tool. The prompt and model live in agent.yaml (tunable),
and the sub-agent task + tool call each emit a trace span. The proxy-pass classifier becomes a
Platform-visible, tunable, evaluable step.

Changes

  • agent.yaml — deepagents orchestrator + a declarative_subagent (phishing-analyzer)
    with its own system_prompt and a YAML verdict
    (is_likely_phishing/confidence/indicators/explanation) the top-level model parses;
    extract_iocs wired as a harness_native stdio MCP server; relay ATIF → Intake telemetry.
  • extract_iocs MCP tool — pure-regex URL/domain extraction (ported from
    email-security-analyst), served over stdio by the email-phishing-iocs console script
    (flat mcps/ package, matching calculator-agent); unit-tested, incl. malformed-URL guard.
  • Sender-inclusive inputdata/build_dataset.py assembles an email column
    (From:/Subject:/body) so the sender (a top phishing tell, and an extract_iocs input)
    reaches the model; the NAT eval fed body only. Eval config uses question_key: email.
    Guards against blank senders and duplicate id_key subjects.
  • DocsREADME.md is a single-quadrant Diataxis tutorial (deploy → invoke → observe →
    evaluate); CUSTOMIZE.md is the how-to for swapping in your own agent.
  • Registered as a uv workspace member so the console script resolves.

Verification

  • Live end-to-end against a running Platform (--mode subprocess, real NVIDIA_API_KEY,
    model nvidia-nemotron-3-nano-30b-a3b): createdeployinvoke returns a correct
    verdict (is_likely_phishing: true, confidence: 0.96), catching the typo-squatted
    paypa1-secure.example sender domain.
  • Architecture confirmed from runtime evidence, not inference: the adapter event graph plus
    the LangGraph checkpointer show orchestrator → phishing-analyzer sub-agent → extract_iocs
    tool call (with its urls/domains result), routed through the Inference Gateway.
  • Traces visible in Studio. Requires Fabric ≥ 0.2.0 for deepagents to emit ATIF (Fabric-team
    release, FABRIC-181) plus the Intake fix in fix(intake): accept ATIF observation on all step types #1189 (merged). main is currently pinned to
    Fabric 0.1.1, so the trace beat lights up once that release lands — the example itself needs
    no change.
  • agent.yaml validates against AgentConfig (nemo-agents-spec-v1, extra="forbid") and
    translates to a typed Fabric config; extract_iocs tests 8/8; ruff / ty clean.

Not exercised: container (--mode docker/k8s) packaging, the Studio Create-Example tile
(ASTD-407), and eval judge weights/prompt (starters — tune per the evaluator plugin). The README
scopes itself to the live-validated path and links the rest.

Tickets

Resolves ASTD-370 (restructure to a tunable/traceable sub-agent), ASTD-371 (sender in the
analyzed input), and ASTD-372 (author the spec-v1 agent.yaml).
Follow-ups filed: ASTD-407 (Studio Create-Example entry), ASTD-408 (specialist sub-agents),
ASTD-409 (mock-mailbox MCP). Trace wiring tracked in ASTD-385.

@walston
walston requested review from a team as code owners August 5, 2026 22:59
@github-actions github-actions Bot added the feat label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Fabric email-phishing agent example with DeepAgents orchestration, MCP-based IOC extraction, dataset generation, evaluation settings, tests, documentation, packaging, and workspace registration.

Changes

Email phishing Fabric example

Layer / File(s) Summary
Analysis orchestration and MCP wiring
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml, plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/mcps/iocs.py, plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/pyproject.toml
Defines the phishing-analysis workflow, deterministic IOC extraction, stdio MCP exposure, model settings, telemetry, workspace paths, and console entry point.
Deterministic IOC extraction and validation
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/tests/test_extract_iocs.py
Tests URL and domain extraction, normalization, punctuation handling, sender domains, deduplication, ordering, and empty inputs.
Dataset evaluation and example documentation
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/data/build_dataset.py, plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/email-phishing-eval.yml, plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md, pyproject.toml
Builds sender-inclusive email records, configures judge-based evaluation, documents deployment and validation, and adds the example to the uv workspace.

Sequence Diagram(s)

sequenceDiagram
  participant DatasetBuilder
  participant DeepAgentsOrchestrator
  participant PhishingAnalyzer
  participant IOCMCP
  participant Evaluator
  DatasetBuilder->>DeepAgentsOrchestrator: assembled email
  DeepAgentsOrchestrator->>PhishingAnalyzer: analysis request
  PhishingAnalyzer->>IOCMCP: extract_iocs(text)
  IOCMCP-->>PhishingAnalyzer: URLs and domains
  PhishingAnalyzer-->>DeepAgentsOrchestrator: YAML verdict
  DeepAgentsOrchestrator-->>Evaluator: generated verdict
  Evaluator->>Evaluator: compare verdict with label
Loading

Possibly related PRs

Suggested reviewers: yamini, tylersbray

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% 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
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 and concisely summarizes the addition of the Fabric spec-v1 email-phishing example.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch astd-370-372-fabric-phishing-example/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: 5

🤖 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/email-phishing-fabric/data/build_dataset.py`:
- Around line 42-47: Update assemble_email to validate the trimmed sender value
and raise an error when the sender is missing or blank, before constructing or
writing the message. Preserve the existing subject and body handling while
ensuring invalid rows cannot be reported as successfully processed.

In `@plugins/nemo-agents/examples/email-phishing-fabric/email-phishing-eval.yml`:
- Line 34: Update dataset generation in build_dataset.py to validate that every
subject used by id_key is unique, failing generation when duplicates are
detected; alternatively, configure id_key to use an existing stable unique
identifier instead of subject. Ensure the configured id_key and generated
dataset preserve uniqueness.

In `@plugins/nemo-agents/examples/email-phishing-fabric/README.md`:
- Around line 12-16: Update the diagram code fence in the README to specify the
text language, changing the untyped fence around the orchestrator diagram to a
text fence while leaving its contents unchanged.
- Around line 1-3: Update the README with a Prerequisites section before the
description, listing uv, the nemo CLI, Platform access, the deepagents adapter,
NVIDIA_API_KEY, and the evaluation model variable; add a Next Steps section
after Status with links for dataset generation, evaluation, and deployment
guidance.
- Around line 57-59: Update the README’s multiline --input example for
email-phishing-fabric-deployment to use Bash ANSI-C quoting with $'...', so each
\n sequence becomes an actual newline before the CLI receives the input.
🪄 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: c80b94c1-1896-4dcf-bea9-5f3bf0d54fe0

📥 Commits

Reviewing files that changed from the base of the PR and between 96cb643 and 6415d38.

⛔ Files ignored due to path filters (2)
  • plugins/nemo-agents/examples/email-phishing-fabric/data/smaller_test.csv is excluded by !**/*.csv
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • plugins/nemo-agents/examples/email-phishing-fabric/README.md
  • plugins/nemo-agents/examples/email-phishing-fabric/agent.yaml
  • plugins/nemo-agents/examples/email-phishing-fabric/data/build_dataset.py
  • plugins/nemo-agents/examples/email-phishing-fabric/email-phishing-eval.yml
  • plugins/nemo-agents/examples/email-phishing-fabric/pyproject.toml
  • plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/iocs.py
  • plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/mcp_server.py
  • plugins/nemo-agents/examples/email-phishing-fabric/tests/test_extract_iocs.py
  • pyproject.toml

Comment thread plugins/nemo-agents/examples/email-phishing-fabric/README.md Outdated
Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md Outdated
Comment thread plugins/nemo-agents/examples/email-phishing-fabric/README.md Outdated

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

🧹 Nitpick comments (1)
plugins/nemo-agents/examples/email-phishing-fabric/README.md (1)

42-48: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Keep this page in one Diátaxis quadrant.

Shape and Tune explain architecture. Run is a how-to. Move the architecture content to an explanation page, or keep this README as one how-to with cross-links.

As per coding guidelines, each documentation page must fit 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/email-phishing-fabric/README.md` around lines 42
- 48, Move the architecture-oriented prose in the README’s Run section out of
this how-to page and keep this page focused only on running the example. Update
the section around extract_iocs so it no longer explains the deepagents adapter,
command resolution, or deployment-mode behavior, and instead cross-link that
material to the appropriate explanation page while preserving the run
instructions here.

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/email-phishing-fabric/README.md`:
- Around line 57-93: The README’s usage documentation must provide parallel CLI
and Python SDK workflows in tabbed local and container alternatives. Update the
local and container sections around the shown `nemo agents` commands to use the
project’s tab-set documentation convention, adding equivalent Python SDK
examples for each variant while preserving the existing CLI commands and
deployment details.
- Around line 50-66: Update the local CLI instructions before the `nemo agents
create` commands to direct users to follow `SETUP.md`, set
`NMP_BASE_URL=http://localhost:8080`, verify Platform readiness, and run
commands via `uv run nemo` or an activated `.venv`. Apply the same setup and
invocation guidance to the additional local command blocks, ensuring the MCP
console script is available on PATH.

---

Nitpick comments:
In `@plugins/nemo-agents/examples/email-phishing-fabric/README.md`:
- Around line 42-48: Move the architecture-oriented prose in the README’s Run
section out of this how-to page and keep this page focused only on running the
example. Update the section around extract_iocs so it no longer explains the
deepagents adapter, command resolution, or deployment-mode behavior, and instead
cross-link that material to the appropriate explanation page while preserving
the run instructions here.
🪄 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: 98592611-ae81-48b8-b795-d33728b112f2

📥 Commits

Reviewing files that changed from the base of the PR and between 6415d38 and 216b003.

📒 Files selected for processing (2)
  • plugins/nemo-agents/examples/email-phishing-fabric/README.md
  • plugins/nemo-agents/examples/email-phishing-fabric/agent.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/nemo-agents/examples/email-phishing-fabric/agent.yaml

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
@walston

walston commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Live-validated --mode subprocess on a running platform (real NVIDIA_API_KEY): create → deploy → invoke returns a correct YAML verdict (is_likely_phishing: true, 0.96, catches the typo-squatted sender domain). Adapter event graph + LangGraph checkpointer confirm the orchestrator delegates to the phishing-analyzer subagent and extract_iocs is actually called (checkpointer holds extract_iocs + its {urls, domains} output), routed through IGW. Container (docker/k8s) package path and Studio path still to validate.

@walston
walston force-pushed the astd-370-372-fabric-phishing-example/nwalston branch from 216b003 to f6f054b Compare August 6, 2026 16:07
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

🤖 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/email-phishing-fabric/README.md`:
- Around line 68-109: Update the README’s Status section to state that the
subprocess path, subagent delegation, and extract_iocs were live-validated,
while Docker/Kubernetes packaging remains unvalidated. Clearly label the
container deployment commands under the Container section as unvalidated, unless
those workflows are actually tested before publishing.

In
`@plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/iocs.py`:
- Around line 27-29: Update the URL extraction logic using _URL_RE and urlsplit
to catch ValueError from malformed candidates, including fullwidth-slash cases,
so untrusted content cannot fail the tool. Require a non-empty hostname before
adding either the URL or its domain, and add a regression test covering the
malformed candidate.
🪄 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: 4532af6e-33a8-4f66-b9f3-160c4121913d

📥 Commits

Reviewing files that changed from the base of the PR and between c71ca67 and f6f054b.

⛔ Files ignored due to path filters (2)
  • plugins/nemo-agents/examples/email-phishing-fabric/data/smaller_test.csv is excluded by !**/*.csv
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • plugins/nemo-agents/examples/email-phishing-fabric/README.md
  • plugins/nemo-agents/examples/email-phishing-fabric/agent.yaml
  • plugins/nemo-agents/examples/email-phishing-fabric/data/build_dataset.py
  • plugins/nemo-agents/examples/email-phishing-fabric/email-phishing-eval.yml
  • plugins/nemo-agents/examples/email-phishing-fabric/pyproject.toml
  • plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/iocs.py
  • plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/mcp_server.py
  • plugins/nemo-agents/examples/email-phishing-fabric/tests/test_extract_iocs.py
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (6)
  • pyproject.toml
  • plugins/nemo-agents/examples/email-phishing-fabric/email-phishing-eval.yml
  • plugins/nemo-agents/examples/email-phishing-fabric/data/build_dataset.py
  • plugins/nemo-agents/examples/email-phishing-fabric/agent.yaml
  • plugins/nemo-agents/examples/email-phishing-fabric/pyproject.toml
  • plugins/nemo-agents/examples/email-phishing-fabric/src/email_phishing_fabric/mcp_server.py

Comment thread plugins/nemo-agents/examples/email-phishing-fabric/README.md Outdated
@walston

walston commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Relocated the example to plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/ (was top-level email-phishing-fabric). That dir is where spec-v1/Fabric examples live (sibling: calculator-agent); top level is NAT. Adopted sibling conventions: flat mcps/ package, console email-phishing-iocs, agent email-phishing-agent, ATOF telemetry. Re-verified: AgentConfig validate + Fabric translate, ty/ruff clean, extract_iocs 8/8, and mcps.iocs/mcps.calculator coexist as namespace packages.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/mcps/iocs.py (1)

38-57: ⚠️ Potential issue | 🟠 Major

Handle malformed URL candidates before calling urlsplit.

The URL regex accepts candidates such as https://exa/mple.com. urlsplit() raises ValueError for this input, so one crafted email can make the MCP tool fail. Catch ValueError around parsing and hostname access, skip candidates without a hostname, and add a regression test.

Proposed fix
-        parsed = urlsplit(url)
-        hostname = parsed.hostname
+        try:
+            parsed = urlsplit(url)
+            hostname = parsed.hostname
+        except ValueError:
+            continue
+        if not hostname:
+            continue

This repeats the unresolved malformed-URL finding from the previous review.

#!/bin/bash
set -euo pipefail

target="plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/mcps/iocs.py"
tests="plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/tests/test_extract_iocs.py"

rg -n -C 6 'urlsplit|_URL_RE|hostname|def extract_iocs' "$target"
rg -n -i 'malformed|fullwidth|ValueError|exa' "$tests" || true

uv run python - <<'PY'
from urllib.parse import urlsplit

try:
    urlsplit("https://exa/mple.com")
except ValueError:
    pass
else:
    raise SystemExit("expected ValueError")
PY
🤖 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-phishing-agent/mcps/iocs.py`
around lines 38 - 57, Update extract_iocs so each URL candidate is parsed with
urlsplit inside ValueError handling, skipping malformed candidates and any
result without a hostname while preserving valid URL and domain extraction. Add
a regression test in test_extract_iocs.py covering a candidate such as
https://exa/mple.com and confirming the tool does not fail.
🧹 Nitpick comments (2)
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml (1)

69-79: 🩺 Stability & Availability | 🔵 Trivial

Verify the MCP command in packaged deployments.

agent.yaml resolves email-phishing-iocs from PATH. The reported validation covers subprocess mode, but it does not prove that Docker or Kubernetes images install the console script and preserve the MCP handshake. Run a packaged smoke test that invokes extract_iocs.

Based on the PR objectives, Docker/Kubernetes packaging remains unvalidated.

🤖 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-phishing-agent/agent.yaml`
around lines 69 - 79, Add a packaged-deployment smoke test for the MCP server
configured by the iocs entry in agent.yaml, covering Docker or Kubernetes
packaging rather than only subprocess mode. Build/package the image, verify the
email-phishing-iocs console script is available on PATH, and invoke extract_iocs
through the stdio MCP handshake to confirm the tool works end to end.
plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md (1)

1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Keep the README within one Diataxis quadrant.

The page combines architecture explanation, tuning reference, and how-to instructions. Choose one primary quadrant, move other material to linked pages, add Prerequisites before the overview, and add Next Steps after Status.

As per coding guidelines, each documentation page must use one Diataxis quadrant, list prerequisites at the top, and include Next Steps at the end.

Also applies to: 35-41, 109-117

🤖 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-phishing-agent/README.md`
around lines 1 - 3, Refocus the README on a single Diataxis quadrant, moving
architecture and tuning reference material to linked documentation pages while
retaining only the chosen page type’s content. Add a Prerequisites section
before the overview, and add a Next Steps section after Status with links to the
relocated material or follow-up guidance.

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-phishing-agent/email-phishing-eval.yml`:
- Around line 5-7: Update the commented evaluation command to use the active
email-phishing-agent example path and agent name instead of
email-phishing-fabric, and rename the associated output directory from the stale
identifier to email-phishing-agent to keep generated artifacts consistent.

---

Outside diff comments:
In
`@plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/mcps/iocs.py`:
- Around line 38-57: Update extract_iocs so each URL candidate is parsed with
urlsplit inside ValueError handling, skipping malformed candidates and any
result without a hostname while preserving valid URL and domain extraction. Add
a regression test in test_extract_iocs.py covering a candidate such as
https://exa/mple.com and confirming the tool does not fail.

---

Nitpick comments:
In
`@plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml`:
- Around line 69-79: Add a packaged-deployment smoke test for the MCP server
configured by the iocs entry in agent.yaml, covering Docker or Kubernetes
packaging rather than only subprocess mode. Build/package the image, verify the
email-phishing-iocs console script is available on PATH, and invoke extract_iocs
through the stdio MCP handshake to confirm the tool works end to end.

In
`@plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md`:
- Around line 1-3: Refocus the README on a single Diataxis quadrant, moving
architecture and tuning reference material to linked documentation pages while
retaining only the chosen page type’s content. Add a Prerequisites section
before the overview, and add a Next Steps section after Status with links to the
relocated material or follow-up guidance.
🪄 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: 184d58cd-1942-4a96-b45a-32592020baeb

📥 Commits

Reviewing files that changed from the base of the PR and between f6f054b and 0ea8c8c.

⛔ Files ignored due to path filters (2)
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/data/smaller_test.csv is excluded by !**/*.csv
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/data/build_dataset.py
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/email-phishing-eval.yml
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/mcps/iocs.py
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/pyproject.toml
  • plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/tests/test_extract_iocs.py
  • pyproject.toml

@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/README.md`:
- Around line 51-53: Add a “Next Steps” section immediately after the Status
section in the email-phishing-agent README, including cross-links to the related
registration, evaluation, and trace-inspection documentation. Ensure this
section is the final content on the page.
- Around line 31-33: Move the “Prereqs” line from the “Use it in Platform (CLI)”
section to directly after the README introduction, before all other
documentation sections, while preserving its existing prerequisite details.
- Around line 12-30: Keep this README focused on a single Diataxis documentation
type by retaining either the component reference or the porting guidance, not
both. Move the other section to a dedicated documentation page and add a clear
cross-link between the pages, preserving the existing details and examples.
- Around line 36-39: Validate the documented Docker/Kubernetes deployment,
Studio workflow, and evaluation-judge tuning steps in the email-phishing-agent
README before presenting them as supported usage. If they cannot be tested, move
the affected instructions near the untested-workflows note into an explicitly
marked draft or unverified section, including the blocks around Deploy, Tune &
evaluate, and the corresponding Studio/evaluation steps.
🪄 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: 363bb4a3-9503-4d28-b7ca-2140db67067e

📥 Commits

Reviewing files that changed from the base of the PR and between 0ea8c8c and 4c28abc.

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

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
Comment thread plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/README.md Outdated
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 32005/40616 78.8% 63.6%
Integration Tests 18555/38542 48.1% 20.8%

@walston
walston marked this pull request as draft August 7, 2026 19:28
@walston
walston marked this pull request as ready for review August 7, 2026 23:01
Port the email-phishing analyzer to a Platform-native nemo-agents-spec-v1
agent: a deepagents orchestrator that delegates classification to a phishing
subagent and calls a deterministic extract_iocs MCP tool. The prompt and
model live in agent.yaml (tunable) and each step emits a trace span, replacing
the opaque MCP-proxy classifier.

- extract_iocs ported as a stdio MCP console tool (pure regex, unit-tested)
- sender-inclusive input: assembled From:/Subject:/body 'email' column so the
  sender (a top phishing tell) reaches the model and extract_iocs
- eval config uses question_key: email
- registered as a workspace member so its package resolves

ASTD-370, ASTD-371, ASTD-372

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
The extract_iocs stdio MCP tool is a console script that Fabric launches as a
parallel child process, resolving the command on PATH. The runtime that must
contain it differs by deploy mode:

- subprocess (default): runs locally from the repo .venv (sys.executable,
  inherits PATH); the example is a workspace member so uv sync --all-packages
  already provides the console script — no image needed.
- docker/k8s: the container lacks the package; bake it in with
  nemo agents package --pyproject (uv pip install .), then deploy --mode
  docker/k8s --image (--publish --registry for k8s).

Replaces the misleading local 'uv pip install + bare deploy' instruction and
the agent.yaml comment. Addresses review P1 (deployed agent could not start
its MCP server under container modes).

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…nt-config/

Move the Fabric (spec-v1) email-phishing example from the top-level examples
dir into nemo-agent-config/email-phishing-agent/, alongside calculator-agent —
that directory is where nemo-agents-spec-v1 (Fabric) examples live; the
top-level dir holds NAT examples. Adopt the sibling's conventions:

- flat mcps/ package (mcps.iocs) instead of src/ layout; extract_iocs util +
  FastMCP server combined; console script email-phishing-iocs
- package nemo-agent-config-example-email-phishing; mcp>=1.28.1,<2
- agent renamed email-phishing-agent; mcp url email-phishing-iocs (default
  harness_native exposure); ATOF telemetry like the sibling
- build_dataset.py source path fixed for the new depth

Addresses review: the -fabric suffix was redundant and the example was
misfiled at the top level.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Parts table, port-it steps, and mirrored Platform-CLI / Studio usage sections
(same five beats: register, deploy, invoke, observe, tune & evaluate). Studio
create/deploy beats marked pending the gallery tile (ASTD-08).

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Lead with a Parts table that pairs each file with what to change, an explicit
cross-file 'keep in sync' note (console name; workspace member), and a compact
mirrored Platform/Studio run to validate the swap.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…torial

Single-quadrant tutorial (prerequisites-first, numbered steps with expected
outcomes, Next Steps) mirroring the calculator-agent sibling; plain markdown
(these example READMEs render on GitHub, not Sphinx, so no MyST tab-sets). Move
the 'swap it for your own' how-to into CUSTOMIZE.md, cross-linked from Next
Steps. Addresses CodeRabbit Diataxis/prereqs/next-steps/fence/quoting findings.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
- iocs.py: guard urlsplit() against unparseable netlocs
- build_dataset.py: reject blank sender; fail on duplicate subjects (id_key)
- email-phishing-eval.yml: replace stale email-phishing-fabric identifiers

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…g-agent

WIP toward ASTD-385. Adds an atif http-storage sink pointing at the local
Intake ingest endpoint, alongside the existing atof file sink. Note: this does
not yet produce Intake spans for the in-process DeepAgents harness (only local
ATOF is emitted today); tracked in ASTD-385. Endpoint is hardcoded to the local
Intake (127.0.0.1:8080), matching the sibling agent-relay-intake.yaml.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston
walston force-pushed the astd-370-372-fabric-phishing-example/nwalston branch from 3aeb1b8 to 854ca84 Compare August 10, 2026 20:27
CodeQL flagged three `"host" in result["domains"]` assertions as *Incomplete URL
substring sanitization*. They are list-membership checks, not sanitization —
`extract_iocs` returns sorted lists — but CodeQL cannot infer the dict value type.

Assert exact list equality instead, matching the other tests in this file. The
assertions get stronger (order + full contents) and the flagged pattern is gone.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston
walston added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit 33cecaf Aug 10, 2026
54 checks passed
@walston
walston deleted the astd-370-372-fabric-phishing-example/nwalston branch August 10, 2026 21:12
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