Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions nim-skills/openfold3-nim/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ allowed-tools: Bash, Read, Write, AskUserQuestion
# OpenFold3 NIM

Predict biomolecular structures with OpenFold3. It supports proteins, DNA, RNA,
small-molecule ligands, and multi-entity assemblies. Use this `SKILL.md` for
basic hosted/local NIM use; load supplemental files only when the task needs
small-molecule ligands, and multi-entity assemblies. Use this guide for
basic hosted and local NIM use; load supplemental files only when the task needs
deeper context:

- `references/api.md`: exact endpoints, schemas, Docker flags, response fields.
- `references/science.md`: purpose, strengths, limitations, and model handoffs.
- `references/parameters.md`: molecule fields, MSAs, templates, samples, tuning.
- `references/validation.md`: artifact checks and scientific sanity checks.
- `references/examples.md`: compact hosted/local request patterns.
- `references/examples.md`: compact hosted and local request patterns.

## Choose Mode

Expand All @@ -34,22 +34,26 @@ Mode difference: the local prediction path has no `/v1/` prefix. Hosted requests
startup uses `NGC_API_KEY` (or `NVIDIA_API_KEY` via the preflight) for
registry login, entitlement checks, and first-run model downloads; pass it
into the container with `-e NGC_API_KEY`. Local inference requests use no
auth header after readiness. Warm-cache key-free startup varies by
image/version and should not be assumed.
auth header after readiness, so bind the host port to loopback with
`-p 127.0.0.1:8000:8000`. Warm-cache key-free startup varies by image version
and should not be assumed.

## Auth And Environment

Do not print API keys. Confirm they exist with shell tests, not echoes.
Use credentials already supplied in the environment or injected by a secret
manager. Do not load credential files, print keys, or enable shell tracing.
Confirm keys exist with shell tests.

Hosted needs `NGC_API_KEY` in the request header. Local startup needs
`NGC_API_KEY`, or `NVIDIA_API_KEY` as a fallback, plus `LOCAL_NIM_CACHE`.
A repo-root `.env` file may be sourced as a local override before validation.

## Local Docker

Use the official OpenFold3 NIM image and mount `LOCAL_NIM_CACHE` at
`/opt/nim/.cache`. First startup downloads model artifacts and can take several
minutes.
`/opt/nim/.cache`. Before executing setup, explain that registry authentication
sends the key to the NVIDIA registry at https://nvcr.io and first startup
downloads about 10–15 GB of model weights into the cache. Run deployment only
when requested; for a setup guide, provide the commands without running them.

When writing local setup commands, copy the preflight below exactly. Do not
replace it with a simple `: "${NGC_API_KEY:?Set NGC_API_KEY}"` check, do not
Expand All @@ -59,28 +63,27 @@ should show the literal `--gpus "device=0"`; choose a different device only
when the user asks.

```bash
set -a
[ -f .env ] && . ./.env
set +a
set +x

if [ -z "${NGC_API_KEY:-}" ] && [ -n "${NVIDIA_API_KEY:-}" ]; then
export NGC_API_KEY="$NVIDIA_API_KEY"
NGC_API_KEY="$NVIDIA_API_KEY"
fi
: "${NGC_API_KEY:?Set NGC_API_KEY or NVIDIA_API_KEY}"
export NGC_API_KEY
: "${LOCAL_NIM_CACHE:?Set LOCAL_NIM_CACHE}"

echo "$NGC_API_KEY" | docker login nvcr.io --username '$oauthtoken' --password-stdin

mkdir -p "${LOCAL_NIM_CACHE}"
chmod 755 "${LOCAL_NIM_CACHE}"

printf '%s\n' "$NGC_API_KEY" | \
docker login nvcr.io --username '$oauthtoken' --password-stdin && \
docker run --rm --name openfold3 \
--runtime=nvidia \
--gpus "device=0" \
--shm-size=16g \
-e NGC_API_KEY \
-v "${LOCAL_NIM_CACHE}:/opt/nim/.cache" \
-p 8000:8000 \
-p 127.0.0.1:8000:8000 \
nvcr.io/nim/openfold/openfold3:latest
```

Expand Down
34 changes: 6 additions & 28 deletions nim-skills/openfold3-nim/config/skillspector-baseline.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,6 @@
# SkillSpector suppression baseline — openfold3-nim
#
# Audited false-positive suppression, auto-applied by the NVSkills Tier 1
# runner via config/skillspector-baseline.yml. Suppressed findings remain in
# the report JSON marked `suppressed: true` with the reason below.
version: 1

