Skip to content

Studio: resolve llama.cpp prebuilts via the release-assets CDN to avoid GitHub API rate limits - #7086

Merged
danielhanchen merged 6 commits into
mainfrom
studio-llama-cdn-resolve
Jul 14, 2026
Merged

danielhanchen merged 6 commits into
mainfrom
studio-llama-cdn-resolve

Conversation

@danielhanchen

@danielhanchen danielhanchen commented Jul 12, 2026 •

Copy link
Copy Markdown
Member

Summary

The prebuilt llama.cpp installer discovers the latest unslothai/llama.cpp release by enumerating the GitHub REST API (GET /repos/unslothai/llama.cpp/releases?per_page=100). Anonymous API calls are capped at 60 per hour per IP, which shared or NAT'd IPs, VPNs, CI, or a few repeated installs exhaust easily. After that every call returns HTTP 403 rate limit exceeded and the installer drops to a slow source build (which then also pulls in OpenSSL, cmake and friends).

The manifest and sha256 assets we already publish on every release are self contained and are served from the release-assets CDN, which is not rate limited. This adds a fast path that resolves and verifies the latest release entirely from that CDN with zero api.github.com calls, and keeps the API enumeration as a fallback.

Change

iter_resolved_published_releases now tries _download_host_resolved_release(repo) first for the fork repo on a latest request:

  1. GET releases/latest/download/llama-prebuilt-sha256.json (302 to the CDN). Gives release_tag and every artifact sha256 plus source provenance.
  2. Using that tag, GET the coverage manifest at releases/download/<tag>/llama-prebuilt-manifest.json.
  3. Download each asset and the source archive by name via releases/download/<tag>/<asset> and codeload, both on the CDN.

It reuses the existing parsers and validation (parse_approved_release_checksums, parse_published_release_bundle, _validate_checksums_against_bundle), so every downloaded binary is verified against the approved sha256 exactly as on the API path. The synthesized release also exposes tag-pinned URLs for artifacts named only in the manifest (their hash can be keyed under an upstream-tag alias in the checksum asset), so the fast path resolves the same assets the API path gets from the real asset list. It is an optimization, not a weaker trust path. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 forces the legacy path.

The CDN latest/download path can only surface the single latest release, so:

  • Any failure (older release without the JSON assets, a rejected checksum, transient network) falls through to the unchanged API enumeration.
  • macOS passes allow_download_host_fast_path = False so it keeps the API multi-release walk-back that skips prebuilts built for a newer macOS than the host.
  • On Windows and Linux a broken latest asset falls to a source build rather than an older release (the general 2-deep release fallback is reduced to 1). This is the accepted tradeoff for avoiding the rate-limited API.

No new CI is required: these assets already exist on every release. The invariants and the manifest schema are documented in studio/docs/llama-cpp-prebuilt-resolution.md.

Verification

Ran the resolver on a real gfx1151 Windows host with every api.github.com entry point patched to throw:

  • selected app-b9964-mix-53618c5-windows-x64-rocm-gfx1151.zip (the correct asset)
  • sha256 matched the installed marker exactly, so verification is intact
  • the asset URL is on the CDN, not api.github.com, and resolution completed with zero API calls
  • with UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 it routes back to the API path

tests/studio/install/test_download_host_resolve.py covers both the routing in iter_resolved_published_releases (fast path used on latest, disabled by caller for macOS, disabled by env, skipped for a pinned tag, None and rejected-checksum both fall back to the API) and the resolve body itself with only download_bytes stubbed: a manifest-only asset gets a tag-pinned URL, and a wrong manifest hash raises PrebuiltFallback. Existing test_selection_logic.py stubs were made forward-compatible with the new keyword argument. ruff check, py_compile and ast.parse pass, and the install/selection test suite shows no new failures (238 passed, 15 pre-existing platform skips).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a "download-host fast path" for resolving prebuilt llama.cpp binaries to avoid GitHub API rate limits. It queries the release-assets CDN directly for the latest release metadata and manifest, falling back to the legacy API path if any step fails. Feedback suggests defensively wrapping the manifest parsing call in a try-except block to gracefully handle HTTP 404 errors (e.g., if a release is incomplete) and fall back to the API without raising a noisy exception.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +2465 to +2467
return None
_validate_checksums_against_bundle(repo, bundle, checksums)
return ResolvedPublishedRelease(bundle = bundle, checksums = checksums)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Defensively wrap the call to parse_published_release_bundle in a try-except block to catch urllib.error.HTTPError with a 404 status code. Just like with the SHA256 asset, if the manifest asset is missing (e.g., during an incomplete or in-progress release publication), we should fail silently and return None to trigger the API fallback, rather than propagating the exception and logging a noisy/misleading warning message to the user.

