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
61 changes: 41 additions & 20 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,12 @@ jobs:
repository: ggml-org/llama.cpp
ref: ${{ steps.tag.outputs.tag }}
path: llamacpp-ui
sparse-checkout: tools/ui
# tools/ui holds the npm project AND the ui.cpp.in / ui.h.in templates;
# scripts/ holds ui-assets.cmake, which consumes them. Both are needed
# since upstream #28445 replaced the embed.cpp host tool.
sparse-checkout: |
tools/ui
scripts
sparse-checkout-cone-mode: true
- uses: actions/setup-node@v7
with:
Expand All @@ -565,30 +570,46 @@ jobs:
npm ci --ignore-scripts
npm run build
test -f dist/index.html
- name: Embed assets into ui.cpp / ui.h (gzip parity with upstream)
working-directory: llamacpp-ui/tools/ui
- name: Embed assets into ui.cpp / ui.h (upstream scripts/ui-assets.cmake)
shell: bash
run: |
set -euo pipefail
# gzip every asset into dist/_gzip/<path> so llama-ui-embed embeds the
# compressed bytes (LLAMA_UI_GZIP parity); embed auto-detects _gzip.
( cd dist && find . -type f -not -path './_gzip/*' | while read -r f; do
mkdir -p "_gzip/$(dirname "$f")"
gzip -9 -c "$f" > "_gzip/$f"
done )
# llama-ui-embed is a self-contained C++17 host tool (no npm) — build + run it.
g++ -O2 -std=c++17 -o llama-ui-embed embed.cpp
mkdir -p "$GITHUB_WORKSPACE/llama/webui-generated"
./llama-ui-embed \
"$GITHUB_WORKSPACE/llama/webui-generated/ui.cpp" \
"$GITHUB_WORKSPACE/llama/webui-generated/ui.h" \
dist
# Upstream #28445 ("ui : embed assets directly with CMake") deleted the
# tools/ui/embed.cpp host tool this step used to compile, and replaced it
# with scripts/ui-assets.cmake -- a plain `cmake -P` script, no npm and no
# host executable. Priority 1 of its provisioning order is "pre-built
# assets in <UI_SOURCE_DIR>/dist", which is exactly what the npm step
# above produced, so BUILD_UI and HF_ENABLED stay OFF: no second npm run
# and no Hugging Face download happen here. LLAMA_UI_GZIP is upstream's
# own knob and replaces the hand-rolled gzip loop this step used to do.
GEN="${RUNNER_TEMP}/ui-assets"
OUT="${GITHUB_WORKSPACE}/llama/webui-generated"
mkdir -p "$GEN" "$OUT"
cmake \
"-DUI_SOURCE_DIR=${GITHUB_WORKSPACE}/llamacpp-ui/tools/ui" \
"-DUI_BINARY_DIR=${GEN}" \
"-DLLAMA_SOURCE_DIR=${GITHUB_WORKSPACE}/llamacpp-ui" \
-DBUILD_UI=OFF \
-DHF_ENABLED=OFF \
-DLLAMA_UI_GZIP=ON \
-P "${GITHUB_WORKSPACE}/llamacpp-ui/scripts/ui-assets.cmake"
# The script also drops a ui-gzip/ working tree next to the generated
# sources; copy only the two files the artifact is defined to carry.
cp "$GEN/ui.cpp" "$GEN/ui.h" "$OUT/"
echo "=== generated WebUI assets ==="
ls -la "$GITHUB_WORKSPACE/llama/webui-generated"
if grep -q LLAMA_UI_HAS_ASSETS "$GITHUB_WORKSPACE/llama/webui-generated/ui.h"; then
echo "LLAMA_UI_HAS_ASSETS: present (real WebUI embedded)"
ls -la "$OUT"
# Guard against a silently empty WebUI. A bare `grep LLAMA_UI_HAS_ASSETS`
# does NOT work here and would pass the failure case: upstream's ui.h.in
# emits "/* #undef LLAMA_UI_HAS_ASSETS */" when the table is empty, so the
# token is present either way. (The old embed.cpp emitted no such line at
# all, which is why the naive grep used to be sufficient.) Assert the ACTIVE
# #define and a non-zero asset count instead -- verified against both paths.
N=$(sed -n 's/.*std::array<llama_ui_asset, \([0-9]\+\)>.*/\1/p' "$OUT/ui.h" | head -1)
if grep -qE '^[[:space:]]*#define[[:space:]]+LLAMA_UI_HAS_ASSETS' "$OUT/ui.h" \
&& [ -n "$N" ] && [ "$N" -gt 0 ]; then
echo "LLAMA_UI_HAS_ASSETS: present, $N assets embedded"
else
echo "ERROR: embed produced an empty asset table" >&2
echo "ERROR: ui-assets.cmake produced an empty asset table (assets=${N:-unknown})" >&2
exit 1
fi
- name: Upload WebUI artifact
Expand Down
40 changes: 26 additions & 14 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Java bindings for [llama.cpp](https://github.com/ggerganov/llama.cpp) via JNI, providing a high-level API for LLM inference in Java. The Java layer communicates with a native C++ library through JNI.

Current llama.cpp pinned version: **b10850**
Current llama.cpp pinned version: **b10870**

## Upgrading CUDA Version

Expand Down Expand Up @@ -470,9 +470,21 @@ Pipeline (`.github/workflows/publish.yml`):
pinned `b<nnnn>` tag from `llama/CMakeLists.txt`'s `GIT_TAG`, sparse-checks-out
`ggml-org/llama.cpp@<tag>` `tools/ui`, runs the upstream Svelte build
(`npm ci && npm run build`), gzips `dist/` into `dist/_gzip/` (LLAMA_UI_GZIP
parity), builds the self-contained `llama-ui-embed` host tool (plain C++17, **no
npm**) and runs it to produce the platform-independent **`webui-generated/ui.cpp`
+ `ui.h`**, uploaded as the `webui-generated` artifact.
parity), then runs upstream's own **`scripts/ui-assets.cmake`** (a plain `cmake -P`
script, **no npm and no host executable**) to produce the platform-independent
**`webui-generated/ui.cpp` + `ui.h`**, uploaded as the `webui-generated` artifact.
Upstream **#28445** deleted the `tools/ui/embed.cpp` host tool this job used to
compile and replaced it with that script plus `ui.cpp.in`/`ui.h.in` templates; the
job passes `BUILD_UI=OFF HF_ENABLED=OFF` so the script takes its priority-1 path
("pre-built assets in `<UI_SOURCE_DIR>/dist`") over the tree npm just built — no
second npm run, no Hugging Face download. `LLAMA_UI_GZIP` is upstream's own knob
and replaced the job's hand-rolled gzip loop. The sparse checkout therefore needs
**`scripts` as well as `tools/ui`**. **The completeness guard cannot be a bare
`grep LLAMA_UI_HAS_ASSETS`**: `ui.h.in` emits `/* #undef LLAMA_UI_HAS_ASSETS */`
for an empty table, so that token is present either way and the check passes the
failure case — the old `embed.cpp` emitted no such line, which is why the naive
grep used to work. The job asserts the **active** `#define` plus a non-zero count
parsed out of `std::array<llama_ui_asset, N>`.
2. **Every native build job** (`needs: [startgate, build-webui]`) downloads that
artifact into `webui-generated/` before building. npm never runs in the dockcross
cross-compilers (which have no node) or per-platform.
Expand All @@ -489,14 +501,14 @@ needs no extra step here, `build-webui` re-reads the tag and rebuilds the matchi
**Building the WebUI locally** (optional — a plain `cmake` build uses the stub and
ships no UI):
```bash
# needs node/npm + network; embed.cpp is plain C++17 (no npm)
git clone --depth 1 --branch b10850 https://github.com/ggml-org/llama.cpp /tmp/lc
( cd /tmp/lc/tools/ui && npm ci && npm run build \
&& ( cd dist && find . -type f -not -path './_gzip/*' \
| while read -r f; do mkdir -p "_gzip/$(dirname "$f")"; gzip -9 -c "$f" > "_gzip/$f"; done ) \
&& g++ -O2 -std=c++17 -o /tmp/llama-ui-embed embed.cpp )
mkdir -p webui-generated
/tmp/llama-ui-embed webui-generated/ui.cpp webui-generated/ui.h /tmp/lc/tools/ui/dist
# needs node/npm + network for the asset build; the embed step is plain cmake -P
git clone --depth 1 --branch b10870 https://github.com/ggml-org/llama.cpp /tmp/lc
( cd /tmp/lc/tools/ui && npm ci && npm run build )
mkdir -p webui-generated /tmp/ui-gen
cmake -DUI_SOURCE_DIR=/tmp/lc/tools/ui -DUI_BINARY_DIR=/tmp/ui-gen \
-DLLAMA_SOURCE_DIR=/tmp/lc -DBUILD_UI=OFF -DHF_ENABLED=OFF -DLLAMA_UI_GZIP=ON \
-P /tmp/lc/scripts/ui-assets.cmake
cp /tmp/ui-gen/ui.cpp /tmp/ui-gen/ui.h webui-generated/
cmake -B build && cmake --build build --target jllama # now embeds the real UI
```
`webui-generated/` is git-ignored.
Expand Down Expand Up @@ -530,7 +542,7 @@ cache lives in **Depot Cache** over sccache's **WebDAV** backend:
- `SCCACHE_WEBDAV_TOKEN: ${{ secrets.DEPOT_TOKEN }}` — a Depot **organization** token, stored
as the repo secret **`DEPOT_TOKEN`**.

Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b10850`), the
Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b10870`), the
~280 upstream object files are byte-identical every run, so a warm cache recompiles only the
*changed* files. Depot's cache is **shared across all branches** (unlike GitHub's
per-branch `actions/cache`), so every branch builds incrementally; a `b<nnnn>` version bump
Expand Down Expand Up @@ -1453,7 +1465,7 @@ ctest --test-dir build --output-on-failure -R "ResultsToJson"

#### Upstream source location (in CMake build tree)

llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b10850`.
llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b10870`.

**GoogleTest** is a separate `BUILD_TESTING`-only FetchContent (`GIT_TAG v1.17.0`), used solely
by the `jllama_test` C++ unit-test binary — not by the shipped library, and not coupled to the
Expand Down
2 changes: 1 addition & 1 deletion 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 b10850](https://img.shields.io/badge/llama.cpp-%23b10850-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10850)
[![llama.cpp b10870](https://img.shields.io/badge/llama.cpp-%23b10870-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10870)
[![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
Loading
Loading