[spring-ai] ToolConverter silently drops enum and items from tool parameter schemas
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 76/100
Rechercherichtung
Der Verlust tritt in ToolConverter#convertSchemaToSpringAi auf, das von convertToSpringAiTools erreicht wird, wenn jedes ToolDefinition input schema erstellt wird; beginne damit, diese Methode und die genai Schema- und Spring AI schema-Typen zu lesen, zwischen denen sie abbildet. Reproduziere mit dem minimalen Beispiel aus dem Issue (eine enum-String-Eigenschaft plus eine Array-Eigenschaft mit items), dann mappe enum_ und items pro Eigenschaft und rekursiere in verschachtelte Eigenschaften. Fertig bedeutet, dass das ausgegebene inputSchema JSON enum und items für diese Parameter enthält, während die bestehenden ToolConverter-Tests weiterhin bestehen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the Bug
ToolConverter#convertSchemaToSpringAi (used by convertToSpringAiTools) maps only
type, properties, description and required when converting a genai Schema
to a Spring AI ToolDefinition input schema. enum and items are silently
dropped.
Impact: any ADK tool whose parameters use enum-constrained strings or typed arrays —
including the mainstream path of annotated FunctionTool methods (enum Java fields,
List<String> parameters) — ends up with a degraded schema sent to the model:
enum parameters become free-form strings (models then send invalid values), and array
parameters lose their element type.
Steps to Reproduce
- Define a
BaseToolwhosedeclaration()returns aFunctionDeclarationwith
parameterscontaining an enum property and an array-with-items property. - Convert it via
new ToolConverter().convertToSpringAiTools(...). - Inspect
getToolDefinition().inputSchema()— noenum, noitems.
Expected Behavior
enum, items (and ideally format, nullable, minItems/maxItems) survive the
conversion, so the model receives the same parameter constraints the ADK tool declared.
Observed Behavior
Identical output on 1.9.0 and 1.11.0 (latest):
declared: color = string + enum ["red","green"], tags = array of string (items)
converted inputSchema:
{"description":"参数","type":"object","properties":{"color":{"description":"颜色","type":"string"},"tags":{"description":"标签","type":"array"}},"required":["color"]}
^ no "enum" ^ no "items"
Environment Details
- ADK Library Version: verified on 1.9.0 and 1.11.0 with identical output;
on currentmain,convertSchemaToSpringAistill only emitstype/properties - OS: macOS (logic bug, OS-independent)
- TS Version: N/A (Java)
Model Information
Model-independent — the loss happens in tool-definition conversion before any model
call. Observed with GLM via an OpenAI-compatible gateway.
Regression
N/A.
Additional Context
We maintain a patched bridge for this reason (among others): we bypass the wrapped
conversion and restore the original callbacks per tool name so the raw schema reaches
the model. A minimal fix is to map enum_ and items in convertSchemaToSpringAi;
serializing the genai Schema to JSON directly would also work and would future-proof
against further field drift.
Minimal Reproduction Code
Schema color = Schema.builder().type("string")
.description("颜色").enum_(List.of("red", "green")).build();
Schema tags = Schema.builder().type("array")
.description("标签").items(Schema.builder().type("string").build()).build();
Schema params = Schema.builder().type("object")
.properties(Map.of("color", color, "tags", tags))
.required(List.of("color"))
.build();
BaseTool tool = new BaseTool("probeTool", "probe") {
@Override public Optional<FunctionDeclaration> declaration() {
return Optional.of(FunctionDeclaration.builder()
.name("probeTool").description("probe").parameters(params).build());
}
@Override public Single<Map<String, Object>> runAsync(Map<String, Object> args, ToolContext ctx) {
return Single.just(Map.of());
}
};
String schema = new ToolConverter()
.convertToSpringAiTools(Map.of("probeTool", tool))
.get(0).getToolDefinition().inputSchema();
// schema contains no "enum" and no "items"
How often has this issue occurred?
Always (100%) — every enum/array tool parameter.
- Vorherrschende Sprache
- Java
- Sterne
- 1.7k
- Forks
- 431
- Ø Merge
- 3 T. 2 Std.
- Gemergte PRs (30 T.)
- 46
Entwicklungsumgebung
Startet den Dev-Container des Projekts im Browser, mit Ihrem eigenen GitHub-Konto.
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus google/adk-java
-
GeminiUtil placeholder user turn ("Continue output. DO NOT look at this line ...") is flagged by prompt injection filtersEvtl. vergeben @innoprej hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 1 Tag
-
[spring-ai] Streaming responses ending with CJK punctuation (。!?) are misclassified as partial and never persisted to the sessionEvtl. vergeben @hirematha hat das vor 3 Tagen übernommen. Offenwaiting on reporter
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
google/adk-java#1608 · 2 Kommentare · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
[core] Client disconnects don't cancel the model stream (per-step flow is cached) — and there is no public API to cancel an in-flight runEvtl. vergeben @hemasekhar-p hat das vor 2 Tagen übernommen. Offenneeds review
google/adk-java#1618 · 6 Kommentare · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
[spring-ai] Bridge drops reasoning_content (thinking) — surface it as partial events and/or persist itEvtl. vergeben @hemasekhar-p hat das vor 3 Tagen übernommen. Offenneeds review
google/adk-java#1616 · 1 Kommentar · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
[FEATURE] Port bypass_multi_tools_limit for built-in search tools from adk-pythonEvtl. vergeben @hirematha hat das vor 3 Tagen übernommen. Offenneeds review
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
google/adk-java#1598 · 1 Kommentar · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in google/adk-java
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 64/100
-
C21 publishes `reactivemongo/core/SSL` as Java 23 bytecode — TLS connections fail on any JDK < 23Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
ReactiveMongo/ReactiveMongo#1520 ·
Maintainer antworten meist innerhalb von 1 Tag
-
enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
liquid-java/liquidjava#373 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
ga4gh/phenopacket-schema#465 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
NationalSecurityAgency/ghidra#9748 ·
Maintainer antworten meist innerhalb von 1 Tag