Skip to content

Spring AI OpenAI 2.0.0 final throws ClassCastException for generic ToolCallingChatOptions #1295

Description

@akbarkanso

Describe the Bug

Spring AI OpenAI 2.0.0 final fails when a Prompt contains provider-neutral ToolCallingChatOptions.

This is exposed by google-adk-spring-ai, which creates generic Spring AI ChatOptions / ToolCallingChatOptions when converting ADK requests into Spring AI prompts. In Spring AI OpenAI 2.0.0 final, OpenAiChatModel.createRequest(...) casts Prompt.getOptions() directly to OpenAiChatOptions, causing a ClassCastException.

This behavior does not appear to occur with Spring AI OpenAI 2.0.0-M4. Based on local testing, 2.0.0-M4 appears to normalize generic prompt options into OpenAiChatOptions before request creation, while 2.0.0 final only injects default options when prompt options are null, allowing non-null generic options to reach the later cast.

Steps to Reproduce

  1. Create a Java project using:

    • com.google.adk:google-adk:1.4.0
    • com.google.adk:google-adk-spring-ai:1.4.0
    • Spring AI BOM 2.0.0
    • Spring AI OpenAI 2.0.0
  2. Configure an OpenAI-backed Spring AI ChatModel.

  3. Create an ADK LlmAgent using SpringAI(chatModel, modelName).

  4. Register at least one tool with the agent.

  5. Invoke the agent so a tool-enabled request is sent to the model.

  6. Observe the runtime exception below.

Expected Behavior

One of the following should occur:

  • Spring AI OpenAI continues accepting or normalizing generic Spring AI ToolCallingChatOptions, as appears to have happened in 2.0.0-M4, or
  • ADK integrations can safely pass provider-neutral Spring AI options without causing runtime failures, or
  • The Spring AI OpenAI contract clearly documents that only OpenAiChatOptions are supported in Prompt.getOptions().

Observed Behavior

The request fails with:

java.lang.ClassCastException: class org.springframework.ai.model.tool.DefaultToolCallingChatOptions
cannot be cast to class org.springframework.ai.openai.OpenAiChatOptions

Stack trace:

at org.springframework.ai.openai.OpenAiChatModel.createRequest(OpenAiChatModel.java:683)
at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:194)
at com.google.adk.models.springai.SpringAI.generateContent(SpringAI.java:176)

Environment Details

  • ADK Library Version (see maven dependency): 1.4.0
  • OS: macOS and Linux
  • TS Version (tsc --version): N/A (Java project)

Model Information

  • Which model is being used: OpenAI-compatible model via Spring AI OpenAI (for example gpt-4o)

🟡 Optional Information

Regression

Yes.

Local validation results:

  • ADK 1.4.0 + Spring AI 2.0.0: fails with DefaultToolCallingChatOptions -> OpenAiChatOptions cast.
  • ADK 1.4.0 + Spring AI 2.0.0-M4: no cast failure; request proceeds to model authentication.

Logs

java.lang.ClassCastException: class org.springframework.ai.model.tool.DefaultToolCallingChatOptions
cannot be cast to class org.springframework.ai.openai.OpenAiChatOptions

at org.springframework.ai.openai.OpenAiChatModel.createRequest(OpenAiChatModel.java:683)
at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:194)
at com.google.adk.models.springai.SpringAI.generateContent(SpringAI.java:176)

Screenshots / Video

N/A

Additional Context

When tools are present, ADK appears to construct generic Spring AI options using:

ToolCallingChatOptions.builder()

Spring AI OpenAI 2.0.0-M4 appears to normalize these options into OpenAiChatOptions before request creation.

Spring AI OpenAI 2.0.0 final appears to only replace options when they are null, then later casts non-null generic options in createRequest(...), resulting in the ClassCastException.

Because ADK emits provider-neutral Spring AI options, this causes tool-enabled ADK agents backed by Spring AI OpenAI 2.0.0 to fail consistently at runtime.

Minimal Reproduction Code

ChatModel chatModel = ...; // OpenAI-backed Spring AI ChatModel

BaseAgent agent =
    LlmAgent.builder()
        .name("test-agent")
        .model(new SpringAI(chatModel, "gpt-4o"))
        .tools(myTool)
        .build();

// Invoke the agent so ADK converts a tool-enabled request into a Spring AI Prompt.

How often has this issue occurred?

  • Always (100%)

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions