fix(ai): remove temperature from AI requests
This commit is contained in:
parent
5cd87e862d
commit
3e01840825
|
|
@ -70,7 +70,7 @@ export interface AiRequestInput {
|
|||
context: AiContext;
|
||||
}
|
||||
|
||||
function buildAgentRequest(input: AiRequestInput, history?: api.AiMessage[]): { messages: api.AiMessage[]; systemPrompt: string; taskContract: api.AiTaskContract; maxTokens: number; temperature: number } {
|
||||
function buildAgentRequest(input: AiRequestInput, history?: api.AiMessage[]): { messages: api.AiMessage[]; systemPrompt: string; taskContract: api.AiTaskContract; maxTokens: number } {
|
||||
const isZh = isChineseLocale(currentLocale());
|
||||
const systemPrompt = buildSystemPrompt(input.action, input.context, input.mode);
|
||||
const userPrompt = buildUserPrompt(input.action, input.context, input.instruction, isZh);
|
||||
|
|
@ -84,23 +84,22 @@ function buildAgentRequest(input: AiRequestInput, history?: api.AiMessage[]): {
|
|||
|
||||
const params = actionParams(input.action);
|
||||
const maxTokens = input.config.enableThinking ? Math.max(params.maxTokens, 8192) : params.maxTokens;
|
||||
return { messages, systemPrompt, taskContract, maxTokens, temperature: params.temperature };
|
||||
return { messages, systemPrompt, taskContract, maxTokens };
|
||||
}
|
||||
|
||||
export async function runAiAction(input: AiRequestInput, history?: api.AiMessage[]): Promise<string> {
|
||||
const { messages, systemPrompt, taskContract, maxTokens, temperature } = buildAgentRequest(input, history);
|
||||
const { messages, systemPrompt, taskContract, maxTokens } = buildAgentRequest(input, history);
|
||||
return api.aiComplete({
|
||||
config: input.config,
|
||||
systemPrompt,
|
||||
messages,
|
||||
taskContract,
|
||||
maxTokens,
|
||||
temperature,
|
||||
});
|
||||
}
|
||||
|
||||
export async function runAiStream(input: AiRequestInput, history: api.AiMessage[] | undefined, onDelta: (delta: string) => void, sessionId?: string, onReasoningDelta?: (delta: string) => void): Promise<void> {
|
||||
const { messages, systemPrompt, taskContract, maxTokens, temperature } = buildAgentRequest(input, history);
|
||||
const { messages, systemPrompt, taskContract, maxTokens } = buildAgentRequest(input, history);
|
||||
const sid = sessionId || uuid();
|
||||
|
||||
await api.aiStream(
|
||||
|
|
@ -111,7 +110,6 @@ export async function runAiStream(input: AiRequestInput, history: api.AiMessage[
|
|||
messages,
|
||||
taskContract,
|
||||
maxTokens,
|
||||
temperature,
|
||||
},
|
||||
(chunk) => {
|
||||
if (!chunk.done) {
|
||||
|
|
@ -123,7 +121,7 @@ export async function runAiStream(input: AiRequestInput, history: api.AiMessage[
|
|||
}
|
||||
|
||||
export async function runAgentStream(input: AiRequestInput, history: api.AiMessage[] | undefined, onEvent: (event: AgentEvent) => void, sessionId?: string): Promise<string> {
|
||||
const { messages, systemPrompt, taskContract, maxTokens, temperature } = buildAgentRequest(input, history);
|
||||
const { messages, systemPrompt, taskContract, maxTokens } = buildAgentRequest(input, history);
|
||||
const sid = sessionId || uuid();
|
||||
|
||||
return api.aiAgentStream(
|
||||
|
|
@ -134,7 +132,6 @@ export async function runAgentStream(input: AiRequestInput, history: api.AiMessa
|
|||
messages,
|
||||
taskContract,
|
||||
maxTokens,
|
||||
temperature,
|
||||
},
|
||||
input.context.connectionId,
|
||||
input.context.database,
|
||||
|
|
@ -155,14 +152,14 @@ export function buildUserPrompt(action: AiAction, context: AiContext, instructio
|
|||
return [`Action: ${action}`, skillInstruction, "", "User request:", userRequest].join("\n");
|
||||
}
|
||||
|
||||
function actionParams(action: AiAction): { maxTokens: number; temperature: number } {
|
||||
function actionParams(action: AiAction): { maxTokens: number } {
|
||||
switch (action) {
|
||||
case "explain":
|
||||
return { maxTokens: 3200, temperature: 0.2 };
|
||||
return { maxTokens: 3200 };
|
||||
case "sampleData":
|
||||
return { maxTokens: 2400, temperature: 0.1 };
|
||||
return { maxTokens: 2400 };
|
||||
default:
|
||||
return { maxTokens: 2400, temperature: 0.15 };
|
||||
return { maxTokens: 2400 };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,6 @@ export interface AiCompletionRequest {
|
|||
messages: AiMessage[];
|
||||
taskContract?: AiTaskContract;
|
||||
maxTokens?: number;
|
||||
temperature?: number;
|
||||
}
|
||||
|
||||
export interface AiModelInfo {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ pub async fn run_agent_loop(
|
|||
on_event: impl Fn(AgentEvent) + Send + Sync + Clone + 'static,
|
||||
cancelled: &Notify,
|
||||
max_tokens: Option<u32>,
|
||||
temperature: Option<f32>,
|
||||
task_contract: Option<&AiTaskContract>,
|
||||
is_agent_mode: bool,
|
||||
) -> Result<String, String> {
|
||||
|
|
@ -124,7 +123,6 @@ pub async fn run_agent_loop(
|
|||
on_event,
|
||||
cancelled,
|
||||
max_tokens,
|
||||
temperature,
|
||||
task_contract,
|
||||
)
|
||||
.await;
|
||||
|
|
@ -181,7 +179,6 @@ pub async fn run_agent_loop(
|
|||
&conversation_messages,
|
||||
&tools,
|
||||
max_tokens,
|
||||
temperature,
|
||||
task_contract.clone(),
|
||||
);
|
||||
|
||||
|
|
@ -434,7 +431,6 @@ fn build_tool_request(
|
|||
messages: &[AiMessage],
|
||||
_tools: &[ToolDefinition], // Tools are injected in ai::stream_with_tools, not via AiCompletionRequest.
|
||||
max_tokens: Option<u32>,
|
||||
temperature: Option<f32>,
|
||||
task_contract: Option<AiTaskContract>,
|
||||
) -> AiCompletionRequest {
|
||||
// Note: tools are passed via the body, not via AiCompletionRequest.
|
||||
|
|
@ -445,7 +441,6 @@ fn build_tool_request(
|
|||
messages: messages.to_vec(),
|
||||
task_contract,
|
||||
max_tokens: max_tokens.or(Some(4096)),
|
||||
temperature: temperature.or(Some(0.2)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +647,6 @@ async fn run_agent_loop_text_only(
|
|||
on_event: impl Fn(AgentEvent) + Send + Sync + 'static,
|
||||
_cancelled: &Notify,
|
||||
max_tokens: Option<u32>,
|
||||
temperature: Option<f32>,
|
||||
task_contract: Option<&AiTaskContract>,
|
||||
) -> Result<String, String> {
|
||||
// Build a schema-enriched system prompt so the LLM can answer schema questions
|
||||
|
|
@ -665,7 +659,6 @@ async fn run_agent_loop_text_only(
|
|||
messages: messages.to_vec(),
|
||||
task_contract: task_contract.cloned(),
|
||||
max_tokens: max_tokens.or(Some(4096)),
|
||||
temperature: temperature.or(Some(0.2)),
|
||||
};
|
||||
|
||||
for attempt in 0..=MAX_CONTRACT_REPAIR_ATTEMPTS {
|
||||
|
|
@ -898,7 +891,6 @@ async fn maybe_compact(
|
|||
}],
|
||||
task_contract: None,
|
||||
max_tokens: Some(1024),
|
||||
temperature: Some(0.1),
|
||||
};
|
||||
|
||||
let summary = match cancelled.notified().now_or_never() {
|
||||
|
|
|
|||
|
|
@ -177,7 +177,6 @@ pub struct AiCompletionRequest {
|
|||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub task_contract: Option<AiTaskContract>,
|
||||
pub max_tokens: Option<u32>,
|
||||
pub temperature: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
|
@ -495,8 +494,8 @@ fn set_chat_completion_token_limit(body: &mut serde_json::Value, config: &AiConf
|
|||
}
|
||||
}
|
||||
|
||||
/// Kimi K2.5+ models (including K2.7-Code) require fixed sampling parameters:
|
||||
/// temperature=1.0, top_p=0.95, n=1. Any other value returns an error.
|
||||
/// Kimi K2.5+ models (including K2.7-Code) handle thinking flags differently
|
||||
/// and reject the OpenAI-compatible `extra_body.chat_template_kwargs` toggle.
|
||||
///
|
||||
/// Matches `kimi-k2.5`, `kimi-k2.6`, `kimi-k2.7-code`, K3+, and future versions,
|
||||
/// while excluding older K2 variants (`kimi-k2`, `kimi-k2-thinking`, etc.).
|
||||
|
|
@ -516,25 +515,6 @@ fn is_kimi_model(model: &str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn supports_temperature(config: &AiConfig) -> bool {
|
||||
!(is_kimi_model(&config.model) || uses_openai_max_completion_tokens(config))
|
||||
}
|
||||
|
||||
fn add_temperature_if_supported_for_config(body: &mut serde_json::Value, config: &AiConfig, temperature: Option<f32>) {
|
||||
if supports_temperature(config) {
|
||||
body["temperature"] = temperature_value(temperature);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_temperature_if_supported(body: &mut serde_json::Value, request: &AiCompletionRequest) {
|
||||
add_temperature_if_supported_for_config(body, &request.config, request.temperature);
|
||||
}
|
||||
|
||||
fn temperature_value(temperature: Option<f32>) -> serde_json::Value {
|
||||
let value = ((temperature.unwrap_or(0.2) as f64) * 100.0).round() / 100.0;
|
||||
json!(value)
|
||||
}
|
||||
|
||||
fn responses_text(data: &serde_json::Value) -> String {
|
||||
if let Some(text) = data["output_text"].as_str().filter(|text| !text.is_empty()) {
|
||||
return text.to_string();
|
||||
|
|
@ -878,7 +858,6 @@ pub async fn call_claude(client: &reqwest::Client, request: AiCompletionRequest)
|
|||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"max_tokens": request.max_tokens.unwrap_or(2048),
|
||||
"temperature": temperature_value(request.temperature),
|
||||
"system": claude_system_prompt(&request.system_prompt),
|
||||
"messages": request.messages,
|
||||
});
|
||||
|
|
@ -915,7 +894,6 @@ pub async fn call_openai_compatible(client: &reqwest::Client, request: AiComplet
|
|||
"messages": messages,
|
||||
});
|
||||
set_chat_completion_token_limit(&mut body_obj, &request.config, request.max_tokens.unwrap_or(2048));
|
||||
add_temperature_if_supported(&mut body_obj, &request);
|
||||
if !request.config.enable_thinking && !is_kimi_model(&request.config.model) {
|
||||
body_obj["extra_body"] = json!({
|
||||
"chat_template_kwargs": { "enable_thinking": false }
|
||||
|
|
@ -942,12 +920,11 @@ pub async fn call_openai_compatible(client: &reqwest::Client, request: AiComplet
|
|||
pub async fn call_responses_api(client: &reqwest::Client, request: AiCompletionRequest) -> Result<String, String> {
|
||||
let headers = maybe_bearer_headers(&request.config)?;
|
||||
|
||||
let mut body = json!({
|
||||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"input": build_responses_input(&request.system_prompt, &request.messages),
|
||||
"max_output_tokens": responses_max_output_tokens(request.max_tokens),
|
||||
});
|
||||
add_temperature_if_supported(&mut body, &request);
|
||||
|
||||
let res = client
|
||||
.post(resolve_endpoint(&request.config))
|
||||
|
|
@ -983,7 +960,6 @@ pub async fn call_gemini(client: &reqwest::Client, request: AiCompletionRequest)
|
|||
"contents": contents,
|
||||
"generationConfig": {
|
||||
"maxOutputTokens": request.max_tokens.unwrap_or(2048),
|
||||
"temperature": temperature_value(request.temperature),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -1100,7 +1076,6 @@ pub async fn test_connection_core(config: &AiConfig) -> Result<AiTestConnectionR
|
|||
let body = json!({
|
||||
"model": &model,
|
||||
"max_tokens": 16,
|
||||
"temperature": temperature_value(Some(0.0)),
|
||||
"system": CLAUDE_DEFAULT_SYSTEM,
|
||||
"messages": [{ "role": "user", "content": TEST_PROMPT }],
|
||||
"stream": true,
|
||||
|
|
@ -1126,7 +1101,7 @@ pub async fn test_connection_core(config: &AiConfig) -> Result<AiTestConnectionR
|
|||
.query(&[("key", config.api_key.as_str()), ("alt", "sse")])
|
||||
.json(&json!({
|
||||
"contents": [{ "parts": [{ "text": TEST_PROMPT }], "role": "user" }],
|
||||
"generationConfig": { "maxOutputTokens": 16, "temperature": temperature_value(Some(0.0)) },
|
||||
"generationConfig": { "maxOutputTokens": 16 },
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
|
|
@ -1141,7 +1116,6 @@ pub async fn test_connection_core(config: &AiConfig) -> Result<AiTestConnectionR
|
|||
let body = json!({
|
||||
"model": &model,
|
||||
"max_tokens": 16,
|
||||
"temperature": temperature_value(Some(0.0)),
|
||||
"system": CLAUDE_DEFAULT_SYSTEM,
|
||||
"messages": [{ "role": "user", "content": TEST_PROMPT }],
|
||||
"stream": true,
|
||||
|
|
@ -1178,7 +1152,6 @@ pub async fn test_connection_core(config: &AiConfig) -> Result<AiTestConnectionR
|
|||
set_chat_completion_token_limit(&mut body, config, 16);
|
||||
body
|
||||
};
|
||||
add_temperature_if_supported_for_config(&mut body_obj, config, Some(0.0));
|
||||
if config.api_style != AiApiStyle::Responses && !config.enable_thinking && !is_kimi_model(&config.model) {
|
||||
body_obj["extra_body"] = json!({
|
||||
"chat_template_kwargs": { "enable_thinking": false }
|
||||
|
|
@ -1352,7 +1325,6 @@ async fn stream_claude(
|
|||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"max_tokens": request.max_tokens.unwrap_or(2048),
|
||||
"temperature": temperature_value(request.temperature),
|
||||
"system": claude_system_prompt(&request.system_prompt),
|
||||
"messages": request.messages,
|
||||
"stream": true,
|
||||
|
|
@ -1435,7 +1407,6 @@ async fn stream_openai(
|
|||
"stream": true,
|
||||
});
|
||||
set_chat_completion_token_limit(&mut body_obj, &request.config, request.max_tokens.unwrap_or(2048));
|
||||
add_temperature_if_supported(&mut body_obj, request);
|
||||
if !request.config.enable_thinking && !is_kimi_model(&request.config.model) {
|
||||
body_obj["extra_body"] = json!({
|
||||
"chat_template_kwargs": { "enable_thinking": false }
|
||||
|
|
@ -1518,13 +1489,12 @@ async fn stream_responses_api(
|
|||
) -> Result<(), String> {
|
||||
let headers = maybe_bearer_headers(&request.config)?;
|
||||
|
||||
let mut body = json!({
|
||||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"input": build_responses_input(&request.system_prompt, &request.messages),
|
||||
"max_output_tokens": responses_max_output_tokens(request.max_tokens),
|
||||
"stream": true,
|
||||
});
|
||||
add_temperature_if_supported(&mut body, request);
|
||||
|
||||
let res = client
|
||||
.post(resolve_endpoint(&request.config))
|
||||
|
|
@ -1608,7 +1578,6 @@ async fn stream_gemini(
|
|||
"contents": contents,
|
||||
"generationConfig": {
|
||||
"maxOutputTokens": request.max_tokens.unwrap_or(2048),
|
||||
"temperature": temperature_value(request.temperature),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -1813,7 +1782,7 @@ async fn stream_claude_with_tools(
|
|||
|
||||
let tool_json: Vec<serde_json::Value> = tools.iter().map(|t| t.to_anthropic_tool()).collect();
|
||||
|
||||
let mut body = json!({
|
||||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"max_tokens": request.max_tokens.unwrap_or(4096),
|
||||
"system": claude_system_prompt(&request.system_prompt),
|
||||
|
|
@ -1821,7 +1790,6 @@ async fn stream_claude_with_tools(
|
|||
"tools": tool_json,
|
||||
"stream": true,
|
||||
});
|
||||
add_temperature_if_supported(&mut body, request);
|
||||
|
||||
let res = client
|
||||
.post(resolve_endpoint(&request.config))
|
||||
|
|
@ -1995,7 +1963,6 @@ async fn stream_openai_with_tools(
|
|||
"stream_options": { "include_usage": true },
|
||||
});
|
||||
set_chat_completion_token_limit(&mut body, &request.config, request.max_tokens.unwrap_or(4096));
|
||||
add_temperature_if_supported(&mut body, request);
|
||||
|
||||
let res = client
|
||||
.post(resolve_endpoint(&request.config))
|
||||
|
|
@ -2098,7 +2065,7 @@ async fn stream_responses_with_tools(
|
|||
let headers = maybe_bearer_headers(&request.config)?;
|
||||
let tool_json: Vec<serde_json::Value> = tools.iter().map(responses_function_tool).collect();
|
||||
|
||||
let mut body = json!({
|
||||
let body = json!({
|
||||
"model": request.config.model,
|
||||
"input": build_responses_input_with_tools(&request.system_prompt, &request.messages),
|
||||
"max_output_tokens": responses_max_output_tokens(request.max_tokens),
|
||||
|
|
@ -2106,7 +2073,6 @@ async fn stream_responses_with_tools(
|
|||
"tool_choice": "auto",
|
||||
"stream": true,
|
||||
});
|
||||
add_temperature_if_supported(&mut body, request);
|
||||
|
||||
let res = client
|
||||
.post(resolve_endpoint(&request.config))
|
||||
|
|
@ -2477,14 +2443,14 @@ mod tests {
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use super::{
|
||||
add_temperature_if_supported_for_config, build_ai_http_client, build_responses_input_with_tools,
|
||||
claude_headers, claude_system_prompt, drain_next_stream_line, emit_responses_function_call_item, gemini_text,
|
||||
is_kimi_model, openai_response_text, openai_stream_reasoning, openai_stream_text, parse_model_list_response,
|
||||
resolve_endpoint, resolve_model_list_endpoint, responses_function_tool, responses_max_output_tokens,
|
||||
responses_stream_text, responses_text, responses_token_usage, set_chat_completion_token_limit,
|
||||
stream_data_payload, supports_temperature, temperature_value, uses_anthropic_messages_api, validate_config,
|
||||
AiApiStyle, AiAuthMethod, AiConfig, AiMessage, AiModelInfo, AiProvider, AiReasoningLevel, StreamToolEvent,
|
||||
StreamingToolCallAccumulator, ToolCallRef, AUTHORIZATION, CLAUDE_DEFAULT_SYSTEM, TEST_PROMPT,
|
||||
build_ai_http_client, build_responses_input_with_tools, claude_headers, claude_system_prompt,
|
||||
drain_next_stream_line, emit_responses_function_call_item, gemini_text, is_kimi_model, openai_response_text,
|
||||
openai_stream_reasoning, openai_stream_text, parse_model_list_response, resolve_endpoint,
|
||||
resolve_model_list_endpoint, responses_function_tool, responses_max_output_tokens, responses_stream_text,
|
||||
responses_text, responses_token_usage, set_chat_completion_token_limit, stream_data_payload,
|
||||
uses_anthropic_messages_api, validate_config, AiApiStyle, AiAuthMethod, AiConfig, AiMessage, AiModelInfo,
|
||||
AiProvider, AiReasoningLevel, StreamToolEvent, StreamingToolCallAccumulator, ToolCallRef, AUTHORIZATION,
|
||||
CLAUDE_DEFAULT_SYSTEM, TEST_PROMPT,
|
||||
};
|
||||
|
||||
/// Reproduce the "Unknown tool:" bug: some OpenAI-compatible providers
|
||||
|
|
@ -3078,82 +3044,17 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn temperature_value_rounds_f32_to_provider_safe_precision() {
|
||||
assert_eq!(temperature_value(Some(0.15)), serde_json::json!(0.15));
|
||||
assert_eq!(temperature_value(Some(0.149)), serde_json::json!(0.15));
|
||||
assert_eq!(temperature_value(None), serde_json::json!(0.2));
|
||||
assert_eq!(serde_json::to_string(&temperature_value(Some(0.15))).unwrap(), "0.15");
|
||||
}
|
||||
fn detects_kimi_models_that_skip_extra_body_thinking_toggle() {
|
||||
assert!(is_kimi_model("kimi-k2.7-code"));
|
||||
assert!(is_kimi_model("kimi-k2.6"));
|
||||
assert!(is_kimi_model("kimi-k2.5"));
|
||||
assert!(is_kimi_model("kimi-k3"));
|
||||
|
||||
#[test]
|
||||
fn omits_temperature_for_openai_reasoning_models() {
|
||||
let mut config = AiConfig {
|
||||
provider: AiProvider::Openai,
|
||||
api_key: "key".to_string(),
|
||||
auth_method: AiAuthMethod::Bearer,
|
||||
endpoint: "https://api.openai.com/v1/chat/completions".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
api_style: AiApiStyle::Completions,
|
||||
proxy_enabled: false,
|
||||
proxy_url: String::new(),
|
||||
enable_thinking: true,
|
||||
reasoning_level: AiReasoningLevel::Default,
|
||||
context_window: None,
|
||||
codex_cli_path: None,
|
||||
codex_cli_env: Default::default(),
|
||||
};
|
||||
|
||||
assert!(!supports_temperature(&config));
|
||||
|
||||
config.model = "o4-mini".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
|
||||
config.model = "gpt-4o".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
|
||||
config.endpoint = "http://localhost:11434/v1".to_string();
|
||||
config.model = "gpt-5-proxy".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
|
||||
config.provider = AiProvider::OpenaiCompatible;
|
||||
config.endpoint = "http://localhost:11434/v1".to_string();
|
||||
config.model = "gpt-5-local".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
|
||||
// Kimi K2.5+ models: temperature is forced to 1.0 by the API
|
||||
config.model = "kimi-k2.7-code".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
assert!(is_kimi_model(&config.model));
|
||||
|
||||
config.model = "kimi-k2.6".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
assert!(is_kimi_model(&config.model));
|
||||
|
||||
config.model = "kimi-k2.5".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
assert!(is_kimi_model(&config.model));
|
||||
|
||||
// K3+ should also be matched
|
||||
config.model = "kimi-k3".to_string();
|
||||
assert!(!supports_temperature(&config));
|
||||
assert!(is_kimi_model(&config.model));
|
||||
|
||||
// Older K2 variants should NOT be matched (they support custom temperature)
|
||||
config.model = "kimi-k2".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
assert!(!is_kimi_model(&config.model));
|
||||
|
||||
config.model = "kimi-k2-thinking".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
assert!(!is_kimi_model(&config.model));
|
||||
|
||||
config.model = "kimi-k2-0711-preview".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
assert!(!is_kimi_model(&config.model));
|
||||
|
||||
config.model = "kimi-k2.4".to_string();
|
||||
assert!(supports_temperature(&config));
|
||||
assert!(!is_kimi_model(&config.model));
|
||||
// Older K2 variants should not skip OpenAI-compatible thinking toggles.
|
||||
assert!(!is_kimi_model("kimi-k2"));
|
||||
assert!(!is_kimi_model("kimi-k2-thinking"));
|
||||
assert!(!is_kimi_model("kimi-k2-0711-preview"));
|
||||
assert!(!is_kimi_model("kimi-k2.4"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -3222,7 +3123,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn omits_temperature_for_kimi_test_connection_body() {
|
||||
fn omits_extra_body_for_kimi_test_connection_body() {
|
||||
let config = AiConfig {
|
||||
provider: AiProvider::OpenaiCompatible,
|
||||
api_key: "key".to_string(),
|
||||
|
|
@ -3245,14 +3146,12 @@ mod tests {
|
|||
"stream": true,
|
||||
});
|
||||
|
||||
add_temperature_if_supported_for_config(&mut body, &config, Some(0.0));
|
||||
if !config.enable_thinking && !is_kimi_model(&config.model) {
|
||||
body["extra_body"] = serde_json::json!({
|
||||
"chat_template_kwargs": { "enable_thinking": false }
|
||||
});
|
||||
}
|
||||
|
||||
assert!(body.get("temperature").is_none());
|
||||
assert!(body.get("extra_body").is_none());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -273,7 +273,6 @@ pub async fn ai_agent_stream(
|
|||
let req_messages = request.messages;
|
||||
let req_task_contract = request.task_contract;
|
||||
let req_max_tokens = request.max_tokens;
|
||||
let req_temperature = request.temperature;
|
||||
let is_agent_mode = body.mode == "agent";
|
||||
let tx2 = tx.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
|
@ -291,7 +290,6 @@ pub async fn ai_agent_stream(
|
|||
},
|
||||
&cancelled,
|
||||
req_max_tokens,
|
||||
req_temperature,
|
||||
req_task_contract.as_ref(),
|
||||
is_agent_mode,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ pub async fn ai_agent_stream(
|
|||
},
|
||||
&cancelled,
|
||||
request.max_tokens,
|
||||
request.temperature,
|
||||
request.task_contract.as_ref(),
|
||||
is_agent_mode,
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue