feat: Added support for modifying the reasoning effort of reasoning models
This commit is contained in:
@@ -575,6 +575,10 @@ impl RoleLike for Agent {
|
||||
self.config.top_p
|
||||
}
|
||||
|
||||
fn reasoning_effort(&self) -> Option<String> {
|
||||
self.config.reasoning_effort.clone()
|
||||
}
|
||||
|
||||
fn enabled_tools(&self) -> Option<Vec<String>> {
|
||||
None
|
||||
}
|
||||
@@ -596,6 +600,10 @@ impl RoleLike for Agent {
|
||||
self.config.top_p = value;
|
||||
}
|
||||
|
||||
fn set_reasoning_effort(&mut self, value: Option<String>) {
|
||||
self.config.reasoning_effort = value;
|
||||
}
|
||||
|
||||
fn set_enabled_tools(&mut self, value: Option<Vec<String>>) {
|
||||
match value {
|
||||
Some(tools) => {
|
||||
@@ -637,6 +645,8 @@ pub struct AgentConfig {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub top_p: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reasoning_effort: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub agent_session: Option<String>,
|
||||
#[serde(default)]
|
||||
pub auto_continue: bool,
|
||||
@@ -732,6 +742,7 @@ impl AgentConfig {
|
||||
model_id: graph.model.clone(),
|
||||
temperature: graph.temperature,
|
||||
top_p: graph.top_p,
|
||||
reasoning_effort: graph.reasoning_effort.clone(),
|
||||
description: graph.description.clone(),
|
||||
global_tools: graph.global_tools.clone(),
|
||||
mcp_servers: graph.mcp_servers.clone(),
|
||||
@@ -766,6 +777,9 @@ impl AgentConfig {
|
||||
if let Some(v) = read_env_value::<f64>(&with_prefix("top_p")) {
|
||||
self.top_p = v;
|
||||
}
|
||||
if let Some(v) = read_env_value::<String>(&with_prefix("reasoning_effort")) {
|
||||
self.reasoning_effort = v;
|
||||
}
|
||||
if let Ok(v) = env::var(with_prefix("global_tools"))
|
||||
&& let Ok(v) = serde_json::from_str(&v)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@ pub struct AppConfig {
|
||||
pub model_id: String,
|
||||
pub temperature: Option<f64>,
|
||||
pub top_p: Option<f64>,
|
||||
pub reasoning_effort: Option<String>,
|
||||
|
||||
pub dry_run: bool,
|
||||
pub stream: bool,
|
||||
@@ -100,6 +101,7 @@ impl Default for AppConfig {
|
||||
model_id: Default::default(),
|
||||
temperature: None,
|
||||
top_p: None,
|
||||
reasoning_effort: None,
|
||||
|
||||
dry_run: false,
|
||||
stream: true,
|
||||
@@ -177,6 +179,7 @@ impl AppConfig {
|
||||
model_id: config.model_id,
|
||||
temperature: config.temperature,
|
||||
top_p: config.top_p,
|
||||
reasoning_effort: None,
|
||||
|
||||
dry_run: config.dry_run,
|
||||
stream: config.stream,
|
||||
@@ -426,6 +429,9 @@ impl AppConfig {
|
||||
if let Some(v) = super::read_env_value::<f64>(&get_env_name("top_p")) {
|
||||
self.top_p = v;
|
||||
}
|
||||
if let Some(v) = super::read_env_value::<String>(&get_env_name("reasoning_effort")) {
|
||||
self.reasoning_effort = v;
|
||||
}
|
||||
|
||||
if let Some(Some(v)) = super::read_env_bool(&get_env_name("dry_run")) {
|
||||
self.dry_run = v;
|
||||
|
||||
@@ -253,6 +253,10 @@ impl Input {
|
||||
patch_messages(&mut messages, model);
|
||||
model.guard_max_input_tokens(&messages)?;
|
||||
let (temperature, top_p) = (self.role().temperature(), self.role().top_p());
|
||||
let reasoning_effort = self
|
||||
.role()
|
||||
.reasoning_effort()
|
||||
.or_else(|| model.default_reasoning_effort().map(|s| s.to_string()));
|
||||
let functions = if model.supports_function_calling() {
|
||||
let fns = self.functions.clone();
|
||||
if let Some(vec) = &fns {
|
||||
@@ -268,6 +272,7 @@ impl Input {
|
||||
messages,
|
||||
temperature,
|
||||
top_p,
|
||||
reasoning_effort,
|
||||
functions,
|
||||
stream,
|
||||
})
|
||||
|
||||
@@ -969,6 +969,16 @@ impl RequestContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_reasoning_effort_on_role_like(&mut self, value: Option<String>) -> bool {
|
||||
match self.role_like_mut() {
|
||||
Some(role_like) => {
|
||||
role_like.set_reasoning_effort(value);
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_enabled_tools_on_role_like(&mut self, value: Option<Vec<String>>) -> bool {
|
||||
match self.role_like_mut() {
|
||||
Some(role_like) => {
|
||||
@@ -1121,6 +1131,10 @@ impl RequestContext {
|
||||
super::format_option_value(&role.temperature()),
|
||||
),
|
||||
("top_p", super::format_option_value(&role.top_p())),
|
||||
(
|
||||
"reasoning_effort",
|
||||
super::format_option_value(&role.reasoning_effort()),
|
||||
),
|
||||
(
|
||||
"enabled_tools",
|
||||
super::format_option_value(&role.enabled_tools().map(|v| v.join(","))),
|
||||
@@ -2009,6 +2023,12 @@ impl RequestContext {
|
||||
self.update_app_config(|app| app.top_p = value);
|
||||
}
|
||||
}
|
||||
"reasoning_effort" => {
|
||||
let value: Option<String> = super::parse_value(value)?;
|
||||
if !self.set_reasoning_effort_on_role_like(value.clone()) {
|
||||
self.update_app_config(|app| app.reasoning_effort = value);
|
||||
}
|
||||
}
|
||||
"enabled_tools" => {
|
||||
let raw: Option<String> = super::parse_value(value)?;
|
||||
let parsed: Option<Vec<String>> = raw.map(|s| super::csv_to_vec(&s));
|
||||
@@ -2303,6 +2323,10 @@ impl RequestContext {
|
||||
super::map_completion_values(values)
|
||||
}
|
||||
".macro" => super::map_completion_values(paths::list_macros()),
|
||||
".reasoning" => {
|
||||
let levels = self.current_model().reasoning_levels();
|
||||
levels.iter().map(|v| (v.clone(), None)).collect()
|
||||
}
|
||||
".starter" => match &self.agent {
|
||||
Some(agent) => agent
|
||||
.conversation_starters()
|
||||
@@ -2318,6 +2342,7 @@ impl RequestContext {
|
||||
"continuation_prompt",
|
||||
"temperature",
|
||||
"top_p",
|
||||
"reasoning_effort",
|
||||
"enabled_tools",
|
||||
"enabled_mcp_servers",
|
||||
"inject_todo_instructions",
|
||||
@@ -2507,6 +2532,10 @@ impl RequestContext {
|
||||
}
|
||||
"skill_instructions" => vec!["null".to_string()],
|
||||
"memory" => super::complete_bool(self.should_inject_memory()),
|
||||
"reasoning_effort" => {
|
||||
let levels = self.current_model().reasoning_levels();
|
||||
levels.to_vec()
|
||||
}
|
||||
_ => vec![],
|
||||
};
|
||||
values = candidates.into_iter().map(|v| (v, None)).collect();
|
||||
|
||||
@@ -32,7 +32,9 @@ pub trait RoleLike {
|
||||
fn enabled_mcp_servers(&self) -> Option<Vec<String>>;
|
||||
fn set_model(&mut self, model: Model);
|
||||
fn set_temperature(&mut self, value: Option<f64>);
|
||||
fn reasoning_effort(&self) -> Option<String>;
|
||||
fn set_top_p(&mut self, value: Option<f64>);
|
||||
fn set_reasoning_effort(&mut self, value: Option<String>);
|
||||
fn set_enabled_tools(&mut self, value: Option<Vec<String>>);
|
||||
fn set_enabled_mcp_servers(&mut self, value: Option<Vec<String>>);
|
||||
}
|
||||
@@ -51,6 +53,8 @@ pub struct Role {
|
||||
temperature: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
top_p: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
reasoning_effort: Option<String>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
@@ -116,6 +120,9 @@ impl Role {
|
||||
"model" => role.model_id = value.as_str().map(|v| v.to_string()),
|
||||
"temperature" => role.temperature = value.as_f64(),
|
||||
"top_p" => role.top_p = value.as_f64(),
|
||||
"reasoning_effort" => {
|
||||
role.reasoning_effort = value.as_str().map(|v| v.to_string())
|
||||
}
|
||||
"enabled_tools" => role.enabled_tools = parse_string_or_array(value),
|
||||
"enabled_mcp_servers" => {
|
||||
role.enabled_mcp_servers = parse_string_or_array(value)
|
||||
@@ -170,6 +177,9 @@ impl Role {
|
||||
if let Some(top_p) = self.top_p() {
|
||||
metadata.push(format!("top_p: {top_p}"));
|
||||
}
|
||||
if let Some(reasoning_effort) = self.reasoning_effort() {
|
||||
metadata.push(format!("reasoning_effort: {reasoning_effort}"));
|
||||
}
|
||||
if let Some(enabled_tools) = &self.enabled_tools {
|
||||
let inline = serde_json::to_string(enabled_tools).unwrap_or_else(|_| "[]".to_string());
|
||||
metadata.push(format!("enabled_tools: {inline}"));
|
||||
@@ -256,6 +266,9 @@ impl Role {
|
||||
enabled_tools,
|
||||
enabled_mcp_servers,
|
||||
);
|
||||
if let Some(v) = role_like.reasoning_effort() {
|
||||
self.set_reasoning_effort(Some(v));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn batch_set(
|
||||
@@ -410,6 +423,10 @@ impl RoleLike for Role {
|
||||
self.top_p
|
||||
}
|
||||
|
||||
fn reasoning_effort(&self) -> Option<String> {
|
||||
self.reasoning_effort.clone()
|
||||
}
|
||||
|
||||
fn enabled_tools(&self) -> Option<Vec<String>> {
|
||||
self.enabled_tools.clone()
|
||||
}
|
||||
@@ -433,6 +450,10 @@ impl RoleLike for Role {
|
||||
self.top_p = value;
|
||||
}
|
||||
|
||||
fn set_reasoning_effort(&mut self, value: Option<String>) {
|
||||
self.reasoning_effort = value;
|
||||
}
|
||||
|
||||
fn set_enabled_tools(&mut self, value: Option<Vec<String>>) {
|
||||
self.enabled_tools = value;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ pub struct Session {
|
||||
temperature: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
top_p: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
reasoning_effort: Option<String>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
@@ -401,6 +403,7 @@ impl Session {
|
||||
self.model_id = role.model().id();
|
||||
self.temperature = role.temperature();
|
||||
self.top_p = role.top_p();
|
||||
self.reasoning_effort = role.reasoning_effort();
|
||||
self.enabled_tools = role.enabled_tools();
|
||||
self.enabled_mcp_servers = role.enabled_mcp_servers();
|
||||
self.model = role.model().clone();
|
||||
@@ -792,6 +795,10 @@ impl RoleLike for Session {
|
||||
self.top_p
|
||||
}
|
||||
|
||||
fn reasoning_effort(&self) -> Option<String> {
|
||||
self.reasoning_effort.clone()
|
||||
}
|
||||
|
||||
fn enabled_tools(&self) -> Option<Vec<String>> {
|
||||
self.enabled_tools.clone()
|
||||
}
|
||||
@@ -823,6 +830,13 @@ impl RoleLike for Session {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_reasoning_effort(&mut self, value: Option<String>) {
|
||||
if self.reasoning_effort != value {
|
||||
self.reasoning_effort = value;
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn set_enabled_tools(&mut self, value: Option<Vec<String>>) {
|
||||
if self.enabled_tools != value {
|
||||
self.enabled_tools = value;
|
||||
|
||||
Reference in New Issue
Block a user