mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
@@ -17,6 +17,7 @@ pub enum ThinkingEffort {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
XHigh,
|
||||
Max,
|
||||
}
|
||||
|
||||
@@ -28,7 +29,8 @@ impl FromStr for ThinkingEffort {
|
||||
"low" => Ok(Self::Low),
|
||||
"medium" | "med" => Ok(Self::Medium),
|
||||
"high" => Ok(Self::High),
|
||||
"max" | "xhigh" => Ok(Self::Max),
|
||||
"xhigh" => Ok(Self::XHigh),
|
||||
"max" => Ok(Self::Max),
|
||||
other => Err(format!("unknown thinking effort: '{other}'")),
|
||||
}
|
||||
}
|
||||
@@ -41,6 +43,7 @@ impl fmt::Display for ThinkingEffort {
|
||||
Self::Low => write!(f, "low"),
|
||||
Self::Medium => write!(f, "medium"),
|
||||
Self::High => write!(f, "high"),
|
||||
Self::XHigh => write!(f, "xhigh"),
|
||||
Self::Max => write!(f, "max"),
|
||||
}
|
||||
}
|
||||
@@ -445,7 +448,7 @@ impl ModelConfig {
|
||||
"low" => ThinkingEffort::Low,
|
||||
"medium" => ThinkingEffort::Medium,
|
||||
"high" => ThinkingEffort::High,
|
||||
"xhigh" => ThinkingEffort::Max,
|
||||
"xhigh" => ThinkingEffort::XHigh,
|
||||
_ => return,
|
||||
};
|
||||
self.model_name = parts[..parts.len() - 1].join("-");
|
||||
@@ -794,7 +797,7 @@ mod tests {
|
||||
]);
|
||||
let config = ModelConfig::new("gpt-5.4-xhigh").unwrap();
|
||||
assert_eq!(config.model_name, "gpt-5.4");
|
||||
assert_eq!(config.thinking_effort(), Some(ThinkingEffort::Max));
|
||||
assert_eq!(config.thinking_effort(), Some(ThinkingEffort::XHigh));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -857,7 +860,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!("med".parse::<ThinkingEffort>(), Ok(ThinkingEffort::Medium));
|
||||
assert_eq!("max".parse::<ThinkingEffort>(), Ok(ThinkingEffort::Max));
|
||||
assert_eq!("xhigh".parse::<ThinkingEffort>(), Ok(ThinkingEffort::Max));
|
||||
assert_eq!("xhigh".parse::<ThinkingEffort>(), Ok(ThinkingEffort::XHigh));
|
||||
assert!("invalid".parse::<ThinkingEffort>().is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,7 @@ fn reasoning_effort_for_config_with_config(
|
||||
ThinkingEffort::Low => &["low", "medium", "high", "xhigh"],
|
||||
ThinkingEffort::Medium => &["medium", "high", "low", "xhigh"],
|
||||
ThinkingEffort::High => &["high", "medium", "xhigh", "low"],
|
||||
ThinkingEffort::XHigh => &["xhigh", "high", "medium", "low"],
|
||||
ThinkingEffort::Max => &["xhigh", "high", "medium", "low"],
|
||||
};
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ impl CodexProvider {
|
||||
"low" => Some(crate::model::ThinkingEffort::Low),
|
||||
"medium" => Some(crate::model::ThinkingEffort::Medium),
|
||||
"high" => Some(crate::model::ThinkingEffort::High),
|
||||
"xhigh" => Some(crate::model::ThinkingEffort::Max),
|
||||
"xhigh" => Some(crate::model::ThinkingEffort::XHigh),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
@@ -84,6 +84,7 @@ impl CodexProvider {
|
||||
ThinkingEffort::Low => Some("low".to_string()),
|
||||
ThinkingEffort::Medium => Some("medium".to_string()),
|
||||
ThinkingEffort::High => Some("high".to_string()),
|
||||
ThinkingEffort::XHigh => Some("xhigh".to_string()),
|
||||
ThinkingEffort::Max => Some("xhigh".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ pub fn adaptive_effort_value(model_config: &ModelConfig) -> Option<&'static str>
|
||||
}
|
||||
|
||||
fn adaptive_effort_value_for_model(
|
||||
model_name: &str,
|
||||
_model_name: &str,
|
||||
effort: Option<ThinkingEffort>,
|
||||
) -> Option<&'static str> {
|
||||
match effort? {
|
||||
@@ -515,7 +515,7 @@ fn adaptive_effort_value_for_model(
|
||||
ThinkingEffort::Low => Some("low"),
|
||||
ThinkingEffort::Medium => Some("medium"),
|
||||
ThinkingEffort::High => Some("high"),
|
||||
ThinkingEffort::Max if is_claude_opus_47(model_name) => Some("xhigh"),
|
||||
ThinkingEffort::XHigh => Some("xhigh"),
|
||||
ThinkingEffort::Max => Some("max"),
|
||||
}
|
||||
}
|
||||
@@ -569,6 +569,7 @@ fn thinking_budget_tokens_for_values(
|
||||
ThinkingEffort::Low => 4000,
|
||||
ThinkingEffort::Medium => 10000,
|
||||
ThinkingEffort::High => 16000,
|
||||
ThinkingEffort::XHigh => 24000,
|
||||
ThinkingEffort::Max => 32000,
|
||||
})
|
||||
}
|
||||
@@ -1281,6 +1282,23 @@ mod tests {
|
||||
let messages = vec![Message::user().with_text("Hello")];
|
||||
let payload = create_request(&config, "system", &messages, &[])?;
|
||||
|
||||
assert_eq!(payload["thinking"]["type"], "adaptive");
|
||||
assert_eq!(payload["thinking"]["display"], "summarized");
|
||||
assert_eq!(payload["output_config"]["effort"], "max");
|
||||
assert_eq!(payload["max_tokens"], 4096);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_request_adaptive_thinking_for_opus_47_xhigh_effort() -> Result<()> {
|
||||
let _guard = env_lock::lock_env([("GOOSE_THINKING_EFFORT", None::<&str>)]);
|
||||
|
||||
let mut config = cfg_with_effort("claude-opus-4-7", "xhigh");
|
||||
config.max_tokens = Some(4096);
|
||||
let messages = vec![Message::user().with_text("Hello")];
|
||||
let payload = create_request(&config, "system", &messages, &[])?;
|
||||
|
||||
assert_eq!(payload["thinking"]["type"], "adaptive");
|
||||
assert_eq!(payload["thinking"]["display"], "summarized");
|
||||
assert_eq!(payload["output_config"]["effort"], "xhigh");
|
||||
@@ -1470,7 +1488,7 @@ mod tests {
|
||||
assert_eq!(payload["thinking"]["type"], "adaptive");
|
||||
assert_eq!(payload["thinking"]["display"], "summarized");
|
||||
assert_eq!(payload["thinking"]["clear_thinking"], false);
|
||||
assert_eq!(payload["output_config"]["effort"], "xhigh");
|
||||
assert_eq!(payload["output_config"]["effort"], "max");
|
||||
assert!(payload["thinking"].get("budget_tokens").is_none());
|
||||
assert_eq!(payload["max_tokens"], 4096);
|
||||
assert_eq!(payload["messages"][0]["content"][0]["type"], "thinking");
|
||||
|
||||
@@ -1114,19 +1114,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_request_reasoning_effort_xhigh() -> anyhow::Result<()> {
|
||||
let model_config = ModelConfig {
|
||||
model_name: "o3-xhigh".to_string(),
|
||||
context_limit: Some(4096),
|
||||
temperature: None,
|
||||
max_tokens: Some(1024),
|
||||
toolshim: false,
|
||||
toolshim_model: None,
|
||||
fast_model_config: None,
|
||||
request_params: None,
|
||||
reasoning: None,
|
||||
};
|
||||
let _guard = env_lock::lock_env([("GOOSE_THINKING_EFFORT", None::<&str>)]);
|
||||
|
||||
let mut model_config = ModelConfig::new_or_fail("gpt-5.4-xhigh");
|
||||
model_config.max_tokens = Some(1024);
|
||||
let request = create_request(&model_config, "system", &[], &[], &ImageFormat::OpenAi)?;
|
||||
assert_eq!(request["model"], "o3");
|
||||
assert_eq!(request["model"], "gpt-5.4");
|
||||
assert_eq!(request["reasoning_effort"], "xhigh");
|
||||
Ok(())
|
||||
}
|
||||
@@ -1209,10 +1202,17 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_request_enabled_thinking_budget_tracks_effort() -> anyhow::Result<()> {
|
||||
let _guard = env_lock::lock_env([
|
||||
("GOOSE_THINKING_EFFORT", None::<&str>),
|
||||
("ANTHROPIC_THINKING_BUDGET", None::<&str>),
|
||||
("CLAUDE_THINKING_BUDGET", None::<&str>),
|
||||
]);
|
||||
|
||||
for (effort, expected_budget) in [
|
||||
("low", 4000),
|
||||
("medium", 10000),
|
||||
("high", 16000),
|
||||
("xhigh", 24000),
|
||||
("max", 32000),
|
||||
] {
|
||||
let mut model_config = ModelConfig::new_or_fail("databricks-claude-3-7-sonnet");
|
||||
|
||||
@@ -553,7 +553,9 @@ fn get_thinking_config(model_config: &ModelConfig) -> Option<ThinkingConfig> {
|
||||
ThinkingEffort::Off | ThinkingEffort::Low | ThinkingEffort::Medium => {
|
||||
ThinkingLevel::Low
|
||||
}
|
||||
ThinkingEffort::High | ThinkingEffort::Max => ThinkingLevel::High,
|
||||
ThinkingEffort::High | ThinkingEffort::XHigh | ThinkingEffort::Max => {
|
||||
ThinkingLevel::High
|
||||
}
|
||||
};
|
||||
|
||||
Some(ThinkingConfig {
|
||||
|
||||
@@ -94,6 +94,7 @@ fn reasoning_effort_for_openrouter(effort: ThinkingEffort) -> &'static str {
|
||||
ThinkingEffort::Low => "low",
|
||||
ThinkingEffort::Medium => "medium",
|
||||
ThinkingEffort::High => "high",
|
||||
ThinkingEffort::XHigh => "xhigh",
|
||||
ThinkingEffort::Max => "xhigh",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +251,7 @@ pub fn openai_reasoning_effort_for_thinking(
|
||||
ThinkingEffort::Low => &["low", "medium", "high", "xhigh"],
|
||||
ThinkingEffort::Medium => &["medium", "high", "low", "xhigh"],
|
||||
ThinkingEffort::High => &["high", "medium", "xhigh", "low"],
|
||||
ThinkingEffort::XHigh => &["xhigh", "high", "medium", "low"],
|
||||
ThinkingEffort::Max => &["xhigh", "high", "medium", "low"],
|
||||
};
|
||||
|
||||
|
||||
@@ -8676,6 +8676,7 @@
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1502,7 +1502,7 @@ export type ThinkingContent = {
|
||||
thinking: string;
|
||||
};
|
||||
|
||||
export type ThinkingEffort = 'off' | 'low' | 'medium' | 'high' | 'max';
|
||||
export type ThinkingEffort = 'off' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
||||
|
||||
export type TokenState = {
|
||||
accumulatedCost?: number | null;
|
||||
|
||||
@@ -53,6 +53,10 @@ const i18n = defineMessages({
|
||||
id: 'switchModelModal.claudeEffortHigh',
|
||||
defaultMessage: 'High - Deep reasoning (default)',
|
||||
},
|
||||
claudeEffortXHigh: {
|
||||
id: 'switchModelModal.claudeEffortXHigh',
|
||||
defaultMessage: 'XHigh - Extended coding and agentic work',
|
||||
},
|
||||
claudeEffortMax: {
|
||||
id: 'switchModelModal.claudeEffortMax',
|
||||
defaultMessage: 'Max - No constraints on thinking depth',
|
||||
@@ -262,6 +266,7 @@ export const SwitchModelModal = ({
|
||||
{ value: 'low', label: intl.formatMessage(i18n.claudeEffortLow) },
|
||||
{ value: 'medium', label: intl.formatMessage(i18n.claudeEffortMedium) },
|
||||
{ value: 'high', label: intl.formatMessage(i18n.claudeEffortHigh) },
|
||||
{ value: 'xhigh', label: intl.formatMessage(i18n.claudeEffortXHigh) },
|
||||
{ value: 'max', label: intl.formatMessage(i18n.claudeEffortMax) },
|
||||
];
|
||||
|
||||
|
||||
@@ -4409,6 +4409,9 @@
|
||||
"switchModelModal.claudeEffortMedium": {
|
||||
"defaultMessage": "Medium - Moderate thinking"
|
||||
},
|
||||
"switchModelModal.claudeEffortXHigh": {
|
||||
"defaultMessage": "XHigh - Extended coding and agentic work"
|
||||
},
|
||||
"switchModelModal.claudeEnabled": {
|
||||
"defaultMessage": "Enabled - Fixed token budget for thinking"
|
||||
},
|
||||
|
||||
@@ -4307,6 +4307,9 @@
|
||||
"switchModelModal.claudeEffortHigh": {
|
||||
"defaultMessage": "高 - 深度推理(默认)"
|
||||
},
|
||||
"switchModelModal.claudeEffortXHigh": {
|
||||
"defaultMessage": "超高 - 长程编码和代理任务"
|
||||
},
|
||||
"switchModelModal.claudeEffortLow": {
|
||||
"defaultMessage": "低 - 最少思考,响应最快"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user