fix: omit max_tokens for OpenAI-compatible requests when unset (#9123)

This commit is contained in:
Sarthak Bhardwaj
2026-05-13 04:00:27 +05:30
committed by GitHub
parent 014ddb84b0
commit b23b95c0bd
+45 -1
View File
@@ -1092,6 +1092,12 @@ pub fn create_request(
} }
} }
// Only emit max_tokens / max_completion_tokens when the user (via
// GOOSE_MAX_TOKENS) or a canonical model record has supplied a value.
// For unknown models on OpenAI-compatible endpoints (e.g. llama_swap,
// lmstudio) sending the historic 4096 default truncates non-trivial
// responses; omitting the field lets the server use its own max.
if let Some(max_tokens) = model_config.max_tokens {
let key = if is_reasoning_model { let key = if is_reasoning_model {
"max_completion_tokens" "max_completion_tokens"
} else { } else {
@@ -1100,7 +1106,8 @@ pub fn create_request(
payload payload
.as_object_mut() .as_object_mut()
.unwrap() .unwrap()
.insert(key.to_string(), json!(model_config.max_output_tokens())); .insert(key.to_string(), json!(max_tokens));
}
if for_streaming { if for_streaming {
payload["stream"] = json!(true); payload["stream"] = json!(true);
@@ -1867,6 +1874,43 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn test_create_request_omits_max_tokens_when_unset() -> anyhow::Result<()> {
// Unknown models on OpenAI-compatible local providers (llama_swap,
// lmstudio) have no canonical record and no GOOSE_MAX_TOKENS, so the
// request must not pin the legacy 4096 default — the server should
// pick its own ceiling. See issue #9007.
let model_config = ModelConfig {
model_name: "some-unknown-local-model".to_string(),
context_limit: None,
temperature: None,
max_tokens: None,
toolshim: false,
toolshim_model: None,
fast_model_config: None,
request_params: None,
reasoning: None,
};
let request = create_request(
&model_config,
"system",
&[],
&[],
&ImageFormat::OpenAi,
false,
)?;
let obj = request.as_object().unwrap();
assert!(
!obj.contains_key("max_tokens"),
"max_tokens should be omitted when model_config.max_tokens is None"
);
assert!(
!obj.contains_key("max_completion_tokens"),
"max_completion_tokens should be omitted when model_config.max_tokens is None"
);
Ok(())
}
#[test] #[test]
fn test_create_request_o1_default() -> anyhow::Result<()> { fn test_create_request_o1_default() -> anyhow::Result<()> {
// Without an explicit effort suffix the API picks its own default; // Without an explicit effort suffix the API picks its own default;