rules:
- id: "PE3"
path: "*SKILL.md"
reason: >-
Reviewed false positive (BioNeMo, omosafi@nvidia.com, 2026-08-12).
PE3 fires on the literal `.env` token in this NIM skill's documented
NGC_API_KEY loading snippet (`[ -f .env ] && . ./.env`), which reads the
user's own repo-root dotenv to obtain their NGC API key for
`docker login nvcr.io`. This is first-party, user-facing setup guidance for
the user's own credential file — not credential theft. No SSH keys, cloud
credential stores, or third-party secret files are accessed.
- id: "PE3"
path: "*references/api.md"
reason: >-
Reviewed false positive (BioNeMo, omosafi@nvidia.com, 2026-08-12).
PE3 fires on the literal `.env` token in this NIM skill's documented
NGC_API_KEY loading snippet (`[ -f .env ] && . ./.env`), which reads the
user's own repo-root dotenv to obtain their NGC API key for
`docker login nvcr.io`. This is first-party, user-facing setup guidance for
the user's own credential file — not credential theft. No SSH keys, cloud
credential stores, or third-party secret files are accessed.
# No findings are suppressed. Keep an explicit per-skill baseline so NVSkills
# does not fall back to the repository-wide baseline for unrelated skills.
# Credential-file loading was removed from the instructions and evaluations.
version: 2
rules: []
fingerprints: []
148 changes: 27 additions & 121 deletions nim-skills/openfold3-nim/evals/evals.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,12 @@
"expected_output": "A Python script that calls the hosted OpenFold3 endpoint with Bearer auth, constructs an inputs payload with the peptide sequence as a protein molecule type including a minimal MSA, saves the returned structure to a PDB or CIF file, and prints the confidence scores.",
"files": [],
"assertions": [
{
"id": "hosted-endpoint-url",
"description": "Uses the correct hosted OpenFold3 endpoint URL",
"check": "Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'"
},
{
"id": "bearer-auth-header",
"description": "Sets Authorization header with Bearer token from NGC_API_KEY",
"check": "Script contains 'Authorization' and 'Bearer' and 'NGC_API_KEY'"
},
{
"id": "inputs-array-structure",
"description": "Payload uses 'inputs' array containing molecule objects",
"check": "Script payload contains 'inputs' key with an array/list containing 'molecules'"
},
{
"id": "molecule-type-protein",
"description": "Molecule object sets type to 'protein'",
"check": "Script contains 'type' and 'protein' in the molecule specification"
},
{
"id": "msa-structure",
"description": "MSA field is provided with nested alignment structure",
"check": "Script contains 'msa' with an alignment string starting with '>query'"
},
{
"id": "saves-structure-output",
"description": "Saves the returned structure to a file and prints confidence scores",
"check": "Script writes structure content to a file and references 'confidence_score' or 'structures_with_scores' from the response"
}
"[hosted-endpoint-url] Uses the correct hosted OpenFold3 endpoint URL: Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'",
"[bearer-auth-header] Sets Authorization header with Bearer token from NGC_API_KEY: Script contains 'Authorization' and 'Bearer' and 'NGC_API_KEY'",
"[inputs-array-structure] Payload uses 'inputs' array containing molecule objects: Script payload contains 'inputs' key with an array/list containing 'molecules'",
"[molecule-type-protein] Molecule object sets type to 'protein': Script contains 'type' and 'protein' in the molecule specification",
"[msa-structure] MSA field is provided with nested alignment structure: Script contains 'msa' with an alignment string starting with '>query'",
"[saves-structure-output] Saves the returned structure to a file and prints confidence scores: Script writes structure content to a file and references 'confidence_score' or 'structures_with_scores' from the response"
]
},
{
Expand All @@ -45,74 +21,28 @@
"expected_output": "A Python script with two molecules in the payload — a protein with sequence and MSA, and a ligand using ccd_codes set to ATP — calling the hosted endpoint, saving structure output, and printing pLDDT and confidence scores.",
"files": [],
"assertions": [
{
"id": "hosted-endpoint-url",
"description": "Uses the correct hosted endpoint URL",
"check": "Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'"
},
{
"id": "two-molecules",
"description": "Payload includes both a protein molecule and a ligand molecule",
"check": "Script payload contains both 'type' set to 'protein' and 'type' set to 'ligand' in two separate molecule objects"
},
{
"id": "ccd-codes-field",
"description": "Ligand uses ccd_codes field set to ATP",
"check": "Script contains 'ccd_codes' and 'ATP'"
},
{
"id": "protein-sequence-present",
"description": "The provided protein sequence appears in the payload",
"check": "Script contains 'MTEYKLVVVGACGVGKSALTIQLIQNHFVDEYDPTIEDSYRKQVVID'"
},
{
"id": "confidence-scores-reported",
"description": "Prints or displays confidence score and pLDDT from response",
"check": "Script references 'confidence_score' and 'complex_plddt_score' or 'plddt' from the response"
},
{
"id": "saves-output-file",
"description": "Saves the predicted structure to a PDB or CIF file",
"check": "Script writes structure content to a file with .pdb or .cif extension"
}
"[hosted-endpoint-url] Uses the correct hosted endpoint URL: Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'",
"[two-molecules] Payload includes both a protein molecule and a ligand molecule: Script payload contains both 'type' set to 'protein' and 'type' set to 'ligand' in two separate molecule objects",
"[ccd-codes-field] Ligand uses ccd_codes field set to ATP: Script contains 'ccd_codes' and 'ATP'",
"[protein-sequence-present] The provided protein sequence appears in the payload: Script contains 'MTEYKLVVVGACGVGKSALTIQLIQNHFVDEYDPTIEDSYRKQVVID'",
"[confidence-scores-reported] Prints or displays confidence score and pLDDT from response: Script references 'confidence_score' and 'complex_plddt_score' or 'plddt' from the response",
"[saves-output-file] Saves the predicted structure to a PDB or CIF file: Script writes structure content to a file with .pdb or .cif extension"
]
},
{
"id": "3",
"prompt": "Help me set up the OpenFold3 NIM locally with Docker. I have an A100 80GB GPU and NGC_API_KEY is set. After setup, predict the structure of this protein: ACDEFGHIKLMNPQRSTVWY.",
"expected_output": "Docker setup commands using shell env first and optional repo-root .env overrides, requiring NGC_API_KEY or NVIDIA_API_KEY fallback plus LOCAL_NIM_CACHE, running with --gpus 'device=0', --shm-size=16g, and the correct cache mount path, then a health check loop and no-auth prediction script targeting localhost:8000.",
"expected_output": "Docker setup commands using supplied environment variables without loading credential files, requiring NGC_API_KEY or NVIDIA_API_KEY fallback plus LOCAL_NIM_CACHE, authenticating to nvcr.io using --password-stdin, and starting the container only after successful login. The container uses --gpus 'device=0', --shm-size=16g, the correct cache mount path, and port 8000 bound to 127.0.0.1, followed by a health check loop and no-auth prediction script targeting localhost:8000.",
"files": [],
"assertions": [
{
"id": "docker-login-nvcr",
"description": "Includes docker login command for nvcr.io with oauthtoken",
"check": "Output contains 'docker login nvcr.io' and 'oauthtoken'"
},
{
"id": "docker-image-tag",
"description": "References the correct OpenFold3 container image",
"check": "Output contains 'nvcr.io/nim/openfold/openfold3'"
},
{
"id": "single-gpu-flag",
"description": "Uses single GPU device specification",
"check": "Output contains '--gpus' and 'device=0'"
},
{
"id": "shm-size-flag",
"description": "Includes --shm-size flag (required for this NIM)",
"check": "Output contains '--shm-size' and '16'"
},
{
"id": "env-contract-and-cache",
"description": "Local setup uses the repo env contract and LOCAL_NIM_CACHE",
"check": "Output sources repo-root .env only if present, supports NVIDIA_API_KEY fallback to NGC_API_KEY, requires LOCAL_NIM_CACHE, and mounts LOCAL_NIM_CACHE to /opt/nim/.cache"
},
{
"id": "local-endpoint-url",
"description": "Prediction script targets localhost:8000 without /v1/ prefix",
"check": "Script contains 'localhost:8000/biology/openfold/openfold3/predict'"
}
"[docker-login-nvcr] Authenticates image pulls before container startup: Commands use docker login nvcr.io with the literal username '$oauthtoken' and --password-stdin, passing NGC_API_KEY via stdin without exposing its value in logs or command-line arguments",
"[login-failure-stops-startup] Prevents startup after failed registry authentication: Commands use an explicit success condition or shell error handling so a failed login prevents container startup",
"[loopback-port-binding] Keeps the unauthenticated local API on loopback: The startup command publishes port 8000 with '-p 127.0.0.1:8000:8000' or equivalent --publish syntax",
"[docker-image-tag] References the correct OpenFold3 container image: Output contains 'nvcr.io/nim/openfold/openfold3'",
"[single-gpu-flag] Uses single GPU device specification: Output contains '--gpus' and 'device=0'",
"[shm-size-flag] Includes --shm-size flag (required for this NIM): Output contains '--shm-size' and '16'",
"[env-contract-and-cache] Local setup uses supplied environment variables and LOCAL_NIM_CACHE: Commands use credentials from the environment without loading credential files, support NVIDIA_API_KEY fallback to NGC_API_KEY, export NGC_API_KEY for the container, require LOCAL_NIM_CACHE, and mount LOCAL_NIM_CACHE to /opt/nim/.cache",
"[local-endpoint-url] Prediction script targets localhost:8000 without /v1/ prefix: Script contains 'localhost:8000/biology/openfold/openfold3/predict'"
]
},
{
Expand All @@ -121,36 +51,12 @@
"expected_output": "A Python script with three molecules in the payload (protein + two DNA chains), diffusion_samples set to 2, output_format set to 'cif', using the hosted endpoint. Saves and names the returned CIF files and prints per-sample confidence scores.",
"files": [],
"assertions": [
{
"id": "hosted-endpoint-url",
"description": "Uses the correct hosted endpoint URL",
"check": "Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'"
},
{
"id": "protein-and-dna-molecules",
"description": "Payload contains one protein molecule and two DNA molecules",
"check": "Script contains 'type' set to 'protein' and 'type' set to 'dna' in the molecules list"
},
{
"id": "dna-sequences-present",
"description": "Both DNA sequences appear in the payload",
"check": "Script contains 'ATCGATCGATCG' and 'CGATCGATCGAT'"
},
{
"id": "diffusion-samples",
"description": "diffusion_samples is set to 2",
"check": "Script contains 'diffusion_samples' and '2'"
},
{
"id": "cif-output-format",
"description": "output_format is set to 'cif'",
"check": "Script contains 'output_format' and 'cif'"
},
{
"id": "multiple-structures-saved",
"description": "Script iterates over structures_with_scores to save each sample",
"check": "Script iterates over the response structures and saves each to a separate .cif file"
}
"[hosted-endpoint-url] Uses the correct hosted endpoint URL: Script contains 'health.api.nvidia.com/v1/biology/openfold/openfold3/predict'",
"[protein-and-dna-molecules] Payload contains one protein molecule and two DNA molecules: Script contains 'type' set to 'protein' and 'type' set to 'dna' in the molecules list",
"[dna-sequences-present] Both DNA sequences appear in the payload: Script contains 'ATCGATCGATCG' and 'CGATCGATCGAT'",
"[diffusion-samples] diffusion_samples is set to 2: Script contains 'diffusion_samples' and '2'",
"[cif-output-format] output_format is set to 'cif': Script contains 'output_format' and 'cif'",
"[multiple-structures-saved] Script iterates over structures_with_scores to save each sample: Script iterates over the response structures and saves each to a separate .cif file"
]
}
]
Expand Down
24 changes: 16 additions & 8 deletions nim-skills/openfold3-nim/references/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,35 +116,43 @@

