[spring-ai] ToolConverter silently drops enum and items from tool parameter schemas
Mantenedores costumam responder em até 2 dias
Avaliação
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Facilidade para iniciantes
- 76/100
Direção de pesquisa
A perda acontece em ToolConverter#convertSchemaToSpringAi, alcançado a partir de convertToSpringAiTools quando cada input schema de ToolDefinition é construído; comece lendo esse método e os tipos genai Schema e Spring AI schema entre os quais ele mapeia. Reproduza com o exemplo mínimo da issue (uma propriedade string enum mais uma propriedade array com items), depois mapeie enum_ e items por propriedade, recursando em propriedades aninhadas. Concluído significa que o inputSchema JSON emitido contém enum e items para esses parâmetros enquanto os testes existentes do ToolConverter continuam passando.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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.
- Linguagem predominante
- Java
- Estrelas
- 1.8k
- Forks
- 446
- Merge médio
- 4d 17h
- PRs com merge (30d)
- 62
Preparar o ambiente
Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de google/adk-java
-
GeminiUtil placeholder user turn ("Continue output. DO NOT look at this line ...") is flagged by prompt injection filtersTalvez já em andamento @hemasekhar-p assumiu há 12 dias. Abertaneeds review
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
google/adk-java#1628 · 1 comentário · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
[spring-ai] Streaming responses ending with CJK punctuation (。!?) are misclassified as partial and never persisted to the sessionTalvez já em andamento @hirematha assumiu há 15 dias. Abertaneeds review
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
google/adk-java#1608 · 3 comentários · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
runLive passes partial events to appendEvent and never aggregates text chunks, unlike ADK PythonTalvez já em andamento @hemasekhar-p assumiu há 8 dias. Abertaneeds review
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 45/100
google/adk-java#1648 · 3 comentários · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
FirestoreSessionService compares event timestamps as text, reordering or skipping same-second eventsTalvez já em andamento @hemasekhar-p assumiu há 8 dias. Abertaneeds review
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 50/100
google/adk-java#1646 · 3 comentários · 1 responsável ·
Mantenedores costumam responder em até 2 dias
-
FirestoreSessionService ignores `app:` / `user:` state prefixes, so app and user state are never shared across sessionsTalvez já em andamento @hemasekhar-p assumiu há 8 dias. Abertawaiting on reporter
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 45/100
google/adk-java#1645 · 4 comentários · 1 responsável ·
Mantenedores costumam responder em até 2 dias
Todas as issues de google/adk-java
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
QuiltMC/update-quilt-meta#28 ·
-
awaiting triage Documentation P3
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 86/100
Mantenedores costumam responder em até 1 dia
-
area/build area/maintainability component/camunda-process-test kind/tech-debt
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia
-
Kafka: Filter empty strings and whitespace in IcebergSinkConfig stringToListTalvez já em andamento @mohamed-elbrik assumiu hoje. Abertabug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
Mantenedores costumam responder em até 1 dia
-
area/kotlin
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
Mantenedores costumam responder em até 1 dia