feat: 添加话题管理功能,支持按 chat_id 隔离话题
This commit is contained in:
parent
e709773464
commit
2cc3b1ce9c
@ -32,6 +32,7 @@ use super::session_message_service::SessionMessageService;
|
|||||||
|
|
||||||
/// Session 按 channel 隔离,每个 channel 一个 Session
|
/// Session 按 channel 隔离,每个 channel 一个 Session
|
||||||
/// History 按 chat_id 隔离,由 Session 统一管理
|
/// History 按 chat_id 隔离,由 Session 统一管理
|
||||||
|
/// Topic 按 chat_id 隔离,存储在 SessionHistory 中
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub channel_name: String,
|
pub channel_name: String,
|
||||||
@ -42,7 +43,6 @@ pub struct Session {
|
|||||||
compressor: ContextCompressor,
|
compressor: ContextCompressor,
|
||||||
history: SessionHistory,
|
history: SessionHistory,
|
||||||
store: Arc<SessionStore>,
|
store: Arc<SessionStore>,
|
||||||
current_topic_id: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BusToolCallEmitter {
|
pub struct BusToolCallEmitter {
|
||||||
@ -153,7 +153,6 @@ impl Session {
|
|||||||
chat_history_ttl_hours,
|
chat_history_ttl_hours,
|
||||||
),
|
),
|
||||||
store,
|
store,
|
||||||
current_topic_id: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,14 +160,18 @@ impl Session {
|
|||||||
self.history.persistent_session_id(chat_id)
|
self.history.persistent_session_id(chat_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置当前话题 ID
|
/// 设置当前话题 ID(指定 chat)
|
||||||
pub fn set_current_topic(&mut self, topic_id: Option<String>) {
|
pub fn set_current_topic(&mut self, chat_id: &str, topic_id: Option<String>) {
|
||||||
self.current_topic_id = topic_id;
|
if let Some(topic_id) = topic_id {
|
||||||
|
self.history.set_chat_topic(chat_id, topic_id);
|
||||||
|
} else {
|
||||||
|
self.history.clear_chat_topic(chat_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取当前话题 ID
|
/// 获取当前话题 ID(指定 chat)
|
||||||
pub fn current_topic(&self) -> Option<&str> {
|
pub fn current_topic(&self, chat_id: &str) -> Option<&str> {
|
||||||
self.current_topic_id.as_deref()
|
self.history.chat_topic(chat_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 切换话题 - 清除当前历史并加载新话题的历史
|
/// 切换话题 - 清除当前历史并加载新话题的历史
|
||||||
@ -183,7 +186,7 @@ impl Session {
|
|||||||
.map_err(|e| AgentError::Other(format!("load topic messages error: {}", e)))?;
|
.map_err(|e| AgentError::Other(format!("load topic messages error: {}", e)))?;
|
||||||
|
|
||||||
self.history.set_history(chat_id, messages);
|
self.history.set_history(chat_id, messages);
|
||||||
self.current_topic_id = Some(topic_id.to_string());
|
self.history.set_chat_topic(chat_id, topic_id.to_string());
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
topic_id = %topic_id,
|
topic_id = %topic_id,
|
||||||
@ -243,15 +246,16 @@ impl Session {
|
|||||||
message: ChatMessage,
|
message: ChatMessage,
|
||||||
) -> Result<(), AgentError> {
|
) -> Result<(), AgentError> {
|
||||||
let session_id = self.persistent_session_id(chat_id);
|
let session_id = self.persistent_session_id(chat_id);
|
||||||
|
let topic_id = self.history.chat_topic(chat_id).map(|s| s.to_string());
|
||||||
self.store
|
self.store
|
||||||
.append_message_with_topic(&session_id, self.current_topic_id.as_deref(), &message)
|
.append_message_with_topic(&session_id, topic_id.as_deref(), &message)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
AgentError::Other(format!("append message persistence error: {}", err))
|
AgentError::Other(format!("append message persistence error: {}", err))
|
||||||
})?;
|
})?;
|
||||||
self.add_message(chat_id, message);
|
self.add_message(chat_id, message);
|
||||||
|
|
||||||
// 更新 topic 的最后活跃时间
|
// 更新 topic 的最后活跃时间
|
||||||
if let Some(topic_id) = &self.current_topic_id {
|
if let Some(ref topic_id) = topic_id {
|
||||||
if let Err(e) = self.store.touch_topic(topic_id) {
|
if let Err(e) = self.store.touch_topic(topic_id) {
|
||||||
tracing::warn!(error = %e, topic_id = %topic_id, "Failed to touch topic");
|
tracing::warn!(error = %e, topic_id = %topic_id, "Failed to touch topic");
|
||||||
}
|
}
|
||||||
@ -337,7 +341,7 @@ impl Session {
|
|||||||
|
|
||||||
pub(crate) fn reload_chat_history(&mut self, chat_id: &str) -> Result<(), AgentError> {
|
pub(crate) fn reload_chat_history(&mut self, chat_id: &str) -> Result<(), AgentError> {
|
||||||
// 如果当前有 topic,加载该 topic 的消息
|
// 如果当前有 topic,加载该 topic 的消息
|
||||||
if let Some(topic_id) = &self.current_topic_id {
|
if let Some(topic_id) = self.history.chat_topic(chat_id) {
|
||||||
let messages = self
|
let messages = self
|
||||||
.store
|
.store
|
||||||
.load_messages_for_topic(topic_id)
|
.load_messages_for_topic(topic_id)
|
||||||
|
|||||||
@ -25,6 +25,7 @@ fn current_timestamp() -> i64 {
|
|||||||
pub(crate) struct SessionHistory {
|
pub(crate) struct SessionHistory {
|
||||||
channel_name: String,
|
channel_name: String,
|
||||||
chat_histories: HashMap<String, Vec<ChatMessage>>,
|
chat_histories: HashMap<String, Vec<ChatMessage>>,
|
||||||
|
chat_topic_ids: HashMap<String, String>, // 每个 chat 的当前 topic
|
||||||
compression_in_flight: HashSet<String>,
|
compression_in_flight: HashSet<String>,
|
||||||
conversations: Arc<dyn ConversationRepository>,
|
conversations: Arc<dyn ConversationRepository>,
|
||||||
skill_events: Arc<dyn SkillEventRepository>,
|
skill_events: Arc<dyn SkillEventRepository>,
|
||||||
@ -41,6 +42,7 @@ impl SessionHistory {
|
|||||||
Self {
|
Self {
|
||||||
channel_name: channel_name.into(),
|
channel_name: channel_name.into(),
|
||||||
chat_histories: HashMap::new(),
|
chat_histories: HashMap::new(),
|
||||||
|
chat_topic_ids: HashMap::new(),
|
||||||
compression_in_flight: HashSet::new(),
|
compression_in_flight: HashSet::new(),
|
||||||
conversations,
|
conversations,
|
||||||
skill_events,
|
skill_events,
|
||||||
@ -117,6 +119,21 @@ impl SessionHistory {
|
|||||||
self.chat_histories.insert(chat_id.to_string(), history);
|
self.chat_histories.insert(chat_id.to_string(), history);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 设置指定 chat 的当前 topic
|
||||||
|
pub(crate) fn set_chat_topic(&mut self, chat_id: &str, topic_id: String) {
|
||||||
|
self.chat_topic_ids.insert(chat_id.to_string(), topic_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取指定 chat 的当前 topic
|
||||||
|
pub(crate) fn chat_topic(&self, chat_id: &str) -> Option<&str> {
|
||||||
|
self.chat_topic_ids.get(chat_id).map(|s| s.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 清除指定 chat 的 topic
|
||||||
|
pub(crate) fn clear_chat_topic(&mut self, chat_id: &str) {
|
||||||
|
self.chat_topic_ids.remove(chat_id);
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn add_message(&mut self, chat_id: &str, message: ChatMessage) {
|
pub(crate) fn add_message(&mut self, chat_id: &str, message: ChatMessage) {
|
||||||
self.get_or_create_history(chat_id).push(message);
|
self.get_or_create_history(chat_id).push(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ impl SessionMessageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let session = self.lifecycle.active_session(channel_name).await?;
|
let session = self.lifecycle.active_session(channel_name).await?;
|
||||||
|
|
||||||
let outbound_messages = AgentExecutionService::new(self.show_tool_results)
|
let outbound_messages = AgentExecutionService::new(self.show_tool_results)
|
||||||
.prepare_and_execute_message(MessageExecutionRequest {
|
.prepare_and_execute_message(MessageExecutionRequest {
|
||||||
session,
|
session,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user