Suggested change
return None
_validate_checksums_against_bundle(repo, bundle, checksums)
return ResolvedPublishedRelease(bundle = bundle, checksums = checksums)
try:
bundle = parse_published_release_bundle(repo, synthetic_release)
except urllib.error.HTTPError as exc:
if exc.code == 404:
return None
raise
if bundle is None:
return None

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 1d01768. The call to parse_published_release_bundle is now wrapped so a manifest 404 (an in-progress release that published the checksum asset before the manifest) returns None and falls back to the API, mirroring the sha256 404 handling, instead of surfacing the generic "resolve unavailable" warning.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a42babafef

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2571 to +2572
yield resolved
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep older fallback releases reachable from fast path

For latest installs of the default fork, returning immediately after the CDN-resolved latest release prevents _fork_manifest_release_plans from walking older releases when that bundle is incompatible with the host. This regresses the existing fallback path for cases such as older macOS hosts (which explicitly raise the limit via DEFAULT_MAX_MACOS_RELEASE_FALLBACKS) or a latest release that lacks a matching GPU/arch asset: the latest bundle is yielded, planning skips it, and no older usable release is ever considered.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macOS is already excluded from the fast path (the caller passes allow_download_host_fast_path = not host.is_macos), so its DEFAULT_MAX_MACOS_RELEASE_FALLBACKS walk-back is preserved. On Windows/Linux the single-latest behavior is the documented, intentional tradeoff for a zero-API resolve: a latest release whose asset is unusable drops to a source build rather than an older release (the 2-deep fallback reduced to 1). That degrades to a source build, not a failure, and older tags are not enumerable from the CDN without the API this path exists to avoid.

