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

Labels

No labels
No labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions