Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

[spring-ai] Streaming responses ending with CJK punctuation (。!?) are misclassified as partial and never persisted to the session

Offen Anfängerfreundlich
#1,608 3 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

Maintainer antworten meist innerhalb von 2 Tagen

@hirematha arbeitet bereits daran.

Seit 05.10.2026.

  • #1620 von @caps-xia — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
84/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
java, spring
Bereich
backend

Rechercherichtung

Beginne bei contrib/spring-ai/src/main/java/com/google/adk/models/springai/MessageConverter.java, Methode isPartialResponse, die nur ASCII . ! ? und Zeilenumbruch prüft. Die minimale Reproduktion des Issues ruft MessageConverter#toLlmResponse direkt mit einer ChatResponse auf, die auf 。 endet, also verwandle das in einen Unit-Test unter contrib/spring-ai/src/test und bestätige, dass derzeit partial=true zurückgegeben wird. Fertig bedeutet, dass eine Antwort, die auf 。!? endet, partial=false ergibt, und sowohl der neue Test als auch die vorhandenen Tests des Moduls bestehen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

needs review
Describe the Bug

In the Spring AI bridge (contrib/spring-ai), MessageConverter#isPartialResponse
decides whether a streaming chunk is partial by checking only ASCII sentence-ending
punctuation: ., !, ?, \n. CJK terminal punctuation (。, !, ?) is not
included.

As a result, when a model's final streaming response ends with a Chinese sentence
mark (which is the normal case for Chinese users), it is classified as partial=true
and therefore never persisted to the session — the reply silently disappears from
conversation history, breaking multi-turn context and session replay.

Steps to Reproduce
  1. Use the official com.google.adk.models.springai.SpringAI model bridge with any
    OpenAI-compatible model, streaming mode (RunConfig SSE).
  2. Send a question that produces a Chinese answer, e.g. 根因是库存扣减为 0 未拦截。
  3. Observe the final LlmResponse: partial is true, and the session event store
    never receives this response.

A minimal unit-level repro (calling the converter directly) is provided below.
No exception/stacktrace is produced — the failure is silent, which is what makes it
hard to notice in production.

Expected Behavior

A response ending with 。 (or ! / ?) is a complete final response in Chinese
and should be partial=false, persisted to the session like its ASCII-. counterpart.

Observed Behavior

Verified against google-adk-spring-ai:1.9.0 on our classpath:

[PROBE] chinese-ending partial = true    <-- bug: final reply treated as partial
[PROBE] ascii-ending   partial = false

Downstream effect: Runner-driven sessions lose the assistant's final answer for
CJK conversations; Session.events() replay shows the question without the reply.
Live streaming looks fine (partials are forwarded to the client), so the loss only
shows up in history, multi-turn follow-ups and session replay.

Environment Details
  • ADK Library Version: verified on 1.9.0, and confirmed still present in
    1.11.0 (latest release) and on current main
    (contrib/spring-ai/src/main/java/com/google/adk/models/springai/MessageConverter.java#isPartialResponse)
  • OS: macOS (behavior is OS-independent — pure string logic)
  • TS Version: N/A (Java)
Model Information

Model-independent. Observed with GLM via an OpenAI-compatible gateway; the
classification happens in MessageConverter before any model-specific handling.

Regression

N/A — the heuristic has been present since we started using the bridge (1.9.0),
and is unchanged through 1.11.0.

Additional Context

Suggested fix, from minimal to better:

  1. Add CJK terminal punctuation to the check: 。!? (plus …, )).
  2. Better: don't infer completeness from punctuation at all. Text legitimately ends
    without sentence-ending characters (lists, code blocks, tables). Partial-ness
    could be derived from chunk position / stream state instead of the last character.

This affects every CJK-language user of the official SpringAI bridge — and because
partials are still forwarded live, the missing persistence only surfaces later
(history / follow-up turns), which makes it easy to misdiagnose as a session-store
problem.

Minimal Reproduction Code
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.adk.models.springai.MessageConverter;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;

import java.util.List;

MessageConverter converter = new MessageConverter(new ObjectMapper());

ChatResponse chineseEnding = new ChatResponse(List.of(new Generation(
        AssistantMessage.builder().content("根因是库存扣减为 0 未拦截。").build())));
ChatResponse asciiEnding = new ChatResponse(List.of(new Generation(
        AssistantMessage.builder().content("Root cause: zero-stock deduction is not blocked.").build())));

boolean chinesePartial = converter.toLlmResponse(chineseEnding, true).partial().orElse(false); // true  (bug)
boolean asciiPartial   = converter.toLlmResponse(asciiEnding, true).partial().orElse(false);   // false
How often has this issue occurred?

Always (100%) — every Chinese final response ending with 。, which is essentially
every conversation.

Vorherrschende Sprache
Java
Sterne
1.8k
Forks
446
Ø Merge
4 T. 20 Std.
Gemergte PRs (30 T.)
59

Entwicklungsumgebung

In Codespaces öffnen

Startet den Dev-Container des Projekts im Browser, mit Ihrem eigenen GitHub-Konto.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus google/adk-java

Alle Issues in google/adk-java

Ähnliche Issues

Weitere Issues zu Java

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.