From efee33539e4c521aa39b61811337504828055f5b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 09:12:50 +0000 Subject: [PATCH 1/3] build(deps): Maven dependencies and plugins to latest stable Cross-repo sweep of 2026-09-27, applied to all four Java repos together so the tool-version matrix in workspace/crossrepostatus.md stays identical. llama: jackson 2.22.3, slf4j 2.0.20, logback 1.6.4 (test), archunit 1.5.1, NullAway 0.14.2, spotless 3.10.3, palantir-java-format 2.99.0 llama-langchain4j: langchain4j-core 1.20.1 llama-atmosphere-agent: atmosphere-ai 4.0.71, jline 4.4.6, slf4j 2.0.20, spotless 3.10.3, palantir 2.99.0, and exec-maven-plugin 3.5.0 -> 3.6.4 (the 2026-09-20 sweep missed this standalone pom) palantir 2.99.0 lays out an assigned switch expression differently; spotless:apply rewrote LoopOptions.java, formatting only. Verified: reactor install; llama verify (1772 tests, spotbugs:check); llama-langchain4j verify (49); llama-kotlin verify (6); llama-atmosphere-agent verify against the installed 5.2.0-SNAPSHOT (159) and spotless:check. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QSXAwbXqx9u5xsMArMvgT8 --- llama-atmosphere-agent/pom.xml | 12 ++++++------ .../ladenthin/llama/atmosphere/LoopOptions.java | 13 ++++++------- llama-langchain4j/pom.xml | 2 +- llama/pom.xml | 14 +++++++------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/llama-atmosphere-agent/pom.xml b/llama-atmosphere-agent/pom.xml index fa2fc4d04..ed489f759 100644 --- a/llama-atmosphere-agent/pom.xml +++ b/llama-atmosphere-agent/pom.xml @@ -47,17 +47,17 @@ SPDX-License-Identifier: MIT - 4.0.70 - 4.4.5 - 2.0.19 + 4.0.71 + 4.4.6 + 2.0.20 1.0.1 6.1.3 3.0 3.16.0 3.6.0 - 3.5.0 - 3.10.2 - 2.98.0 + 3.6.4 + 3.10.3 + 2.99.0 net.ladenthin.llama.atmosphere.LocalAgent diff --git a/llama-atmosphere-agent/src/main/java/net/ladenthin/llama/atmosphere/LoopOptions.java b/llama-atmosphere-agent/src/main/java/net/ladenthin/llama/atmosphere/LoopOptions.java index e9210ad09..136429799 100644 --- a/llama-atmosphere-agent/src/main/java/net/ladenthin/llama/atmosphere/LoopOptions.java +++ b/llama-atmosphere-agent/src/main/java/net/ladenthin/llama/atmosphere/LoopOptions.java @@ -88,13 +88,12 @@ static Duration parseDuration(String text) { } catch (NumberFormatException e) { throw new IllegalArgumentException("Not a duration: " + text + " (try 30s, 5m or 2h)", e); } - Duration duration = - switch (Character.isDigit(unit) ? 'm' : unit) { - case 's' -> Duration.ofSeconds(amount); - case 'm' -> Duration.ofMinutes(amount); - case 'h' -> Duration.ofHours(amount); - default -> throw new IllegalArgumentException("Unknown time unit in " + text + " (use s, m or h)"); - }; + Duration duration = switch (Character.isDigit(unit) ? 'm' : unit) { + case 's' -> Duration.ofSeconds(amount); + case 'm' -> Duration.ofMinutes(amount); + case 'h' -> Duration.ofHours(amount); + default -> throw new IllegalArgumentException("Unknown time unit in " + text + " (use s, m or h)"); + }; if (duration.isZero() || duration.isNegative()) { throw new IllegalArgumentException("The interval must be positive: " + text); } diff --git a/llama-langchain4j/pom.xml b/llama-langchain4j/pom.xml index 34d5582af..0a5185f66 100644 --- a/llama-langchain4j/pom.xml +++ b/llama-langchain4j/pom.xml @@ -57,7 +57,7 @@ SPDX-License-Identifier: MIT UTF-8 17 - 1.20.0 + 1.20.1 6.1.3 3.0 4.2.3 - 2.22.2 + 2.22.3 3.8.7 - 2.0.19 - 1.6.3 + 2.0.20 + 1.6.4 1.28 6.1.3 3.0 @@ -96,12 +96,12 @@ SPDX-License-Identifier: MIT contributor PR that bumps this MUST be rejected. See CLAUDE.md section "jqwik prompt-injection in test output" for full context. --> 1.9.3 - 1.5.0 + 1.5.1 4.10.4.1 7.7.4 1.14.0 - 3.10.2 - 2.98.0 + 3.10.3 + 2.99.0 UTF-8 2026-09-01T07:57:45Z From 3a8e5ab58f108bb7a6ef7d7c0de53fa10ab8f859 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 09:12:50 +0000 Subject: [PATCH 2/3] build(android): Gradle 9.8.0, Compose BOM 2026.09.00, appcompat 1.8.0, Compose compiler plugin 2.4.20 - gradle-version 9.7.1 -> 9.8.0 in all seven setup-gradle steps. AGP 9.4.0 needs >= 9.6.0, so nothing else has to move; the four stale "AGP 9.3.0 requires Gradle >= 9.5.0" comments now name the real floor. - android-llmservice: Compose BOM 2026.06.01 -> 2026.09.00, appcompat 1.7.1 -> 1.8.0 (minSdk 23, the app is on 28), Compose compiler plugin 2.4.10 -> 2.4.20 (now the same Kotlin as llama-kotlin). - CLAUDE.md, android-llmservice/README.md and the Atmosphere version note follow. Not buildable here: dl.google.com (AGP, androidx) is blocked in this sandbox, so the Android side is validated by CI's build-android-llmservice and android-consumer-test jobs, not locally. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QSXAwbXqx9u5xsMArMvgT8 --- .github/workflows/publish.yml | 22 +++++++++++----------- CLAUDE.md | 8 ++++---- android-llmservice/README.md | 2 +- android-llmservice/app/build.gradle.kts | 4 ++-- android-llmservice/settings.gradle.kts | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1b7ebafbb..26b620fb4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -245,7 +245,7 @@ jobs: distribution: temurin - uses: gradle/actions/setup-gradle@v6 with: - gradle-version: "9.7.1" + gradle-version: "9.8.0" - name: Sign a throwaway artifact via useInMemoryPgpKeys (BouncyCastle) shell: bash env: @@ -1128,8 +1128,8 @@ jobs: distribution: temurin - uses: gradle/actions/setup-gradle@v6 with: - # AGP 9.3.0 (the .github/android-consumer-test fixture) requires Gradle >= 9.5.0. - gradle-version: "9.7.1" + # AGP 9.4.0 (the .github/android-consumer-test fixture) requires Gradle >= 9.6.0. + gradle-version: "9.8.0" - name: Build core jar (byte-identical classes payload for the AAR) run: > mvn -B --no-transfer-progress -pl llama -am -DskipTests -Denforcer.skip=true @@ -1259,8 +1259,8 @@ jobs: distribution: temurin - uses: gradle/actions/setup-gradle@v6 with: - # AGP 9.3.0 (the .github/android-consumer-test fixture) requires Gradle >= 9.5.0. - gradle-version: "9.7.1" + # AGP 9.4.0 (the .github/android-consumer-test fixture) requires Gradle >= 9.6.0. + gradle-version: "9.8.0" - name: Enable KVM group permissions (GitHub-hosted runner) run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules @@ -1353,10 +1353,10 @@ jobs: distribution: temurin - uses: gradle/actions/setup-gradle@v6 with: - # AGP 9.3.0 (android-llmservice) requires Gradle >= 9.5.0; also satisfies Kotlin + # AGP 9.4.0 (android-llmservice) requires Gradle >= 9.6.0; also satisfies Kotlin # 2.4's Gradle-plugin floor. The AAR/lib-only jobs stay on an older Gradle since # they build no AGP project. - gradle-version: "9.7.1" + gradle-version: "9.8.0" - name: Build core jar + install llama-kotlin facade to mavenLocal # install (not package) so the app's Gradle build resolves llama-kotlin + # the core POM from mavenLocal. llama-kotlin's core dep is provided-scope, so the @@ -1439,8 +1439,8 @@ jobs: distribution: temurin - uses: gradle/actions/setup-gradle@v6 with: - # AGP 9.3.0 (android-llmservice) requires Gradle >= 9.5.0. - gradle-version: "9.7.1" + # AGP 9.4.0 (android-llmservice) requires Gradle >= 9.6.0. + gradle-version: "9.8.0" - name: Enable KVM group permissions (GitHub-hosted runner) run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules @@ -3823,7 +3823,7 @@ jobs: # downloads above; the core jar was just built by the reactor deploy. - uses: gradle/actions/setup-gradle@v6 with: - gradle-version: "9.7.1" + gradle-version: "9.8.0" - name: Publish Android AAR snapshots (llama-android + llama-android-opencl) run: | mkdir -p llama-android/natives/cpu/arm64-v8a llama-android/natives/cpu/x86_64 llama-android/natives/opencl/arm64-v8a @@ -4081,7 +4081,7 @@ jobs: # built by the reactor deploy. - uses: gradle/actions/setup-gradle@v6 with: - gradle-version: "9.7.1" + gradle-version: "9.8.0" - name: Publish Android AAR release bundle to Central Portal shell: bash run: | diff --git a/CLAUDE.md b/CLAUDE.md index 4afed0117..b655cf90c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2178,7 +2178,7 @@ installed (`-Dllama.version=`); a user copies the folder and ru **released** core the READMEs describe (currently `5.2.0`, written as if released so the docs are right the moment the release lands). -**What Atmosphere is, for this purpose.** `org.atmosphere:atmosphere-ai` (4.0.70) ships +**What Atmosphere is, for this purpose.** `org.atmosphere:atmosphere-ai` (4.0.71) ships `BuiltInAgentRuntime` + `OpenAiCompatibleClient`: a zero-framework OpenAI client that *always* streams (`stream:true`), accumulates `delta.tool_calls` by `index`, executes `ToolDefinition` executors, re-submits the conversation (assistant `tool_calls` message **without** a `content` key, @@ -2581,7 +2581,7 @@ domain is the only string that must be globally unique. Structure (mirrors the consumer-test's plumbing): - **`settings.gradle.kts`** — `rootProject.name = "android-llmservice"`; pins AGP `9.4.0` + the - Compose compiler plugin (`2.4.10`); `mavenLocal()` first so the freshly-built AAR + façade + Compose compiler plugin (`2.4.20`); `mavenLocal()` first so the freshly-built AAR + façade resolve there in CI (Maven Central for real users). Stay at `>= 9.2.1`: `9.2.1` (not `9.2.0`) first fixed a real R8 regression (`ClassNotFoundException` on `com.android.tools.r8.RecordTag` after upgrading Gradle to 9.x with AGP 9.2.0) that hits this project directly since @@ -2589,11 +2589,11 @@ Structure (mirrors the consumer-test's plumbing): `.github/android-consumer-test` fixture is pinned the same way. AGP 9.4.x requires Gradle >= 9.6.0 and JDK 17+; CI already runs JDK 21 everywhere (`env.JAVA_VERSION`), so only the `gradle-version` pin on the jobs that build this project (and the `.github/android-consumer-test` fixture) - needed bumping (currently `9.7.1`). AGP 9.0+ has **built-in Kotlin support** (a runtime dependency on + needed bumping (currently `9.8.0`). AGP 9.0+ has **built-in Kotlin support** (a runtime dependency on Kotlin Gradle plugin 2.2.10+), so the standalone `org.jetbrains.kotlin.android` plugin is no longer applied — applying it now fails the build with "no longer required for Kotlin support since AGP 9.0" (`app/build.gradle.kts` line 7). The Compose compiler plugin still applies - separately and its 2.4.10 pin exceeds AGP's 2.2.10 floor, so no other version changed. + separately and its 2.4.20 pin exceeds AGP's 2.2.10 floor, so no other version changed. - **`app/build.gradle.kts`** — `namespace`/`applicationId` `net.ladenthin.android.llmservice`, `minSdk 28` (AAR floor), `compileSdk 37` (raised from 35 — Compose/lifecycle/activity AAR metadata now requires it), `targetSdk 35`, Jetpack Compose, `androidx.appcompat` (only for diff --git a/android-llmservice/README.md b/android-llmservice/README.md index 8c4d67939..65d8e0a8f 100644 --- a/android-llmservice/README.md +++ b/android-llmservice/README.md @@ -199,7 +199,7 @@ gradle -p android-llmservice connectedDebugAndroidTest -PjllamaVersion="$VERSION ``` android-llmservice/ -├── settings.gradle.kts # AGP 9.4.0 (built-in Kotlin) + Compose plugin 2.4.10, mavenLocal first +├── settings.gradle.kts # AGP 9.4.0 (built-in Kotlin) + Compose plugin 2.4.20, mavenLocal first ├── gradle.properties ├── requirements.md # spec of record: every feature the app implements today (no unit tests) ├── TODO.md # roadmap: not-yet-built features diff --git a/android-llmservice/app/build.gradle.kts b/android-llmservice/app/build.gradle.kts index 1d67ae913..83eefa5b6 100644 --- a/android-llmservice/app/build.gradle.kts +++ b/android-llmservice/app/build.gradle.kts @@ -120,10 +120,10 @@ dependencies { // AppCompat: only for its per-app language API (AppCompatDelegate.setApplicationLocales), // which powers the in-app flag language picker and persists the choice across restarts. - implementation("androidx.appcompat:appcompat:1.7.1") + implementation("androidx.appcompat:appcompat:1.8.0") // Jetpack Compose UI (BOM pins the mutually consistent runtime versions). - val composeBom = platform("androidx.compose:compose-bom:2026.06.01") + val composeBom = platform("androidx.compose:compose-bom:2026.09.00") implementation(composeBom) implementation("androidx.activity:activity-compose:1.13.0") implementation("androidx.compose.material3:material3") diff --git a/android-llmservice/settings.gradle.kts b/android-llmservice/settings.gradle.kts index bab2f43ba..841b400a8 100644 --- a/android-llmservice/settings.gradle.kts +++ b/android-llmservice/settings.gradle.kts @@ -23,11 +23,11 @@ pluginManagement { // AGP 9.0+ has built-in Kotlin support (runtime dependency on Kotlin Gradle plugin // 2.2.10+), so the standalone org.jetbrains.kotlin.android plugin is no longer // applied/needed — see https://developer.android.com/build/migrate-to-built-in-kotlin. - // The Compose compiler plugin (2.4.10) still applies separately and exceeds AGP's + // The Compose compiler plugin (2.4.20) still applies separately and exceeds AGP's // 2.2.10 floor. plugins { id("com.android.application") version "9.4.0" - id("org.jetbrains.kotlin.plugin.compose") version "2.4.10" + id("org.jetbrains.kotlin.plugin.compose") version "2.4.20" } } From 865b741018a7b3ca44982236b2212bba14220521 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 09:12:50 +0000 Subject: [PATCH 3/3] test: LlamaLoggerTest skips cleanly without libjllama JUnit runs @AfterEach even when the test body was aborted by an assumption, so restoreConsoleLogging() called LlamaModel.setLogger on every skipped test. Without the native library that fails in LlamaModel's static initializer (UnsatisfiedLinkError, then NoClassDefFoundError), which is what has kept the SonarQube workflow red on main and on every PR: 6 errors, all LlamaLoggerTest.restoreConsoleLogging:85. The teardown now uses the same nativeLibraryOnClasspath() guard as the tests. Verified: mvn -f llama/pom.xml verify without a native library -- 1772 tests, 0 failures, 0 errors (was 6 errors). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QSXAwbXqx9u5xsMArMvgT8 --- .../test/java/net/ladenthin/llama/LlamaLoggerTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llama/src/test/java/net/ladenthin/llama/LlamaLoggerTest.java b/llama/src/test/java/net/ladenthin/llama/LlamaLoggerTest.java index fa2374f29..ffcb80624 100644 --- a/llama/src/test/java/net/ladenthin/llama/LlamaLoggerTest.java +++ b/llama/src/test/java/net/ladenthin/llama/LlamaLoggerTest.java @@ -80,8 +80,16 @@ public String toString() { } } + /** + * Runs after the skipped tests too: JUnit calls {@code @AfterEach} even when the test body was + * aborted by an assumption. Without the guard, a build without {@code libjllama} (the SonarQube + * job) fails here on {@code LlamaModel}'s static initializer instead of skipping. + */ @AfterEach void restoreConsoleLogging() { + if (!nativeLibraryOnClasspath()) { + return; + } LlamaModel.setLogger(LogFormat.TEXT, null); }