From 661c4ff205004e279a883fb3aea9ac8980e77d0b Mon Sep 17 00:00:00 2001 From: Swarom Muley Date: Thu, 8 Oct 2026 10:08:31 -0700 Subject: [PATCH 1/2] fix(packaging): remove Insights Git dependencies from PyPI metadata Signed-off-by: Swarom Muley --- packages/nemo_helix/pyproject.toml | 2 - plugins/nemo-insights/README.md | 17 +++++++ plugins/nemo-insights/pyproject.toml | 2 - pyproject.toml | 12 +++-- .../sdk/vendor/test_wrapper_entry_points.py | 9 ++++ uv.lock | 48 +++++++++++-------- 6 files changed, 61 insertions(+), 29 deletions(-) diff --git a/packages/nemo_helix/pyproject.toml b/packages/nemo_helix/pyproject.toml index 463e38a1351..728996dcd11 100644 --- a/packages/nemo_helix/pyproject.toml +++ b/packages/nemo_helix/pyproject.toml @@ -467,7 +467,6 @@ nemo-helix-sdk = [ nemo-insights-plugin = [ "fastapi>=0.115", "httpx", - "insight-agent @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137", "nemo-fabric-adapter-contract>=0.3.0,<0.4.0", "nemo-fabric-adapters-common>=0.3.0,<0.4.0", "nemo-helix-plugin", @@ -477,7 +476,6 @@ nemo-insights-plugin = [ "opentelemetry-sdk>=1.42.1", "pydantic>=2.12.0", "pyyaml>=6.0.3", - "trace-ingest @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137#subdirectory=packages/trace-ingest", "typer>=0.20.0", "tzdata==2026.2", ] diff --git a/plugins/nemo-insights/README.md b/plugins/nemo-insights/README.md index f2503478ecb..8fd4ef8eade 100644 --- a/plugins/nemo-insights/README.md +++ b/plugins/nemo-insights/README.md @@ -23,6 +23,23 @@ uv sync The plugin is installed by default through the root workspace's `enabled-plugins` group. +## Install analyst dependencies for PyPI installations + +PyPI does not accept Git dependencies in wheel metadata, so `nemo-helix[all]` +does not install `insight-agent` and `trace-ingest`. For a `uv tool install` +installation, include both when installing Helix before running Insights analysis: + +```bash +uv tool install --force \ + --with "insight-agent @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137" \ + --with "trace-ingest @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137#subdirectory=packages/trace-ingest" \ + "nemo-helix[all]" +``` + +For a virtual environment, install the same two requirements with `uv pip install` +in the environment that runs the analyst. Source checkouts and the platform images +install these pinned dependencies through the workspace's `insights` group. + ## CLI Submit analysis through NeMo Helix. Replace `` with the name diff --git a/plugins/nemo-insights/pyproject.toml b/plugins/nemo-insights/pyproject.toml index bd7bd31cad1..241c1c9a40c 100644 --- a/plugins/nemo-insights/pyproject.toml +++ b/plugins/nemo-insights/pyproject.toml @@ -9,7 +9,6 @@ requires-python = ">=3.12,<3.15" dependencies = [ "fastapi>=0.115", "httpx", - "insight-agent @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137", "nemo-fabric-adapter-contract>=0.3.0,<0.4.0", "nemo-fabric-adapters-common>=0.3.0,<0.4.0", "nemo-helix", @@ -20,7 +19,6 @@ dependencies = [ "opentelemetry-sdk>=1.42.1", "pydantic>=2.12.0", "pyyaml>=6.0.3", - "trace-ingest @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137#subdirectory=packages/trace-ingest", "typer>=0.20.0", "tzdata==2026.2", ] diff --git a/pyproject.toml b/pyproject.toml index d0132a70fb7..e00bf700ec6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,8 +68,12 @@ dependencies = [ version = "0.0.0" [dependency-groups] -# Insights analyst plugin convenience group. -insights = ["nemo-insights-plugin"] +# Keep Git-only analyst dependencies out of published wheel metadata. +insights = [ + "nemo-insights-plugin", + "insight-agent @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137", + "trace-ingest @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137#subdirectory=packages/trace-ingest", +] typecheck = ["transformers>=5.5.0,<5.9.0"] # The scaled-evals plugin is opt-in: it is a path dependency rather than a workspace # member, so neither `enabled-plugins` nor `uv sync --all-packages` installs it. It needs @@ -184,7 +188,7 @@ enabled-plugins = [ "nemo-anonymizer-plugin", "nemo-data-designer-plugin[retrieval-sdg]", "nemo-evaluator-plugin", - "nemo-insights-plugin", + { include-group = "insights" }, "nemo-guardrails-plugin", "nemo-auditor-plugin", "nemo-safe-synthesizer-plugin", @@ -251,7 +255,7 @@ cpu-tasks = [ # managed CPU task environment. Hermes requires a separate execution image. "nemo-agents-plugin[all]", # Insights Analyst Fabric adapter and insights.analysis execute extension. - "nemo-insights-plugin", + { include-group = "insights" }, "nemo-evaluator-plugin", "nemo-sandboxed-gym[server,opensandbox]", "nemo-anonymizer-plugin", diff --git a/tools/nemo-helix-sdk-tools/tests/sdk/vendor/test_wrapper_entry_points.py b/tools/nemo-helix-sdk-tools/tests/sdk/vendor/test_wrapper_entry_points.py index 128905de703..82cdd75ab22 100644 --- a/tools/nemo-helix-sdk-tools/tests/sdk/vendor/test_wrapper_entry_points.py +++ b/tools/nemo-helix-sdk-tools/tests/sdk/vendor/test_wrapper_entry_points.py @@ -16,6 +16,7 @@ import pytest import tomlkit +from packaging.requirements import Requirement REPO_ROOT = Path(__file__).resolve().parents[5] WRAPPER_PYPROJECT = REPO_ROOT / "packages" / "nemo_helix" / "pyproject.toml" @@ -35,6 +36,14 @@ def _load(path: Path) -> dict: return tomlkit.parse(path.read_text(encoding="utf-8")).unwrap() +def test_wrapper_dependencies_have_no_direct_urls() -> None: + project = _load(WRAPPER_PYPROJECT)["project"] + dependency_groups = [project.get("dependencies", []), *project.get("optional-dependencies", {}).values()] + for dependencies in dependency_groups: + for dependency in dependencies: + assert Requirement(dependency).url is None, f"PyPI rejects direct dependency: {dependency}" + + def _source_pyproject(source: Path) -> Path: for candidate in [source, *source.parents]: pyproject = candidate / "pyproject.toml" diff --git a/uv.lock b/uv.lock index acc53c7d896..e0945bd24c3 100644 --- a/uv.lock +++ b/uv.lock @@ -4978,7 +4978,6 @@ all = [ { name = "gunicorn", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "hvac", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "jinja2", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "jsonschema", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "kubernetes", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5051,7 +5050,6 @@ all = [ { name = "sqlmodel", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "streaming-form-data", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tenacity", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "types-aioboto3", extra = ["s3"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tzdata", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5513,7 +5511,6 @@ nemo-helix-sdk = [ nemo-insights-plugin = [ { name = "fastapi", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-fabric-adapter-contract", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-fabric-adapters-common", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-helix-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5523,7 +5520,6 @@ nemo-insights-plugin = [ { name = "opentelemetry-sdk", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "pydantic", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "pyyaml", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tzdata", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] @@ -5634,7 +5630,6 @@ plugins = [ { name = "garak-api", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "gunicorn", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "jinja2", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "langchain", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "langchain-aws", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5684,7 +5679,6 @@ plugins = [ { name = "pyyaml", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "requests", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "rich", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tzdata", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "uvicorn", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5732,7 +5726,6 @@ services = [ { name = "gunicorn", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "hvac", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "jinja2", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "jsonschema", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "kubernetes", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -5805,7 +5798,6 @@ services = [ { name = "sqlmodel", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "streaming-form-data", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tenacity", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "types-aioboto3", extra = ["s3"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tzdata", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -6058,10 +6050,6 @@ requires-dist = [ { name = "hvac", marker = "extra == 'jobs-service'", specifier = ">=2.3.0" }, { name = "hvac", marker = "extra == 'nhx-common'", specifier = ">=2.3.0" }, { name = "hvac", marker = "extra == 'services'", specifier = ">=2.3.0" }, - { name = "insight-agent", marker = "extra == 'all'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "insight-agent", marker = "extra == 'nemo-insights-plugin'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "insight-agent", marker = "extra == 'plugins'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "insight-agent", marker = "extra == 'services'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "jinja2", marker = "extra == 'all'", specifier = ">=3.1" }, { name = "jinja2", marker = "extra == 'harbor'", specifier = ">=3.1.6" }, { name = "jinja2", marker = "extra == 'nemo-agents-plugin'", specifier = ">=3.1" }, @@ -6650,10 +6638,6 @@ requires-dist = [ { name = "tenacity", marker = "extra == 'rl-service'", specifier = ">=8.5.0" }, { name = "tenacity", marker = "extra == 'services'", specifier = ">=8.5.0" }, { name = "tenacity", marker = "extra == 'unsloth-service'", specifier = ">=8.5.0" }, - { name = "trace-ingest", marker = "extra == 'all'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "trace-ingest", marker = "extra == 'nemo-insights-plugin'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "trace-ingest", marker = "extra == 'plugins'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, - { name = "trace-ingest", marker = "extra == 'services'", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "typer", marker = "extra == 'all'", specifier = ">=0.9.0" }, { name = "typer", marker = "extra == 'all'", specifier = ">=0.12.5" }, { name = "typer", marker = "extra == 'all'", specifier = ">=0.20.0" }, @@ -7074,7 +7058,6 @@ source = { editable = "plugins/nemo-insights" } dependencies = [ { name = "fastapi", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-fabric-adapter-contract", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-fabric-adapters-common", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-helix", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7085,7 +7068,6 @@ dependencies = [ { name = "opentelemetry-sdk", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "pydantic", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "pyyaml", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, - { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "tzdata", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] @@ -7094,7 +7076,6 @@ dependencies = [ requires-dist = [ { name = "fastapi", specifier = ">=0.115" }, { name = "httpx" }, - { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-fabric-adapter-contract", specifier = ">=0.3.0,<0.4.0" }, { name = "nemo-fabric-adapters-common", specifier = ">=0.3.0,<0.4.0" }, { name = "nemo-helix", editable = "packages/nemo_helix" }, @@ -7105,7 +7086,6 @@ requires-dist = [ { name = "opentelemetry-sdk", specifier = ">=1.42.1" }, { name = "pydantic", specifier = ">=2.12.0" }, { name = "pyyaml", specifier = ">=6.0.3" }, - { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "typer", specifier = ">=0.20.0" }, { name = "tzdata", specifier = "==2026.2" }, ] @@ -7583,6 +7563,7 @@ dependencies = [ [package.dev-dependencies] agents-deepagents-e2e-services = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agents-plugin", extra = ["deepagents"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7614,8 +7595,10 @@ agents-deepagents-e2e-services = [ { name = "nhx-platform-seed", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-secrets", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-studio", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] core-services = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7642,8 +7625,10 @@ core-services = [ { name = "nhx-models", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-platform", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-secrets", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] cpu-tasks = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agent-optimization-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agents-plugin", extra = ["all"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7657,6 +7642,7 @@ cpu-tasks = [ { name = "nhx-common", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-hello-world", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-platform", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] dev = [ { name = "aiohttp", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7722,6 +7708,7 @@ dev = [ { name = "typer", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] enabled-plugins = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7737,8 +7724,10 @@ enabled-plugins = [ { name = "nemo-safe-synthesizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-switchyard-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-unsloth-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] functional-services = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7770,6 +7759,7 @@ functional-services = [ { name = "nhx-platform-seed", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-secrets", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nhx-studio", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] gpu-tasks = [ { name = "nemo-helix", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7779,7 +7769,9 @@ gpu-tasks = [ { name = "nhx-platform", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] insights = [ + { name = "insight-agent", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, { name = "nemo-insights-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "trace-ingest", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] nhx-base = [ { name = "nemo-helix", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, @@ -7840,6 +7832,7 @@ requires-dist = [ [package.metadata.requires-dev] agents-deepagents-e2e-services = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, { name = "nemo-agents-plugin", extras = ["deepagents"], editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, @@ -7874,8 +7867,10 @@ agents-deepagents-e2e-services = [ { name = "nhx-platform-seed", editable = "services/platform-seed" }, { name = "nhx-secrets", editable = "services/core/secrets" }, { name = "nhx-studio", editable = "services/studio" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, ] core-services = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, @@ -7903,8 +7898,10 @@ core-services = [ { name = "nhx-models", editable = "services/core/models" }, { name = "nhx-platform", editable = "packages/nhx_platform" }, { name = "nhx-secrets", editable = "services/core/secrets" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, ] cpu-tasks = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-agent-optimization-plugin", editable = "plugins/nemo-agent-optimization" }, { name = "nemo-agents-plugin", extras = ["all"], editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, @@ -7918,6 +7915,7 @@ cpu-tasks = [ { name = "nhx-common", editable = "packages/nhx_common" }, { name = "nhx-hello-world", editable = "services/hello-world" }, { name = "nhx-platform", editable = "packages/nhx_platform" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, ] dev = [ { name = "aiohttp", specifier = ">=3.14.1" }, @@ -7985,6 +7983,7 @@ dev = [ { name = "typer", specifier = ">=0.9.0" }, ] enabled-plugins = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, @@ -8000,8 +7999,10 @@ enabled-plugins = [ { name = "nemo-safe-synthesizer-plugin", editable = "plugins/nemo-safe-synthesizer" }, { name = "nemo-switchyard-plugin", editable = "plugins/nemo-switchyard" }, { name = "nemo-unsloth-plugin", editable = "plugins/nemo-unsloth" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, ] functional-services = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, @@ -8035,6 +8036,7 @@ functional-services = [ { name = "nhx-platform-seed", editable = "services/platform-seed" }, { name = "nhx-secrets", editable = "services/core/secrets" }, { name = "nhx-studio", editable = "services/studio" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, ] gpu-tasks = [ { name = "nemo-helix", editable = "packages/nemo_helix" }, @@ -8043,7 +8045,11 @@ gpu-tasks = [ { name = "nhx-models", editable = "services/core/models" }, { name = "nhx-platform", editable = "packages/nhx_platform" }, ] -insights = [{ name = "nemo-insights-plugin", editable = "plugins/nemo-insights" }] +insights = [ + { name = "insight-agent", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, + { name = "nemo-insights-plugin", editable = "plugins/nemo-insights" }, + { name = "trace-ingest", git = "https://github.com/NVIDIA-NeMo/labs-trace-intel.git?subdirectory=packages%2Ftrace-ingest&rev=cd639d223e06ee9d27783df6b461d302ceb09137" }, +] nhx-base = [ { name = "nemo-helix", editable = "packages/nemo_helix" }, { name = "nemo-helix-plugin", editable = "packages/nemo_helix_plugin" }, From 05d0e405088bf9ca5d46ea07c48b8cd47945346d Mon Sep 17 00:00:00 2001 From: Swarom Muley Date: Thu, 8 Oct 2026 10:27:51 -0700 Subject: [PATCH 2/2] fix(insights): explain missing analyst runtime dependencies Signed-off-by: Swarom Muley --- plugins/nemo-insights/README.md | 14 ++++- .../src/nemo_insights_plugin/analyst/run.py | 16 +++++- .../nemo-insights/tests/test_analyst_run.py | 56 ++++++++++++++++++- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/plugins/nemo-insights/README.md b/plugins/nemo-insights/README.md index 8fd4ef8eade..e13b5ebb3d8 100644 --- a/plugins/nemo-insights/README.md +++ b/plugins/nemo-insights/README.md @@ -36,9 +36,17 @@ uv tool install --force \ "nemo-helix[all]" ``` -For a virtual environment, install the same two requirements with `uv pip install` -in the environment that runs the analyst. Source checkouts and the platform images -install these pinned dependencies through the workspace's `insights` group. +For a virtual environment, install both pinned requirements in the environment +that runs the analyst: + +```bash +uv pip install \ + "insight-agent @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137" \ + "trace-ingest @ git+https://github.com/NVIDIA-NeMo/labs-trace-intel.git@cd639d223e06ee9d27783df6b461d302ceb09137#subdirectory=packages/trace-ingest" +``` + +Source checkouts and the platform images install these pinned dependencies through +the workspace's `insights` group. ## CLI diff --git a/plugins/nemo-insights/src/nemo_insights_plugin/analyst/run.py b/plugins/nemo-insights/src/nemo_insights_plugin/analyst/run.py index 2e9c8df554a..dc9afe15cdf 100644 --- a/plugins/nemo-insights/src/nemo_insights_plugin/analyst/run.py +++ b/plugins/nemo-insights/src/nemo_insights_plugin/analyst/run.py @@ -23,8 +23,6 @@ setup_analyst_observability, ) from nemo_insights_plugin.analyst.result import AnalystResult -from nemo_insights_plugin.analyst.trace_intel import analyze_snapshot, load_existing_insights -from nemo_insights_plugin.analyst.trace_snapshot import load_trace_snapshot from nooa.context_blocks import EventBase from nooa.events import LLMComplete, PythonOutput @@ -123,6 +121,20 @@ async def run_analyst_change_set( instrumenting it. ``None`` runs uninstrumented. Independent of *enable_observability*, which is the older direct-to-Intake path. """ + try: + from nemo_insights_plugin.analyst.trace_intel import analyze_snapshot, load_existing_insights + from nemo_insights_plugin.analyst.trace_snapshot import load_trace_snapshot + except ModuleNotFoundError as exc: + if exc.name not in {"insight_agent", "trace_ingest"}: + raise + raise RuntimeError( + "The Insights analyst requires the separately installed insight-agent and trace-ingest packages. " + "Install the pinned dependencies in the environment running the analyst. " + "For uv tool and virtual-environment installation commands, see " + "https://github.com/NVIDIA-NeMo/nemo-helix/blob/release/0.7/plugins/nemo-insights/README.md" + "#install-analyst-dependencies-for-pypi-installations" + ) from exc + observability = None model_clients: ConfiguredModelClients | None = None insights_output_path = str(insights_output) if insights_output else None diff --git a/plugins/nemo-insights/tests/test_analyst_run.py b/plugins/nemo-insights/tests/test_analyst_run.py index 079bec658f8..eef9eec6125 100644 --- a/plugins/nemo-insights/tests/test_analyst_run.py +++ b/plugins/nemo-insights/tests/test_analyst_run.py @@ -3,12 +3,15 @@ """The ``run_analyst`` client injection contract.""" +import subprocess +import sys from typing import Any, cast import pytest from nemo_helix_plugin.client.client import AsyncNemoClient from nemo_helix_plugin.nooa_model_client import ConfiguredModelClients from nemo_insights_plugin.analyst import run as run_module +from nemo_insights_plugin.analyst import trace_intel, trace_snapshot from nemo_insights_plugin.analyst.observability import AnalystEvaluationContext from nooa.context_blocks import ResultStatus from nooa.events import LLMComplete, PythonOutput @@ -82,9 +85,9 @@ async def fake_load_snapshot(*args: object, **kwargs: object) -> object: seen["snapshot_kwargs"] = kwargs return object() - monkeypatch.setattr(run_module, "analyze_snapshot", fake_analyze_snapshot) - monkeypatch.setattr(run_module, "load_existing_insights", fake_load_existing) - monkeypatch.setattr(run_module, "load_trace_snapshot", fake_load_snapshot) + monkeypatch.setattr(trace_intel, "analyze_snapshot", fake_analyze_snapshot) + monkeypatch.setattr(trace_intel, "load_existing_insights", fake_load_existing) + monkeypatch.setattr(trace_snapshot, "load_trace_snapshot", fake_load_snapshot) class Observability: def shutdown(self) -> None: @@ -93,6 +96,53 @@ def shutdown(self) -> None: monkeypatch.setattr(run_module, "setup_analyst_observability", lambda **_kwargs: Observability()) +@pytest.mark.parametrize("missing_dependency", ["insight_agent", "trace_ingest", "unexpected_dependency"]) +def test_missing_analyst_dependencies(missing_dependency: str) -> None: + # A fresh process exercises adapter imports without cached analyst dependencies. + script = """ +import asyncio +import importlib.abc +import sys +from unittest.mock import AsyncMock + +missing = sys.argv[1] +blocked = "insight_agent" if missing == "unexpected_dependency" else missing + +class BlockDependency(importlib.abc.MetaPathFinder): + def find_spec(self, fullname, path=None, target=None): + if fullname.split(".")[0] == blocked: + raise ModuleNotFoundError(f"No module named '{missing}'", name=missing) + +sys.meta_path.insert(0, BlockDependency()) +from nemo_insights_plugin import fabric_adapter +from nemo_insights_plugin.analyst.run import run_analyst + +async def check(): + client = AsyncMock() + expected = ModuleNotFoundError if missing == "unexpected_dependency" else RuntimeError + try: + await run_analyst(agent="agent", ethos=None, workspace="default", base_url=None, client=client) + except expected as error: + if missing == "unexpected_dependency": + assert error.name == missing + else: + assert error.__cause__.name == missing + message = str(error) + for text in ("insight-agent", "trace-ingest", "uv tool", "virtual-environment", + "#install-analyst-dependencies-for-pypi-installations"): + assert text in message + else: + raise AssertionError("Missing dependency did not fail analyst execution") + client.close.assert_awaited_once() + +asyncio.run(check()) +""" + result = subprocess.run( + [sys.executable, "-c", script, missing_dependency], capture_output=True, text=True, timeout=30 + ) + assert result.returncode == 0, result.stdout + result.stderr + + async def test_injected_client_is_used_and_closed(monkeypatch: pytest.MonkeyPatch) -> None: client = FakeClient() seen: dict[str, object] = {}