Comment thread studio/install_llama_prebuilt.py Outdated
Comment on lines +2412 to +2413
return (
f"https://github.com/{repo}/releases/latest/download/"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve publish-time ordering for latest resolution

When the default fork's GitHub /releases/latest pointer lags the newest published build, this fast path can install a stale release even though the existing resolver sorts releases by published_at; Studio already documents that /releases/latest can lag by commit date and previously caused detection/apply disagreement (studio/backend/utils/llama_cpp_freshness.py:112-116). Because this URL is now used before the API enumeration and returns on success, affected users get the older pointer target instead of the newest usable published prebuilt.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and it matches our own history: detection deliberately moved off /releases/latest to published_at in #6219/#6234/#6338 because that pointer lags for out-of-order mix builds. A fully published_at-correct resolution only exists in the rate-limited API response, so it cannot be reproduced from the CDN.

In 1d01768 I pin the fast path to the tag from the /releases/latest redirect (authoritative, and verified against the checksum asset's own release_tag), and document the residual created_at/make_latest vs published_at divergence in llama-cpp-prebuilt-resolution.md. It is mitigated in practice:

  • Today /releases/latest for unslothai/llama.cpp equals the published_at newest (GitHub's semver tiebreak picks the highest build).
  • is_behind()'s base-build guard keeps a divergence from ever surfacing as the downgrade / sticky "update available" banner that Studio: fix llama.cpp update banner offering a downgrade / sticking on mix releases #6219 fixed.
  • UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 forces the published_at API path if a future stream ever makes it matter.

@danielhanchen
danielhanchen force-pushed the studio-llama-cdn-resolve branch from 92bad08 to ccd72b7 Compare July 12, 2026 10:26

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 759e1db4c4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread studio/install_llama_prebuilt.py Outdated
Comment on lines +2441 to +2444
release_tag = sha_payload.get("release_tag")
if not isinstance(release_tag, str) or not release_tag:
return None
checksums = parse_approved_release_checksums(repo, release_tag, sha_payload)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the latest release tag before pinning

When the latest release's checksum asset is stale or copy-pasted with an older existing release_tag, this fast path accepts that self-reported tag and then validates the payload against the same value. The legacy API path had an independent release tag from GitHub and would reject this mismatch, but here all synthesized asset URLs are built for the stale tag, so a latest install can silently install an older release instead of falling back to the API path. Derive/check the actual latest tag independently, e.g. from the redirect target, before pinning URLs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1d01768. The latest tag is now derived from the /releases/latest redirect target (github.com, still no api.github.com) rather than the checksum asset's self-reported release_tag, so the existing release_tag cross-check in parse_approved_release_checksums is a real check again: a stale or mis-tagged checksum asset now mismatches the redirect tag and falls back to the API.

Comment on lines +2455 to +2459
"assets": [
{
"name": name,
"browser_download_url": _release_asset_download_url(repo, release_tag, name),
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not fabricate availability for unchecked assets

If the latest manifest/checksum JSON advertises an asset whose upload failed or was deleted, this synthetic release map still invents a browser_download_url for it, so the normal selectors treat the binary as present and only discover the 404/hash failure during installation. The API path used the real release asset list, so the same release would skip the missing asset during planning and could report no prebuilt or try another candidate instead of failing after selection.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only triggers on a malformed or incomplete release (the manifest or checksum JSON names an asset that was never uploaded or was deleted). It cannot install an unverified binary: every download is sha256-checked (download_file_verified) and apply_approved_hashes fails closed. The only difference from the API path is discovering the missing asset at download time rather than during planning, after which validate_prebuilt_attempts moves to the next attempt / source build exactly as the API path would. The real asset list only exists in the api.github.com response, so this cannot be tightened without the call the fast path exists to avoid; it is noted as an accepted tradeoff in the doc.

`.../releases/download/<release_tag>/<asset>` (same CDN) and
`codeload.github.com`. No API call.

Net result for a normal install: zero `api.github.com` calls. Checksum and

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route visual-server backfill through the CDN

For a fresh install where the DiffusionGemma visual-server is not already present, the install path still calls ensure_diffusion_visual_server(), which enumerates release assets through github_release_assets(DEFAULT_PUBLISHED_REPO, release_tag) and therefore hits api.github.com. Under the exact rate-limit scenario this change is meant to avoid, the main install succeeds but the visual-server backfill is silently skipped, even though the fast path already has enough checksum/asset-name data to synthesize CDN URLs for that asset too.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ensure_diffusion_visual_server call to github_release_assets is unchanged by this PR and is best-effort by design (it already swallows failures and returns). This change is a strict improvement here: pre-PR a rate-limited install failed entirely, whereas now the main install succeeds and only the optional DiffusionGemma backfill is skipped under the rate limit. Routing that backfill through the CDN using the fast path's checksum/asset-name data is a worthwhile follow-up to fully realize the zero-API goal, but it is a separate enhancement rather than a regression in this change, so I will do it in a follow-up.

…ast path

Add tag-pinned CDN URLs for any manifest artifact whose hash is keyed under an
upstream-tag alias in the checksum asset, so the fast path resolves the same
assets the API path does. Cover the resolve body directly (only download_bytes
stubbed) and soften the doc's validation-equivalence wording.
Derive the authoritative latest tag from GitHub's /releases/latest redirect
target instead of trusting the checksum asset's self-reported release_tag, so the
existing release_tag cross-check in parse_approved_release_checksums is a real
check again: a stale or mis-tagged checksum asset now falls back to the API. Pin
every fast-path URL to that tag. Fall back to the API on a manifest 404 as well,
since an in-progress release can publish the checksum asset before the manifest,
matching the sha256 404 handling. Document the releases/latest (created_at /
make_latest) versus published_at ordering divergence and why it is an accepted,
mitigated tradeoff.
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 1d0176816e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Remove studio/docs/llama-cpp-prebuilt-resolution.md and the docstring pointer to
it; the resolution rationale (the created_at/make_latest vs published_at ordering
nuance) stays inline in _download_host_latest_release_tag.
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b93b90ec5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

published_release_tag,
# macOS relies on the multi-release walk-back to skip too-new prebuilts,
# which the single-latest download-host path cannot provide.
allow_download_host_fast_path = not host.is_macos,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve older-release fallback with the fast path

For non-macOS latest installs this enables the download-host path even though _fork_manifest_release_plans() still has allow_older_release_fallback set. That fast path yields only the latest release and then returns, while install_prebuilt() can only retry releases that were precomputed in release_plans; if the latest Linux/Windows bundle is missing, incompatible with the host, or fails validation/download, the installer now goes straight to source build instead of trying the older releases that the previous API enumeration collected up to DEFAULT_MAX_PREBUILT_RELEASE_FALLBACKS. Please either keep enumerating older releases after the fast-path latest candidate or disable the single-release fast path whenever the older-release fallback is needed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the intended, documented tradeoff (see the comments on iter_resolved_published_releases and _fork_manifest_release_plans). macOS keeps the full API walk-back: the caller passes allow_download_host_fast_path = not host.is_macos. On Windows/Linux the single-latest resolve degrades a broken latest to a source build rather than an older release, and the fork releases are comprehensive (the latest bundle covers every gfx/sm/arch/OS: gfx103X/110X/1150/1151/120X/908/90a, all CUDA lines, CPU, arm64, macOS), so the older-release fallback was effectively never exercised. Older tags are not enumerable from the CDN without the api.github.com calls this path exists to avoid. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API walk-back.

by created_at/make_latest, which can lag the published_at newest the freshness
detection uses. Returns None when the repo has no such release (404) so the
caller falls back to the API."""
url = f"https://github.com/{urllib.parse.quote(repo, safe = '/')}/releases/latest"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve latest by published_at in the fast path

On default-repo latest installs this pins the fast path to GitHub's /releases/latest redirect, but studio/backend/utils/llama_cpp_freshness.py still resolves latest as the non-draft/non-prerelease release with the maximum published_at and explicitly avoids that pointer. When GitHub's latest pointer lags or is manually set, --resolve-prebuilt/install can install the older redirected release while the update checker reports the newer published release, recreating the sticky update/downgrade behavior the freshness code is designed to avoid.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A published_at-correct resolution only exists in the api.github.com response, so it cannot be reproduced from the CDN in a zero-API path. The fast path pins to the verified /releases/latest redirect tag; the residual created_at/make_latest vs published_at divergence is called out in the _download_host_latest_release_tag docstring and is mitigated: today /releases/latest for unslothai/llama.cpp equals the published_at newest (GitHub's semver tiebreak), and is_behind()'s base-build guard prevents a divergence from surfacing as the downgrade / sticky "update available" banner the freshness code guards against. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 forces the published_at API path if a future release stream ever makes it matter.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 5b93b90ec5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Jul 14, 2026
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a62284d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

than the checksum asset's self-reported release_tag. /releases/latest resolves by
created_at/make_latest, which can lag the published_at newest the freshness
detection uses. None on 404 so the caller falls back to the API."""
url = f"https://github.com/{urllib.parse.quote(repo, safe = '/')}/releases/latest"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve published_at latest semantics

When GitHub's /releases/latest pointer is behind the newest published_at release (the case the freshness helper explicitly handles in studio/backend/utils/llama_cpp_freshness.py:109-155), this fast path now installs the older redirect tag and returns before the API enumeration that previously matched freshness. The backend will still report the newer published release as available, so applying an update can leave the banner stuck or cause repeated/downgrade attempts for users in that repo state; the CDN path needs to select the same published_at-newest tag or the freshness code must be changed with it.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A published_at-correct resolution only exists in the api.github.com response, so it cannot be reproduced from the CDN in a zero-API path. The fast path pins to the verified /releases/latest redirect tag; the residual created_at/make_latest vs published_at divergence is called out in the _download_host_latest_release_tag docstring and is mitigated: today /releases/latest for unslothai/llama.cpp equals the published_at newest (GitHub's semver tiebreak), and is_behind()'s base-build guard prevents a divergence from surfacing as the downgrade / sticky "update available" banner the freshness code guards against. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 forces the published_at API path if a future release stream ever makes it matter.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a62284d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2612 to +2614
if resolved is not None:
yield resolved
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve older-release walk-back after fast path

When the CDN-resolved latest release exists but has no usable asset for the current non-macOS host (for example a Linux CUDA host whose SM/runtime is not covered, or a release with no fork bundle), this early return prevents _fork_manifest_release_plans() from walking back through older releases even though that function still enables older-release fallback for all latest installs and continues after per-release PrebuiltFallback. The result is a source-build fallback where an older published prebuilt would previously be selected; the existing test_latest_skips_non_installable_release_and_keeps_searching behavior is bypassed because the new tests disable this fast path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the intended, documented tradeoff (see the comments on iter_resolved_published_releases and _fork_manifest_release_plans). macOS keeps the full API walk-back: the caller passes allow_download_host_fast_path = not host.is_macos. On Windows/Linux the single-latest resolve degrades a broken latest to a source build rather than an older release, and the fork releases are comprehensive (the latest bundle covers every gfx/sm/arch/OS: gfx103X/110X/1150/1151/120X/908/90a, all CUDA lines, CPU, arm64, macOS), so the older-release fallback was effectively never exercised. Older tags are not enumerable from the CDN without the api.github.com calls this path exists to avoid. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API walk-back.

than the checksum asset's self-reported release_tag. /releases/latest resolves by
created_at/make_latest, which can lag the published_at newest the freshness
detection uses. None on 404 so the caller falls back to the API."""
url = f"https://github.com/{urllib.parse.quote(repo, safe = '/')}/releases/latest"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep latest resolution aligned with freshness

For default latest installs this switches the resolver to GitHub's /releases/latest pointer, but the adjacent comment notes that pointer can lag the newest published_at release, and studio/backend/utils/llama_cpp_freshness.py deliberately avoids it because that mismatch caused stale/downgrade banners. In that lag window the fast path installs the older pointer target and returns before the API enumeration can find the newest published prebuilt, so users can still be prompted to update immediately after an update/install.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A published_at-correct resolution only exists in the api.github.com response, so it cannot be reproduced from the CDN in a zero-API path. The fast path pins to the verified /releases/latest redirect tag; the residual created_at/make_latest vs published_at divergence is called out in the _download_host_latest_release_tag docstring and is mitigated: today /releases/latest for unslothai/llama.cpp equals the published_at newest (GitHub's semver tiebreak), and is_behind()'s base-build guard prevents a divergence from surfacing as the downgrade / sticky "update available" banner the freshness code guards against. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 forces the published_at API path if a future release stream ever makes it matter.

Comment on lines +2498 to +2502
for artifact in bundle.artifacts:
bundle.assets.setdefault(
artifact.asset_name,
_release_asset_download_url(repo, release_tag, artifact.asset_name),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not fabricate missing release asset URLs

When the manifest is available before one of the binary assets is uploaded, or the manifest is stale, this unconditionally adds a tag-pinned URL for each manifest artifact even though the fast path never checked the release's real asset list. That bypasses the existing release.assets.get(...) missing-asset rejection used by the API path, so --resolve-prebuilt can report an unavailable prebuilt and installs can select a URL that only fails later with a 404 instead of rejecting the release during planning.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a real difference from the API path, but it is bounded to a transient in-progress-publish window and degrades to the same outcome, so it stays below the fix bar.

  • Fail-closed install: an asset is only ever installed if its name (or alias) is in the approved sha256.json (apply_approved_hashes, install_llama_prebuilt.py:6156). sha256.json is produced by hashing the built files, so in a finished release every hashed asset exists; a manifest that over-lists an artifact with no approved hash is dropped, never installed unverified.
  • Graceful degradation: a fabricated URL for a not-yet-uploaded binary 404s at download; download_file surfaces that as a plain urllib HTTPError, which validate_prebuilt_attempts catches (install_llama_prebuilt.py:6838) and wraps into PrebuiltFallback, moving to the next attempt and finally the source build. It is never a crash or a silent/zero-byte install, and checksum verification still gates any 200 response.
  • Net effect: for a host whose only covering asset is mid-upload, both paths end at the source build; the fast path just takes one doomed download first, and it self-heals the moment the release finishes uploading.

Verified in an isolated sandbox: the API path rejects the missing asset during planning while the fast path fabricates its URL (divergence reproduced), the fabricated URL 404s as a catchable HTTPError, a present asset with the wrong hash is still refused, and an artifact absent from sha256.json is dropped fail-closed.

The --resolve-prebuilt probe can briefly report the soon-to-exist URL during that window; UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API asset-list check for anyone who needs planning-time rejection.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a62284d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2612 to +2614
if resolved is not None:
yield resolved
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve older-release walk-back after CDN resolution

When the CDN fast path successfully resolves the latest release but that release is not installable for the host (for example a Linux/Windows latest manifest with no compatible GPU/CPU asset, or a latest plan that later fails validation), this early return prevents _fork_manifest_release_plans from seeing any older releases. The existing planner has allow_older_release_fallback for all latest installs and tests such as test_latest_skips_non_installable_release_and_keeps_searching cover skipping a bad latest release, but the new default path only disables the fast path on macOS, so Linux/Windows now source-build instead of trying the older valid prebuilt.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the intended, documented tradeoff (see the comments on iter_resolved_published_releases and _fork_manifest_release_plans). macOS keeps the full API walk-back: the caller passes allow_download_host_fast_path = not host.is_macos. On Windows/Linux the single-latest resolve degrades a broken latest to a source build rather than an older release, and the fork releases are comprehensive (the latest bundle covers every gfx/sm/arch/OS: gfx103X/110X/1150/1151/120X/908/90a, all CUDA lines, CPU, arm64, macOS), so the older-release fallback was effectively never exercised. Older tags are not enumerable from the CDN without the api.github.com calls this path exists to avoid. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API walk-back.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a62284d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2498 to +2501
for artifact in bundle.artifacts:
bundle.assets.setdefault(
artifact.asset_name,
_release_asset_download_url(repo, release_tag, artifact.asset_name),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid treating manifest-only assets as uploaded

When the latest release is partially published or the manifest contains a stale/typoed artifact, this adds a download URL for every manifest artifact even if that asset is not actually present on the GitHub release. The existing API path only exposes names from the release asset list, so selectors skip missing artifacts via release.assets.get(...); the fast path can instead select a non-existent targeted bundle and only fail later with a 404, bypassing an available fallback asset in the same release or falling straight to source build.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified the sharper form of this (a partial-publish best-fit falling through to another in-release asset on the API path but not the fast path), and it is a real behavioral difference in theory, but it is unreachable on the fork's real release input, so it stays below the fix bar.

Why it cannot be observed in practice:

  • The fork uploads llama-prebuilt-manifest.json and llama-prebuilt-sha256.json LAST, after every binary, and marks the release published only after that. On the current latest (b9987-mix-53618c5) all 38 binaries uploaded at 01:33:58-01:34:52, both JSONs at 01:34:53, and the release published at 01:35:05.
  • The fast path only engages once it can fetch sha256.json AND /releases/latest resolves to the release. /releases/latest points at a release only once it is marked latest/published, and sha256.json is the last asset. So by the time the fast path can see the release, every asset its manifest/checksums reference is already present. There is no window where sha256.json lists a binary that is not yet uploaded.

Defense in depth if a future release tool ever changed that order:

  • Fail-closed install: an asset installs only if its name (or alias) is in the approved sha256.json (install_llama_prebuilt.py:6156); sha256.json is produced by hashing built files, so a manifest that over-lists a typoed/absent artifact has no approved hash and is dropped, never installed unverified.
  • Graceful degradation: a fabricated URL for a not-yet-uploaded binary 404s as a plain urllib HTTPError, caught at install_llama_prebuilt.py:6838 and wrapped into PrebuiltFallback -> next attempt -> source build; never a crash or a zero-byte install, and checksum verification still gates any 200.
  • Self-healing + opt-out: the state would clear the moment the release finishes uploading, and UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API asset-list check for anyone who needs planning-time rejection.

Reproduced and bounded in an isolated sandbox: the API path skips the mid-upload best-fit and selects the second compatible in-release bundle while the fast path commits to the fabricated best-fit, and for a fully published release (the only state /releases/latest exposes) the two paths are identical for every host in the cuda12 overlap.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a62284d1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

published_release_tag,
# macOS relies on the multi-release walk-back to skip too-new prebuilts,
# which the single-latest download-host path cannot provide.
allow_download_host_fast_path = not host.is_macos,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve latest-release walk-back outside macOS

When latest is requested on Linux or Windows, _fork_manifest_release_plans still sets allow_older_release_fallback=True and callers expect up to DEFAULT_MAX_PREBUILT_RELEASE_FALLBACKS plans, but this passes allow_download_host_fast_path=True; the fast path yields only the latest release and returns. If that release has no compatible asset for the host (for example the existing test_latest_skips_non_installable_release_and_keeps_searching scenario), the planner exhausts the iterator and falls back to source build instead of trying the next older prebuilt.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the intended, documented tradeoff (see the comments on iter_resolved_published_releases and _fork_manifest_release_plans). macOS keeps the full API walk-back: the caller passes allow_download_host_fast_path = not host.is_macos. On Windows/Linux the single-latest resolve degrades a broken latest to a source build rather than an older release, and the fork releases are comprehensive (the latest bundle covers every gfx/sm/arch/OS: gfx103X/110X/1150/1151/120X/908/90a, all CUDA lines, CPU, arm64, macOS), so the older-release fallback was effectively never exercised. Older tags are not enumerable from the CDN without the api.github.com calls this path exists to avoid. UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API walk-back.

Comment on lines +2498 to +2501
for artifact in bundle.artifacts:
bundle.assets.setdefault(
artifact.asset_name,
_release_asset_download_url(repo, release_tag, artifact.asset_name),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify manifest-only assets before planning them

Here the fast path turns every artifact listed in the manifest into a presumed release asset, but the selection code treats bundle.assets as evidence that the archive actually exists. In a partially published or malformed release where the manifest is present but one binary upload is missing, --resolve-prebuilt can report the asset as available and install will only fail later with a 404; the API path would not include that missing asset in release_asset_map and would skip or fall back instead.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified the sharper form of this (a partial-publish best-fit falling through to another in-release asset on the API path but not the fast path), and it is a real behavioral difference in theory, but it is unreachable on the fork's real release input, so it stays below the fix bar.

Why it cannot be observed in practice:

  • The fork uploads llama-prebuilt-manifest.json and llama-prebuilt-sha256.json LAST, after every binary, and marks the release published only after that. On the current latest (b9987-mix-53618c5) all 38 binaries uploaded at 01:33:58-01:34:52, both JSONs at 01:34:53, and the release published at 01:35:05.
  • The fast path only engages once it can fetch sha256.json AND /releases/latest resolves to the release. /releases/latest points at a release only once it is marked latest/published, and sha256.json is the last asset. So by the time the fast path can see the release, every asset its manifest/checksums reference is already present. There is no window where sha256.json lists a binary that is not yet uploaded.

Defense in depth if a future release tool ever changed that order:

  • Fail-closed install: an asset installs only if its name (or alias) is in the approved sha256.json (install_llama_prebuilt.py:6156); sha256.json is produced by hashing built files, so a manifest that over-lists a typoed/absent artifact has no approved hash and is dropped, never installed unverified.
  • Graceful degradation: a fabricated URL for a not-yet-uploaded binary 404s as a plain urllib HTTPError, caught at install_llama_prebuilt.py:6838 and wrapped into PrebuiltFallback -> next attempt -> source build; never a crash or a zero-byte install, and checksum verification still gates any 200.
  • Self-healing + opt-out: the state would clear the moment the release finishes uploading, and UNSLOTH_LLAMA_DISABLE_DOWNLOAD_HOST_RESOLVE=1 restores the API asset-list check for anyone who needs planning-time rejection.

Reproduced and bounded in an isolated sandbox: the API path skips the mid-upload best-fit and selects the second compatible in-release bundle while the fast path commits to the fabricated best-fit, and for a fully published release (the only state /releases/latest exposes) the two paths are identical for every host in the cuda12 overlap.

@danielhanchen
danielhanchen merged commit 2f3eae9 into main Jul 14, 2026
47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant