From 2dbb63504d1b86d362de6c7f06e5d78d07c57ebf Mon Sep 17 00:00:00 2001 From: Marcello Muscara Date: Mon, 26 Oct 2026 18:00:41 +0100 Subject: [PATCH] chore(deps): hold Spring AI at 2.0.1 and give it its own Renovate PR Spring AI 2.0.2 upgrades openai-java from 4.49.0 to 4.80.0. Since openai-java 4.66.0 (openai/openai-java#1027) StreamResponse.close() closes the transport before the reader. Cancelling a stream from another thread, which a stop or the turn deadline does, then closes the OkHttp body under an in-flight read: Okio throws "Unbalanced enter/exit", the connection is never released or closed, and the model call runs to its end. Bisected with Spring AI 2.0.2 held fixed: openai-java 4.65.0 passes, 4.66.1 fails the same four chat tests, and 4.92.0 still fails. Note the reason next to springAi, and move Spring AI out of the backend group so a held version no longer turns that group red. --- gradle/libs.versions.toml | 5 +++++ renovate.json | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cef8c93..02da8a1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,11 @@ flexmark = "0.64.8" # OpenAI-compatible endpoint including Ollama, because `base_url` decides who answers, and a # third model module would buy nothing. Pinned rather than tracked for the same reason jsoup # and freemarker are — a judge that suddenly answers differently should show up as a diff. +# Held at 2.0.1: 2.0.2 brings openai-java 4.80.0, and since openai-java 4.66.0 (openai/openai-java#1027) +# closing a stream from another thread closes the OkHttp body under the in-flight read, which throws +# "Unbalanced enter/exit" and leaves the connection open, so stopping a chat turn no longer ends the +# model call. Retry once a Spring AI release ships an openai-java with that fixed (4.92.0 is not): +# ChatStreamTest, ChatConversationTest and ChatTurnDeadlineTest turn green again. springAi = "2.0.1" # The GraalVM build tools. Applied for BOTH images and not only the native one: applying # it is what makes the Boot plugin register `processAot`, and Spring AOT is half of the JVM diff --git a/renovate.json b/renovate.json index 76abc6b..b43abc0 100644 --- a/renovate.json +++ b/renovate.json @@ -35,6 +35,12 @@ "matchPackageNames": ["/^org\\.springframework\\.boot/", "/^io\\.spring\\.dependency-management/"], "groupName": "spring boot" }, + { + "description": "Spring AI gets its own pull request. It is held back in libs.versions.toml, and inside the backend group a held version turns the whole group red; on its own, its CI result says whether the next release fixed it.", + "matchPackageNames": ["/^org\\.springframework\\.ai/"], + "groupName": null, + "automerge": false + }, { "description": "native-build-tools carries the GraalVM reachability-metadata repository version with it, so a bump changes which third-party metadata the native image is compiled against. Its own pull request, read before merging.", "matchPackageNames": ["/^org\\.graalvm\\.buildtools/"],