Skip to content

build(deps): pin lemonade 11.5.1 from a single source of truth - #177

Draft
rominf wants to merge 5 commits into
mainfrom
feat/lemonade-11-5-1
Draft

build(deps): pin lemonade 11.5.1 from a single source of truth#177
rominf wants to merge 5 commits into
mainfrom
feat/lemonade-11-5-1

Conversation

@rominf

@rominf rominf commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Bumps the pinned Lemonade embeddable runtime from 10.10.0 to 11.5.1, and removes the reason the pin kept going wrong.

Before this PR the version was a hand-written literal in seven places across four files, with nothing tying them together. They had drifted:

Where Held Should have been
engines/lemonade — the version rocm engines install lemonade downloads 10.10.0 (5 constants) latest pin
rocm-dash-tui — offline fallback when the GitHub releases API is unreachable 10.6.0 same as the engine
apps/rocm — the runtime-id label recorded in user config 10.6.0 the env_id the adapter reports

So a host that could not reach the releases API installed a runtime five minor versions behind the one the engine pinned, and a doc comment in the same block had been wrong since 10.10.0. Nothing caught any of it.

What changes

1. One pin, in a config file. runtime-deps.toml at the repository root now holds the version:

[runtime.lemonade]
version = "11.5.1"

One [runtime.<name>] table per managed runtime, each with one or more string fields — a runtime that needs more than a version (a version plus an ABI tag, say) adds a field rather than reshaping the schema.

2. Everything else is derived. A new rocm-deps crate has a build.rs that turns each field into a constant (runtime.lemonade.versionLEMONADE_VERSION) and provides the helpers that build archive names (lemonade-embeddable-<ver>-<os-arch>.{tar.gz|zip}) and download URLs from it. The engine adapter, the dashboard fallback, and the runtime-id label all call those helpers, so there is no second place a version can be written. Bumping Lemonade is now a one-line edit to the TOML.

Generating at build time rather than committing a generated .rs means there is nothing that can go stale, so this needs no cargo xtask ... --check gate the way MANIFEST.md and THIRD_PARTY_NOTICES.txt do. A missing or malformed pin is a build error, and the two crates that used to disagree now cannot: they read the same constant.

3. A single environment override. ROCM_CLI_LEMONADE_VERSION replaces the pin for one invocation, following the ROCM_CLI_* convention already used by ROCM_CLI_VLLM_ROCM_INDEX_URL:

ROCM_CLI_LEMONADE_VERSION=11.6.0 rocm engines install lemonade

Because the names and URLs are derived from the resolved version rather than stored alongside it, the override reaches all of them — it cannot leave a URL pointing at the pin. A leading v is optional and a blank value falls back to the pin, so a mistyped override degrades to the tested default instead of producing a broken URL. Only the pinned version is tested, so an override prints a warning naming both versions before installing:

Warning: using Lemonade 11.6.0 from ROCM_CLI_LEMONADE_VERSION; the tested version is 11.5.1.

This is the convention vLLM is expected to adopt next; no vLLM entries are added here.

Behaviour changes

  • The Lemonade runtime installed by rocm engines install lemonade moves to 11.5.1.
  • The offline fallback and the runtime-id label recorded in user config now match that pin instead of naming 10.6.0. The label is an opaque identifier, not a lookup key, but it is persisted, so it is called out rather than buried.
  • ROCM_CLI_LEMONADE_VERSION is new.
  • Only windows-x64 and ubuntu-x64 remain wired up in the engine adapter. The release also publishes ubuntu-arm64 and macos-arm64; the adapter still does not select them, and the doc comment that claimed otherwise is corrected.

A bug the bump would otherwise have hit

Reviewing the bump surfaced a pre-existing defect that this PR would have made live for every user: upgrading did nothing.

