diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ce60915d51..54b1c7f622 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -839,6 +839,49 @@ jobs: coverage.json coverage-html/ + fabric-wheel-smoke: + name: Fabric wheel install smoke (Linux) + needs: [changes] + if: > + !cancelled() && + needs.changes.outputs.deps == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + # This job installs and imports third-party wheels; don't leave GITHUB_TOKEN in .git/config. + persist-credentials: false + - name: Install uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + with: + python-version: "3.11" + enable-cache: true + cache-dependency-glob: uv.lock + # Installs the published nemo-fabric wheels (+ codex/claude/deepagents adapters) from the lock. + # Linux is where jobs actually execute the runtime, and it validates that the manylinux + # nemo-fabric-runtime wheel installs on the runner's glibc. + - name: Install nemo-evaluator-sdk[fabric] from the lock + run: uv sync --frozen --package nemo-evaluator-sdk --extra fabric + # Import the Fabric SDK surface that agent_eval/runtimes/fabric/runtime.py depends on, so the + # published package is exercised for real instead of only via the hermetic fake-nemo_fabric tests. + - name: Import the Fabric SDK surface the runtime uses + run: | + uv run --frozen --no-sync python - <<'PY' + import nemo_fabric + from nemo_fabric import ( + EnvironmentConfig, + Fabric, + FabricConfig, + FabricProfileConfig, + RunRequest, + RunResult, + ) + print("nemo_fabric import OK:", nemo_fabric.__file__) + PY + python-integration-test: name: Python integration tests needs: [policy-wasm] @@ -1772,6 +1815,7 @@ jobs: - policy-wasm - python-unit-test-tools - python-unit-test + - fabric-wheel-smoke # Enable if you want this required # - python-integration-test - require-nvskills diff --git a/packages/nemo_evaluator_sdk/pyproject.toml b/packages/nemo_evaluator_sdk/pyproject.toml index 4bcff065d2..a61ce36a83 100644 --- a/packages/nemo_evaluator_sdk/pyproject.toml +++ b/packages/nemo_evaluator_sdk/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "ragas==0.4.3", "langchain-openai>=1.3.5", "langchain-nvidia-ai-endpoints>=1.4.3,<2.0.0", - "nemo-relay>=0.4.0,<0.5.0", + "nemo-relay>=0.5.0,<0.7", ] version = "0.0.0" @@ -54,6 +54,21 @@ harbor = [ nemo-platform = [ "nemo-platform-sdk", ] +# NeMo Fabric agent-eval runtime (FabricAgentRuntime / FabricContainerRuntime). Installs the +# published Fabric SDK + adapters instead of a source build. Notes: +# * The native `nemo-fabric-runtime` wheel (which provides the `nemo_fabric` module) ships +# manylinux *and* macOS arm64 as of 0.1.0rc2, so the extra resolves on every environment in +# [tool.uv] environments and needs no platform marker. macOS-native dev can still use +# script/dev-install-fabric.sh to build Fabric from source; that script also cargo-installs the +# `nemo-relay` gateway binary (not published to PyPI) needed for live ATIF trajectory capture. +# * Fabric has not cut a final 0.1.0 yet, so the explicit prerelease in the specifier scopes uv's +# prerelease allowance to just this package (workspace prerelease = "if-necessary-or-explicit"). +# * The `hermes` extra is intentionally omitted: hermes-agent pins `requests==2.33.0` exactly, +# which conflicts with the workspace's `requests>=2.33.1` floor (root pyproject.toml). Re-add it +# once hermes-agent loosens that pin. (hermes is Python<3.14-gated upstream regardless.) +fabric = [ + "nemo-fabric[claude,codex,deepagents,runtime]>=0.1.0rc2", +] [build-system] requires = ["hatchling"] diff --git a/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/_common.py b/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/_common.py index 4ed7e12e24..82b695aad3 100644 --- a/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/_common.py +++ b/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/_common.py @@ -23,7 +23,13 @@ from nemo_evaluator_sdk.agent_eval.tasks import AgentEvalTask from nemo_evaluator_sdk.agent_eval.trials import AgentEvalTrial, AgentEvalTrialStatus from nemo_evaluator_sdk.values.evidence import CandidateEvidence, EvidenceDescriptor -from nemo_relay.observability import AtifConfig, AtofConfig, ComponentSpec, ObservabilityConfig +from nemo_relay.observability import ( + AtifConfig, + AtofConfig, + AtofFileSinkConfig, + ComponentSpec, + ObservabilityConfig, +) # Trajectory profile identity + the file-exporter output names we choose (Relay accepts these as # inputs). Shared so both runtimes select/emit the trajectory under identical names. @@ -122,11 +128,17 @@ def trajectory_telemetry(*, relay_dir: str, agent_name: str, agent_version: str) agent_name=agent_name, agent_version=agent_version, ), + # nemo-relay 0.6 moved ATOF's destination out of AtofConfig and into a list of typed + # sinks; the file sink carries the fields the flat 0.5 config used to hold directly. atof=AtofConfig( enabled=True, - output_directory=relay_dir, - filename=ATOF_FILENAME, - mode="overwrite", + sinks=[ + AtofFileSinkConfig( + output_directory=relay_dir, + filename=ATOF_FILENAME, + mode="overwrite", + ) + ], ), ) ) diff --git a/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py b/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py index 47d31788b0..59e15cddc4 100644 --- a/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py +++ b/packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py @@ -559,6 +559,7 @@ def _relay_config(self, relay_dir: Path) -> dict[str, Any]: from nemo_relay.observability import ( # ty: ignore[unresolved-import] AtifConfig, AtofConfig, + AtofFileSinkConfig, ComponentSpec, ObservabilityConfig, ) @@ -575,11 +576,17 @@ def _relay_config(self, relay_dir: Path) -> dict[str, Any]: agent_name=self._runtime_name, agent_version="fabric", ), + # nemo-relay 0.6 moved ATOF's destination out of AtofConfig and into a list of typed + # sinks; the file sink carries the fields the flat 0.5 config used to hold directly. atof=AtofConfig( enabled=True, - output_directory=relay_dir_str, - filename=_ATOF_FILENAME, - mode="overwrite", + sinks=[ + AtofFileSinkConfig( + output_directory=relay_dir_str, + filename=_ATOF_FILENAME, + mode="overwrite", + ) + ], ), ) ) diff --git a/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_container_runtime.py b/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_container_runtime.py index a20d0e31d6..13ab68eab4 100644 --- a/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_container_runtime.py +++ b/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_container_runtime.py @@ -320,10 +320,14 @@ def test_trajectory_profile_built_from_relay_types() -> None: component = FabricContainerRuntime._trajectory_profile()["telemetry"]["config"]["components"][0] assert component["kind"] == "observability" and component["enabled"] is True cfg = component["config"] - # The ATIF/ATOF file exporter is configured with the names both runtimes agree on. + # The ATIF/ATOF file exporter is configured with the names both runtimes agree on. Since + # nemo-relay 0.6 the ATOF destination lives in a typed sink list rather than flat on the config. assert cfg["atif"]["enabled"] is True assert cfg["atif"]["filename_template"] == crt._common.ATIF_FILENAME_TEMPLATE - assert cfg["atof"]["filename"] == crt._common.ATOF_FILENAME + assert cfg["atof"]["enabled"] is True + (atof_sink,) = cfg["atof"]["sinks"] + assert atof_sink["type"] == "file" + assert atof_sink["filename"] == crt._common.ATOF_FILENAME async def test_sandbox_exception_is_isolated_per_task(tmp_path: Path) -> None: diff --git a/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py b/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py index 34b77e94fb..5d6508188b 100644 --- a/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py +++ b/packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py @@ -101,7 +101,14 @@ def __init__(self, **kwargs: Any) -> None: self.kwargs = kwargs def to_dict(self) -> dict[str, Any]: - return {key: (value.to_dict() if hasattr(value, "to_dict") else value) for key, value in self.kwargs.items()} + return {key: _unwrap(value) for key, value in self.kwargs.items()} + + +def _unwrap(value: Any) -> Any: + """Recursively render a fake relay config value, including inside sink lists.""" + if isinstance(value, list): + return [_unwrap(item) for item in value] + return value.to_dict() if hasattr(value, "to_dict") else value class _FakeComponentSpec: @@ -244,6 +251,7 @@ def plan(self, agent: Any, *, profiles: Any = None, base_dir: Any = None) -> _Fa observability_mod = types.ModuleType("nemo_relay.observability") observability_mod.AtifConfig = _FakeRelayConfig # type: ignore[attr-defined] observability_mod.AtofConfig = _FakeRelayConfig # type: ignore[attr-defined] + observability_mod.AtofFileSinkConfig = _FakeRelayConfig # type: ignore[attr-defined] observability_mod.ObservabilityConfig = _FakeRelayConfig # type: ignore[attr-defined] observability_mod.ComponentSpec = _FakeComponentSpec # type: ignore[attr-defined] relay_mod.observability = observability_mod # type: ignore[attr-defined] diff --git a/packages/nemo_platform/pyproject.toml b/packages/nemo_platform/pyproject.toml index fd7944b7e7..7321e64617 100644 --- a/packages/nemo_platform/pyproject.toml +++ b/packages/nemo_platform/pyproject.toml @@ -295,7 +295,7 @@ nemo-evaluator-sdk = [ "ragas==0.4.3", "langchain-openai>=1.3.5", "langchain-nvidia-ai-endpoints>=1.4.3,<2.0.0", - "nemo-relay>=0.4.0,<0.5.0", + "nemo-relay>=0.5.0,<0.7", ] # Generated from [tool.bundle-package]; do not edit by hand. diff --git a/script/dev-install-fabric.sh b/script/dev-install-fabric.sh index 6c966fc324..29d5f7405d 100755 --- a/script/dev-install-fabric.sh +++ b/script/dev-install-fabric.sh @@ -4,20 +4,30 @@ # # Dev-only: set up the local dependencies the Fabric eval runner needs so the type checker and a # live FabricAgentRuntime run work end-to-end: -# 1. the native `nemo-fabric` SDK (with the codex + relay extras) into the project venv, and -# 2. the `nemo-relay` gateway binary (required for ATIF trajectory capture on the codex harness). +# 1. the native `nemo-fabric` SDK (with the codex + relay + runtime extras) into the project venv, and +# 2. the `nemo-relay` gateway binary (required for ATIF trajectory capture on out-of-process +# harnesses like codex). # This is an imperative install — it does NOT touch uv.lock, and CI intentionally runs without it # (the `# ty: ignore[unresolved-import]` in agent_eval/runtimes/fabric/runtime.py covers the CI case). # -# nemo-fabric and the nemo-relay gateway are private/native builds with no published wheel/binary in -# our index, so they can't be locked dependencies yet (see -# plugins/nemo-evaluator/docs/design/fabric-runner-integration.md, Tier 3). A live codex run also -# needs the `codex` CLI + `codex login` auth. +# You no longer need this script just to get the SDK: `nemo-fabric` publishes wheels to PyPI +# (manylinux + macOS arm64 as of 0.1.0rc2) and is a locked `fabric` extra on nemo-evaluator-sdk — +# install it with `uv sync --extra fabric` (or `uv pip install "nemo-evaluator-sdk[fabric]"`). +# This script remains the path for (a) running against an unreleased NeMo-Fabric checkout, (b) Intel +# macOS, where no nemo-fabric-runtime wheel is published, and (c) the relay gateway binary below. +# +# The `nemo-relay` gateway is NOT on PyPI (the pip `nemo-relay` package ships only the Python +# bindings, not the daemon), but NeMo-Relay publishes prebuilt gateway binaries on its GitHub +# releases (macOS arm64 + static-musl Linux). We download one directly — no NeMo-Relay checkout or +# Rust build needed. A live codex run also needs the `codex` CLI + `codex login` auth. +# See plugins/nemo-evaluator/docs/design/fabric-runner-integration.md. # # Usage: -# script/dev-install-fabric.sh # NeMo-Fabric+NeMo-Relay under $HOME/workspace -# NEMO_FABRIC_REPO=... NEMO_RELAY_REPO=... script/dev-install-fabric.sh -# script/dev-install-fabric.sh --uninstall # restore the CI-equivalent (no nemo-fabric) state +# script/dev-install-fabric.sh # SDK from checkout + downloaded gateway +# NEMO_FABRIC_REPO=/path/to/NeMo-Fabric script/dev-install-fabric.sh +# NEMO_RELAY_VERSION=0.6.0-rc.2 script/dev-install-fabric.sh # pin a different gateway release +# NEMO_RELAY_REPO=/path/to/NeMo-Relay script/dev-install-fabric.sh # force a source build instead +# script/dev-install-fabric.sh --uninstall # restore the CI-equivalent state set -euo pipefail VENV_PY=".venv/bin/python" @@ -27,14 +37,19 @@ if [ ! -x "$VENV_PY" ]; then fi if [ "${1:-}" = "--uninstall" ]; then - uv pip uninstall --python "$VENV_PY" nemo-fabric + # Remove the runtime (which provides the importable `nemo_fabric`) + adapters, not just the + # metapackage, so `import nemo_fabric` fails again and the venv matches the CI/lock state. + uv pip uninstall --python "$VENV_PY" \ + nemo-fabric nemo-fabric-runtime nemo-fabric-adapters-codex nemo-fabric-adapters-common echo "Removed nemo-fabric; venv is back to the lock-consistent / CI-equivalent state." - echo "(The nemo-relay gateway binary, if installed, is left in place — remove it from ~/.cargo/bin manually if desired.)" + echo "(The nemo-relay gateway binary, if installed, is left in place — remove ~/.cargo/bin/nemo-relay manually if desired.)" exit 0 fi -# nemo-fabric builds a Rust/pyo3 extension via maturin and the relay gateway is a Rust CLI, so cargo -# must be on PATH. +# This script always installs the SDK from a NeMo-Fabric checkout, and the `runtime` extra builds +# nemo-fabric-runtime (a Rust/pyo3 extension) from source via maturin, so cargo must be on PATH. The +# relay gateway is downloaded prebuilt below and does NOT need cargo unless a source build is forced +# via NEMO_RELAY_REPO. if ! command -v cargo >/dev/null 2>&1 && [ -f "$HOME/.cargo/env" ]; then # shellcheck disable=SC1091 . "$HOME/.cargo/env" @@ -44,32 +59,86 @@ if ! command -v cargo >/dev/null 2>&1; then exit 1 fi -# 1. nemo-fabric SDK (+ codex and relay extras) into the project venv. +# 1. nemo-fabric SDK into the project venv. The `runtime` extra provides the importable `nemo_fabric` +# module (built from source here); `codex`+`relay` add the codex adapter + ATIF trajectory deps. FABRIC_REPO="${NEMO_FABRIC_REPO:-$HOME/workspace/NeMo-Fabric}" if [ ! -d "$FABRIC_REPO" ]; then echo "NeMo-Fabric checkout not found at: $FABRIC_REPO" >&2 echo "Clone it (gh repo clone NVIDIA/NeMo-Fabric) or set NEMO_FABRIC_REPO=/path/to/NeMo-Fabric." >&2 exit 1 fi -echo "Building + installing nemo-fabric[codex,relay] from $FABRIC_REPO into $VENV_PY ..." -uv pip install --python "$VENV_PY" "${FABRIC_REPO}[codex,relay]" +echo "Building + installing nemo-fabric[codex,relay,runtime] from $FABRIC_REPO into $VENV_PY ..." +uv pip install --python "$VENV_PY" "${FABRIC_REPO}[codex,relay,runtime]" "$VENV_PY" -c "import nemo_fabric; from nemo_fabric import Fabric, RunResult; print('nemo_fabric OK:', nemo_fabric.__file__)" -# 2. nemo-relay gateway binary (codex -> OTLP -> gateway -> trajectory-*.atif.json). Required for -# trajectory capture; the pip `nemo-relay` package does NOT ship this executable. +# 2. nemo-relay gateway binary — required for live ATIF trajectory capture on out-of-process +# harnesses (codex). The pip `nemo-relay` package does NOT ship this daemon, so we download the +# prebuilt binary from the NeMo-Relay GitHub releases (override with NEMO_RELAY_VERSION). Set +# NEMO_RELAY_REPO to force a source build (e.g. on a platform with no prebuilt asset). +NEMO_RELAY_VERSION="${NEMO_RELAY_VERSION:-0.5.0}" +RELAY_BIN_DIR="${CARGO_HOME:-$HOME/.cargo}/bin" +# Skip provisioning only when an existing nemo-relay already matches NEMO_RELAY_VERSION, so an +# explicit version request is honored rather than silently short-circuited by any PATH match. +need_relay_install=1 if command -v nemo-relay >/dev/null 2>&1; then - echo "nemo-relay gateway already on PATH: $(command -v nemo-relay) ($(nemo-relay --version 2>/dev/null || echo '?'))" -else - RELAY_REPO="${NEMO_RELAY_REPO:-$HOME/workspace/NeMo-Relay}" - if [ ! -d "$RELAY_REPO" ]; then - echo "nemo-relay gateway not on PATH and NeMo-Relay checkout not found at: $RELAY_REPO" >&2 - echo "Clone it (gh repo clone NVIDIA/NeMo-Relay) or set NEMO_RELAY_REPO=/path/to/NeMo-Relay." >&2 - echo "Trajectory (ATIF) capture will fail without the nemo-relay gateway." >&2 - exit 1 + installed_relay_ver="$(nemo-relay --version 2>/dev/null | awk '{print $NF}')" + if [ "$installed_relay_ver" = "$NEMO_RELAY_VERSION" ]; then + echo "nemo-relay gateway already on PATH at requested version ${installed_relay_ver}: $(command -v nemo-relay)" + need_relay_install=0 + else + echo "nemo-relay ${installed_relay_ver:-?} on PATH differs from requested ${NEMO_RELAY_VERSION}; (re)installing ..." + fi +fi + +if [ "$need_relay_install" = 1 ]; then + # Map host platform -> NeMo-Relay release target triple (no Intel-macOS asset is published). + relay_target="" + case "$(uname -s):$(uname -m)" in + Darwin:arm64) relay_target="aarch64-apple-darwin" ;; + Linux:x86_64) relay_target="x86_64-unknown-linux-musl" ;; + Linux:aarch64 | Linux:arm64) relay_target="aarch64-unknown-linux-musl" ;; + esac + + if [ -n "$relay_target" ] && [ -z "${NEMO_RELAY_REPO:-}" ]; then + asset="nemo-relay-cli-${relay_target}-${NEMO_RELAY_VERSION}" + base="https://github.com/NVIDIA/NeMo-Relay/releases/download/${NEMO_RELAY_VERSION}" + tmp="$(mktemp -d)" + echo "Downloading nemo-relay gateway ${NEMO_RELAY_VERSION} (${relay_target}) from GitHub releases ..." + curl -fsSL -o "${tmp}/nemo-relay" "${base}/${asset}" + curl -fsSL -o "${tmp}/nemo-relay.sha256" "${base}/${asset}.sha256" + want="$(awk '{print $1}' "${tmp}/nemo-relay.sha256")" + if command -v sha256sum >/dev/null 2>&1; then + got="$(sha256sum "${tmp}/nemo-relay" | awk '{print $1}')" + else + got="$(shasum -a 256 "${tmp}/nemo-relay" | awk '{print $1}')" + fi + if [ "$want" != "$got" ]; then + echo "Checksum mismatch for ${asset}: expected ${want}, got ${got}" >&2 + rm -rf "$tmp" + exit 1 + fi + mkdir -p "$RELAY_BIN_DIR" + install -m 0755 "${tmp}/nemo-relay" "${RELAY_BIN_DIR}/nemo-relay" + rm -rf "$tmp" + echo "nemo-relay gateway installed: ${RELAY_BIN_DIR}/nemo-relay ($("${RELAY_BIN_DIR}/nemo-relay" --version 2>/dev/null || echo '?'))" + # Warn if the install dir isn't on PATH — live tests resolve the gateway via shutil.which(). + case ":${PATH}:" in + *":${RELAY_BIN_DIR}:"*) : ;; + *) echo "NOTE: ${RELAY_BIN_DIR} is not on PATH — add it so 'nemo-relay' is found: export PATH=\"${RELAY_BIN_DIR}:\$PATH\"" >&2 ;; + esac + else + # Fallback: source build from a NeMo-Relay checkout (no prebuilt asset for this platform, e.g. + # Intel macOS, or NEMO_RELAY_REPO set explicitly to force a build). + RELAY_REPO="${NEMO_RELAY_REPO:-$HOME/workspace/NeMo-Relay}" + if [ ! -d "$RELAY_REPO" ]; then + echo "No prebuilt nemo-relay gateway for $(uname -s):$(uname -m) and no NeMo-Relay checkout at: $RELAY_REPO" >&2 + echo "Clone NVIDIA/NeMo-Relay (or set NEMO_RELAY_REPO), or set NEMO_RELAY_VERSION to a release with an asset for your platform." >&2 + exit 1 + fi + echo "Building + installing the nemo-relay gateway from $RELAY_REPO (cargo install) ..." + cargo install --path "$RELAY_REPO/crates/cli" --locked + echo "nemo-relay gateway installed: $(command -v nemo-relay) ($(nemo-relay --version 2>/dev/null || echo '?'))" fi - echo "Building + installing the nemo-relay gateway from $RELAY_REPO (cargo install) ..." - cargo install --path "$RELAY_REPO/crates/cli" --locked - echo "nemo-relay gateway installed: $(command -v nemo-relay) ($(nemo-relay --version 2>/dev/null || echo '?'))" fi cat <<'EOF' diff --git a/sdk/python/nemo-platform/pyproject.toml b/sdk/python/nemo-platform/pyproject.toml index a1b726ade3..4e595c4c2b 100644 --- a/sdk/python/nemo-platform/pyproject.toml +++ b/sdk/python/nemo-platform/pyproject.toml @@ -61,7 +61,7 @@ nemo-evaluator-sdk = [ "ragas==0.4.3", "langchain-openai>=1.3.5", "langchain-nvidia-ai-endpoints>=1.4.3,<2.0.0", - "nemo-relay>=0.4.0,<0.5.0", + "nemo-relay>=0.5.0,<0.7", ] [project.entry-points."nemo.skills"] diff --git a/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/_common.py b/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/_common.py index 47fd59e63b..38826c9a12 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/_common.py +++ b/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/_common.py @@ -23,7 +23,13 @@ from nemo_platform.beta.evaluator.agent_eval.tasks import AgentEvalTask from nemo_platform.beta.evaluator.agent_eval.trials import AgentEvalTrial, AgentEvalTrialStatus from nemo_platform.beta.evaluator.values.evidence import CandidateEvidence, EvidenceDescriptor -from nemo_relay.observability import AtifConfig, AtofConfig, ComponentSpec, ObservabilityConfig +from nemo_relay.observability import ( + AtifConfig, + AtofConfig, + AtofFileSinkConfig, + ComponentSpec, + ObservabilityConfig, +) # Trajectory profile identity + the file-exporter output names we choose (Relay accepts these as # inputs). Shared so both runtimes select/emit the trajectory under identical names. @@ -122,11 +128,17 @@ def trajectory_telemetry(*, relay_dir: str, agent_name: str, agent_version: str) agent_name=agent_name, agent_version=agent_version, ), + # nemo-relay 0.6 moved ATOF's destination out of AtofConfig and into a list of typed + # sinks; the file sink carries the fields the flat 0.5 config used to hold directly. atof=AtofConfig( enabled=True, - output_directory=relay_dir, - filename=ATOF_FILENAME, - mode="overwrite", + sinks=[ + AtofFileSinkConfig( + output_directory=relay_dir, + filename=ATOF_FILENAME, + mode="overwrite", + ) + ], ), ) ) diff --git a/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py b/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py index e8c5fae220..091176068e 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py +++ b/sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py @@ -559,6 +559,7 @@ def _relay_config(self, relay_dir: Path) -> dict[str, Any]: from nemo_relay.observability import ( # ty: ignore[unresolved-import] AtifConfig, AtofConfig, + AtofFileSinkConfig, ComponentSpec, ObservabilityConfig, ) @@ -575,11 +576,17 @@ def _relay_config(self, relay_dir: Path) -> dict[str, Any]: agent_name=self._runtime_name, agent_version="fabric", ), + # nemo-relay 0.6 moved ATOF's destination out of AtofConfig and into a list of typed + # sinks; the file sink carries the fields the flat 0.5 config used to hold directly. atof=AtofConfig( enabled=True, - output_directory=relay_dir_str, - filename=_ATOF_FILENAME, - mode="overwrite", + sinks=[ + AtofFileSinkConfig( + output_directory=relay_dir_str, + filename=_ATOF_FILENAME, + mode="overwrite", + ) + ], ), ) ) diff --git a/uv.lock b/uv.lock index 42abc6acc5..d002c88e9e 100644 --- a/uv.lock +++ b/uv.lock @@ -653,6 +653,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/76/cab7af7f16c0b09347f2ebe7ffda7101132f786acb767666dce43055faab/botocore_stubs-1.42.41-py3-none-any.whl", hash = "sha256:9423110fb0e391834bd2ed44ae5f879d8cb370a444703d966d30842ce2bcb5f0", size = 66759, upload-time = "2026-02-03T20:46:13.02Z" }, ] +[[package]] +name = "bracex" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/01/5f394b8bcd6e5b92f73130990960423bbb19711f906bd9fe9ea5557c667c/bracex-3.0.1.tar.gz", hash = "sha256:4e38e32392e4a4780fe15d644bfc7c8514057cfc3861e060b11814ce829c25e4", size = 44019, upload-time = "2026-07-20T13:43:00.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/8f/6f7273a7adb8d73fc8d21ede4376a3e475e52f98435c6007f69100dec8ca/bracex-3.0.1-py3-none-any.whl", hash = "sha256:6523ad83aeb5098a4ee597cff0f964442ff74e460bd3fafaffab6a013ff2288c", size = 11940, upload-time = "2026-07-20T13:42:59.268Z" }, +] + [[package]] name = "cachetools" version = "7.0.5" @@ -778,6 +787,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/34/15f08edd4628f65217de1fc3c1a27c82e46fe357d60c217fc9881e12ebcc/circuitbreaker-2.1.3-py3-none-any.whl", hash = "sha256:87ba6a3ed03fdc7032bc175561c2b04d52ade9d5faf94ca2b035fbdc5e6b1dd1", size = 7737, upload-time = "2025-03-31T08:12:07.802Z" }, ] +[[package]] +name = "claude-agent-sdk" +version = "0.2.120" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", 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 = "mcp", 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 = "sniffio", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/7f/7b69aed292a4edecae132e4dbe6b6decb4e88ec142fc91d117b19058c9e0/claude_agent_sdk-0.2.120.tar.gz", hash = "sha256:e428552f79a76e0d85789369eeb58249b33f350200124e5fc86b24168bd00805", size = 268639, upload-time = "2026-07-15T23:18:50.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/85/5e8958704db0f8195e63f8ec4a80c5fb14756edc785bb3535e0dc5d91104/claude_agent_sdk-0.2.120-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5ead9fb4bdaf70069978703ec6d74b30bd269e9632a4aea4dc8c4e999ac3a1b", size = 71110966, upload-time = "2026-07-15T23:18:54.743Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f8/248e3f58d0f0aa7d76bd34b11b18135cc124f5b9a9b55219cc1ca03d662a/claude_agent_sdk-0.2.120-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:abc73ccdf3decca566cd18084e74bc2f2d10b8b77cc1fd5ed4299d5c15e5078b", size = 81027434, upload-time = "2026-07-15T23:19:03.318Z" }, + { url = "https://files.pythonhosted.org/packages/11/59/6adb0c53534646f1d5ddc41226ff37b2adc413a472e2f87a9011548a137f/claude_agent_sdk-0.2.120-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:888070c246c92e102c52001d26532cd3646a700656d7c368f2f91a1d3c16b534", size = 82084704, upload-time = "2026-07-15T23:19:08.729Z" }, +] + [[package]] name = "click" version = "8.3.1" @@ -1202,6 +1227,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] +[[package]] +name = "deepagents" +version = "0.6.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { 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-anthropic", 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-core", 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-google-genai", 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 = "langsmith", 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 = "wcmatch", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/db/a6acdc72a9e90c3f07ed10de35c951734a02d4facb693bb59684ad368801/deepagents-0.6.12.tar.gz", hash = "sha256:1f281c0bc5a63132f62e2ee345c1dc593b23188da6e23016401f6879fbe54b5f", size = 211364, upload-time = "2026-06-25T17:26:52.775Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/49/af7219b3c13520fee047bb807cfaefba17f8e4584c551d946773589a4f08/deepagents-0.6.12-py3-none-any.whl", hash = "sha256:28b8fa0119ca0a689e3e18e288c4634e4046062acfc87a1cb34289d3af3a1c88", size = 236120, upload-time = "2026-06-25T17:26:51.736Z" }, +] + [[package]] name = "defusedxml" version = "0.7.1" @@ -1712,6 +1754,15 @@ dev = [ { name = "pytest-asyncio", specifier = ">=0.24.0" }, ] +[[package]] +name = "filetype" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/29/745f7d30d47fe0f251d3ad3dc2978a23141917661998763bebb6da007eb1/filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb", size = 998020, upload-time = "2022-11-02T17:34:04.141Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970, upload-time = "2022-11-02T17:34:01.425Z" }, +] + [[package]] name = "flake8" version = "6.1.0" @@ -1880,6 +1931,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/eb/c6c2478d8a8d633460be40e2a8a6f8f429171997a35a96f81d3b680dec83/google_auth-2.49.1-py3-none-any.whl", hash = "sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7", size = 240737, upload-time = "2026-03-12T19:30:53.159Z" }, ] +[package.optional-dependencies] +requests = [ + { 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')" }, +] + +[[package]] +name = "google-genai" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", 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 = "distro", 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 = "google-auth", extra = ["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 = "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 = "pydantic", extra = ["email"], 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 = "sniffio", 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 = "typing-extensions", 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 = "websockets", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/59/9ea84cbeb8f09694564d3b0ee9dd59003551b308d47b61f251415df93982/google_genai-2.12.1.tar.gz", hash = "sha256:78c25217885d63dc430ca7c4526853512b164a25a93a8a0d0af5b85971aa1db0", size = 636710, upload-time = "2026-07-16T16:15:02.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/b4/1369fb413fc2ba7f78acace5590b6e9990c52ab5d1d166aafaa1ae2c28c8/google_genai-2.12.1-py3-none-any.whl", hash = "sha256:686d5ec39bda345151d3ed1bac3915f01f49138b1ea519af2eb98f11cc55ebc4", size = 1023403, upload-time = "2026-07-16T16:14:59.79Z" }, +] + [[package]] name = "googleapis-common-protos" version = "1.73.1" @@ -2715,6 +2792,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/ec/0f942e78a621f8e3162ff1ed24284f469aaf51fb4607ee5831c626f2b2bc/langchain-1.3.14-py3-none-any.whl", hash = "sha256:4d10dbe91005952cddd56d0dc77aa108964da6bae90ab20063653957e901f782", size = 139560, upload-time = "2026-07-16T13:28:16.498Z" }, ] +[[package]] +name = "langchain-anthropic" +version = "1.4.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anthropic", 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-core", 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", extra = ["email"], 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/22/40ab129b08329ca295b391aa1d48267692b42594757084c6918e22b655ac/langchain_anthropic-1.4.8.tar.gz", hash = "sha256:c76891b2044d56105ff13c106ed12650637b53bd598a4bdf15b4796eefa2a4ec", size = 708524, upload-time = "2026-06-26T21:28:46.916Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/14/746235c4da89d9bc6a608c5f489f628e03feb8f697195c146e452c8f23c8/langchain_anthropic-1.4.8-py3-none-any.whl", hash = "sha256:778e9301b6fd517824f76ec1776975ce8add97a1f6a36c50ae3c2f4b03a66f7f", size = 52366, upload-time = "2026-06-26T21:28:45.535Z" }, +] + [[package]] name = "langchain-aws" version = "1.1.0" @@ -2804,6 +2895,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/d0/cfce61b53b79974a4883ff7675fe516192ae715e0f925e063e5869b6a929/langchain_exa-1.1.0-py3-none-any.whl", hash = "sha256:7eb4e1b6004f74fe278467470a4e76ba3b74a17df13f64e64745f0780f63d845", size = 7972, upload-time = "2026-03-26T17:00:09.239Z" }, ] +[[package]] +name = "langchain-google-genai" +version = "4.2.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filetype", 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 = "google-genai", 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-core", 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", extra = ["email"], 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/0c/bc60dabc362ca7c6ffe8c4bcc2f724c7e566b43eb230cee51419f88f784c/langchain_google_genai-4.2.7.tar.gz", hash = "sha256:03b1463ffe4d42435f43c7870467f2215f684bb46400d2543435d10157c80ac7", size = 281605, upload-time = "2026-07-06T13:51:58.724Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/f9/d73d1e712591723aaddb7a7b1e94978cd2320c29acfe0d26b6169a2f26f0/langchain_google_genai-4.2.7-py3-none-any.whl", hash = "sha256:0d9c388d0e6c629718fca6abb19c6fdca728a9a7873d0324c1ec821288b5b571", size = 70702, upload-time = "2026-07-06T13:51:57.499Z" }, +] + [[package]] name = "langchain-huggingface" version = "1.2.2" @@ -2833,6 +2939,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5e/48/99e81a0d33334f3bc7c310d15c19a2a972d0cf8d708c8369258a5db2d74e/langchain_litellm-0.6.5-py3-none-any.whl", hash = "sha256:dce2ebfddddd0dfd6b1ed473399ccc095dd2f5cb6adfe1336d7bbe489ef32b4b", size = 26359, upload-time = "2026-05-08T12:48:42.154Z" }, ] +[[package]] +name = "langchain-mcp-adapters" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core", 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 = "mcp", 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 = "typing-extensions", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/66/1cc7039e2daaddcdea9d8887851fe6eb67401925999b2aa394aa855c7132/langchain_mcp_adapters-0.2.2.tar.gz", hash = "sha256:12d39e91ae4389c54b61b221094e53850b6e152934d8bc10c80665d600e76530", size = 37942, upload-time = "2026-03-16T17:13:30.35Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/2f/15d5e6c1765d8404a9cce38d8c81d7b33fb3392f9db5b992c000dddbd2a3/langchain_mcp_adapters-0.2.2-py3-none-any.whl", hash = "sha256:d08e64954e86281002653071b7430e0377c9a577cb4ac3143abfeb3e24ef8797", size = 23288, upload-time = "2026-03-16T17:13:29.073Z" }, +] + [[package]] name = "langchain-milvus" version = "0.3.3" @@ -2948,6 +3068,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/b4/71425e3e38be92611300b9cc5e46a5bf98ab23f5ea8a75b73d02a2f1413c/langgraph_checkpoint-4.1.1-py3-none-any.whl", hash = "sha256:25d29144b082827218e7bc3f1e9b0566a4bb007895cd6cc26f66a8428739f56e", size = 56212, upload-time = "2026-05-22T16:57:37.203Z" }, ] +[[package]] +name = "langgraph-checkpoint-sqlite" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiosqlite", 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 = "langgraph-checkpoint", 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 = "sqlite-vec", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e3/ea/83917c2369acf8a10a894d4247655fd063c07924ba5bc4e83c85d2eaeded/langgraph_checkpoint_sqlite-3.1.0.tar.gz", hash = "sha256:f926916ebc1b985d802cc9c820026036e84db9d910d62c97b57e4ba64f67d5ae", size = 147902, upload-time = "2026-05-12T03:34:52.503Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/07/b342811a16327900af2747c752ea19676172fcddf9b592cc384031076623/langgraph_checkpoint_sqlite-3.1.0-py3-none-any.whl", hash = "sha256:cc9b40df0076feae8a9ad42ae713621b148b00ac23adc09dc1dc66090a46e5ad", size = 38587, upload-time = "2026-05-12T03:34:51.231Z" }, +] + [[package]] name = "langgraph-prebuilt" version = "1.1.0" @@ -4113,6 +4247,9 @@ dependencies = [ agent-runtimes = [ { name = "openai-agents", extra = ["docker"], 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')" }, ] +fabric = [ + { name = "nemo-fabric", extra = ["claude", "codex", "deepagents", "runtime"], 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')" }, +] harbor = [ { name = "harbor", marker = "(python_full_version >= '3.12' and platform_machine == 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.12' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux')" }, ] @@ -4134,8 +4271,9 @@ requires-dist = [ { name = "jsonschema", specifier = ">=4.23.0" }, { name = "langchain-nvidia-ai-endpoints", specifier = ">=1.4.3,<2.0.0" }, { name = "langchain-openai", specifier = ">=1.3.5" }, + { name = "nemo-fabric", extras = ["claude", "codex", "deepagents", "runtime"], marker = "extra == 'fabric'", specifier = ">=0.1.0rc2" }, { name = "nemo-platform-sdk", marker = "extra == 'nemo-platform'", editable = "sdk/python/nemo-platform" }, - { name = "nemo-relay", specifier = ">=0.4.0,<0.5.0" }, + { name = "nemo-relay", specifier = ">=0.5.0,<0.7" }, { name = "openai", specifier = ">=1.61.0" }, { name = "openai-agents", extras = ["docker"], marker = "extra == 'agent-runtimes'", specifier = ">=0.17.3,<0.18" }, { name = "pandas", specifier = ">=1.5.3" }, @@ -4145,7 +4283,7 @@ requires-dist = [ { name = "rouge-score", specifier = "==0.1.2" }, { name = "sacrebleu", specifier = ">=2.5.1" }, ] -provides-extras = ["agent-runtimes", "engine", "harbor", "nemo-platform"] +provides-extras = ["agent-runtimes", "engine", "harbor", "nemo-platform", "fabric"] [package.metadata.requires-dev] dev = [ @@ -4188,54 +4326,89 @@ requires-dist = [ [[package]] name = "nemo-fabric" -version = "0.1.0a20260724" +version = "0.1.0rc2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nemo-fabric-runtime", 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')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/02/6553d9b6612f2dd3464060e1afbaf849c124cd8c845530914b4cbcd462b1/nemo_fabric-0.1.0a20260724.tar.gz", hash = "sha256:7134673f3d7c63f2aaec59ce36b640e1700a63375bbdbe2809a137617d109f40", size = 6291, upload-time = "2026-07-24T09:11:45.053Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/c8/3e52e902133b76bcd9aaba27a2752f6869569b28b80be38b9a049c068ae2/nemo_fabric-0.1.0rc2.tar.gz", hash = "sha256:bc0a31d5ff6b8a9326c8a14cedb6da98cf9966e0fd2eabe101f5f331be2a171d", size = 6555, upload-time = "2026-07-27T21:47:43.569Z" } [package.optional-dependencies] +claude = [ + { name = "nemo-fabric-adapters-claude", 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')" }, +] +codex = [ + { name = "nemo-fabric-adapters-codex", 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')" }, +] +deepagents = [ + { name = "nemo-fabric-adapters-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')" }, +] runtime = [ { name = "nemo-fabric-runtime", 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')" }, ] +[[package]] +name = "nemo-fabric-adapters-claude" +version = "0.1.0rc2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "claude-agent-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 = "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 = "tomli-w", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/fc/1a292a61e90de64b97ffdacc56d040a561bb0ec137e4b536c3fe5b857231/nemo_fabric_adapters_claude-0.1.0rc2.tar.gz", hash = "sha256:0f7519a209643e37be67f45590a09209d6660561ba5c5b6a527e7ada652d03e5", size = 8228, upload-time = "2026-07-27T21:48:07.725Z" } + [[package]] name = "nemo-fabric-adapters-codex" -version = "0.1.0a20260724" +version = "0.1.0rc2" source = { registry = "https://pypi.org/simple" } dependencies = [ { 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 = "openai-codex", 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 = "tomli-w", 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')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/65/6b/f6949c2e9350e5eb15fd171f775e50ed0565cd8ff08bf68157855475ac5f/nemo_fabric_adapters_codex-0.1.0a20260724.tar.gz", hash = "sha256:246e43bf6222560d63167fa89c27e9e03a152ea47cfe156601cb4a6100b9b656", size = 7567, upload-time = "2026-07-24T09:11:35.44Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/e2/6a410a7f56fbbf11010748b5f53e90266bebe09953e5c43127e68c24f865/nemo_fabric_adapters_codex-0.1.0rc2.tar.gz", hash = "sha256:d6eb896dcedfad0546fdc00206e432c9fa438e9910a30c12c6ddc78a3cbb1f1b", size = 7564, upload-time = "2026-07-27T21:47:50.886Z" } [[package]] name = "nemo-fabric-adapters-common" -version = "0.1.0a20260724" +version = "0.1.0rc2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/17/057fa7330912ec05e9950169fe3c5990f8fe58bce23dda8b1397e32d2df2/nemo_fabric_adapters_common-0.1.0a20260724.tar.gz", hash = "sha256:965fad6446b42e85271b93e66491b188fadeabefa0d899ddf589e3d99537b61d", size = 5800, upload-time = "2026-07-24T09:11:32.409Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/1c/74d5eb88fc4c448123ec902bafb473816c2f504b4b22ca0c6d1debd77cd5/nemo_fabric_adapters_common-0.1.0rc2.tar.gz", hash = "sha256:f64f71c15801d4fd341bdc898542a761f9ce457bd5f1bb649fab9d7f125a4cb7", size = 5775, upload-time = "2026-07-27T21:47:34.914Z" } + +[[package]] +name = "nemo-fabric-adapters-deepagents" +version = "0.1.0rc2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "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 = "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-mcp-adapters", 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-openai", 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 = "langgraph", 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 = "langgraph-checkpoint-sqlite", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/6a/d367a4613b462616196af773454b1ce0455efe499727aa969b0fb8304bfb/nemo_fabric_adapters_deepagents-0.1.0rc2.tar.gz", hash = "sha256:2b301b23d9f5c623db0d2e995a9921aa1caa1132f23ba4f361029415c2604cfb", size = 8830, upload-time = "2026-07-27T21:47:38.718Z" } [[package]] name = "nemo-fabric-adapters-hermes" -version = "0.1.0a20260724" +version = "0.1.0rc2" source = { registry = "https://pypi.org/simple" } dependencies = [ { 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 = "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')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/5b/a67590fe64bc71ceeab17fc35a1b01309016acf3fa7a5d5a4406b8be2bfc/nemo_fabric_adapters_hermes-0.1.0a20260724.tar.gz", hash = "sha256:1a4dbb3a985453435833cf3fee80f9a69f11786189a712d8c895ca33b8fb3976", size = 6215, upload-time = "2026-07-24T09:11:42.582Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/e3/853c11dd962be6bf4de98b4446b3771fa82e1a482f67b3143283d5931789/nemo_fabric_adapters_hermes-0.1.0rc2.tar.gz", hash = "sha256:321e8bfe993eb767b33985ff19efe3827336f88a6fa8c57c050afed98b11f900", size = 6198, upload-time = "2026-07-27T21:47:47.685Z" } [[package]] name = "nemo-fabric-runtime" -version = "0.1.0a20260724" +version = "0.1.0rc2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic", extra = ["email"], 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 = "typing-extensions", 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')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/fe/0256c408a5d6c5e8a1576c8d2672252d85f1537dac7aa08584cef11ef5d2/nemo_fabric_runtime-0.1.0a20260724.tar.gz", hash = "sha256:b9a5eb4de344d981863f76b2d8f586e6fbcbc3c69ed6cdc333167b78f64e6331", size = 5275, upload-time = "2026-07-24T09:11:23.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/94/3281a536bdbfd4ea88860c8721ade71ff80d6e843e24db905d676f452c7b/nemo_fabric_runtime-0.1.0rc2.tar.gz", hash = "sha256:38082a899701bf6fd01d69445797b1595649f2d978cf7cfd137a7a42417bf5d8", size = 5261, upload-time = "2026-07-27T21:47:26.851Z" } [[package]] name = "nemo-guardrails-plugin" @@ -5157,7 +5330,7 @@ requires-dist = [ { name = "nemo-platform-sdk", marker = "extra == 'nmp-common'", editable = "sdk/python/nemo-platform" }, { name = "nemo-platform-sdk", marker = "extra == 'plugins'", editable = "sdk/python/nemo-platform" }, { name = "nemo-platform-sdk", marker = "extra == 'services'", editable = "sdk/python/nemo-platform" }, - { name = "nemo-relay", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=0.4.0,<0.5.0" }, + { name = "nemo-relay", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=0.5.0,<0.7" }, { name = "nemo-safe-synthesizer", marker = "extra == 'all'", specifier = "==0.1.7" }, { name = "nemo-safe-synthesizer", marker = "extra == 'nemo-safe-synthesizer-plugin'", specifier = "==0.1.7" }, { name = "nemo-safe-synthesizer", marker = "extra == 'plugins'", specifier = "==0.1.7" }, @@ -5655,7 +5828,7 @@ requires-dist = [ { name = "langchain-nvidia-ai-endpoints", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=1.4.3,<2.0.0" }, { name = "langchain-openai", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=1.3.5" }, { name = "nemo-platform-plugin", editable = "packages/nemo_platform_plugin" }, - { name = "nemo-relay", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=0.4.0,<0.5.0" }, + { name = "nemo-relay", marker = "extra == 'nemo-evaluator-sdk'", specifier = ">=0.5.0,<0.7" }, { name = "ngcsdk", specifier = ">=4.8.2" }, { name = "nvidia-ml-py", specifier = ">=13.0.0" }, { name = "openai" }, @@ -5754,12 +5927,12 @@ test = [ [[package]] name = "nemo-relay" -version = "0.4.0" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/f0/1626672dd86005570afbcd4e368f5f271bcd2104ceaee883e839b11bfc81/nemo_relay-0.4.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:d5f14fe5c8e5fbcc26827cc88e5b867f4ad37d6f983100cbf31705234c39f9d3", size = 6674344, upload-time = "2026-06-12T23:24:02.707Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/956142c558334ec8594d97da6a1a717e70ba43685659dbdf18965c87c3f5/nemo_relay-0.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5a5f5dec1428085f6c41c3645f1773f9cfb154cfa47306c93d6514091a8006", size = 5989959, upload-time = "2026-06-12T23:24:04.496Z" }, - { url = "https://files.pythonhosted.org/packages/6c/56/e5172ec8486deb23dabf5c948be81b8172840efdfcda42b1da1a8d9ef969/nemo_relay-0.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f92883b81540076e4b6c5e754eb7726225336634204ebd22ff730ccbcfb2723", size = 6332992, upload-time = "2026-06-12T23:24:06.288Z" }, + { url = "https://files.pythonhosted.org/packages/25/65/d320016505457cc30971f575e8dadffb923b7cfc780ab8bb25a4ce9d305c/nemo_relay-0.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:ad5dae6febf6532d7b113abc2a404679c8feffc499df3034b93d9a078185d2bb", size = 9917779, upload-time = "2026-07-22T20:07:48.961Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c0/f33250e71c4206da1b339072893f9a1e39295fe1aceb9a2fef4b8620a0f2/nemo_relay-0.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0cd9570f64c6956fe3bfb82af1cdb3ee70cb50b51098cdb0de831c3f9b4e904", size = 8888375, upload-time = "2026-07-22T20:07:51.049Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f4/d1dfaed022da0f6f14765a122867f976a69cc520fe1faaf99757f5719d1f/nemo_relay-0.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:849daa9e45158ac581e54506e0fcc7a24f557d1ed06dbdc074f5de7a00393cbc", size = 9336372, upload-time = "2026-07-22T20:07:53.224Z" }, ] [[package]] @@ -10249,6 +10422,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/ac/227298acc7230cdd56feb108b0f3a42e47f2e0d58bee50e35cd5facab7de/sqlfluff-4.2.2-py3-none-any.whl", hash = "sha256:62dbfbcd33728351043d216767ec017754a24cd8fb624e8321f61a79988b4fa7", size = 1005710, upload-time = "2026-06-04T15:36:51.661Z" }, ] +[[package]] +name = "sqlite-vec" +version = "0.1.10a4" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/52/ca3edf018d67f7736ad7520770b66031063b54f8a0b1bc3622ead3a9f646/sqlite_vec-0.1.10a4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8d1b8cffdd8fe86d48efc3e447569da3874e4cf7d61ad2ddf5a8ece102294b0e", size = 197402, upload-time = "2026-05-18T06:54:33.456Z" }, + { url = "https://files.pythonhosted.org/packages/21/b4/571bc81c408521eb2390dcfee987ebeda8a63f3cf765626381a6f0191274/sqlite_vec-0.1.10a4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f8fada13f6e48c2ea14709ba9f30429a13d3a291616671b62ca48bb36aebcb", size = 190124, upload-time = "2026-05-18T06:54:34.925Z" }, + { url = "https://files.pythonhosted.org/packages/79/27/57ccbf098b2bb4ab4f0ee138cf1e38235f84636f74e0a52464b9a8aa1c0e/sqlite_vec-0.1.10a4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux1_x86_64.whl", hash = "sha256:f1897fa54780aaee4ce216091a51193f6383060099325360163550836f803eff", size = 213876, upload-time = "2026-05-18T06:54:35.949Z" }, +] + [[package]] name = "sqlmodel" version = "0.0.37" @@ -11305,6 +11488,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/d4/ed38dd3b1767193de971e694aa544356e63353c33a85d948166b5ff58b9e/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49", size = 457546, upload-time = "2025-10-14T15:06:13.372Z" }, ] +[[package]] +name = "wcmatch" +version = "11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex", 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')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/25/1da725838132221e33568973da484ff43813662ccc06ebf7f6e3abddfcd5/wcmatch-11.0.tar.gz", hash = "sha256:55d95c2447789712774b198ceec72939e88b5618f1f8f0a9b605bf7740b63b96", size = 141360, upload-time = "2026-07-10T05:50:24.183Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/12/f38b6fee116274d7221743caab07d765032e1370bb54cad8714f87aeb0e8/wcmatch-11.0-py3-none-any.whl", hash = "sha256:3a5977ace27e075eef67eb03d539563f1a19018b62881949a42932cf66926934", size = 42914, upload-time = "2026-07-10T05:50:22.995Z" }, +] + [[package]] name = "wcwidth" version = "0.6.0"