fix(aiagent): use tool-based structured output for all claude models (#6979)
* fix(aiagent): use tool-based structured output for all claude models Extended is_anthropic_provider to check if model starts with 'claude' regardless of provider. This ensures the tool-based structured output logic is used for all Claude models, not just when using Anthropic or OpenRouter providers. Closes #6977 Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> * fix --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
This commit is contained in:
@@ -8,7 +8,6 @@ use std::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
use windmill_common::{
|
||||
ai_providers::AIProvider,
|
||||
db::DB,
|
||||
error::Error,
|
||||
flow_conversations::{add_message_to_conversation_tx, MessageType},
|
||||
@@ -311,12 +310,9 @@ pub fn get_step_name_from_flow(
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if the provider is Anthropic (either direct or through OpenRouter)
|
||||
pub fn is_anthropic_provider(provider: &ProviderWithResource) -> bool {
|
||||
let provider_is_anthropic = provider.kind.is_anthropic();
|
||||
let is_openrouter_anthropic =
|
||||
provider.kind == AIProvider::OpenRouter && provider.model.starts_with("anthropic/");
|
||||
provider_is_anthropic || is_openrouter_anthropic
|
||||
/// Claude models starts with claude if provider is anthropic, or anthropic for openrouter and other providers
|
||||
pub fn is_claude_model(model: &str) -> bool {
|
||||
model.starts_with("claude") || model.starts_with("anthropic")
|
||||
}
|
||||
|
||||
/// Cleanup MCP clients by gracefully shutting down connections
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::ai::tools::{execute_tool_calls, ToolExecutionContext};
|
||||
use crate::ai::utils::{
|
||||
add_message_to_conversation, any_tool_needs_previous_result, cleanup_mcp_clients,
|
||||
filter_schema_by_input_transforms, find_unique_tool_name, get_flow_context,
|
||||
get_flow_job_runnable_and_raw_flow, get_step_name_from_flow, is_anthropic_provider,
|
||||
load_mcp_tools, parse_raw_script_schema, update_flow_status_module_with_actions,
|
||||
get_flow_job_runnable_and_raw_flow, get_step_name_from_flow, is_claude_model, load_mcp_tools,
|
||||
parse_raw_script_schema, update_flow_status_module_with_actions,
|
||||
update_flow_status_module_with_actions_success,
|
||||
};
|
||||
use crate::memory_oss::{read_from_memory, write_to_memory};
|
||||
@@ -471,14 +471,14 @@ pub async fn run_agent(
|
||||
.map(|props| !props.is_empty())
|
||||
.unwrap_or(false);
|
||||
|
||||
let is_anthropic = is_anthropic_provider(&args.provider);
|
||||
let is_claude_model = is_claude_model(&args.provider.model);
|
||||
let mut used_structured_output_tool = false;
|
||||
let mut structured_output_tool_name: Option<String> = None;
|
||||
|
||||
// For text output with schema, handle structured output
|
||||
if has_output_properties && output_type == &OutputType::Text {
|
||||
let schema = args.output_schema.as_ref().unwrap();
|
||||
if is_anthropic {
|
||||
if is_claude_model {
|
||||
// Anthropic uses a tool for structured output
|
||||
let unique_tool_name = find_unique_tool_name("structured_output", tool_defs.as_deref());
|
||||
structured_output_tool_name = Some(unique_tool_name.clone());
|
||||
|
||||
Reference in New Issue
Block a user