The embeddable runtime directory is not version-scoped, so prepare_embeddable downloaded the new archive and then skipped extraction because lemond was already present from the previous version — leaving the old binaries in place while reporting the new version. One layer up, the CLI asked the adapter whether a runtime was installed and ignored which version came back, so a bump never reached the install path at all.

Both now compare versions. The adapter re-extracts when the recorded version differs from the one being installed, and the CLI requires the detected env id to match the one it asked for — which is meaningful only because that id is now derived from the pin. The adapter's decision is a pure function, so the upgrade case is covered by a test without needing a real archive.

What 11.5.1 brings over 10.10.0

  • Ten MiniCPM text and vision GGUF models added to the built-in llama.cpp catalog.
  • Router Builder gains a Test Prompt tab and a POST /routing/validate endpoint that runs a routing policy against a sample prompt and returns the decision plus a step-by-step trace.
  • lemonade bench adds an image-generation benchmark mode with capability-aware scenario/model filtering and a --timeout flag.
  • Tool-calling requests to llama.cpp with large JSON schema bounds are now accepted (previously rejected by a grammar limit).
  • Upstream breaking changes worth knowing: llama.cpp non-streaming responses return the requested model id instead of the local .gguf absolute path; registered/imported collections list under their canonical prefixed id; auto backend selection now prefers Vulkan on AMD systems across all engines.

Asset naming is identical between the two releases, so the bump itself is a pure version substitution, and no checksum is pinned anywhere.

Tests

The old pins had no test coverage at all — nothing failed if a constant was wrong. Added, following the pure-resolution style already used for the vLLM env overrides (the resolver takes the override as a parameter, so no test touches process environment):

  • Derived archive names and URLs match the published shape for the configured version.
  • An overridden version flows through to both the archive name and the URL, and the resulting URL no longer mentions the pin.
  • Absent, empty, whitespace-only and bare-v overrides all fall back to the pin; a usable override is trimmed and v-stripped.
  • Only an override produces the warning.
  • The dashboard fallback resolves to the same version the engine installs, and its artifact matches the derived archive name — a regression that reintroduced a second constant would fail here.
  • A version change forces re-extraction over an existing runtime tree, while an unchanged version does not.

A stale lemonade version string in an e2e-report test fixture is refreshed alongside; it is self-contained so it never failed, but it kept drifting.

Verification

Ran locally on Linux x86_64 (no GPU):

  • cargo test --workspace --all-targets --no-fail-fast — all pass except two pre-existing rocm-core failures (proc_lifecycle::tests::tree_stop_waits_for_descendants, tree_forced_kill_reaches_sigterm_ignoring_descendant), which reproduce identically on an unmodified origin/main checkout in this environment and are unrelated.
  • cargo clippy --locked --workspace --all-targets -- -D warnings — clean.
  • cargo clippy --locked -p e2e-cucumber --test e2e -- -D warnings — clean.
  • cargo fmt --all --check — clean.
  • python scripts/smoke_local.pysmoke: ok.
  • cargo xtask manifest --check and cargo xtask tpn --check — both pass with the new crate. The MANIFEST table lists external crates only, and rocm-deps's only dependency (toml, build-only) is already in the tree.

End to end, against the real release:

  • With no override, rocm-engine-lemonade install downloaded lemonade-embeddable-11.5.1-ubuntu-x64.tar.gz (6512136 bytes) from the upstream release — so the bumped URL resolves for real, not just in a unit test.
  • With ROCM_CLI_LEMONADE_VERSION=v99.0.0, it printed the override warning and requested .../download/v99.0.0/lemonade-embeddable-99.0.0-ubuntu-x64.tar.gz, confirming the version reaches the warning, the archive name and the URL together.

Temporarily adding two pin entries whose names differ only by separator (lemonade-x and lemonade_x) failed the build with runtime.lemonade-x.version and runtime.lemonade_x.version both generate LEMONADE_X_VERSION; rename one, confirming the generator's collision guard and that editing the pin file rebuilds the crate.