## Docker Reference

Provide credentials and the cache path through the environment; this example
does not load credential files. Keep shell tracing disabled. Registry login
uses the key on stdin, and the container starts only if login succeeds.
The container uses the key for entitlement checks and first-run model downloads
of about 10–15 GB. Local inference is unauthenticated, so the published host
port binds to loopback.

```bash
set -a
[ -f .env ] && . ./.env
set +a
set +x

# Keep this fallback even when NGC_API_KEY is already set; it is the repo env contract.
if [ -z "${NGC_API_KEY:-}" ] && [ -n "${NVIDIA_API_KEY:-}" ]; then
export NGC_API_KEY="$NVIDIA_API_KEY"
NGC_API_KEY="$NVIDIA_API_KEY"
fi
: "${NGC_API_KEY:?Set NGC_API_KEY or NVIDIA_API_KEY in the environment or repo-root .env}"
: "${NGC_API_KEY:?Set NGC_API_KEY or NVIDIA_API_KEY}"
export NGC_API_KEY
: "${LOCAL_NIM_CACHE:?Set LOCAL_NIM_CACHE}"

: "${LOCAL_NIM_CACHE:?Set LOCAL_NIM_CACHE in the environment or repo-root .env}"
mkdir -p "${LOCAL_NIM_CACHE}"
chmod 755 "${LOCAL_NIM_CACHE}"

printf '%s\n' "$NGC_API_KEY" | \
docker login nvcr.io --username '$oauthtoken' --password-stdin && \
docker run --rm --name openfold3 \
--runtime=nvidia \
--gpus "device=0" \
--shm-size=16g \
-e NGC_API_KEY \
-v "${LOCAL_NIM_CACHE}:/opt/nim/.cache" \
-p 8000:8000 \
-p 127.0.0.1:8000:8000 \
nvcr.io/nim/openfold/openfold3:latest
```

| Flag | Value | Notes |
|---|---|---|
| `--gpus` | `device=0` | Single GPU only; choose another device only when required |
| `--shm-size` | `16g` | Required |
| `-p` | `127.0.0.1:8000:8000` | Bind the unauthenticated API to the host's loopback address |
| Cache mount | `/opt/nim/.cache` | ~10–15 GB model weights |
| Image | `nvcr.io/nim/openfold/openfold3:latest` | v1.4.0 as of 2025 |

Expand Down
Loading
Loading