Compare commits

..

2 Commits

4 changed files with 33 additions and 14 deletions

View File

@ -210,12 +210,13 @@ impl Session {
pub fn ensure_chat_loaded(&mut self, chat_id: &str) -> Result<(), AgentError> {
// 检查历史是否存在且对应正确的话题
let current_topic = self.history.chat_topic(chat_id);
// 先获取 topic 信息并转换为 owned String避免借用冲突
let current_topic: Option<String> = self.history.chat_topic(chat_id).map(|s| s.to_string());
let stored_topic = self.history.history_topic(chat_id);
if self.chat_history_exists(chat_id) {
// 如果历史已存在,但话题不匹配,需要重新加载
if current_topic != stored_topic {
if current_topic.as_deref() != stored_topic {
tracing::info!(
chat_id = %chat_id,
current_topic = ?current_topic,
@ -227,8 +228,8 @@ impl Session {
return Ok(());
}
// 历史不存在,正常加载
self.history.ensure_chat_loaded(chat_id)
// 历史不存在,按 topic 加载(如果设置了 topic
self.history.ensure_chat_loaded(chat_id, current_topic.as_deref())
}
fn chat_history_exists(&self, chat_id: &str) -> bool {

View File

@ -65,7 +65,11 @@ impl SessionHistory {
.map_err(|err| AgentError::Other(format!("session persistence error: {}", err)))
}
pub(crate) fn ensure_chat_loaded(&mut self, chat_id: &str) -> Result<(), AgentError> {
pub(crate) fn ensure_chat_loaded(
&mut self,
chat_id: &str,
topic_id: Option<&str>,
) -> Result<(), AgentError> {
// 获取 session 记录(用于检查最后活跃时间)
let session_record = self.ensure_persistent_session(chat_id)?;
@ -93,10 +97,16 @@ impl SessionHistory {
return Ok(());
}
let history = self
.conversations
.load_messages(&self.persistent_session_id(chat_id))
.map_err(|err| AgentError::Other(format!("session history load error: {}", err)))?;
// 如果提供了 topic_id按 topic 加载;否则按 session 加载
let history = if let Some(tid) = topic_id {
self.conversations
.load_messages_for_topic(tid)
.map_err(|err| AgentError::Other(format!("session history load error: {}", err)))?
} else {
self.conversations
.load_messages(&self.persistent_session_id(chat_id))
.map_err(|err| AgentError::Other(format!("session history load error: {}", err)))?
};
self.chat_histories.insert(chat_id.to_string(), history);
Ok(())
}

View File

@ -22,6 +22,8 @@ pub trait ConversationRepository: Send + Sync + 'static {
fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError>;
fn load_messages_for_topic(&self, topic_id: &str) -> Result<Vec<ChatMessage>, StorageError>;
fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError>;
fn append_message_with_topic(
@ -162,6 +164,10 @@ impl ConversationRepository for super::SessionStore {
super::SessionStore::load_messages(self, session_id)
}
fn load_messages_for_topic(&self, topic_id: &str) -> Result<Vec<ChatMessage>, StorageError> {
super::SessionStore::load_messages_for_topic(self, topic_id)
}
fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError> {
super::SessionStore::append_message(self, session_id, message)
}

View File

@ -602,24 +602,26 @@ fn chunk_text(text: &str, limit: usize) -> Vec<String> {
chunks.push(remaining.to_string());
break;
}
let window = &remaining[..limit];
// Find the nearest valid character boundary
let end = remaining.floor_char_boundary(limit);
let window = &remaining[..end];
let cut = window
.rfind("\n\n")
.filter(|&i| i > limit * 3 / 10)
.filter(|&i| i > end * 3 / 10)
.map(|i| i + 2)
.or_else(|| {
window
.rfind('\n')
.filter(|&i| i > limit * 3 / 10)
.filter(|&i| i > end * 3 / 10)
.map(|i| i + 1)
})
.or_else(|| {
window
.rfind(' ')
.filter(|&i| i > limit * 3 / 10)
.filter(|&i| i > end * 3 / 10)
.map(|i| i + 1)
})
.unwrap_or(limit);
.unwrap_or(end);
chunks.push(remaining[..cut].to_string());
remaining = &remaining[cut..];
}