A full install-and-serve against the 11.5.1 runtime still needs a GPU runner and has not been done here.

Draft until someone can confirm a live install against the 11.5.1 runtime on a GPU runner.

rominf added 5 commits August 4, 2026 09:56
Move the pinned Lemonade embeddable runtime from 10.10.0 to 11.5.1.
Asset naming is unchanged between the two releases, so the download
URLs only need the version substituted.

Also refresh a stale lemonade version in an e2e-report test fixture so
it stops drifting from the pinned version.

Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
The dash offline fallback version is documented to track the latest
release ("Bump deliberately"), but it still named 10.6.0 while the
engine pin moved to 11.5.1. A host whose GitHub releases API call fails
would silently install a runtime several minor versions behind the pin.

Also correct the host-triple mapping doc, which claimed the release
ships only the three archives we select; it also publishes ubuntu-arm64.

Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
The Lemonade embeddable version was written out seven times across five
constants in the engine adapter, and again as an independent constant in
the dashboard TUI. Nothing tied those together, so they drifted: the two
constants sat five minor versions apart, the runtime-id label in the CLI
was four behind both, and a doc comment had been stale since 10.10.0.

Move the pin into `runtime-deps.toml` at the repository root and add a
small `rocm-deps` crate whose build script turns each `[runtime.<name>]`
field into a constant. Archive names, download URLs, the dashboard's
offline fallback, and the managed runtime-id label are all derived from
that one value, so a bump is a one-line edit and the tree can no longer
hold two different Lemonade versions. Generating at build time rather
than committing generated source means there is nothing to drift and no
`--check` gate to keep honest.

The schema is a table per runtime with one or more string fields, so a
runtime needing more than a version (a version plus an ABI tag, say) is
additive rather than a reshape.

No behaviour change beyond the runtime-id label, which now matches the
`env_id` the adapter actually reports instead of naming an older release.

Signed-off-by: Roman Inflianskas <roman.inflianskas@amd.com>
Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
Trying a Lemonade release other than the pinned one meant editing source
and rebuilding. Add `ROCM_CLI_LEMONADE_VERSION`, following the existing
`ROCM_CLI_*` convention, which replaces the `runtime-deps.toml` default
for the invocation. Because every archive name and download URL is
derived from the resolved version, an override reaches all of them; it
cannot leave a URL pointing at the pin.

A leading `v` is optional and a blank value falls back to the pin, so a
mistyped or empty override degrades to the tested default instead of
producing a broken URL. Only the pin is tested, so an override prints a
warning naming both versions before the install proceeds.

Resolution is a pure function taking the override as a parameter, so the
tests cover it without touching process environment.

Signed-off-by: Roman Inflianskas <roman.inflianskas@amd.com>
Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
The embeddable runtime directory is not version-scoped, so after a bump
`prepare_embeddable` downloaded the new archive but skipped extraction
because `lemond` was already there from the previous version. The old
binaries stayed in place and were then reported as the new version. The
CLI made the same mistake one layer up: it asked the adapter whether a
runtime was installed and ignored which version came back, so a bump
never even reached the install path.

Compare versions in both places. The adapter re-extracts when the
recorded version differs from the one being installed, and the CLI now
requires the detected env id to be the one it asked for — which the
previous commit made meaningful by deriving that id from the pin. The
decision in the adapter is a pure function so the upgrade case is tested
without a real archive.

Also guard the pin generator against two entries whose names differ only
by separator (`rocm-abi` and `rocm_abi` both fold to `ROCM_ABI`), and
escape generated literals with Debug formatting instead of a hand-written
rule about which characters are allowed.

Signed-off-by: Roman Inflianskas <roman.inflianskas@amd.com>
Signed-off-by: Roman Inflianskas <Roman.Inflianskas@amd.com>
@rominf rominf changed the title build(deps): bump lemonade embeddable to 11.5.1 build(deps): pin lemonade 11.5.1 from a single source of truth Aug 4, 2026
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