feat(tui): expose auto route in turn metadata (#2410)
Harvested from #2406 with thanks to @axobase001. Adds auto-selected model and reasoning effort to turn metadata while keeping user text isolated in its own content block. Includes the comment cleanup requested in review. Partially addresses #2380.
This commit is contained in:
@@ -910,7 +910,13 @@ impl Engine {
|
||||
self.emit_session_updated().await;
|
||||
}
|
||||
|
||||
fn turn_metadata_block(&self) -> ContentBlock {
|
||||
fn turn_metadata_block(
|
||||
&self,
|
||||
routed_model: &str,
|
||||
auto_model: bool,
|
||||
reasoning_effort: Option<&str>,
|
||||
reasoning_effort_auto: bool,
|
||||
) -> ContentBlock {
|
||||
let today = chrono::Local::now().format("%Y-%m-%d").to_string();
|
||||
let working_set_summary = self
|
||||
.session
|
||||
@@ -919,11 +925,17 @@ impl Engine {
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty());
|
||||
|
||||
let summary = if let Some(working_set_summary) = working_set_summary {
|
||||
format!("Current local date: {today}\n{working_set_summary}")
|
||||
} else {
|
||||
format!("Current local date: {today}")
|
||||
};
|
||||
let mut lines = vec![format!("Current local date: {today}")];
|
||||
if auto_model {
|
||||
lines.push(format!("Auto model route: {routed_model}"));
|
||||
}
|
||||
if reasoning_effort_auto && let Some(reasoning_effort) = reasoning_effort {
|
||||
lines.push(format!("Auto reasoning effort: {reasoning_effort}"));
|
||||
}
|
||||
if let Some(working_set_summary) = working_set_summary {
|
||||
lines.push(working_set_summary);
|
||||
}
|
||||
let summary = lines.join("\n");
|
||||
|
||||
ContentBlock::Text {
|
||||
text: format!("<turn_meta>\n{summary}\n</turn_meta>"),
|
||||
@@ -932,10 +944,32 @@ impl Engine {
|
||||
}
|
||||
|
||||
fn user_text_message_with_turn_metadata(&self, text: String) -> Message {
|
||||
self.user_text_message_with_turn_metadata_for_route(
|
||||
text,
|
||||
&self.session.model,
|
||||
self.session.auto_model,
|
||||
self.session.reasoning_effort.as_deref(),
|
||||
self.session.reasoning_effort_auto,
|
||||
)
|
||||
}
|
||||
|
||||
fn user_text_message_with_turn_metadata_for_route(
|
||||
&self,
|
||||
text: String,
|
||||
routed_model: &str,
|
||||
auto_model: bool,
|
||||
reasoning_effort: Option<&str>,
|
||||
reasoning_effort_auto: bool,
|
||||
) -> Message {
|
||||
Message {
|
||||
role: "user".to_string(),
|
||||
content: vec![
|
||||
self.turn_metadata_block(),
|
||||
self.turn_metadata_block(
|
||||
routed_model,
|
||||
auto_model,
|
||||
reasoning_effort,
|
||||
reasoning_effort_auto,
|
||||
),
|
||||
ContentBlock::Text {
|
||||
text,
|
||||
cache_control: None,
|
||||
@@ -989,7 +1023,7 @@ impl Engine {
|
||||
// failure is non-fatal (the helper logs at WARN).
|
||||
if self.config.snapshots_enabled {
|
||||
// Clone the user prompt now — `content` is moved into
|
||||
// `user_text_message_with_turn_metadata` below, so we need
|
||||
// `user_text_message_with_turn_metadata_for_route` below, so we need
|
||||
// a copy for both pre- and post-turn snapshot labels. The
|
||||
// label carries a truncated first line so `/restore`
|
||||
// listings are human-readable.
|
||||
@@ -1010,7 +1044,7 @@ impl Engine {
|
||||
crate::retry_status::clear();
|
||||
|
||||
// Clone user prompt for post-turn snapshot label before `content`
|
||||
// is moved into `user_text_message_with_turn_metadata` below.
|
||||
// is moved into `user_text_message_with_turn_metadata_for_route` below.
|
||||
let snapshot_prompt_post = content.clone();
|
||||
|
||||
// Check if we have the appropriate client
|
||||
@@ -1041,7 +1075,13 @@ impl Engine {
|
||||
let force_update_plan_first = should_force_update_plan_first(mode, &content);
|
||||
|
||||
// Add user message to session
|
||||
let user_msg = self.user_text_message_with_turn_metadata(content);
|
||||
let user_msg = self.user_text_message_with_turn_metadata_for_route(
|
||||
content,
|
||||
&model,
|
||||
auto_model,
|
||||
reasoning_effort.as_deref(),
|
||||
reasoning_effort_auto,
|
||||
);
|
||||
self.session.add_message(user_msg);
|
||||
|
||||
let previous_goal_objective = self.config.goal_objective.clone();
|
||||
|
||||
@@ -1467,6 +1467,32 @@ fn turn_metadata_includes_current_local_date_without_working_set() {
|
||||
assert!(text.contains(&format!("Current local date: {today}")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_metadata_includes_auto_model_route() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let config = EngineConfig {
|
||||
workspace: tmp.path().to_path_buf(),
|
||||
..Default::default()
|
||||
};
|
||||
let (engine, _handle) = Engine::new(config, &Config::default());
|
||||
|
||||
let user_msg = engine.user_text_message_with_turn_metadata_for_route(
|
||||
"debug this regression".to_string(),
|
||||
"deepseek-v4-pro",
|
||||
true,
|
||||
Some("max"),
|
||||
true,
|
||||
);
|
||||
let first_block = user_msg.content.first().expect("turn metadata block");
|
||||
let ContentBlock::Text { text, .. } = first_block else {
|
||||
panic!("expected text metadata block");
|
||||
};
|
||||
|
||||
assert!(text.contains("Auto model route: deepseek-v4-pro"));
|
||||
assert!(text.contains("Auto reasoning effort: max"));
|
||||
assert!(!text.contains("debug this regression"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_text_message_keeps_current_turn_input_after_turn_metadata() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
|
||||
Reference in New Issue
Block a user