fix(goose): exclude preprompt from session title generation (#8793)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -731,16 +731,44 @@ pub trait Provider: Send + Sync {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first 3 user messages as strings for session naming
|
/// Returns the first 3 user messages as strings for session naming,
|
||||||
|
/// filtering out assistant-only content (e.g. preprompt blocks).
|
||||||
fn get_initial_user_messages(&self, messages: &Conversation) -> Vec<String> {
|
fn get_initial_user_messages(&self, messages: &Conversation) -> Vec<String> {
|
||||||
messages
|
messages
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|m| m.role == rmcp::model::Role::User)
|
.filter(|m| m.role == rmcp::model::Role::User)
|
||||||
.take(MSG_COUNT_FOR_SESSION_NAME_GENERATION)
|
.take(MSG_COUNT_FOR_SESSION_NAME_GENERATION)
|
||||||
.map(|m| m.as_concat_text())
|
.map(|m| {
|
||||||
|
m.content
|
||||||
|
.iter()
|
||||||
|
.filter_map(|c| c.filter_for_audience(rmcp::model::Role::User))
|
||||||
|
.filter_map(|c| c.as_text().map(|s| s.to_string()))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extracts preprompt context (assistant-audience blocks) from the first user message.
|
||||||
|
/// These are content blocks visible to the assistant but not the user.
|
||||||
|
fn get_preprompt_context(&self, messages: &Conversation) -> String {
|
||||||
|
messages
|
||||||
|
.iter()
|
||||||
|
.filter(|m| m.role == rmcp::model::Role::User)
|
||||||
|
.take(1)
|
||||||
|
.flat_map(|m| m.content.iter())
|
||||||
|
.filter_map(|c| {
|
||||||
|
// If this block is NOT visible to the user, it's preprompt/assistant-only content
|
||||||
|
if c.filter_for_audience(rmcp::model::Role::User).is_none() {
|
||||||
|
c.as_text().map(|s| s.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate a session name/description based on the conversation history
|
/// Generate a session name/description based on the conversation history
|
||||||
/// Creates a prompt asking for a concise description in 4 words or less.
|
/// Creates a prompt asking for a concise description in 4 words or less.
|
||||||
async fn generate_session_name(
|
async fn generate_session_name(
|
||||||
@@ -749,6 +777,7 @@ pub trait Provider: Send + Sync {
|
|||||||
messages: &Conversation,
|
messages: &Conversation,
|
||||||
) -> Result<String, ProviderError> {
|
) -> Result<String, ProviderError> {
|
||||||
let context = self.get_initial_user_messages(messages);
|
let context = self.get_initial_user_messages(messages);
|
||||||
|
let preprompt_context = self.get_preprompt_context(messages);
|
||||||
let system = crate::prompt_template::render_template(
|
let system = crate::prompt_template::render_template(
|
||||||
"session_name.md",
|
"session_name.md",
|
||||||
&std::collections::HashMap::<String, String>::new(),
|
&std::collections::HashMap::<String, String>::new(),
|
||||||
@@ -758,8 +787,19 @@ pub trait Provider: Send + Sync {
|
|||||||
use super::cli_common::{
|
use super::cli_common::{
|
||||||
SESSION_NAME_BEGIN_MARKER, SESSION_NAME_END_MARKER, SESSION_NAME_SUFFIX,
|
SESSION_NAME_BEGIN_MARKER, SESSION_NAME_END_MARKER, SESSION_NAME_SUFFIX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let preprompt_section = if preprompt_context.is_empty() {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"---BEGIN BACKGROUND CONTEXT (for understanding only, do NOT base the title on this)---\n{}\n---END BACKGROUND CONTEXT---\n\n",
|
||||||
|
preprompt_context
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let user_text = format!(
|
let user_text = format!(
|
||||||
"{}\n{}\n{}\n\n{}",
|
"{}{}\n{}\n{}\n\n{}",
|
||||||
|
preprompt_section,
|
||||||
SESSION_NAME_BEGIN_MARKER,
|
SESSION_NAME_BEGIN_MARKER,
|
||||||
context.join("\n"),
|
context.join("\n"),
|
||||||
SESSION_NAME_END_MARKER,
|
SESSION_NAME_END_MARKER,
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ pub(crate) fn generate_simple_session_description(
|
|||||||
})
|
})
|
||||||
.map(|text| {
|
.map(|text| {
|
||||||
// Strip the wrapper added by generate_session_name so we get
|
// Strip the wrapper added by generate_session_name so we get
|
||||||
// the actual user content.
|
// the actual user content. First strip the optional background context section.
|
||||||
|
let text = text
|
||||||
|
.rfind(SESSION_NAME_BEGIN_MARKER)
|
||||||
|
.and_then(|idx| text.get(idx..))
|
||||||
|
.unwrap_or(text);
|
||||||
let stripped = text
|
let stripped = text
|
||||||
.strip_prefix(SESSION_NAME_BEGIN_MARKER)
|
.strip_prefix(SESSION_NAME_BEGIN_MARKER)
|
||||||
.unwrap_or(text)
|
.unwrap_or(text)
|
||||||
|
|||||||
Reference in New Issue
Block a user