@moldesk/registry 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,219 @@
1
+ schemaVersion: 1
2
+ name: diffdock
3
+ displayName: DiffDock-L
4
+ modelVersion: "1.1"
5
+ adapterVersion: 0.2.0
6
+ description: Blind small-molecule docking against a protein, returning ranked poses and confidence (not binding affinity).
7
+ category: docking
8
+ status: planned
9
+ license: MIT
10
+ homepage: https://github.com/gcorso/DiffDock
11
+ source:
12
+ repository: https://github.com/gcorso/DiffDock
13
+ # `main` already ships DiffDock-L by default (upstream README: "By default the
14
+ # repository now runs the new model [DiffDock-L]... use GitHub commit history
15
+ # to run the original DiffDock model" for legacy v1). Verified live against
16
+ # upstream on 2026-09-23 via `git ls-remote` (this was HEAD of `main` at that
17
+ # time) — re-verify before promoting this model past `planned`, since `main`
18
+ # moves.
19
+ revision: 85c49b60d3e0b0182a59ee43a34a6d7036981284
20
+ runtimes:
21
+ # Linux/NVIDIA only. Upstream's pinned dependency stack (torch==1.13.1+cu117
22
+ # plus matching cu117-built torch-geometric extension wheels) is CUDA/Linux
23
+ # specific with no Apple Silicon build; there is no genuine CPU-only path
24
+ # either (upstream exposes no --device/--cpu/--gpu flag — device selection is
25
+ # its own unconditional `torch.device('cuda' if torch.cuda.is_available() else
26
+ # 'cpu')`). `nvidiaGpu`/`cuda` are `required`, not `recommended`: this
27
+ # adapter's verifyInstallation runs a mandatory CUDA probe, matching the
28
+ # Boltz Linux/CUDA precedent, so a CUDA-less host fails install verification
29
+ # rather than silently succeeding into a CPU-fallback-capable install.
30
+ - kind: python
31
+ # torch==1.13.1+cu117's matching PyTorch Geometric extension wheels
32
+ # (torch-scatter/torch-cluster/torch-sparse/torch-spline-conv at the exact
33
+ # pinned +pt113cu117 build) are published on data.pyg.org only up to
34
+ # cp310 — verified live on 2026-09-23 by listing
35
+ # https://data.pyg.org/whl/torch-1.13.1+cu117.html: no cp311 build exists
36
+ # for these packages at this torch+CUDA combination. Python 3.10, not
37
+ # 3.11, is required for this runtime entry.
38
+ python: "3.10"
39
+ installer: uv
40
+ platforms:
41
+ - linux-x64
42
+ # PyTorch's own cu117 build is on a real PEP-503-compatible extra index
43
+ # (the officially documented `--extra-index-url` pattern) — added
44
+ # ALONGSIDE default PyPI, never replacing it, so ordinary packages
45
+ # (pandas, scipy, rdkit, …) still resolve normally. PyTorch Geometric's
46
+ # CUDA extension wheels (torch-scatter/torch-cluster/torch-sparse/
47
+ # torch-spline-conv) are published only as a flat wheel-listing page —
48
+ # genuinely a `--find-links` page, not a PEP-503 index (verified live on
49
+ # 2026-09-24: the page has no per-package subdirectory structure) —
50
+ # upstream's own environment.yml uses exactly this split
51
+ # (`--extra-index-url https://download.pytorch.org/whl/cu117` /
52
+ # `--find-links https://pytorch-geometric.com/whl/torch-1.13.1+cu117.html`;
53
+ # findLinks below points at data.pyg.org directly, the canonical host
54
+ # that URL redirects to, confirmed to serve the identical wheel listing).
55
+ extraIndexUrls:
56
+ - https://download.pytorch.org/whl/cu117
57
+ findLinks:
58
+ - https://data.pyg.org/whl/torch-1.13.1+cu117.html
59
+ # Every ABI-sensitive CUDA extension package pinned below also carries a
60
+ # real `hashes` entry (downloaded and verified byte-for-byte on
61
+ # 2026-09-24) AND is listed here so `--only-binary <name>` is passed on
62
+ # every install invocation — install fails closed rather than silently
63
+ # falling back to a from-source build if wheel resolution ever fails.
64
+ # torch-geometric is deliberately excluded: it has no published wheel at
65
+ # all (PyPI only ships an sdist), and it is pure Python with no CUDA/ABI
66
+ # concern, so building it from source is normal and expected.
67
+ binaryOnly:
68
+ - torch
69
+ - torch-cluster
70
+ - torch-scatter
71
+ - torch-sparse
72
+ - torch-spline-conv
73
+ nvidiaGpu: required
74
+ cuda:
75
+ level: required
76
+ # Upstream's own environment.yml (not requirements.txt, which omits this
77
+ # entirely) installs an older `setuptools` via conda BEFORE anything else
78
+ # (verified live on 2026-09-24). It also keeps `pkg_resources`, which several
79
+ # of the pinned packages expect, available in the bare uv venv.
80
+ preInstall:
81
+ - name: setuptools
82
+ version: 69.5.1
83
+ # `openfold` is intentionally NOT installed. Upstream builds it so ESMFold can
84
+ # predict a structure from a bare sequence (`inference.py --protein_sequence`,
85
+ # `esm.pretrained.esmfold_v1()`), but compiling its CUDA extension needs a
86
+ # full CUDA 11.7 toolkit (nvcc) matching torch 1.13.1+cu117, which modern GPU
87
+ # hosts (CUDA 12.x) do not have and which PyPI does not ship (the cu11 nvcc
88
+ # wheel has no compiler driver). This adapter only accepts a protein
89
+ # structure file (`proteinPath`), so that code path is never reached; docking
90
+ # from a PDB uses only ESM2 embeddings (`esm.pretrained`), which do not need
91
+ # openfold.
92
+ requirements:
93
+ - name: torch
94
+ version: 1.13.1+cu117
95
+ hashes:
96
+ - 14c5c9db09df8cf1b3942a3479c779da6e293a84a162d8a6ac71e2bde30e30c5
97
+ - name: torch-geometric
98
+ version: "2.2.0"
99
+ hashes:
100
+ - fdb282451fc33270e8e0b81d9aec7b70590363227dab0b1a7cb50a91d7b98e1d
101
+ - name: torch-cluster
102
+ version: 1.6.0+pt113cu117
103
+ hashes:
104
+ - ee94470e92ec17ec94fdeae19e2c0a7bf1cb15505c8f8c4206388774f6c4886a
105
+ - name: torch-scatter
106
+ version: 2.1.0+pt113cu117
107
+ hashes:
108
+ - 9e26507e54f0cf7b09fe039c5a5d897f53bbbb991c86d4c27115909411236168
109
+ - name: torch-sparse
110
+ version: 0.6.16+pt113cu117
111
+ hashes:
112
+ - c23999bc4e24379d8ae807176bb31eb6ce47288fc5e0126141761339b0f07225
113
+ - name: torch-spline-conv
114
+ version: 1.2.1+pt113cu117
115
+ hashes:
116
+ - cf39e3af57084261afaabb233055f5f0b00df5bba51bd58947112ee4f9a7eb6f
117
+ # environment.yml pins e3nn==0.5.1 and adds pytorch-lightning==1.9.5,
118
+ # neither of which matches/exists in requirements.txt (which pins
119
+ # e3nn==0.5.0 and omits pytorch-lightning entirely) — verified live on
120
+ # 2026-09-24 that environment.yml is the more carefully maintained,
121
+ # explicitly-sequenced install recipe (it has ordering-rationale
122
+ # comments requirements.txt lacks), so its pins are followed here.
123
+ - name: e3nn
124
+ version: "0.5.1"
125
+ - name: pytorch-lightning
126
+ version: "1.9.5"
127
+ - name: fair-esm
128
+ version: "2.0.0"
129
+ extras:
130
+ - esmfold
131
+ - name: rdkit
132
+ version: 2022.03.3
133
+ - name: scipy
134
+ version: "1.12.0"
135
+ - name: scikit-learn
136
+ version: "1.1.0"
137
+ - name: networkx
138
+ version: 2.8.4
139
+ - name: pandas
140
+ version: 1.5.1
141
+ # Upstream pins prody 2.2.0, which has no wheel for CPython 3.10 and whose C
142
+ # extension (rtbtools.c) fails to compile on current toolchains. 2.4.1 builds
143
+ # and imports on 3.10 (verified on Linux x64) and DiffDock only uses it for
144
+ # PDB parsing/chi angles in datasets/parse_chi.py.
145
+ - name: prody
146
+ version: "2.4.1"
147
+ # Upstream leaves numpy unpinned; unpinned resolves to numpy 2.x, which breaks
148
+ # the pinned pandas 1.5.1 and torch 1.13.1 builds. 1.23.5 matches that era.
149
+ - name: numpy
150
+ version: "1.23.5"
151
+ - name: pybind11
152
+ version: 2.11.1
153
+ - name: torchmetrics
154
+ version: 0.11.0
155
+ # Upstream's own requirements.txt/environment.yml pin dllogger unpinned
156
+ # (`dllogger@git+https://github.com/NVIDIA/dllogger.git`, no @revision) —
157
+ # a real upstream laxity, not something to carry over. This pins the
158
+ # exact commit that was dllogger's HEAD when verified on 2026-09-23; a
159
+ # future revalidation should re-check whether upstream has since pinned
160
+ # a specific commit of its own to adopt instead.
161
+ - name: dllogger
162
+ source: https://github.com/NVIDIA/dllogger
163
+ revision: 0478734ff7be75adde8d160e04872664d1c62e5f
164
+ # `inference.py` silently downloads `diffdock_models.zip` from a GitHub release
165
+ # on first run when `--model_dir` doesn't already exist
166
+ # (`utils/download.py:download_and_extract`), and separately, every run
167
+ # unconditionally computes ESM2 language-model embeddings
168
+ # (`utils/inference_utils.py`'s `InferenceDataset` is always constructed with
169
+ # `lm_embeddings=True`), which downloads the `esm2_t33_650M_UR50D` checkpoint
170
+ # into torch.hub's cache dir on first use — both are real, verified network
171
+ # fetches into an otherwise uncontrolled location, not just the one obvious
172
+ # weights archive. All three artifacts are pinned here with checksums
173
+ # downloaded and verified byte-for-byte on 2026-09-23, and the adapter always
174
+ # passes `--model_dir`/`--confidence_model_dir` pointing at the pre-populated
175
+ # `diffdock-weights` target plus `TORCH_HOME` pointing at the pre-populated
176
+ # `torch-home` target, so neither download path is ever reached during a real
177
+ # run.
178
+ assets:
179
+ - id: diffdock-l-weights
180
+ url: https://github.com/gcorso/DiffDock/releases/download/v1.1/diffdock_models.zip
181
+ source: https://github.com/gcorso/DiffDock
182
+ sha256: 5a95b6a1555be47ab1d6f0a8ffd25152f7fe32f5956005bb821e13e7a37d4a3d
183
+ sizeBytes: 129825226
184
+ archive: zip
185
+ target: diffdock-weights
186
+ - id: esm2-t33-650m-ur50d
187
+ url: https://dl.fbaipublicfiles.com/fair-esm/models/esm2_t33_650M_UR50D.pt
188
+ source: https://github.com/facebookresearch/esm
189
+ license: MIT
190
+ sha256: ea9d0522b335a8778dea6535a65301f10208dece28cd5865482b0b1fc446168c
191
+ sizeBytes: 2604537549
192
+ target: torch-home/hub/checkpoints/esm2_t33_650M_UR50D.pt
193
+ - id: esm2-t33-650m-ur50d-contact-regression
194
+ url: https://dl.fbaipublicfiles.com/fair-esm/regression/esm2_t33_650M_UR50D-contact-regression.pt
195
+ source: https://github.com/facebookresearch/esm
196
+ license: MIT
197
+ sha256: 8ffe6edbd4173dc8d45c2cd5cb27d43aad77ec26b4c768200c58ae1f96693575
198
+ sizeBytes: 3687
199
+ target: torch-home/hub/checkpoints/esm2_t33_650M_UR50D-contact-regression.pt
200
+ hardware:
201
+ platforms:
202
+ - linux-x64
203
+ nvidiaGpu: required
204
+ cuda:
205
+ level: required
206
+ input:
207
+ formats:
208
+ - .json
209
+ required: true
210
+ outputs:
211
+ - id: top_pose
212
+ glob: "*/rank1.sdf"
213
+ required: true
214
+ - id: ranked_poses
215
+ glob: "*/rank*_confidence*.sdf"
216
+ required: true
217
+ - id: poses_summary
218
+ glob: "poses_summary.json"
219
+ required: true
@@ -0,0 +1,67 @@
1
+ schemaVersion: 1
2
+ name: ligandmpnn
3
+ displayName: LigandMPNN
4
+ modelVersion: 0.1.2
5
+ adapterVersion: 0.1.0
6
+ description: Protein sequence design for protein-ligand and multimer systems (Dauparas et al. 2023).
7
+ category: sequence-design
8
+ status: beta
9
+ license: MIT
10
+ homepage: https://github.com/dauparas/LigandMPNN
11
+ source:
12
+ repository: https://github.com/dauparas/LigandMPNN
13
+ revision: 26ec57ac976ade5379920dbd43c7f97a91cf82de
14
+ runtimes:
15
+ - kind: python
16
+ python: "3.11"
17
+ installer: uv
18
+ requirements:
19
+ - name: biopython
20
+ version: "1.79"
21
+ - name: filelock
22
+ version: 3.13.1
23
+ - name: fsspec
24
+ version: 2024.3.1
25
+ - name: Jinja2
26
+ version: 3.1.3
27
+ - name: MarkupSafe
28
+ version: 2.1.5
29
+ - name: ml-collections
30
+ version: 0.1.1
31
+ - name: dm-tree
32
+ version: 0.1.8
33
+ - name: torch
34
+ version: 2.2.1
35
+ - name: numpy
36
+ version: "1.23.5"
37
+ - name: prody
38
+ version: 2.4.1
39
+ - name: pyparsing
40
+ version: 3.1.1
41
+ - name: scipy
42
+ version: 1.12.0
43
+ # prody 2.4.1 imports `pkg_resources` at import time; a bare uv venv has no
44
+ # setuptools, and setuptools >= 81 no longer ships pkg_resources.
45
+ - name: setuptools
46
+ version: 69.5.1
47
+ assets:
48
+ - id: ligandmpnn-checkpoint
49
+ url: https://files.ipd.uw.edu/pub/ligandmpnn/ligandmpnn_v_32_010_25.pt
50
+ source: LigandMPNN upstream model parameter distribution
51
+ license: MIT
52
+ sha256: 161cd264061fda9680cbb940255522ae42f2966c552d045d87913d9452a80970
53
+ target: model_params/ligandmpnn_v_32_010_25.pt
54
+ sizeBytes: 10541943
55
+ archive: none
56
+ hardware:
57
+ platforms:
58
+ - darwin-arm64
59
+ - linux-x64
60
+ input:
61
+ formats:
62
+ - .pdb
63
+ required: true
64
+ outputs:
65
+ - id: sequences
66
+ glob: "seqs/*.fa"
67
+ required: true
@@ -0,0 +1,169 @@
1
+ schemaVersion: 1
2
+ name: opendde
3
+ displayName: OpenDDE Preview
4
+ modelVersion: 1.1.1
5
+ adapterVersion: 0.1.0
6
+ description: All-atom biomolecular co-folding (proteins, nucleic acids, ligands, ions) from Aureka AI Research — upstream preview release.
7
+ category: structure-prediction
8
+ # Upstream itself labels this a preview ("CLI flags, input/output JSON fields,
9
+ # and released checkpoints may change between versions ... not yet intended for
10
+ # production pipelines"), so this stays `beta` regardless of verification.
11
+ status: beta
12
+ license: Apache-2.0
13
+ homepage: https://github.com/aurekaresearch/OpenDDE
14
+ source:
15
+ repository: https://github.com/aurekaresearch/OpenDDE
16
+ # Tag v1.1.1 (annotated tag object 1e986714b6a397d0d812d58ee78e1c7dc8c75cf2
17
+ # peels to this commit), verified via `git ls-remote --tags` on 2026-09-26.
18
+ # The PyPI `opendde==1.1.1` wheel pinned below was unpacked and compared
19
+ # file-by-file against this commit's `opendde/` and `runner/` trees: all 117
20
+ # files byte-identical, and `opendde/config/model_manifest.json` in both
21
+ # declares package version 1.1.1.
22
+ revision: ddfa1df8aff1babf1fddac4247b7d2351bd0ce9f
23
+ adapterVerification:
24
+ lastVerifiedAt: "2026-09-26T12:31:00.000Z"
25
+ platforms:
26
+ - darwin-arm64
27
+ notes: >-
28
+ Clean `moldesk install opendde` on an Apple M3 (macOS 26.6.2, Python
29
+ 3.11.16, torch 2.7.1, opendde 1.1.1). verifyInstallation passed: asset
30
+ sizes and SHA-256, a real MPS tensor op, pinned versions, and CLI flags.
31
+ `moldesk run opendde examples/opendde/tiny.json` succeeded in 39 s with
32
+ upstream logging "Selected inference device: mps". Outputs: a parseable
33
+ mmCIF and confidence JSON, checksummed in run.json. The ligand-file
34
+ example also passed, with companion staging verified after the source
35
+ files were deleted. Invalid device/template params were rejected before
36
+ launch. Linux/CUDA was not run (no NVIDIA hardware), so it is not
37
+ advertised. Full evidence is in models/opendde/README.md.
38
+ runtimes:
39
+ # Apple Silicon: native PyPI torch (MPS-enabled macOS arm64 build), no
40
+ # CUDA/cuEquivariance extra, never the NVIDIA-only Docker image. Upstream
41
+ # documents `--device mps` on Apple Silicon; the live gate for this entry is
42
+ # recorded in models/opendde/README.md.
43
+ - kind: python
44
+ python: "3.11"
45
+ installer: uv
46
+ platforms:
47
+ - darwin-arm64
48
+ # Measured on the 2026-09-26 live install: the resulting .venv is 823 MB.
49
+ # Download is an estimate (compressed wheels, torch alone is 68.6 MB).
50
+ estimatedDownloadBytes: 300000000
51
+ estimatedDiskBytes: 865000000
52
+ requirements:
53
+ # Exact artifact digest of opendde-1.1.1-py3-none-any.whl from PyPI.
54
+ - name: opendde
55
+ version: 1.1.1
56
+ hashes:
57
+ - 94b193bd360e017c9cfab08d199ec9333cb2919a49fe1d9270c659c4b2efe544
58
+ # opendde 1.1.1 itself pins `torch==2.7.1`; this is PyPI's
59
+ # torch-2.7.1-cp311-none-macosx_11_0_arm64.whl.
60
+ - name: torch
61
+ version: 2.7.1
62
+ hashes:
63
+ - aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730
64
+ # Linux x64 + NVIDIA: upstream's documented `--torch-backend cu126
65
+ # "opendde[gpu]"` install (cuEquivariance/Triton kernels), expressed through
66
+ # the closed-enum `torchBackend` field rather than a pip argument fragment.
67
+ # NOT advertised in `hardware.platforms` below: no NVIDIA hardware was
68
+ # available to run the CUDA live gate, so a Linux host is rejected by the
69
+ # compatibility check before this entry is ever selected. Add `linux-x64` to
70
+ # `hardware.platforms` only after that gate passes (see README).
71
+ - kind: python
72
+ python: "3.11"
73
+ installer: uv
74
+ platforms:
75
+ - linux-x64
76
+ torchBackend: cu126
77
+ nvidiaGpu: required
78
+ cuda:
79
+ level: required
80
+ minDriverCudaVersion: "12.6"
81
+ requirements:
82
+ - name: opendde
83
+ version: 1.1.1
84
+ extras:
85
+ - gpu
86
+ hashes:
87
+ - 94b193bd360e017c9cfab08d199ec9333cb2919a49fe1d9270c659c4b2efe544
88
+ # download.pytorch.org/whl/cu126: torch-2.7.1+cu126-cp311-cp311-manylinux_2_28_x86_64.whl
89
+ - name: torch
90
+ version: 2.7.1+cu126
91
+ hashes:
92
+ - e1a8465165708c2e2e90786ade8a3e1b1d01eca1f022792cd397caad9d8c21bc
93
+ # `opendde pred` would otherwise download the checkpoint and CCD files into
94
+ # `$OPENDDE_ROOT_DIR` (default `~/.cache/opendde`) on first use. They are pinned
95
+ # here instead to the exact Hugging Face commit upstream's own
96
+ # `opendde/config/model_manifest.json` / `dependency_url.py` name
97
+ # (aurekaresearch/OpenDDE @ eddd563ce96571f784012edd8f045181c8f8627d), with the
98
+ # sizes and SHA-256 digests upstream publishes there — independently confirmed
99
+ # against Hugging Face's X-Linked-Size / X-Linked-ETag for each file on
100
+ # 2026-09-26. The adapter points OPENDDE_ROOT_DIR at `assets/opendde-root`.
101
+ #
102
+ # Deliberately NOT installed:
103
+ # - `opendde_abag.pt` (antibody–antigen checkpoint, 2625271509 bytes, sha256
104
+ # 5cf37441ddef2a2f148b81dd4a218ad274f996fecaf17dec901ab6cf1351713d): the asset
105
+ # model has no opt-in/optional asset concept, so installing it would force an
106
+ # extra 2.6 GB on every user.
107
+ # - Template/RNA-MSA search databases (pdb_seqres ~220 MB, Rfam ~220 MB,
108
+ # RNAcentral ~13 GB, NT-RNA ~75 GB, plus a PDB mmCIF mirror) and the
109
+ # template-only `obsolete_to_successor.json`/`release_date_cache.json`. The
110
+ # adapter rejects `use_template=true`, and `use_rna_msa=true` without
111
+ # precomputed per-chain RNA A3M files, so nothing ever reaches for them.
112
+ assets:
113
+ - id: opendde-v1-checkpoint
114
+ url: https://huggingface.co/aurekaresearch/OpenDDE/resolve/eddd563ce96571f784012edd8f045181c8f8627d/opendde.pt
115
+ source: https://huggingface.co/aurekaresearch/OpenDDE
116
+ license: Apache-2.0
117
+ sha256: 7b826620390afad877ee2babc6a4d0df81b94d3a0be030959853d6a7da0807cc
118
+ sizeBytes: 2625249069
119
+ target: opendde-root/checkpoint/opendde.pt
120
+ - id: opendde-ccd-components
121
+ url: https://huggingface.co/aurekaresearch/OpenDDE/resolve/eddd563ce96571f784012edd8f045181c8f8627d/common/components.cif
122
+ source: https://huggingface.co/aurekaresearch/OpenDDE
123
+ sha256: bb31ae5cf6c8bc669924313077cb4231ee5ffefd3a20118cd14f3ec89f8bb6a5
124
+ sizeBytes: 490777362
125
+ target: opendde-root/common/components.cif
126
+ - id: opendde-ccd-rdkit-mols
127
+ url: https://huggingface.co/aurekaresearch/OpenDDE/resolve/eddd563ce96571f784012edd8f045181c8f8627d/common/components.cif.rdkit_mol.pkl
128
+ source: https://huggingface.co/aurekaresearch/OpenDDE
129
+ sha256: d1cfb71f5993a3ebea7c47877022d7f597bbfbaf86e28a4770e957da6c50cd35
130
+ sizeBytes: 142498117
131
+ target: opendde-root/common/components.cif.rdkit_mol.pkl
132
+ hardware:
133
+ platforms:
134
+ - darwin-arm64
135
+ # ~3.26 GB of assets plus ~1.5 GB for the managed Python environment.
136
+ minDiskGb: 6
137
+ input:
138
+ formats:
139
+ - .json
140
+ required: true
141
+ outputs:
142
+ # Upstream writes <out_dir>/<job_name>/seed_<seed>/predictions/… (verified
143
+ # against runner/dumper.py and docs/infer_json_format.md at the pinned
144
+ # revision). Segment-wise globs, so an unrelated .cif/.json elsewhere under
145
+ # output/ can never satisfy these.
146
+ - id: structures
147
+ glob: "*/seed_*/predictions/*_sample_*.cif"
148
+ required: true
149
+ - id: confidence
150
+ glob: "*/seed_*/predictions/*_summary_confidence_sample_*.json"
151
+ required: true
152
+ - id: atom_confidence
153
+ glob: "*/seed_*/predictions/*_full_data_sample_*.json"
154
+ required: false
155
+ # Adapter-written PDB copy of each mmCIF (per-atom pLDDT in the B-factor
156
+ # column, CONECT records for ligand bonds). The mmCIF stays the primary
157
+ # result; structures legacy PDB can't represent are listed in
158
+ # moldesk-pdb-export-errors.json instead of failing the run.
159
+ - id: structures_pdb
160
+ glob: "*/seed_*/predictions/*_sample_*.pdb"
161
+ required: false
162
+ - id: pdb_export_errors
163
+ glob: "moldesk-pdb-export-errors.json"
164
+ required: false
165
+ # Adapter-written copy of the job with companion references rewritten to
166
+ # their staged paths; only present when the job references files.
167
+ - id: resolved_job
168
+ glob: "moldesk-resolved-job.json"
169
+ required: false
@@ -0,0 +1,43 @@
1
+ schemaVersion: 1
2
+ name: proteinmpnn
3
+ displayName: ProteinMPNN
4
+ modelVersion: v_48_020
5
+ adapterVersion: 0.1.0
6
+ description: Structure-conditioned protein sequence design (Dauparas et al., Science 2022).
7
+ category: sequence-design
8
+ status: beta
9
+ license: MIT
10
+ homepage: https://github.com/dauparas/ProteinMPNN
11
+ source:
12
+ repository: https://github.com/dauparas/ProteinMPNN
13
+ revision: 8907e6671bfbfc92303b5f79c4b5e6ce47cdef57
14
+ runtimes:
15
+ - kind: python
16
+ python: "3.11"
17
+ installer: uv
18
+ requirements:
19
+ - name: torch
20
+ version: 2.2.1
21
+ - name: numpy
22
+ version: 1.26.4
23
+ assets:
24
+ - id: proteinmpnn-checkpoint
25
+ url: https://raw.githubusercontent.com/dauparas/ProteinMPNN/8907e6671bfbfc92303b5f79c4b5e6ce47cdef57/vanilla_model_weights/v_48_020.pt
26
+ source: ProteinMPNN pinned source revision
27
+ license: MIT
28
+ sha256: c9cb4a671d79604111231f8dbfc7c590e06f1197453b7a6854ac6661a642f5bd
29
+ target: vanilla_model_weights/v_48_020.pt
30
+ sizeBytes: 6681301
31
+ archive: none
32
+ hardware:
33
+ platforms:
34
+ - darwin-arm64
35
+ - linux-x64
36
+ input:
37
+ formats:
38
+ - .pdb
39
+ required: true
40
+ outputs:
41
+ - id: sequences
42
+ glob: "seqs/*.fa"
43
+ required: true
@@ -0,0 +1,24 @@
1
+ import type { ModelManifestV1, PlatformId, PythonRuntimeSpec, RuntimeSpec, SourceSpec } from "./schema.js";
2
+ /**
3
+ * Maps the running process's OS/arch to a manifest `PlatformId`. Returns `undefined`
4
+ * for any host outside the two platforms MoleculeDesk v0.1 supports — callers must
5
+ * treat that as "no platform id", not throw here, since a legacy runtime entry with
6
+ * no `platforms` field must still resolve on hosts outside this enum (matching the
7
+ * pre-existing behavior of installs that never checked platform at all).
8
+ */
9
+ export declare function detectHostPlatformId(platform?: string, arch?: string): PlatformId | undefined;
10
+ /**
11
+ * Resolves exactly one python runtime entry from `runtimes` for the given host
12
+ * platform. An entry with no `platforms` field matches every platform (legacy,
13
+ * single-runtime manifests such as ProteinMPNN/LigandMPNN); an entry with a
14
+ * `platforms` field matches only when it includes `platform`.
15
+ *
16
+ * Fails closed:
17
+ * - zero matches -> `RUNTIME_PLATFORM_UNSUPPORTED`
18
+ * - more than one match -> `RUNTIME_SELECTION_AMBIGUOUS` (a manifest-authoring bug —
19
+ * two runtime entries must never both claim the same host platform).
20
+ */
21
+ export declare function selectPythonRuntime(runtimes: readonly RuntimeSpec[], platform: PlatformId | undefined): PythonRuntimeSpec;
22
+ /** The effective source for an already-selected python runtime entry: its own
23
+ * per-entry override when present, otherwise the manifest-level `source`. */
24
+ export declare function effectiveRuntimeSource(manifest: Pick<ModelManifestV1, "source">, runtime: Pick<PythonRuntimeSpec, "source">): SourceSpec | undefined;
@@ -0,0 +1,54 @@
1
+ import { MoldeskError } from "./errors.js";
2
+ /**
3
+ * Maps the running process's OS/arch to a manifest `PlatformId`. Returns `undefined`
4
+ * for any host outside the two platforms MoleculeDesk v0.1 supports — callers must
5
+ * treat that as "no platform id", not throw here, since a legacy runtime entry with
6
+ * no `platforms` field must still resolve on hosts outside this enum (matching the
7
+ * pre-existing behavior of installs that never checked platform at all).
8
+ */
9
+ export function detectHostPlatformId(platform = process.platform, arch = process.arch) {
10
+ if (platform === "darwin" && arch === "arm64")
11
+ return "darwin-arm64";
12
+ if (platform === "linux" && arch === "x64")
13
+ return "linux-x64";
14
+ return undefined;
15
+ }
16
+ /**
17
+ * Resolves exactly one python runtime entry from `runtimes` for the given host
18
+ * platform. An entry with no `platforms` field matches every platform (legacy,
19
+ * single-runtime manifests such as ProteinMPNN/LigandMPNN); an entry with a
20
+ * `platforms` field matches only when it includes `platform`.
21
+ *
22
+ * Fails closed:
23
+ * - zero matches -> `RUNTIME_PLATFORM_UNSUPPORTED`
24
+ * - more than one match -> `RUNTIME_SELECTION_AMBIGUOUS` (a manifest-authoring bug —
25
+ * two runtime entries must never both claim the same host platform).
26
+ */
27
+ export function selectPythonRuntime(runtimes, platform) {
28
+ const pythonRuntimes = runtimes.filter((r) => r.kind === "python");
29
+ const matches = pythonRuntimes.filter((r) => r.platforms === undefined || (platform !== undefined && r.platforms.includes(platform)));
30
+ if (matches.length === 0) {
31
+ throw new MoldeskError({
32
+ code: "RUNTIME_PLATFORM_UNSUPPORTED",
33
+ message: platform
34
+ ? `No python runtime entry supports platform ${platform}.`
35
+ : "No python runtime entry supports this host platform.",
36
+ remediation: "Run on darwin-arm64 or linux-x64, or pick a model whose runtimes[] declares this platform.",
37
+ details: { platform, candidateCount: pythonRuntimes.length },
38
+ });
39
+ }
40
+ if (matches.length > 1) {
41
+ throw new MoldeskError({
42
+ code: "RUNTIME_SELECTION_AMBIGUOUS",
43
+ message: `${matches.length} python runtime entries match platform ${platform ?? "this host"}; a manifest must declare at most one match per platform.`,
44
+ remediation: "Fix the manifest so no two runtime entries' `platforms` (or absence thereof) overlap for the same host platform.",
45
+ details: { platform, matchCount: matches.length },
46
+ });
47
+ }
48
+ return matches[0];
49
+ }
50
+ /** The effective source for an already-selected python runtime entry: its own
51
+ * per-entry override when present, otherwise the manifest-level `source`. */
52
+ export function effectiveRuntimeSource(manifest, runtime) {
53
+ return runtime.source ?? manifest.source;
54
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { MoldeskError } from "./errors.js";
3
+ import { detectHostPlatformId, effectiveRuntimeSource, selectPythonRuntime } from "./runtime-selection.js";
4
+ function pythonRuntime(overrides = {}) {
5
+ return {
6
+ kind: "python",
7
+ python: "3.11",
8
+ installer: "uv",
9
+ requirements: [{ name: "torch" }],
10
+ ...overrides,
11
+ };
12
+ }
13
+ describe("detectHostPlatformId", () => {
14
+ it("maps darwin/arm64 to darwin-arm64", () => {
15
+ expect(detectHostPlatformId("darwin", "arm64")).toBe("darwin-arm64");
16
+ });
17
+ it("maps linux/x64 to linux-x64", () => {
18
+ expect(detectHostPlatformId("linux", "x64")).toBe("linux-x64");
19
+ });
20
+ it("returns undefined for unsupported platform/arch combinations", () => {
21
+ expect(detectHostPlatformId("win32", "x64")).toBeUndefined();
22
+ expect(detectHostPlatformId("darwin", "x64")).toBeUndefined();
23
+ expect(detectHostPlatformId("linux", "arm64")).toBeUndefined();
24
+ });
25
+ });
26
+ describe("selectPythonRuntime", () => {
27
+ it("resolves a legacy manifest with no platforms field on its one entry, on any platform", () => {
28
+ const legacy = pythonRuntime();
29
+ expect(selectPythonRuntime([legacy], "darwin-arm64")).toBe(legacy);
30
+ expect(selectPythonRuntime([legacy], "linux-x64")).toBe(legacy);
31
+ expect(selectPythonRuntime([legacy], undefined)).toBe(legacy);
32
+ });
33
+ it("resolves a single match among per-platform entries", () => {
34
+ const darwin = pythonRuntime({ platforms: ["darwin-arm64"] });
35
+ const linux = pythonRuntime({ platforms: ["linux-x64"] });
36
+ expect(selectPythonRuntime([darwin, linux], "darwin-arm64")).toBe(darwin);
37
+ expect(selectPythonRuntime([darwin, linux], "linux-x64")).toBe(linux);
38
+ });
39
+ it("fails closed with RUNTIME_PLATFORM_UNSUPPORTED on zero matches", () => {
40
+ const linuxOnly = pythonRuntime({ platforms: ["linux-x64"] });
41
+ try {
42
+ selectPythonRuntime([linuxOnly], "darwin-arm64");
43
+ expect.unreachable();
44
+ }
45
+ catch (error) {
46
+ expect(error).toBeInstanceOf(MoldeskError);
47
+ expect(error.code).toBe("RUNTIME_PLATFORM_UNSUPPORTED");
48
+ }
49
+ });
50
+ it("fails closed with RUNTIME_PLATFORM_UNSUPPORTED when the host platform is undetected", () => {
51
+ const linuxOnly = pythonRuntime({ platforms: ["linux-x64"] });
52
+ expect(() => selectPythonRuntime([linuxOnly], undefined)).toThrowError(MoldeskError);
53
+ });
54
+ it("fails closed with RUNTIME_SELECTION_AMBIGUOUS when two entries both match the same platform", () => {
55
+ const first = pythonRuntime({ platforms: ["darwin-arm64"] });
56
+ const second = pythonRuntime({ platforms: ["darwin-arm64"], python: "3.12" });
57
+ try {
58
+ selectPythonRuntime([first, second], "darwin-arm64");
59
+ expect.unreachable();
60
+ }
61
+ catch (error) {
62
+ expect(error).toBeInstanceOf(MoldeskError);
63
+ expect(error.code).toBe("RUNTIME_SELECTION_AMBIGUOUS");
64
+ }
65
+ });
66
+ it("ignores non-python runtime entries entirely", () => {
67
+ const docker = { kind: "docker", image: "x", digest: `sha256:${"a".repeat(64)}`, gpu: "none" };
68
+ const python = pythonRuntime();
69
+ expect(selectPythonRuntime([docker, python], "linux-x64")).toBe(python);
70
+ });
71
+ });
72
+ describe("effectiveRuntimeSource", () => {
73
+ const manifestSource = { repository: "https://github.com/example/manifest-level", revision: "a".repeat(40) };
74
+ const entrySource = { repository: "https://github.com/example/entry-level", revision: "b".repeat(40) };
75
+ it("prefers the per-entry source override when present", () => {
76
+ expect(effectiveRuntimeSource({ source: manifestSource }, { source: entrySource })).toEqual(entrySource);
77
+ });
78
+ it("falls back to the manifest-level source when the entry has none", () => {
79
+ expect(effectiveRuntimeSource({ source: manifestSource }, {})).toEqual(manifestSource);
80
+ });
81
+ it("returns undefined when neither is set", () => {
82
+ expect(effectiveRuntimeSource({}, {})).toBeUndefined();
83
+ });
84
+ });