fix: strip message wrapper in CLI session title generation (#7996)

Signed-off-by: Extra Small <littleshuai.bot@gmail.com>
This commit is contained in:
Extra Small
2026-03-26 12:56:36 -07:00
committed by GitHub
parent 27e197e467
commit 65376e011b
2 changed files with 34 additions and 4 deletions
+8 -2
View File
@@ -715,9 +715,15 @@ pub trait Provider: Send + Sync {
) )
.map_err(|e| ProviderError::ContextLengthExceeded(e.to_string()))?; .map_err(|e| ProviderError::ContextLengthExceeded(e.to_string()))?;
use super::cli_common::{
SESSION_NAME_BEGIN_MARKER, SESSION_NAME_END_MARKER, SESSION_NAME_SUFFIX,
};
let user_text = format!( let user_text = format!(
"---BEGIN USER MESSAGES---\n{}\n---END USER MESSAGES---\n\nGenerate a short title for the above messages.", "{}\n{}\n{}\n\n{}",
context.join("\n") SESSION_NAME_BEGIN_MARKER,
context.join("\n"),
SESSION_NAME_END_MARKER,
SESSION_NAME_SUFFIX,
); );
let message = Message::user().with_text(&user_text); let message = Message::user().with_text(&user_text);
let result = self let result = self
+26 -2
View File
@@ -3,6 +3,7 @@ use serde_json::Value;
use super::base::{ProviderUsage, Usage}; use super::base::{ProviderUsage, Usage};
use super::errors::ProviderError; use super::errors::ProviderError;
use crate::conversation::message::{Message, MessageContent}; use crate::conversation::message::{Message, MessageContent};
use crate::utils::safe_truncate;
use rmcp::model::Role; use rmcp::model::Role;
pub(crate) fn extract_usage_tokens(usage_info: &Value) -> Usage { pub(crate) fn extract_usage_tokens(usage_info: &Value) -> Usage {
@@ -32,6 +33,10 @@ pub(crate) fn error_from_event(provider_name: &str, parsed: &Value) -> ProviderE
} }
} }
pub(crate) const SESSION_NAME_BEGIN_MARKER: &str = "---BEGIN USER MESSAGES---";
pub(crate) const SESSION_NAME_END_MARKER: &str = "---END USER MESSAGES---";
pub(crate) const SESSION_NAME_SUFFIX: &str = "Generate a short title for the above messages.";
pub(crate) fn is_session_description_request(system: &str) -> bool { pub(crate) fn is_session_description_request(system: &str) -> bool {
system.contains("four words or less") || system.contains("4 words or less") system.contains("four words or less") || system.contains("4 words or less")
} }
@@ -50,10 +55,29 @@ pub(crate) fn generate_simple_session_description(
}) })
}) })
.map(|text| { .map(|text| {
text.split_whitespace() // Strip the wrapper added by generate_session_name so we get
// the actual user content.
let stripped = text
.strip_prefix(SESSION_NAME_BEGIN_MARKER)
.unwrap_or(text)
.trim_start_matches(['\n', '\r']);
let full_suffix = format!("{}\n\n{}", SESSION_NAME_END_MARKER, SESSION_NAME_SUFFIX);
let stripped = stripped
.strip_suffix(&full_suffix)
.or_else(|| stripped.strip_suffix(SESSION_NAME_END_MARKER))
.unwrap_or(stripped)
.trim();
let desc: String = stripped
.split_whitespace()
.take(4) .take(4)
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" ") .join(" ");
if desc.is_empty() {
"Simple task".to_string()
} else {
safe_truncate(&desc, 100)
}
}) })
.unwrap_or_else(|| "Simple task".to_string()); .unwrap_or_else(|| "Simple task".to_string());