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" } } 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 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); }