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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .agents/skills/bump-engines/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ Each engine's `engines/<engine>/AGENTS.md` owns its pin, release id convention a

4. Sweep for the old release id, version and digest. Keep measurement-provenance comments in model files. A bump that changes no flag never needs backend test edits; if one does, the test asserts a committed declaration, which is a coupling bug to fix. When upstream forces an adapter change (step 2), its tests change with it.

5. Qualify on hardware. Flag audits miss default-behaviour changes, which only the gated tests and real deployments catch, so this step is required:
* Run `just backend::test-nvidia` on an amd64 NVIDIA host and on GB10.
* Deploy each changed engine's profiles on every platform it supports, each on a host whose memory fits its per-device minimum. A row passes when it reaches Ready, answers two completions, shows draft acceptance above 0 where speculative, and launches with the argv the adapter produces.
* Report sizing estimates that read low by more than 5% or 500 MiB, measured with the check of the `model-sizing` skill, and a largest fit that doesn't start or lands far below the engine's real start limit; don't refit sizing in a bump unless upstream changed how the engine holds memory, which needs the user's approval.
5. Qualify on every platform the engine runs on (root `AGENTS.md` "Platform scope"), macOS included. Flag audits miss default-behaviour changes, which only the hardware tests and real deployments catch, so this step is required:
* Run the hardware tests in the engine's `AGENTS.md` "Validate" on a host of each platform.
* Deploy each changed engine's profiles on one platform, each on a host whose memory fits its per-device minimum. On the other platforms, deploy only the profiles most exposed to the audited upstream changes (drafts, the engine's memory paths) and any that read low; full sweeps cost hours of hardware and many GB of downloads. A row passes when it reaches Ready, answers two completions, shows draft acceptance above 0 where speculative, and launches with the argv the adapter produces.
* Report sizing estimates that read low by more than 5% or 500 MiB, measured with the check of the `model-sizing` skill, and a largest fit that doesn't start or lands far below the engine's real start limit; don't refit sizing in a bump unless upstream changed how the engine holds memory, which needs the user's approval. A model that only overruns its margin gets, with approval, a small offset fitted to the measurements already taken, not a new sizing campaign.
* Run remote hosts one at a time, with one remote command per row: an ssh agent that prompts for approval rejects concurrent signing.
* Check a host's free disk before each new model download. The model cache is shared with other workspaces, so report a nearly full disk to the user instead of pruning it.

6. Fix any `AGENTS.md` step that proved wrong.
4 changes: 2 additions & 2 deletions backend/core/src/model/engine/llama_cpp/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn classify(rejections: &[(u16, &str)], status: u16, body: &[u8]) -> Option<Inva
/// message format, where `%d` stands for a token count.
///
/// A prompt larger than the micro-batch is a server error, and one larger than a slot's context
/// is a context-size error (b11723 `tools/server/server-context.cpp`).
/// is a context-size error (b12359 `tools/server/server-context.cpp`).
const OVERSIZED_PROMPT_REJECTIONS: [(u16, &str); 2] = [
(
500,
Expand All @@ -69,7 +69,7 @@ const OVERSIZED_PROMPT_REJECTIONS: [(u16, &str); 2] = [
];

/// llama.cpp's refusal of a chat prompt larger than a slot's context: the HTTP status it answers
/// with and its message format (b11723 `tools/server/server-context.cpp`).
/// with and its message format (b12359 `tools/server/server-context.cpp`).
const OVERSIZED_CHAT_REJECTIONS: [(u16, &str); 1] = [(
400,
"request (%d tokens) exceeds the available context size (%d tokens), try increasing it",
Expand Down
2 changes: 1 addition & 1 deletion backend/core/src/model/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,7 @@ mod tests {
inputs.hardware_class_id.as_str(),
),
(
"llama-cpp-2026-10-19",
"llama-cpp-2026-11-13",
"metal",
dotcore_domain::test_support::nix::STORE_PATH,
"apple",
Expand Down
2 changes: 1 addition & 1 deletion backend/core/src/test_support/nix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub(crate) fn apple_metal_snapshot(model_id: &str) -> ModelDeploymentSnapshot {
panic!("Apple Metal fixture requires a local snapshot");
};
let engine = local.engine_artifact.as_mut().expect("snapshot engine");
engine.engine_release_id = "llama-cpp-2026-10-19".to_owned();
engine.engine_release_id = "llama-cpp-2026-11-13".to_owned();
let mut artifact = EngineArtifact {
selectors: Vec::new(),
..engine_artifact("metal", &locked_flake(), "darwin", "arm64", "apple")
Expand Down
7 changes: 4 additions & 3 deletions backend/core/tests/gated/apple_hardware_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,12 @@ fn hw_apple_gpu_is_observed_with_a_fixed_device_id_across_polls() {
NodeAcceleratorObservation::from_hardware_snapshot("node-a", &snapshots[0], false),
NodeAcceleratorObservation::available_at(
"node-a",
NodeAcceleratorFacts::apple(),
NodeAcceleratorFacts::apple()
.with_device_memory(gpu.device_id.clone(), None, None)
.with_device_model(gpu.model.clone())
.with_host_memory(host_total, host_available),
observed_at
)
.with_device_memory(gpu.device_id.clone(), None, None)
.with_host_memory(host_total, host_available)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ artifacts:
configurations:
- configurationId: "nvidia-cuda"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
artifactBindings:
- bindingId: "split-q8"
Expand Down
11 changes: 11 additions & 0 deletions backend/site/src/node/target_inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,17 @@ impl NodeAcceleratorFacts {
self
}

/// Names the product model the vendor reports for the device added last.
#[cfg(any(test, feature = "test-support"))]
pub fn with_device_model(mut self, model: impl Into<String>) -> Self {
self.memory
.devices
.last_mut()
.expect("a device to name")
.model = model.into();
self
}

/// Replaces the host memory facts.
#[cfg(any(test, feature = "test-support"))]
pub fn with_host_memory(mut self, total_bytes: u64, available_bytes: u64) -> Self {
Expand Down
4 changes: 2 additions & 2 deletions catalog/engines/llama-cpp-macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# flake as `engines.llama-cpp.native`. The packaged master catalog rewrites `self` to the locked Dotcore
# revision with precomputed store paths, and fails unless the version equals the engine package
# version (checked by `checks.dotcore-catalog`).
engineReleaseId: "llama-cpp-2026-10-19"
engineReleaseId: "llama-cpp-2026-11-13"
engineKind: "ENGINE_KIND_LLAMA_CPP"
version: "b11723"
version: "b12359" # v1.0.0
parameterSchema:
schemaId: "llama-cpp-v2"
parameters:
Expand Down
4 changes: 2 additions & 2 deletions catalog/engines/llama-cpp.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Each artifact names a Docker image derivation package; the package pins the exact image.
# NVIDIA host integration testing remains an explicit responsibility.
engineReleaseId: "llama-cpp-linux-2026-10-19"
engineReleaseId: "llama-cpp-linux-2026-11-13"
engineKind: "ENGINE_KIND_LLAMA_CPP"
version: "b11723"
version: "b12359" # v1.0.0
# Same schema id as the macOS release, so one model configuration can approve artifacts of both.
parameterSchema:
schemaId: "llama-cpp-v2"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/clef-flash.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ configurations:
# The model card's encoder default; the weights accept up to the model's maximum context.
maximumContextTokens: 16384
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q4-k-m"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/gemma-4-12b-it-qat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- { engineReleaseId: "llama-cpp-linux-2026-10-19", engineArtifactId: "cuda13" }
- { engineReleaseId: "llama-cpp-2026-10-19", engineArtifactId: "metal" }
- { engineReleaseId: "llama-cpp-linux-2026-11-13", engineArtifactId: "cuda13" }
- { engineReleaseId: "llama-cpp-2026-11-13", engineArtifactId: "metal" }
artifactBindings:
- bindingId: "primary"
modelArtifactId: "primary"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/gemma-4-26b-a4b-it.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/gemma-4-31b-it.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/gemma-4-e2b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q4-k-m"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/gemma-4-e4b-it-qat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- { engineReleaseId: "llama-cpp-linux-2026-10-19", engineArtifactId: "cuda13" }
- { engineReleaseId: "llama-cpp-2026-10-19", engineArtifactId: "metal" }
- { engineReleaseId: "llama-cpp-linux-2026-11-13", engineArtifactId: "cuda13" }
- { engineReleaseId: "llama-cpp-2026-11-13", engineArtifactId: "metal" }
artifactBindings:
- bindingId: "primary"
modelArtifactId: "primary"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/muse-glimmer-30b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
2 changes: 1 addition & 1 deletion catalog/models/nanbeige-4-3-33b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ artifacts:
configurations:
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
artifactBindings:
- bindingId: "q3-iq3-s"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/nemotron-3-5-lightning-30b-a3b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
13 changes: 8 additions & 5 deletions catalog/models/ornith-1-5-35b-a3b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q4-k-m"
Expand Down Expand Up @@ -479,7 +479,9 @@ configurations:
# The prompt cache shares the unified pool with the model.
parameters:
promptCacheOnAccelerator: 1
baseOffsetBytes: 0
# Measured on a GB10 with llama.cpp b12359 (2026-11-13): the derived base terms read up to
# 392 MiB low at the profile defaults (Q4_K_M; Q6_K 267 MiB).
baseOffsetBytes: 469762048
bindingSizing:
# Derived from qwen3-6 q4-xl (GB10): main-weight difference -1,158,046,240 B.
- bindingId: "q4-k-m"
Expand Down Expand Up @@ -513,8 +515,9 @@ configurations:
# The prompt cache stays in host memory, outside the GPU's own memory.
parameters:
promptCacheOnAccelerator: 0
# The qwen3-6 dedicated-memory offset (400 MiB, from its RTX 5090 smoke runs).
baseOffsetBytes: 419430400
# Measured on an RTX 5090 with llama.cpp b12359 (2026-11-13): the derived base terms read up
# to 766 MiB low at the profile defaults (Q4_K_M; Q5_K_M 704 MiB, Q6_K 640 MiB).
baseOffsetBytes: 889192448
# The binding parameters are the nvidia-unified values verbatim, as in qwen3-6.
bindingSizing:
- bindingId: "q4-k-m"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/qwen3-5-4b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/qwen3-5-9b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/qwen3-6-35b-a3b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ configurations:
# One configuration for every platform: CUDA on Linux NVIDIA, Metal on macOS.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
4 changes: 2 additions & 2 deletions catalog/models/qwen3-8-27b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ configurations:
# targets and the Metal binary on macOS native targets; both releases share a parameter schema.
- configurationId: "llama-cpp"
engineArtifacts:
- engineReleaseId: "llama-cpp-linux-2026-10-19"
- engineReleaseId: "llama-cpp-linux-2026-11-13"
engineArtifactId: "cuda13"
- engineReleaseId: "llama-cpp-2026-10-19"
- engineReleaseId: "llama-cpp-2026-11-13"
engineArtifactId: "metal"
artifactBindings:
- bindingId: "q3-xl"
Expand Down
42 changes: 16 additions & 26 deletions engines/llama-cpp/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,28 @@

## How it is built

* Linux: [`docker-image.lock.json`](docker-image.lock.json) pins the upstream image by digest; the
node pulls it on first use or loads its stored image. The release declares the driver floor.
* macOS: `engines.llama-cpp.native` ([`package.nix`](package.nix)), `aarch64-darwin` only. The
release tarball is installed unmodified (rewriting the Mach-O files would break their
signatures): tools and dylibs under `libexec/llama-cpp/`, linked into `bin/`; the main program is
`llama-server`.
* Linux: [`docker-image.lock.json`](docker-image.lock.json) pins upstream's CUDA image by digest.
The release declares the driver floor.
* macOS: [`package.nix`](package.nix) installs upstream's macOS arm64 release tarball unmodified;
rewriting its Mach-O files would break their signatures.
* The package builds with the repository flake's nixpkgs, so a root nixpkgs bump can change its
store path; existing deployments keep the store path they pinned.
* Nothing here is part of root `just build`, `test` or `check`.
* Shared parameters: [`engines/AGENTS.md`](../AGENTS.md) says where their flags and rules live.

## Update

1. Pick the newest tag that has both the Linux image and the macOS asset (the two usually move
together). Linux image: `just image-lock ghcr.io/ggml-org/llama.cpp:server-cuda13-<tag>`. Images
appear after the release tarballs, so the newest tag can lack one; the recipe then fails.
2. macOS package: check the release has a `llama-<tag>-bin-macos-arm64.tar.gz` asset (some, such as
`b10156`, have none). Set `version` in [`package.nix`](package.nix) to the tag, and `src.hash`
to the asset's SHA-256 in SRI form (`sha256-...`): the release asset's `digest`, or
`nix store prefetch-file` on its URL; convert hex with `nix hash convert --hash-algo sha256 <hex>`.
3. Declare new releases with the tag as `version`: `llama-cpp-linux-<date>` in `llama-cpp.yaml` and
`llama-cpp-<date>` in `llama-cpp-macos.yaml`, after the build's publish date, and move every
model approving the old releases to them. Releases are immutable, and the macOS package `version`
must equal its release's `version` (`checks.dotcore-catalog` fails otherwise); keep an older
release by pinning it to the `github:dotcoreai/dotcore/<rev>` revision that built it.
* Target upstream's newest stable release (`v<semver>`), not a nightly. It shares its commit with a
nightly build tag (`b<build>`): both artifacts are published under that build, and it is the
release `version` (note the semver in a comment).
* Lock the release's CUDA image by its index digest, never by tag. Images can lag the tarballs, and
not every nightly gets one.
* The macOS package `version` must equal its release's `version`; the catalog check fails
otherwise.
* Releases are immutable: declare new ones with the date convention of `llama-cpp.yaml` and
`llama-cpp-macos.yaml`, and move every model approving the old ones.

## Validate

1. `just smoke` (on a Mac): prints the package store path and `llama-server --version`; the build
number must match the tag. No model or GPU needed.
2. Linux image, on an NVIDIA host: `just image-load`, then from the root
`just dev::workload-launch <model> <profile> --device nvidia.com/gpu=0` with a small model
approving the new release; the workload answers a request.
3. `just backend::test-nvidia` on an NVIDIA host (from the root) deploys the engine from the
workspace's development source through its loader, as a node does.
* `just smoke` on a Mac checks the package and the build number it reports.
* The backend's hardware test recipes on each platform in the root "Platform scope":
`test-nvidia` (NVIDIA hosts), `test-gb10` (GB10) and `test-apple` (Mac).
Loading