fix(cli): make uv tool install the front door for nemo-platform - #1248
fix(cli): make uv tool install the front door for nemo-platform#1248callingmedic911 wants to merge 15 commits into
Conversation
_version.py queried nemo-platform-sdk, a distribution that only exists in the workspace. PyPI users get the SDK bundled inside the nemo-platform wheel, so the lookup raised and fell back to 0.0.0 for nemo --version, telemetry client_version, and the SDK client User-Agent. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
uv tool environments cannot be extended with pip. Detect them through the uv-receipt.toml uv writes at the environment root and print the matching uv tool install command instead. Drops the Python 3.14 variant of the hint: the nemo-platform wheel declares requires-python <3.14, so no install that can print this message runs on 3.14. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
The documented path created a venv and installed nemo-platform without the [all] extra, so nemo services run failed on a fresh install. Make the tool install the lead everywhere the install is documented, keep the venv variant for SDK imports and constrained environments, and label the source checkout as the contributor path. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
uv enforces the lower bound of requires-python but installs the wheel on Python 3.14 despite the declared <3.14 upper bound, where the [all] extra then fails building dependencies from source. Naming the interpreter keeps the documented command deterministic. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
test-nemo-cli.sh called nemo --version without checking the output, which is how the 0.0.0 fallback went unnoticed. Assert it, and add a uv tool install leg to the wheel-test matrix so the documented front door is covered; the plugin has no CLI, so it keeps only the venv leg. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
The generated SDK pyproject claimed >=3.12 with a 3.14 classifier while the nemo-platform wheel it ships in supports 3.12-3.13. Tighten both, and build wheels on 3.12 by default rather than 3.11, which the wrapper's requires-python already excludes. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
|
Test wheels are stamped with a sentinel 0.0.0.dev<timestamp>, which a prefix match rejected. The CLI's missing-metadata fallback is a bare 0.0.0, so compare against that. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
The generator has been syntactically invalid since it landed: a missing closing quote on the version-probe line made bash swallow the following lines, so `bash -n` fails and the file could never be regenerated. Also resolve on 3.12, since the wrapper's requires-python floor now rejects the 3.11 probe environment, and pass --no-config so the snapshot is a set a user can actually resolve rather than one shaped by the repo's override-dependencies. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
nemo-platform[all] could not be installed from PyPI: nvidia-nat-core 1.8.0 caps cryptography at <47 while data-designer-engine 0.8.0 requires >=48.0.1. The workspace hid this behind [tool.uv] override-dependencies, which no wheel user gets. NAT 1.9 is the first line whose cap overlaps data-designer's; it ships only pre-releases today, so every NAT distribution in the closure is named explicitly — uv accepts a pre-release only when a requirement it reads names one. A user install now resolves to cryptography 48.0.1, which is below the 50.0.0 that fixes CVE-2026-69247; the workspace override keeps developers on 50. Only an upstream cap relaxation can give wheel users the patched version. Regenerating the constraints also picks up version drift that accumulated while the generator was broken. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
The install step runs inside the checkout, so uv applied the repo's [tool.uv] override-dependencies and resolved a dependency set no user can get. That is why the venv leg passed while the uv tool leg — which does not read project config — failed on the real conflict. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
State the supported Python range once in the prerequisites and move the --python escape hatch to CLI troubleshooting, where a user whose default interpreter is out of range will look. uv enforces only the lower bound of requires-python, so the flag cannot be dropped entirely. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
Drops the transitive packages NAT 1.9 no longer pulls (oci, langchain-exa, langchain-milvus, wikipedia, and friends) and adds nvidia-nat-config-optimizer. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
…lves" This reverts commit 548ac20 and its license refresh (b4cc5b2), and drops the CI changes that depend on them. NAT publishes no stable release above 1.8.0 — only daily 1.9.0a builds — so the bump put pre-releases of our own toolkit into a shipped wheel. Wait for 1.9.0 stable instead. Deferred with it: the uv tool install leg in wheel-test and --no-config on the wheel installs. Both only pass once nemo-platform[all] resolves without the repo's override-dependencies, which needs the NAT cryptography cap relaxed. Published 0.3.0 still installs, so this affects the next release, not users today. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughChangesInstallation and compatibility
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
docs/cli/index.mdx (1)
31-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRender parallel installation choices as tabs.
These sections present alternative installation workflows sequentially. The repository guideline requires tab sets for parallel alternatives.
docs/cli/index.mdx#L31-L44: place tool and virtual-environment installation in separate tabs.docs/get-started/setup.mdx#L27-L43: place full-service, SDK/CLI-only, and virtual-environment workflows in separate tabs.SETUP.md#L89-L91: place source-checkout and published-wheel setup in separate tabs.packages/nemo_platform/README.md#L27-L34: place full-service and SDK/CLI-only installation in separate tabs.As per coding guidelines, “Use tab sets for parallel alternatives or variants.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/cli/index.mdx` around lines 31 - 44, Render the parallel installation workflows as tabs using the repository’s established tab-set pattern: in docs/cli/index.mdx lines 31-44, separate tool and virtual-environment installation; in docs/get-started/setup.mdx lines 27-43, separate full-service, SDK/CLI-only, and virtual-environment workflows; in SETUP.md lines 89-91, separate source-checkout and published-wheel setup; and in packages/nemo_platform/README.md lines 27-34, separate full-service and SDK/CLI-only installation.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/cli/index.mdx`:
- Around line 33-36: Update the published-wheel installation workflows to ensure
the uv tool executable directory is available before running nemo, using uv tool
update-shell followed by the required shell refresh or qualifying the PATH
statement. Apply this consistently in docs/cli/index.mdx lines 33-36,
docs/get-started/setup.mdx lines 27-30, SETUP.md lines 89-91, and
packages/nemo_platform/README.md lines 28-34.
In `@script/test-nemo-cli.sh`:
- Around line 61-62: Update the version validation condition after extracting
version to anchor the entire value, accepting only semantic versions with
optional .dev followed by exactly 14 digits or rc followed by digits. Preserve
rejection of 0.0.0 and add a regression case demonstrating that an invalid
suffix such as trailing garbage is rejected.
---
Nitpick comments:
In `@docs/cli/index.mdx`:
- Around line 31-44: Render the parallel installation workflows as tabs using
the repository’s established tab-set pattern: in docs/cli/index.mdx lines 31-44,
separate tool and virtual-environment installation; in
docs/get-started/setup.mdx lines 27-43, separate full-service, SDK/CLI-only, and
virtual-environment workflows; in SETUP.md lines 89-91, separate source-checkout
and published-wheel setup; and in packages/nemo_platform/README.md lines 27-34,
separate full-service and SDK/CLI-only installation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 4d699ccb-60db-4c91-bc0d-e3f8c9785430
⛔ Files ignored due to path filters (7)
sdk/python/nemo-platform/pyproject.tomlis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/_version.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/services/cli.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/local/install.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/local/services.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/vendored/nemo_platform_ext/local/test_install.pyis excluded by!sdk/**
📒 Files selected for processing (15)
.github/actions/build-nemo-platform-wheel/action.yamlREADME.mdSETUP.mddocs/cli/index.mdxdocs/cli/troubleshooting.mdxdocs/get-started/setup.mdxpackages/nemo_platform/README.mdpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/services/cli.pypackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.pypackages/nemo_platform_ext/src/nemo_platform_ext/local/install.pypackages/nemo_platform_ext/src/nemo_platform_ext/local/services.pypackages/nemo_platform_ext/tests/local/test_install.pyscript/compile-wheel-constraints.shscript/test-nemo-cli.shtools/nemo-platform-sdk-tools/src/nemo_platform_sdk_tools/sdk/post_generation_update.py
| Install the PyPI `nemo-platform` wrapper package with [uv](https://docs.astral.sh/uv/). uv puts the `nemo` command on your PATH in its own isolated environment, so there is no virtual environment to create or activate. If you are working from a source checkout, run `make bootstrap` from the repository root instead; the generated SDK package under `sdk/python/nemo-platform/pyproject.toml` does not define the wrapper extras. | ||
|
|
||
| ```bash | ||
| pip install "nemo-platform[all]" | ||
| uv tool install "nemo-platform[all]" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target files ---'
for f in docs/cli/index.mdx docs/get-started/setup.mdx SETUP.md packages/nemo_platform/README.md; do
if [ -f "$f" ]; then
echo "### $f"
nl -ba "$f" | sed -n '20,105p'
else
echo "MISSING: $f"
fi
done
printf '%s\n' '--- PATH and uv tool references ---'
rg -n -i 'uv tool|update-shell|PATH|nemo setup|nemo ' \
docs/cli/index.mdx docs/get-started/setup.mdx SETUP.md packages/nemo_platform/README.mdRepository: NVIDIA-NeMo/nemo-platform
Length of output: 20355
🌐 Web query:
uv tool install executable directory PATH uv tool update-shell official documentation
💡 Result:
When you install a tool using uv tool install, the tool's executables are placed in a designated executable directory [1][2]. For these tools to be accessible from your shell, this directory must be included in your system's PATH variable [2][3]. If the directory is not already in your PATH, uv will display a warning upon installation [1][2]. You can resolve this by running the command: uv tool update-shell This command automatically detects your shell and attempts to add the tool executable directory to your appropriate shell configuration file [2][4]. After running it, you must either restart your shell or source your shell configuration file (e.g., source ~/.bashrc) for the changes to take effect [4]. Key details about the executable directory: - To identify the current path of your tool executable directory, you can run: uv tool dir --bin [4][5]. - The default location is typically ~/.local/bin on Unix systems, though this can be configured via environment variables like UV_TOOL_BIN_DIR [4][5]. - If uv tool update-shell does not work for your specific setup, you can manually add the output of uv tool dir --bin to your PATH in your shell configuration file (e.g., export PATH="$(uv tool dir --bin):$PATH") [4].
Citations:
- 1: https://docs.astral.sh/uv/guides/tools/
- 2: https://docs.astral.sh/uv/concepts/tools/
- 3: https://github.com/astral-sh/uv/blob/main/docs/concepts/tools.md
- 4: https://mintlify.wiki/astral-sh/uv/cli/tool-update-shell
- 5: https://docs.astral.sh/uv/reference/storage/
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
targets = {
"docs/cli/index.mdx": (33, 36),
"docs/get-started/setup.mdx": (27, 30),
"SETUP.md": (89, 91),
"packages/nemo_platform/README.md": (28, 39),
}
for name, (start, end) in targets.items():
path = Path(name)
print(f"### {name}")
if not path.is_file():
print("MISSING")
continue
lines = path.read_text().splitlines()
for number in range(start, min(end, len(lines)) + 1):
print(f"{number}: {lines[number - 1]}")
print("contains PATH setup:", any(
"uv tool update-shell" in line or "uv tool dir --bin" in line
for line in lines
))
print()
print("repository-wide uv PATH setup references:")
for path in Path(".").rglob("*"):
if path.is_file() and ".git" not in path.parts:
try:
text = path.read_text()
except (UnicodeDecodeError, OSError):
continue
if "uv tool update-shell" in text or "uv tool dir --bin" in text:
print(path)
PYRepository: NVIDIA-NeMo/nemo-platform
Length of output: 2213
Ensure the uv tool executable directory is on PATH before running nemo.
uv tool install does not guarantee that the executable directory is on the current shell’s PATH. Add uv tool update-shell with the required shell refresh, or qualify the PATH claim, in all four published-wheel workflows: docs/cli/index.mdx, docs/get-started/setup.mdx, SETUP.md, and packages/nemo_platform/README.md.
📍 Affects 4 files
docs/cli/index.mdx#L33-L36(this comment)docs/get-started/setup.mdx#L27-L30SETUP.md#L89-L91packages/nemo_platform/README.md#L28-L34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/cli/index.mdx` around lines 33 - 36, Update the published-wheel
installation workflows to ensure the uv tool executable directory is available
before running nemo, using uv tool update-shell followed by the required shell
refresh or qualifying the PATH statement. Apply this consistently in
docs/cli/index.mdx lines 33-36, docs/get-started/setup.mdx lines 27-30, SETUP.md
lines 89-91, and packages/nemo_platform/README.md lines 28-34.
Source: MCP tools
| version="${version_output#nemo version }" | ||
| if [[ "${version}" == "0.0.0" ]] || [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- target script ---'
cat -n script/test-nemo-cli.sh | sed -n '1,110p'
printf '%s\n' '--- version-related references ---'
rg -n --hidden -S '0\.0\.0\.dev|nemo version|version_output|test-nemo-cli|dev[<"'\'' ]|__version__' . \
-g '!node_modules' -g '!dist' -g '!build' | sed -n '1,240p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 29007
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- files ---'
git ls-files | rg '(^|/)(script/test-nemo-cli\.sh|.*(version|nemo).*)$' | sed -n '1,160p'
printf '%s\n' '--- target script ---'
cat -n script/test-nemo-cli.sh | sed -n '45,75p'
printf '%s\n' '--- version grammar references ---'
rg -n --hidden -S '0\.0\.0\.dev|nemo version|version_output|__version__|VERSION' . \
-g '!node_modules' -g '!dist' -g '!build' | sed -n '1,240p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 39872
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
import pathlib, re
target = pathlib.Path("script/test-nemo-cli.sh")
text = target.read_text()
for i, line in enumerate(text.splitlines(), 1):
if "version_output" in line or "version}" in line or "0.0.0" in line:
print(f"{target}:{i}:{line}")
print("--- current condition behavior ---")
pattern = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+")
for value in ("1.2.3", "1.2.3garbage", "0.0.0", "0.0.0.dev123", "1.2", "v1.2.3"):
accepted = value == "0.0.0" or pattern.match(value) is not None
print(f"{value!r}: {'accepted' if accepted else 'rejected'}")
print("--- repository declarations containing supported version forms ---")
for path in pathlib.Path(".").rglob("*"):
if not path.is_file() or any(part in {"node_modules", ".git", "dist", "build"} for part in path.parts):
continue
try:
data = path.read_text(errors="ignore")
except OSError:
continue
for i, line in enumerate(data.splitlines(), 1):
if re.search(r"0\.0\.0\.dev|nemo version|__version__", line):
print(f"{path}:{i}:{line}")
PYRepository: NVIDIA-NeMo/nemo-platform
Length of output: 6464
🌐 Web query:
"script/test-nemo-cli.sh" "0.0.0.dev"
💡 Result:
There is no standard or official script named "script/test-nemo-cli.sh" in the NVIDIA NeMo Agent Toolkit or related NeMo repositories [1][2][3][4]. Based on an analysis of the NeMo Agent Toolkit and associated testing infrastructure: 1. Testing Mechanism: The NeMo Agent Toolkit uses pytest as its primary test framework [2]. Automated testing is typically managed via the orchestration script ci/scripts/run_tests.py, which handles multi-project testing and environment setup [1][2]. 2. CLI Testing: CLI functionality (often involving the nat command) is validated through integrated test suites [5], including end-to-end (E2E) tests that verify CLI behavior under various conditions [6][5]. 3. Versioning: The version string "0.0.0.dev" is a common development placeholder used in Python packages (often managed via setuptools_scm or similar tools) to indicate an unreleased or development build, rather than a specific script argument. If you encountered this filename in a specific project or documentation, it is likely a custom, project-specific utility rather than an official component of the NeMo ecosystem [7][4]. You may wish to check the root directory of the repository where you found this reference for local documentation or a README file.
Citations:
- 1: https://github.com/NVIDIA/NeMo-Agent-Toolkit/blob/f33952bf/ci/scripts/run_tests.py
- 2: https://deepwiki.com/NVIDIA/NeMo-Agent-Toolkit/14.3-running-tests
- 3: https://deepwiki.com/NVIDIA/NeMo-Agent-Toolkit/14.1-test-infrastructure
- 4: https://github.com/NVIDIA/NeMo-Agent-Toolkit
- 5: https://deepwiki.com/NVIDIA/NeMo-Agent-Toolkit/15.5-local-ci-execution
- 6: https://github.com/NVIDIA/NemoClaw/blob/main/test/e2e-scenario/live/docs-validation.test.ts
- 7: https://github.com/IDEA-XL/MolClaw/blob/main/scripts/test-cli.sh
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- exact Bash condition behavior ---'
for version in \
'1.2.3' \
'1.2.3garbage' \
'0.0.0' \
'0.0.0.dev123' \
'0.0.0.dev20260512010101' \
'1.2.3.dev123' \
'1.2.3+local'
do
if [[ "${version}" == "0.0.0" ]] || [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
result=rejected
else
result=accepted
fi
printf '%-28s %s\n' "${version}" "${result}"
done
printf '%s\n' '--- version stamping implementation ---'
cat -n .github/scripts/stamp_sdk_version.py | sed -n '1,220p'
printf '%s\n' '--- version stamping tests ---'
cat -n tests/unit/release/test_stamp_sdk_version.py | sed -n '80,145p'
printf '%s\n' '--- relevant package configuration ---'
rg -n -A18 -B8 'dynamic|version|stamp_sdk_version|UV_DYNAMIC_VERSIONING_BYPASS' \
pyproject.toml packages/nemo_platform_ext/pyproject.toml sdk/python/nemo-platform/pyproject.toml \
.github/actions/build-nemo-platform-wheel/action.yaml 2>/dev/null | sed -n '1,260p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 26036
Match the complete stamped version grammar.
The current check accepts 1.2.3garbage. Anchor the match and allow valid .dev<14 digits> and rc<digits> suffixes. Add a regression case for an invalid suffix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@script/test-nemo-cli.sh` around lines 61 - 62, Update the version validation
condition after extracting version to anchor the entire value, accepting only
semantic versions with optional .dev followed by exactly 14 digits or rc
followed by digits. Preserve rejection of 0.0.0 and add a regression case
demonstrating that an invalid suffix such as trailing garbage is rejected.
Render the two install paths as tab sets, per the Fern guideline, and cut the prose to what distinguishes them: the tool install is global and needs no activation, the virtual environment is for importing the SDK. Stop claiming uv puts nemo on PATH unconditionally — it lands in the uv tool executable directory, so command-not-found now covers both install methods and points at uv tool update-shell. The interpreter entry cites uv's documented behaviour of ignoring requires-python for tools. Also anchor the version assertion so a trailing-garbage suffix cannot pass while the stamped .post/.dev/local forms still do. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
packages/nemo_platform/README.md (1)
24-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a Python SDK tab.
This section provides CLI installation commands and only mentions SDK use. Add a Python SDK example in a tab set beside the CLI path, or link to
docs/pysdk/client/index.mdx:5-15from that tab. As per coding guidelines, “Provide both Python SDK and CLI examples in tab-sets for consistency and to support multiple user workflows.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/nemo_platform/README.md` around lines 24 - 36, Add a tab set to the installation section with separate CLI and Python SDK tabs, keeping the existing CLI commands in the CLI tab and adding a Python SDK example or link to the client documentation in the SDK tab. Use the repository’s established tab-set format and preserve the current installation guidance.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/get-started/setup.mdx`:
- Around line 33-34: Update the installation guidance following the uv tool
installation in docs/get-started/setup.mdx (lines 33-34) and
packages/nemo_platform/README.md (lines 26-30): replace “available everywhere”
with instructions to run uv tool update-shell, then restart the shell or source
its configuration so nemo is available on PATH.
- Around line 33-34: Pin every [all] install command to
nemo-platform[all]==0.3.0 to avoid the current dependency conflict: update both
commands in docs/get-started/setup.mdx at lines 33-34 and 45-46, and both
commands in packages/nemo_platform/README.md at lines 29-30 and 35-36.
- Around line 33-34: Pin both uv tool installation commands in
docs/get-started/setup.mdx (lines 33-34) to Python 3.13 by adding the --python
3.13 option. Update packages/nemo_platform/README.md (lines 29-30) to list uv
>=0.9.14 in the prerequisites.
In `@packages/nemo_platform/README.md`:
- Around line 32-36: Update the installation instructions in the README to
include creating and activating a virtual environment before running the
nemo-platform installation command, or link to the existing setup guidance in
docs/get-started/setup.mdx.
---
Nitpick comments:
In `@packages/nemo_platform/README.md`:
- Around line 24-36: Add a tab set to the installation section with separate CLI
and Python SDK tabs, keeping the existing CLI commands in the CLI tab and adding
a Python SDK example or link to the client documentation in the SDK tab. Use the
repository’s established tab-set format and preserve the current installation
guidance.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 22aaf8bd-fc65-4591-963e-46fbc404f621
📒 Files selected for processing (6)
README.mddocs/cli/index.mdxdocs/cli/troubleshooting.mdxdocs/get-started/setup.mdxpackages/nemo_platform/README.mdscript/test-nemo-cli.sh
🚧 Files skipped from review as they are similar to previous changes (4)
- docs/cli/index.mdx
- README.md
- script/test-nemo-cli.sh
- docs/cli/troubleshooting.mdx
| uv tool install "nemo-platform[all]" | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- docs/get-started/setup.mdx ---'
cat -n docs/get-started/setup.mdx | sed -n '1,80p'
printf '%s\n' '--- packages/nemo_platform/README.md ---'
cat -n packages/nemo_platform/README.md | sed -n '1,60p'
printf '%s\n' '--- uv tool references ---'
rg -n -i 'uv tool|PATH|shell reload|nemo-platform\[all\]' docs packages/nemo_platform README.md 2>/dev/null || trueRepository: NVIDIA-NeMo/nemo-platform
Length of output: 50384
🏁 Script executed:
#!/bin/bash
set -u
printf '%s\n' '--- cited documentation ranges ---'
sed -n '25,42p' docs/get-started/setup.mdx
printf '%s\n' '--- cited README range ---'
sed -n '20,36p' packages/nemo_platform/README.md
printf '%s\n' '--- uv availability and relevant help ---'
if command -v uv >/dev/null 2>&1; then
uv --version
uv tool --help | sed -n '1,160p'
printf '%s\n' '--- uv tool dir --bin ---'
uv tool dir --bin
else
printf '%s\n' 'uv is not installed in the sandbox'
fiRepository: NVIDIA-NeMo/nemo-platform
Length of output: 1358
🌐 Web query:
site:docs.astral.sh/uv uv tool install PATH shell restart executable directory
💡 Result:
When you install a tool using uv tool install, the tool's executables are placed in a specific executable directory (bin directory) [1][2][3]. For these tools to be accessible directly from your shell, this directory must be included in your system's PATH environment variable [1][4]. If the directory is not already in your PATH, uv will display a warning upon installation [1][2]. To resolve this, you can run the following command to automatically add the executable directory to your shell's configuration files: uv tool update-shell [1][5] After running this command, you will typically need to restart your shell session (or source your configuration file, e.g., source ~/.bashrc or source ~/.zshrc) for the changes to take effect and for the new PATH to be recognized [1][4]. You can locate the tool executable directory on your system by running: uv tool dir --bin [3] This ensures that the symlinks or copies of the tool's executables are correctly referenced by your shell [1][4].
Citations:
- 1: https://docs.astral.sh/uv/concepts/tools/
- 2: https://docs.astral.sh/uv/guides/tools/
- 3: https://docs.astral.sh/uv/reference/storage/
- 4: https://docs.astral.sh/uv/concepts/tools/?featured_on=talkpython
- 5: https://docs.astral.sh/uv/getting-started/features/
Document uv PATH setup
If the uv tool executable directory is not on PATH, nemo is not immediately available. In both files, replace “available everywhere” with guidance to run uv tool update-shell, then restart the shell or source its configuration.
📍 Affects 2 files
docs/get-started/setup.mdx#L33-L34(this comment)packages/nemo_platform/README.md#L26-L30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/get-started/setup.mdx` around lines 33 - 34, Update the installation
guidance following the uv tool installation in docs/get-started/setup.mdx (lines
33-34) and packages/nemo_platform/README.md (lines 26-30): replace “available
everywhere” with instructions to run uv tool update-shell, then restart the
shell or source its configuration so nemo is available on PATH.
Source: MCP tools
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- referenced documentation ---'
for f in docs/get-started/setup.mdx packages/nemo_platform/README.md; do
if [ -f "$f" ]; then
printf '\n### %s\n' "$f"
nl -ba "$f" | sed -n '20,55p'
else
printf 'MISSING %s\n' "$f"
fi
done
printf '%s\n' '--- package metadata and all extra ---'
rg -n -S --glob '!*node_modules*' \
'nemo-platform|optional-dependencies|extras_require|\[all\]|all\s*=|dependency|conflict|next release' \
pyproject.toml setup.py setup.cfg packages docs .github 2>/dev/null | sed -n '1,240p'
printf '%s\n' '--- repository files near package metadata ---'
git ls-files | rg '(^|/)(pyproject\.toml|setup\.py|setup\.cfg|requirements[^/]*|CHANGELOG|.*release.*|.*manifest.*)$' | sed -n '1,160p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 33075
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- setup instructions ---'
for f in docs/get-started/setup.mdx packages/nemo_platform/README.md; do
printf '\n### %s\n' "$f"
sed -n '20,55p' "$f"
done
printf '%s\n' '--- package metadata ---'
sed -n '1,220p' packages/nemo_platform/pyproject.toml
printf '%s\n' '--- relevant repository changes ---'
git diff --stat
git diff -- docs/get-started/setup.mdx packages/nemo_platform/README.md packages/nemo_platform/pyproject.toml | sed -n '1,260p'
printf '%s\n' '--- all references to the published install commands ---'
rg -n -F \
-e 'uv tool install "nemo-platform[all]"' \
-e 'pip install "nemo-platform[all]"' \
-e 'nemo-platform[all]' \
docs packages README.md 2>/dev/null | sed -n '1,220p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 37354
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- wrapper extra definitions ---'
rg -n -A12 -B4 \
'^\[project\.optional-dependencies\]|^all\s*=|^services\s*=|^core-service\s*=|^service' \
packages/nemo_platform/pyproject.toml | sed -n '1,260p'
printf '%s\n' '--- bundling documentation ---'
sed -n '1,155p' packages/nemo_platform/BUNDLING.md
printf '%s\n' '--- package version and release references ---'
rg -n -S \
'^\[tool\.hatch|version|release|0\.[0-9]+\.[0-9]+|next release|unresolved|conflict' \
packages/nemo_platform/pyproject.toml packages/nemo_platform/BUNDLING.md \
docs/about/release-notes/current-release.mdx .github/release* .github/workflows/release.yaml \
2>/dev/null | sed -n '1,240p'
printf '%s\n' '--- repository state ---'
git status --short
git log -5 --oneline -- packages/nemo_platform/pyproject.toml docs/get-started/setup.mdx packages/nemo_platform/README.mdRepository: NVIDIA-NeMo/nemo-platform
Length of output: 32952
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- recent dependency-related commits ---'
for c in 1c5a6b0e0 89868b26e 548ac20d8 76d1643aa; do
printf '\n### %s\n' "$c"
git show --stat --oneline "$c"
git show --format=fuller --no-ext-diff "$c" -- \
packages/nemo_platform/pyproject.toml \
docs/get-started/setup.mdx \
packages/nemo_platform/README.md \
plugins/nemo-agents/pyproject.toml \
uv.lock | sed -n '1,280p'
done
printf '%s\n' '--- resolver tooling availability ---'
command -v uv || true
command -v pip || true
command -v python3 || trueRepository: NVIDIA-NeMo/nemo-platform
Length of output: 50383
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
import subprocess
import tomllib
from pathlib import Path
metadata = tomllib.loads(
Path("packages/nemo_platform/pyproject.toml").read_text(encoding="utf-8")
)
extras = metadata["project"]["optional-dependencies"]
assert extras["all"] == ["nemo-platform[services]"]
assert any(dep == "nemo-platform[plugins]" for dep in extras["services"])
assert any("nvidia-nat-core>=1.8.0,<1.9" == dep for dep in extras["nemo-agents-plugin"])
for path in (
Path("docs/get-started/setup.mdx"),
Path("packages/nemo_platform/README.md"),
):
text = path.read_text(encoding="utf-8")
assert text.count('uv tool install "nemo-platform[all]"') == 1
assert text.count('pip install "nemo-platform[all]"') == 1
print(f"{path}: both published commands are unpinned")
message = subprocess.check_output(
["git", "show", "-s", "--format=%B", "1c5a6b0e0"],
text=True,
)
required = (
"Published 0.3.0 still installs",
"this affects the next release",
"nemo-platform[all] resolves without the repo's override-dependencies",
)
for phrase in required:
assert phrase in message
print("1c5a6b0e0: records that 0.3.0 installs but the next release remains unresolved")
print("all -> services:", extras["all"])
print("NAT constraint:", next(
dep for dep in extras["nemo-agents-plugin"]
if dep.startswith("nvidia-nat-core")
))
PYRepository: NVIDIA-NeMo/nemo-platform
Length of output: 283
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
import subprocess
from pathlib import Path
pyproject = Path("packages/nemo_platform/pyproject.toml").read_text(encoding="utf-8")
for expected in (
'all = ["nemo-platform[services]"]',
'"nemo-platform[plugins]"',
'"nvidia-nat-core>=1.8.0,<1.9"',
):
assert expected in pyproject, expected
for path in (
Path("docs/get-started/setup.mdx"),
Path("packages/nemo_platform/README.md"),
):
text = path.read_text(encoding="utf-8")
assert text.count('uv tool install "nemo-platform[all]"') == 1
assert text.count('pip install "nemo-platform[all]"') == 1
print(f"{path}: both published commands are unpinned")
message = subprocess.check_output(
["git", "show", "-s", "--format=%B", "1c5a6b0e0"],
text=True,
)
for phrase in (
"Published 0.3.0 still installs",
"this affects the next release",
"nemo-platform[all] resolves without the repo's override-dependencies",
):
assert phrase in message, phrase
print("1c5a6b0e0: records that 0.3.0 installs but the next release remains unresolved")
print("all -> services and NAT remains constrained to the 1.8 line")
PYRepository: NVIDIA-NeMo/nemo-platform
Length of output: 458
Pin or gate the [all] install commands. NAT 1.8 caps cryptography below the version required by data-designer==0.8.0. Use nemo-platform[all]==0.3.0 until the dependency conflict is resolved, or defer all four commands in docs/get-started/setup.mdx and packages/nemo_platform/README.md.
📍 Affects 2 files
docs/get-started/setup.mdx#L33-L34(this comment)docs/get-started/setup.mdx#L45-L46packages/nemo_platform/README.md#L29-L30packages/nemo_platform/README.md#L35-L36
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/get-started/setup.mdx` around lines 33 - 34, Pin every [all] install
command to nemo-platform[all]==0.3.0 to avoid the current dependency conflict:
update both commands in docs/get-started/setup.mdx at lines 33-34 and 45-46, and
both commands in packages/nemo_platform/README.md at lines 29-30 and 35-36.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- relevant files ---'
git ls-files 'docs/get-started/setup.mdx' 'packages/nemo_platform/README.md' \
| while IFS= read -r f; do
printf '\n--- %s ---\n' "$f"
wc -l "$f"
rg -n -C 5 'uv|python|requires-python|requires_python|Python|version' "$f" || true
done
printf '\n--- package and project metadata candidates ---\n'
git ls-files | rg '(^|/)(pyproject\.toml|setup\.py|setup\.cfg|.*requirements.*|.*uv.*|README\.md)$' \
| head -200
printf '\n--- Python requirement declarations ---\n'
rg -n -C 3 'requires-python|requires_python|python_requires|Programming Language :: Python|Python :: 3\.(12|13)|uv' \
--glob 'pyproject.toml' --glob 'setup.py' --glob 'setup.cfg' --glob '*.md' --glob '*.mdx' . \
| head -300Repository: NVIDIA-NeMo/nemo-platform
Length of output: 35084
🏁 Script executed:
#!/bin/bash
set -eu
for f in packages/nemo_platform/pyproject.toml pyproject.toml .cursor/rules/uv.mdc README.md; do
if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
printf '\n--- %s ---\n' "$f"
wc -l "$f"
rg -n -C 6 'requires-python|requires_python|python|tool\.uv|uv|index|resolution|conflict|nemo-platform' "$f" | head -240
fi
done
printf '\n--- all nemo-platform Python requirements ---\n'
rg -n -C 4 'requires-python|requires_python|python_requires' \
packages/nemo_platform/pyproject.toml sdk/python/nemo-platform/pyproject.toml \
pyproject.toml 2>/dev/null || true
printf '\n--- install command occurrences ---\n'
rg -n -C 2 'uv tool install "nemo-platform\[all\]"|uv tool install' \
docs/get-started/setup.mdx packages/nemo_platform/README.md README.mdRepository: NVIDIA-NeMo/nemo-platform
Length of output: 27416
🌐 Web query:
Astral uv official documentation uv tool install --python interpreter selection default behavior requires-python
💡 Result:
When using uv tool install, the default Python interpreter selection and the handling of requires-python constraints behave according to the following logic: Python Interpreter Selection By default, uv attempts to select an appropriate Python interpreter for the tool environment [1]. It uses standard Python discovery logic [1], which searches for interpreters in the PATH, virtual environments, and managed installations (via uv python install) [2][3][4]. If no specific interpreter is requested via the --python flag, uv follows a preference hierarchy [5][4]: 1. The python-preference setting (defaulting to managed) determines whether uv prioritizes its own managed installations or system-installed interpreters [5][4]. 2. If multiple candidates exist, uv prioritizes newer versions among managed installations, while for system interpreters, it typically selects the first compatible version found [5][4]. 3. If no suitable Python version is found, uv may automatically download and install a required managed Python version [3][4]. Requires-Python Handling Historically, uv tool install did not automatically infer Python requirements from a package's metadata, which often led to resolution failures if the default discovered interpreter was incompatible [6][7]. However, recent updates have introduced mechanisms to improve this [8]: - Inference: uv can now inspect the requires-python metadata (e.g., from pyproject.toml or wheel distribution metadata) to refine the Python version request [8]. - Resolution and Refinement: If initial resolution fails due to an incompatible interpreter, uv can automatically attempt to refine the choice—including downloading a compliant managed Python version—to satisfy the tool's requirements [9]. For precise control, you can always explicitly specify the required Python version or range using the --python flag [1], for example: uv tool install --python ">=3.10" This approach overrides default discovery and ensures the tool is installed in an environment using a compatible interpreter [1][7].
Citations:
- 1: https://docs.astral.sh/uv/concepts/tools/
- 2: Selecting a Python interpreter astral-sh/uv#2386
- 3: https://docs.astral.sh/uv/guides/install-python/
- 4: https://github.com/astral-sh/uv/blob/4eef8fa3/docs/concepts/python-versions.md
- 5: https://docs.astral.sh/uv/concepts/python-versions/
- 6: uv tool install does not respect python-requires astral-sh/uv#14110
- 7:
uv tool installfails to download newer Python whenpipis installed in system python astral-sh/uv#10282 - 8: Infer Python version requests from source trees in
uv toolinvocations astral-sh/uv#19577 - 9: https://github.com/astral-sh/uv/blob/93fc6f04/crates/uv/src/commands/tool/install.rs
🌐 Web query:
site:docs.astral.sh/uv OR site:github.com/astral-sh/uv uv 0.9.14 tool install requires-python compatible interpreter release
💡 Result:
In uv version 0.9.14, the uv tool install command is designed to be aware of the requires-python metadata of the package being installed [1][2]. When you run uv tool install, uv performs the following steps: 1. Initial Interpreter Selection: It initially identifies a Python interpreter based on your environment and system defaults [2]. 2. Resolution and Compatibility Check: It attempts to resolve the package's dependencies. If the initially selected interpreter does not satisfy the package's Requires-Python constraint, the resolution will fail [3][1]. 3. Automated Refinement: If resolution fails due to an incompatible Python version, uv attempts to automatically refine the interpreter [3][1]. It will search for a compatible Python version—including downloading a managed Python interpreter if necessary—that satisfies the package's requires-python requirements [3][1]. It is important to note that uv tool ignores local project-specific configuration files such as .python-version or pyproject.toml files found in the current working directory [4]. Additionally, while uv respects the lower bounds of requires-python constraints during dependency resolution, it intentionally ignores upper bounds [5]. You can always override the automatic discovery by explicitly specifying the desired interpreter using the --python flag, for example: uv tool install --python 3.12 <package_name> [4][6].
Citations:
- 1: Respect
requires-pythonwhen installing tools astral-sh/uv#10401 - 2: https://github.com/astral-sh/uv/blob/2318e48e/crates/uv/src/commands/tool/install.rs
- 3: https://github.com/astral-sh/uv/blob/93fc6f04/crates/uv/src/commands/tool/install.rs
- 4: https://docs.astral.sh/uv/concepts/tools/
- 5: uv tool install does not respect python-requires astral-sh/uv#14110
- 6: https://github.com/astral-sh/uv/blob/8ee34679/docs/guides/tools.md
🌐 Web query:
site:github.com/astral-sh/uv/pull/19577 uv tool install requires-python version
💡 Result:
When using uv tool install, the command generally ignores non-global Python version requests, including requires-python values found in a pyproject.toml file [1][2]. Instead, it uses standard Python version discovery logic to create an isolated virtual environment for the tool [1][2]. If you need to use a specific Python version for a tool, you should use the --python flag during the installation command [1][2]. Note: Recent developments in the uv repository (as of mid-2026) have introduced experimental efforts to infer Python version requirements from source trees (e.g., peeking at pyproject.toml when installing tools from a local directory) to improve compatibility and reduce installation failures [3]. However, the stable documentation maintains that uv tool install generally ignores requires-python metadata to maintain consistent, isolated environments [1][2].
Citations:
- 1: https://docs.astral.sh/uv/concepts/tools/
- 2: https://docs.astral.sh/uv/concepts/tools/index.md
- 3: Infer Python version requests from source trees in
uv toolinvocations astral-sh/uv#19577
🏁 Script executed:
#!/bin/bash
set -eu
if command -v uv >/dev/null 2>&1; then
printf '%s\n' '--- installed uv version ---'
uv --version
printf '%s\n' '--- uv tool install options ---'
uv tool install --help | rg -n -C 2 -- '--python|requires-python|version|managed'
else
printf '%s\n' 'uv is not installed in the sandbox\n'
fiRepository: NVIDIA-NeMo/nemo-platform
Length of output: 200
🌐 Web query:
site:docs.astral.sh/uv/concepts/tools/ "requires-python" "uv tool install"
💡 Result:
When using the uv tool install command, uv ignores the requires-python constraint specified in a pyproject.toml file [1][2]. While uv uses standard Python version discovery logic to create an isolated virtual environment for the tool, it explicitly excludes non-global Python version requests, including.python-version files and requires-python metadata [1][2]. If you need to install a tool with a specific Python version requirement, you must explicitly provide the --python option during the installation command [1][2]. For example: uv tool install --python If the Python version selected for the tool is later uninstalled, the tool environment will be broken and the tool may become unusable [1][2].
Citations:
🌐 Web query:
site:docs.astral.sh/uv/concepts/tools/ "The Python version" "--python" tool install
💡 Result:
To specify a Python version when installing a tool with the uv package manager, you can use the --python option [1][2]. For example, to install a package with a specific Python version using uv, you would use the following syntax [1][2]: uv tool install --python Each tool installed via uv is linked to a specific Python version [1][2]. When using the --python option, uv uses its standard Python version discovery logic to locate the requested version, while ignoring local configuration files like.python-version or pyproject.toml requirements [1][2]. If the specified Python version is later uninstalled from your system, the tool environment will become broken and the tool may no longer function [1][2].
Citations:
🌐 Web query:
site:docs.astral.sh/uv/guides/tools/ "python" "tool install"
💡 Result:
To install Python tools for personal use, the current recommended approach is to use tools like uv or pipx, which create isolated environments for each application to prevent dependency conflicts. Using uv, you can install a tool into a persistent environment where its executables are added to your PATH, allowing you to run them directly [1][2]. To install a tool using uv, use the following command: uv tool install For example, to install ruff: uv tool install ruff When installed this way, uv places the tool's executables in a bin directory [1][2]. If the directory is not already in your PATH, you can update your shell configuration using: uv tool update-shell If you want to specify a particular Python version for the tool, you can provide it during installation [1][2]: uv tool install --python 3.10 ruff Unlike installing packages with standard pip into your global environment, using these dedicated tool managers ensures that each application's dependencies remain isolated [1][2].
Citations:
🌐 Web query:
site:docs.astral.sh/uv/concepts/tools/ "Requires-Python" package metadata tool environment
💡 Result:
The Requires-Python metadata field is a specification used in Python packaging to declare the range of Python versions that a package or project supports [1][2][3]. This field is typically defined in a projects configuration file, such as pyproject.toml. When working with packaging tools and environments, the Requires-Python value serves as a constraint for installation. For instance, if a user attempts to install a package into an environment running a Python version outside the range specified in Requires-Python, the packaging tool should identify this incompatibility and prevent the installation. However, usage can vary by tool context. For example, some modern tooling like uv, when managing isolated tool environments, may ignore the Requires-Python value from a projects pyproject.toml in favor of specific version discovery logic or explicit user-provided version requirements [1][3]. In these specific tool environments, the tool links the environment to a designated Python version rather than strictly adhering to the metadata constraint defined within the project itself [1][2].
Citations:
- 1: https://docs.astral.sh/uv/concepts/tools/?featured_on=talkpython
- 2: https://docs.astral.sh/uv/concepts/tools/index.md
- 3: https://docs.astral.sh/uv/concepts/tools/
Pin the tool environment to Python 3.13. uv tool install does not use local Python constraints during interpreter discovery, while nemo-platform requires Python 3.12–3.13. Apply --python 3.13 to both commands. Add uv >=0.9.14 to the package README prerequisites.
📍 Affects 2 files
docs/get-started/setup.mdx#L33-L34(this comment)packages/nemo_platform/README.md#L29-L30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/get-started/setup.mdx` around lines 33 - 34, Pin both uv tool
installation commands in docs/get-started/setup.mdx (lines 33-34) to Python 3.13
by adding the --python 3.13 option. Update packages/nemo_platform/README.md
(lines 29-30) to list uv >=0.9.14 in the prerequisites.
Source: MCP tools
| Use a virtual environment instead when you also import the SDK from your own code. `nemo` then works only while the environment is active: | ||
|
|
||
| ```bash | ||
| pip install "nemo-platform[all]" | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,90p' packages/nemo_platform/README.md
printf '\n--- related setup references ---\n'
rg -n -i 'virtual environment|python -m venv|nemo-platform\[all\]|pip install|uv sync|NeMoPlatform' packages/nemo_platform docs README.md 2>/dev/null | head -200Repository: NVIDIA-NeMo/nemo-platform
Length of output: 28297
🏁 Script executed:
cat -n packages/nemo_platform/README.md | sed -n '1,90p'
printf '\n--- related setup references ---\n'
rg -n -i 'virtual environment|python -m venv|nemo-platform\[all\]|pip install|uv sync|NeMoPlatform' packages/nemo_platform docs README.md 2>/dev/null | head -200Repository: NVIDIA-NeMo/nemo-platform
Length of output: 27070
🏁 Script executed:
sed -n '25,60p' docs/get-started/setup.mdx
printf '\n--- CLI installation tabs ---\n'
sed -n '32,60p' docs/cli/index.mdx
printf '\n--- interpreter behavior probe ---\n'
python3 - <<'PY'
import os
import sys
print("current interpreter:", sys.executable)
print("virtual environment active:", sys.prefix != sys.base_prefix)
print("pip target for `python -m pip`:", sys.prefix)
print("PATH pip candidates:")
for directory in os.environ.get("PATH", "").split(os.pathsep):
candidate = os.path.join(directory, "pip")
if os.path.isfile(candidate) and os.access(candidate, os.X_OK):
print(candidate)
PYRepository: NVIDIA-NeMo/nemo-platform
Length of output: 1738
Create and activate the virtual environment before installing.
This command can install into the current system interpreter. Add the setup sequence or link to docs/get-started/setup.mdx.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/nemo_platform/README.md` around lines 32 - 36, Update the
installation instructions in the README to include creating and activating a
virtual environment before running the nemo-platform installation command, or
link to the existing setup guidance in docs/get-started/setup.mdx.
Drop the uv tool update-shell step: uv's own installer puts its bin directory on PATH, so the command-not-found entry only needs the virtual environment case. Cut the wheel-publishing detail from the interpreter entry. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aditya Pandey <aditya@autospace.co>
mckornfield
left a comment
There was a problem hiding this comment.
know we have the nat question still. I also think we should make pip install the last option, personally I'd prefer just uv tool install or uv install and then pip last (or not at all because it sucks)
|
|
||
| ```bash | ||
| uv pip install "nemo-platform[all]" | ||
| pip install "nemo-platform[all]" |
There was a problem hiding this comment.
should we just prefer the uv way, tool or not?
Blocker:
nvidia-nat-core1.8.0 capscryptographyat<47whiledata-designer-engine0.8.0 requires>=48.0.1, sonemo-platform[all]built from currentmaindoes not resolve from PyPI.Possible path:
uv tool install "nemo-platform[all]"is the documented install path now.nemo --versionto 0.0.0 for PyPi user.uv tool ...vspip ...based on how user set up nemo-platform.uv toolas recommended path.script/compile-wheel-constraints.sh: a missing closing quote makesbash -nfail — so the constraints could never be regenerated.>=3.12, the wrapper wheel it ships in supports 3.12-3.13.Cursor's description
Summary
uv tool install "nemo-platform[all]"is the documented install path now. Along the way this fixesnemo --versionreporting0.0.0for every PyPI user, makes the missing-extra hint print a command that works where the user actually installed, and repairs the constraints generator. A dependency conflict that blocks the same install path for the next release is documented below and deferred.Changes
_version.pyqueriesnemo-platforminstead ofnemo-platform-sdk. The SDK distribution only exists in the workspace (nemo-platform-sdkis 404 on PyPI) — PyPI users get the SDK bundled inside the wrapper wheel, so the lookup raised and fell back to0.0.0, which also reached telemetryclient_versionand the SDK client User-Agent. Both names report the same version in the workspace, so nothing changes for contributors. The edit is in the generator template, andSDK_DISTRIBUTION_NAMEis untouched because it still names the distribution being built.local/install.pydetects a uv tool environment through theuv-receipt.tomluv writes at the environment root, so the missing-extra hint printsuv tool install 'nemo-platform[all]'there andpip install 'nemo-platform[all]'in a virtual environment. Used bynemo services run, thenemo setuppreflight, andlocal/services.py. The Python 3.14 variant of that hint is gone: the wheel declaresrequires-python <3.14.uv tool install "nemo-platform[all]"(repo README, PyPI README,docs/get-started/setup.mdx,docs/cli/index.mdx), keep the virtual environment variant for SDK imports, and labelSETUP.mdas the contributor path.script/test-nemo-cli.shassertsnemo --versionreports a real version. It printed the output without checking it, which is how the0.0.0fallback went unnoticed. The CI wheel-test job runs this script, so the existing venv legs now guard the regression.script/compile-wheel-constraints.shhas been syntactically invalid since it landed — a missing closing quote makesbash -nfail — so the constraints could never be regenerated. Fixed, and moved to a 3.12 probe environment because the wrapper'srequires-pythonfloor rejects the old 3.11 one.>=3.12with aProgramming Language :: Python :: 3.14classifier while the wheel it ships in supports 3.12-3.13; both are tightened. The wheel build action defaults to 3.12 rather than 3.11, whichrequires-pythonalready excludes.Python version handling
--python 3.13stays out of the install commands. The prerequisites state 3.12-3.13, and the escape hatch lives in CLI troubleshooting, because uv enforces only the lower bound ofrequires-python: it planned to installnumpy==1.24.4, which declares<3.12, into a 3.14 environment, and it preferred a managed 3.14 over the system 3.12 for a tool install of this wheel. Metadata cannot keep a uv install on a supported interpreter, and the resulting failure is a source build of a dependency with no 3.14 wheels, so troubleshooting is where it belongs. NAT itself declares<3.14, so 3.14 support is gated upstream regardless.Deferred: the next release cannot be installed with
[all]nvidia-nat-core1.8.0 capscryptographyat<47whiledata-designer-engine0.8.0 requires>=48.0.1, sonemo-platform[all]built from currentmaindoes not resolve from PyPI. Reproduce withuv pip install --no-config "data-designer==0.8.0" "nvidia-nat-core==1.8.0". Published 0.3.0 predates the conflict and still installs, so users today are unaffected — the next release is not.Two things hid this. The repo carries
[tool.uv] override-dependencieswithcryptography>=50(for CVE-2026-69247), andwheel-testinstalls from inside the checkout, so uv applies that override and tests a dependency set no user can obtain. Running the same install from/tmp, or with--no-config, fails.A branch that fixed it (NAT
>=1.9.0a20260811,--no-configon the wheel installs, and auv tool installleg inwheel-test, all verified green) was reverted in 1c5a6b0: NAT publishes no stable release above 1.8.0, only daily1.9.0abuilds, and shipping pre-releases of our own toolkit in a released wheel is not a trade worth making. The follow-up, once NAT 1.9.0 is released:nvidia-nat-core/nvidia-nat-langchaininplugins/nemo-agentsand its examples. Note that uv accepts a pre-release only when a requirement it reads names one, so a pre-release line also requires naming every NAT distribution in the closure — a stable 1.9.0 removes that.--no-configto the wheel installs inwheel-testso CI stops resolving with the repo's overrides.uv tool installmatrix leg, which is the only leg that exercises the documented front door and the only one that catches this class of break, sinceuv tool installignores project config.The only interim that avoids pre-releases is downgrading
data-designerfrom 0.8.0 to 0.7.0, whose engine wantscryptography>=46.0.7,<47and so overlaps NAT 1.8.0. That is a feature downgrade across four pins in another team's plugin, and it still lands users below the CVE fix, so it is not proposed here. Note that every published NAT and data-designer release capscryptographybelow the patched 50.0.0; only an upstream cap relaxation gets wheel users onto it.Type of Change
Quality Gates
Verification
Signed-off-by:traileruv run pre-commit run -apasses, or any blocked checks are identified belowTargeted validation:
/tmp, no checkout and no activated virtual environment, against a wheel built from this branch:uv tool install <wheel>lands on 3.13 andnemo --versionreports0.3.0.post258.dev0+1c5a6b0e0;nemo services runprints the uv tool remediation, and the same check in a pip virtual environment prints the pip remediation; adding the extra (with a localcryptographyoverride for the conflict above) and runningscript/test-nemo-cli.shboots all 17 services and reportsplatform healthy; default+system workspaces present(exit 0).nemo version 0.0.0fails the script, and the CI sentinel0.0.0.dev19700101000000passes.uv run pytest packages/nemo_platform_ext/tests— 1751 passed, 4 skipped.uv run pytest plugins/nemo-agents/tests— 989 passed, 1 failed:test_is_port_free_returns_false_for_occupied_port, which turns on kernelSO_REUSEADDRsemantics on this VM and passes in CI.uv run ruff check .,uv lock --check(uv 0.9.14), andbash -n script/compile-wheel-constraints.share clean.uv run pre-commit run -a— ruff, ruff format, ty typechecks, config reference, uv.lock drift, copyright headers pass;helm-docs,uv-lock(wants uv 0.9.14) and the three Flox version-consistency hooks fail for environment reasons only.Summary by CodeRabbit
Summary by CodeRabbit
New Features
uv tool installoptions for the CLI and full platform services.Bug Fixes
Documentation