Skip to content

fix(model): delegate supportsNativeStructuredOutput to formatter#1832

Closed
chickenlj wants to merge 1 commit into
mainfrom
fix/1742-structured-output-fallback
Closed

fix(model): delegate supportsNativeStructuredOutput to formatter#1832
chickenlj wants to merge 1 commit into
mainfrom
fix/1742-structured-output-fallback

Conversation

@chickenlj

Copy link
Copy Markdown
Collaborator

Summary

  • OpenAIChatModel.supportsNativeStructuredOutput() hardcoded true, but many OpenAI-compatible backends (DeepSeek, vLLM, Ollama, GLM) don't support response_format with json_schema. This caused agent.call(msg, OutputClass.class) to fail with HTTP 400 on these backends.
  • Added supportsNativeStructuredOutput() to OpenAIChatFormatter (default true) and overrode to false in DeepSeekFormatter, DeepSeekMultiAgentFormatter, GLMFormatter, and GLMMultiAgentFormatter.
  • OpenAIChatModel now delegates to the formatter, so the agent automatically falls back to the generate_response tool approach for unsupported backends.

Fixes #1742
Fixes #1720

OpenAIChatModel.supportsNativeStructuredOutput() hardcoded true, but
many OpenAI-compatible backends (DeepSeek, vLLM, Ollama, GLM) do not
support response_format with json_schema. This caused structured output
calls (agent.call(msg, OutputClass.class)) to fail with HTTP 400.

Add supportsNativeStructuredOutput() to OpenAIChatFormatter (default
true) and override to false in DeepSeekFormatter, GLMFormatter, and
their multi-agent variants. OpenAIChatModel now delegates to the
formatter, so the agent automatically falls back to the generate_response
tool approach for unsupported backends.

Fixes #1742
Fixes #1720
@chickenlj chickenlj requested review from a team and Copilot June 18, 2026 07:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review

This PR fixes a bug where OpenAIChatModel.supportsNativeStructuredOutput() was hardcoded to true, causing HTTP 400 errors on OpenAI-compatible backends (DeepSeek, GLM) that don't support response_format with json_schema. The fix introduces supportsNativeStructuredOutput() to OpenAIChatFormatter (defaulting to true) and overrides it to false in DeepSeek/GLM formatters. OpenAIChatModel now delegates to the formatter via instanceof check. This correctly resolves issues #1742 and #1720. The approach is sound — pushing the capability query to the formatter layer where provider-specific knowledge belongs. Suggestion: consider adding supportsNativeStructuredOutput() to the Formatter interface as a default method to eliminate the instanceof dependency. Unit tests for the new method are recommended.

*
* @return true if native structured output is supported, false otherwise
*/
public boolean supportsNativeStructuredOutput() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[recommended] Architecture improvement: supportsNativeStructuredOutput() is defined on OpenAIChatFormatter concrete class rather than the Formatter interface, requiring OpenAIChatModel to use instanceof check. Consider adding default boolean supportsNativeStructuredOutput() { return false; } to the Formatter interface, eliminating the instanceof dependency and making it easier for custom formatters to declare their capabilities.

@@ -193,7 +193,10 @@ public String getModelName() {

@Override
public boolean supportsNativeStructuredOutput() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[recommended] Missing unit tests: No tests were added for the new supportsNativeStructuredOutput() delegation. Recommended coverage: (1) OpenAIChatFormatter default returns true; (2) DeepSeekFormatter / GLMFormatter return false; (3) OpenAIChatModel correctly delegates to the formatter; (4) Non-OpenAIChatFormatter formatters return false.

@AgentScopeJavaBot AgentScopeJavaBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review

This PR fixes a bug where OpenAIChatModel.supportsNativeStructuredOutput() was hardcoded to true, causing HTTP 400 errors on OpenAI-compatible backends (DeepSeek, GLM) that don't support response_format with json_schema. The fix introduces supportsNativeStructuredOutput() to OpenAIChatFormatter (defaulting to true) and overrides it to false in DeepSeek/GLM formatters. OpenAIChatModel now delegates to the formatter via instanceof check. This correctly resolves issues #1742 and #1720. The approach is sound — pushing the capability query to the formatter layer where provider-specific knowledge belongs. Suggestion: consider adding supportsNativeStructuredOutput() to the Formatter interface as a default method to eliminate the instanceof dependency. Unit tests for the new method are recommended.

*
* @return true if native structured output is supported, false otherwise
*/
public boolean supportsNativeStructuredOutput() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[recommended] Architecture improvement: supportsNativeStructuredOutput() is defined on OpenAIChatFormatter concrete class rather than the Formatter interface, requiring OpenAIChatModel to use instanceof check. Consider adding default boolean supportsNativeStructuredOutput() { return false; } to the Formatter interface, eliminating the instanceof dependency and making it easier for custom formatters to declare their capabilities.

@@ -193,7 +193,10 @@ public String getModelName() {

@Override
public boolean supportsNativeStructuredOutput() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[recommended] Missing unit tests: No tests were added for the new supportsNativeStructuredOutput() delegation. Recommended coverage: (1) OpenAIChatFormatter default returns true; (2) DeepSeekFormatter / GLMFormatter return false; (3) OpenAIChatModel correctly delegates to the formatter; (4) Non-OpenAIChatFormatter formatters return false.

@AgentScopeJavaBot AgentScopeJavaBot added bug Something isn't working area/core/model Model providers and formatters labels Jun 19, 2026
@chickenlj chickenlj closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core/model Model providers and formatters bug Something isn't working

Projects

None yet

3 participants