Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
ec9b629
chore: upgrade llama.cpp from b10456 to b10470
Aug 25, 2026
dee4585
chore: upgrade llama.cpp from b10470 to b10472
Aug 25, 2026
adbeeb3
chore: upgrade llama.cpp from b10472 to b10481
Aug 25, 2026
18ac941
chore: upgrade llama.cpp from b10481 to b10488
Aug 25, 2026
368189d
chore: upgrade llama.cpp from b10488 to b10499
Aug 25, 2026
c2191ec
chore: upgrade llama.cpp from b10499 to b10507
Aug 25, 2026
337945c
chore: upgrade llama.cpp from b10507 to b10509
Aug 25, 2026
d78c161
chore: upgrade llama.cpp from b10509 to b10519
Aug 25, 2026
643e5dd
chore: upgrade llama.cpp from b10519 to b10532
Aug 25, 2026
97d4af2
chore: upgrade llama.cpp from b10532 to b10541
Aug 25, 2026
50b85c5
chore: upgrade llama.cpp from b10541 to b10545
Aug 25, 2026
7db7bad
chore: upgrade llama.cpp from b10545 to b10549
Aug 25, 2026
c8bf06d
chore: upgrade llama.cpp from b10549 to b10566
Aug 25, 2026
a5fe54e
chore: upgrade llama.cpp from b10566 to b10568
Aug 25, 2026
e4a2ffa
chore: upgrade llama.cpp from b10568 to b10569
Aug 25, 2026
2c381b6
chore: upgrade llama.cpp from b10569 to b10578
Aug 25, 2026
7657ecd
chore: upgrade llama.cpp from b10578 to b10584
Aug 25, 2026
8d3f641
chore: upgrade llama.cpp from b10584 to b10585
Aug 25, 2026
e4a8149
chore: upgrade llama.cpp from b10585 to b10590
Aug 25, 2026
90cd0bf
chore: upgrade llama.cpp from b10590 to b10593
Aug 25, 2026
9208267
chore: upgrade llama.cpp from b10593 to b10599
Aug 25, 2026
12e25a5
chore: upgrade llama.cpp from b10599 to b10612
Aug 25, 2026
d29f323
chore: upgrade llama.cpp from b10612 to b10614
Aug 25, 2026
721dbeb
chore: upgrade llama.cpp from b10614 to b10615
Aug 25, 2026
3d755e4
chore: upgrade llama.cpp from b10615 to b10618 (final target)
Aug 25, 2026
7ad392e
refactor: harden against the common_json conversion trap
Aug 25, 2026
aa67015
fix: carry a patch for /models emitting vocab_type as boolean
Aug 25, 2026
029c79f
chore: renumber patch 0009 -> 0010 and correct the bump records
Aug 25, 2026
484755a
docs: correct the bump records the review found unsupported
Aug 25, 2026
40550b4
fix: make the llama.cpp patch applier idempotent via a stamp
claude Aug 25, 2026
93d0679
test: stop the model-gated Java tests self-skipping in CI
claude Aug 25, 2026
d18f315
fix: rebuild getMetrics() from both upstream introspection tasks
claude Aug 25, 2026
e9794b0
feat: give RouterClient an API key; fix hidden-model diagnosis
claude Aug 25, 2026
8e51479
docs: record the five closed gaps and drop their TODO entries
claude Aug 25, 2026
2dc248e
docs: record the metrics-contract restoration in bump history
claude Aug 25, 2026
3cfd057
feat: expose the mmproj device selector added upstream
claude Aug 25, 2026
68e09d4
docs: record this branch's work in the changelog
claude Aug 25, 2026
af75fc4
fix: reject the -1 penalty-window sentinel llama.cpp removed
claude Aug 25, 2026
601c4f8
docs: refresh stale claims and harden the upgrade review
claude Aug 25, 2026
2987d3e
test: fix the streaming assertion for a thinking-only response
claude Aug 25, 2026
50650ec
fix: bound the metrics wait and restore counter key spellings
claude Aug 25, 2026
7be24a6
fix: repair LlamaQuantizer's JNI linkage and the -1 sentinel
claude Aug 25, 2026
7b68897
docs: add the missing SPDX header to the win32-argv doc
claude Aug 25, 2026
e443758
docs: record the macOS confirmations for the quantizer fix
claude Aug 25, 2026
cfda4a9
ci: echo the crash log into the job log at all six test jobs
claude Aug 26, 2026
269076e
docs: localise the TTS abort to memset(NULL, 0, n) at load
claude Aug 26, 2026
2f99c3e
docs: correct two misreadings of the TTS crash frames
claude Aug 26, 2026
4c39d6b
chore: upgrade llama.cpp from b10618 to b10631
claude Aug 26, 2026
999034b
fix: resolve CPU params on hand-built common_params (TTS abort)
claude Aug 26, 2026
03e4a05
fix: give the router worker JVM the main classes on its classpath
claude Aug 26, 2026
fe4de0a
chore: upgrade llama.cpp from b10631 to b10636
claude Aug 26, 2026
2204ab1
chore: upgrade llama.cpp from b10636 to b10639
claude Aug 26, 2026
b151f72
chore: ignore the per-bump build-b<version> verification trees
claude Aug 26, 2026
b0d69c1
docs: record b10639 verification and the inlining false alarm
claude Aug 26, 2026
cc67ea7
test: stop fork/rewind tests spending their budget on thinking
claude Aug 26, 2026
ca60947
fix: stop one malformed UTF-8 byte from 500-ing a generation
claude Aug 26, 2026
7b9309d
docs: record the 8-patch re-verification for b10639
claude Aug 26, 2026
6cdd7b0
chore: upgrade llama.cpp from b10639 to b10644
claude Aug 27, 2026
fe5ef7b
fix: close every finding from the b10456-b10644 upgrade audit
claude Aug 27, 2026
3abe8bc
ci: stop the crash-log step asserting an unobserved abort
claude Aug 27, 2026
f9f654c
docs: repoint the CI-confirmation SHAs after the history rewrite
claude Aug 27, 2026
e02867b
style: reflow the modalities emit to satisfy clang-format
claude Aug 27, 2026
4dba16f
chore: upgrade llama.cpp from b10644 to b10649
claude Aug 27, 2026
c5d3d23
fix: wake the task queue before posting; close the second-audit findings
claude Aug 27, 2026
0fa4bf3
feat: expose the video-decoding parameters refused at the b10649 bump
claude Aug 27, 2026
ce330a1
ci: give the langchain4j integration job the crash diagnostics it lacked
claude Aug 27, 2026
dd07b0e
test: budget the langchain4j chat tests past Qwen3's thinking block
claude Aug 27, 2026
7da5c50
docs: close the two TODO entries this PR actually fixed
claude Aug 27, 2026
7319e62
docs: correct the remaining stale counts and the video-input claim
claude Aug 27, 2026
5859a6d
fix: honour upstream's video-fps sentinel; narrow the mmproj clearing
claude Aug 27, 2026
267d975
feat: upgrade llama.cpp from b10649 to b10679
claude Aug 28, 2026
6566b5d
fix: correct upstream tag attributions and three real defects
claude Aug 28, 2026
65d5f37
docs: note the one-time concurrency-group transition
claude Aug 28, 2026
b32485f
test: guard the idle-sleep wake path and jsonSchemaToGrammar
claude Aug 28, 2026
9eb94b7
fix: wake and re-sync before touching the model after idle sleep
claude Aug 29, 2026
cce1911
fix: refresh our own load-progress user_data on every model load
claude Aug 29, 2026
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
280 changes: 280 additions & 0 deletions .github/workflows/publish.yml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
target
build
build-android
# Per-bump verification trees. The llama.cpp upgrade runbook requires a FRESH build
# directory for every version bump -- the patch applier pins its stamp to the checked-out
# llama.cpp commit and deliberately aborts rather than guess when an existing dir's stamp
# names a different one -- and the convention names them build-b<version>.
build-b*
cmake-build-*
.DS_Store
.directory
Expand Down
295 changes: 295 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

206 changes: 155 additions & 51 deletions CLAUDE.md

Large diffs are not rendered by default.

64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
**Build:**
![Java 8+](https://img.shields.io/badge/Java-8%2B-informational)
![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows%20%7C%20Android-lightgrey)
[![llama.cpp b10456](https://img.shields.io/badge/llama.cpp-%23b10456-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10456)
[![llama.cpp b10679](https://img.shields.io/badge/llama.cpp-%23b10679-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10679)
[![JPMS](https://img.shields.io/badge/JPMS-modular%20JAR-25A162)](https://openjdk.org/projects/jigsaw/)
![JUnit](https://img.shields.io/badge/tested%20with-JUnit6-25A162)
[![JSpecify](https://img.shields.io/badge/JSpecify-1.0.0%20%40NullMarked-25A162)](https://jspecify.dev)
Expand Down Expand Up @@ -489,6 +489,45 @@ OpenAI-compatible `/v1/chat/completions` server. For a strictly CPU-only run, us
`setDevices("none").setMmprojOffload(false)` in addition to `setGpuLayers(0)`; projector offload
has its own upstream default.

On a multi-GPU host the projector can be placed independently of the weights with
`setMmprojDevice("CUDA1")` (llama.cpp `--mmproj-device`, added upstream in b10541). Exactly one
device may be named; the literal `"none"` keeps the projector on the CPU. `OpenAiCompatServer`'s CLI
accepts the same flag as `-mmdev`/`--mmproj-device`, and `NativeServer` forwards it verbatim like
every other llama-server flag.

`setMmprojDevice(...)` and `setMmprojOffload(...)` write the **same** upstream field
(`common_params::mmproj_use_gpu`), so where they disagree the outcome would depend on argv order —
and the rendered argv comes from a `HashMap`, whose order is unspecified. The builder therefore
resolves the two genuinely ambiguous combinations by dropping the earlier call, and leaves the rest
alone:

| Combination | Resolves to | Builder behaviour |
|---|---|---|
| named device + `setMmprojOffload(true)` | `(use_gpu=true, device)` in either order | both kept — no clash |
| named device + `setMmprojOffload(false)` | order-dependent | **last call wins** |
| `"none"` + `setMmprojOffload(true)` | order-dependent | **last call wins** |
| `"none"` + `setMmprojOffload(false)` | `(use_gpu=false)` in either order | both kept — no clash |

So a multi-GPU projector pin survives an explicit `setMmprojOffload(true)`; only a call that would
actually contradict the other is dropped. If you need a device after disabling offload, call
`setMmprojDevice` last.

**Video input — decode settings only, so far.** `mtmd` has carried a video path since llama.cpp
**b9562** (#24269); **b10647** (#24318) added the `--video-*` CLI flags and the
`mtmd_helper_init_opt` plumbing that surfaces them. It is compiled into the shipped desktop library
(`MTMD_VIDEO` is on by default, gated on `LLAMA_SUBPROCESS`, which upstream force-disables on
Android and iOS). Its decode settings are exposed
as `setVideoFps(float)`, `setVideoTimestampInterval(long)` and `setVideoFfmpegDir(String)`. The last
one matters most in a JVM: upstream shells out to `ffmpeg`/`ffprobe` and resolves them from `PATH`,
which an application server, an Android app or a JAR-only container frequently does not have them on —
naming the directory is then the only way for video to work at all.

What is **not** here yet is the content part: upstream's wire type for a video is
`{"type":"input_video","input_video":{"data":"<base64>"}}` (raw base64, not a `data:` URI, unlike
`image_url`), gated server-side on `mtmd_helper_support_video`. `ContentPart` has no `videoFile(...)`
factory emitting that shape, so these knobs currently configure a path this API cannot yet feed
directly. Tracked in `TODO.md`.

**Audio input** works identically — load an audio-capable model (Ultravox, Qwen2.5-Omni, …) with its
audio `--mmproj` and add a `ContentPart.audioFile(...)` (or `inputAudio(bytes, "wav"|"mp3")`) part. It
serializes to the OpenAI `input_audio` content part and routes through the same `mtmd` pipeline:
Expand Down Expand Up @@ -694,7 +733,11 @@ request, so generation and `save`/`restore` operate on the same KV state.
Typed results expose logical prompt, generated, cached prompt, and evaluated prompt counts through
`Usage`. Per-request timing also remains available through `Timings.getCacheN()`.
`LlamaModel.getMetricsTyped().getSlotMetrics()` reports each slot's logical, processed, cached,
decoded, and remaining token counts.
decoded, and remaining token counts, and the same `ServerMetrics` view carries the server-wide
lifetime counters — including cached prompt tokens (`getCumulativeCachedPromptTokens()`) and the
speculative-decoding tallies (`getDraftTokensTotal()`, `getDraftAcceptedTotal()`,
`getDraftVerifyStepsTotal()`, `getDraftAcceptedPerPosition()`, plus the derived
`getDraftAcceptanceRate()`), which upstream otherwise exposes only as Prometheus text.

The embedded HTTP server exposes the same native JSON at authenticated `GET /metrics`, with the slot
array alone at `GET /slots`. OpenAI responses preserve
Expand Down Expand Up @@ -779,7 +822,7 @@ java -cp target/llama-<version>.jar net.ladenthin.llama.server.OpenAiCompatServe
Run with `--help` for the full option list (`-m/--model`, `--host`, `-p/--port`, `-c/--ctx-size`,
`-b/--batch-size`, `-ub/--ubatch-size`, `-ngl/--n-gpu-layers`, `-t/--threads`, `-tb/--threads-batch`,
`-ctk/--cache-type-k`, `-ctv/--cache-type-v`, `--jinja`, `--chat-template-kwargs`, `--parallel`,
`--model-id`, `--api-key`, `--mmproj`, `--embedding`, `--reranking`). The tuning flags mirror
`--model-id`, `--api-key`, `--mmproj`, `-mmdev/--mmproj-device`, `--embedding`, `--reranking`). The tuning flags mirror
llama.cpp's server, so an invocation like
`--jinja --chat-template-kwargs '{"reasoning_effort":"low"}' -ctk q8_0 -ctv q8_0 -b 4096 -ub 2048`
works directly.
Expand Down Expand Up @@ -923,6 +966,21 @@ client.unloadModel("Qwen3-0.6B-Q4_K_M"); // POST /models/unload
failed-worker marker. Chat requests then select a model per request via the standard
`"model"` field on `POST /v1/chat/completions`.

Against a router started with `--api-key`, pass the key — it is sent as
`Authorization: Bearer <key>` on every call. All of them need it: `/models/load` and
`/models/unload` were always gated, and since llama.cpp b10519 the listing endpoints are too.

```java
RouterClient client = new RouterClient(8080, System.getenv("LLAMA_API_KEY"));
// or, for a remote router: new RouterClient("router.internal", 8080, key)
```

> [!NOTE]
> `awaitModelLoaded` waits by polling `GET /models`, so it cannot observe a model the router
> deliberately hides from that listing — a cache model deduplicated by a preset with
> `dedup-cache-models` still loads and still serves by name, but never appears. For those, skip the
> await and issue the request directly; with autoload the router waits for the worker itself.

### LangChain4j integration

A separate artifact, **`net.ladenthin:llama-langchain4j`**, adapts a `LlamaModel` to
Expand Down
Loading
Loading