Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Ouverte Adaptée aux débutants
#1,608 1 commentaire 0 réactions 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@caps-xia y travaille déjà.

Depuis le 6/10/2026.

  • #1620 par @caps-xia — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
84/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
java, spring
Domaine
backend

Piste de recherche

Commencez à contrib/spring-ai/src/main/java/com/google/adk/models/springai/MessageConverter.java, méthode isPartialResponse, qui ne vérifie que les caractères ASCII . ! ? et le saut de ligne. La reproduction minimale de l'issue appelle directement MessageConverter#toLlmResponse avec une ChatResponse se terminant par 。, donc transformez cela en un test unitaire sous contrib/spring-ai/src/test et confirmez qu'il renvoie actuellement partial=true. Terminé signifie qu'une réponse se terminant par 。!? donne partial=false, et que le nouveau test ainsi que les tests existants du module passent.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
Java
Étoiles
1.7k
Forks
431
Merge moyen
2 j 20 h
PR mergées (30 j)
42

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de google/adk-java

Toutes les issues de google/adk-java

Issues similaires

Plus d'issues Java

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.