feat: 添加确保会话存在的功能,优化子智能体会话管理

This commit is contained in:
oudecheng 2026-05-20 17:21:14 +08:00
parent 1dcdd24519
commit 8d530dcd6b
3 changed files with 59 additions and 8 deletions

View File

@ -269,12 +269,22 @@ impl SessionStore {
chat_id: &str, chat_id: &str,
) -> Result<SessionRecord, StorageError> { ) -> Result<SessionRecord, StorageError> {
let session_id = persistent_session_id(channel_name, chat_id); let session_id = persistent_session_id(channel_name, chat_id);
if let Some(record) = self.get_session(&session_id)? { self.ensure_session(&session_id, channel_name, chat_id, &format!("{}:{}", channel_name, chat_id))
}
/// 确保指定 session_id 的会话存在(如果不存在则创建)
pub fn ensure_session(
&self,
session_id: &str,
channel_name: &str,
chat_id: &str,
title: &str,
) -> Result<SessionRecord, StorageError> {
if let Some(record) = self.get_session(session_id)? {
return Ok(record); return Ok(record);
} }
let now = current_timestamp(); let now = current_timestamp();
let title = format!("{}:{}", channel_name, chat_id);
let conn = self.conn.lock().expect("session db mutex poisoned"); let conn = self.conn.lock().expect("session db mutex poisoned");
conn.execute( conn.execute(
" "
@ -288,7 +298,7 @@ impl SessionStore {
)?; )?;
drop(conn); drop(conn);
self.get_session(&session_id)? self.get_session(session_id)?
.ok_or_else(|| rusqlite::Error::QueryReturnedNoRows.into()) .ok_or_else(|| rusqlite::Error::QueryReturnedNoRows.into())
} }

View File

@ -11,6 +11,15 @@ pub trait ConversationRepository: Send + Sync + 'static {
chat_id: &str, chat_id: &str,
) -> Result<SessionRecord, StorageError>; ) -> Result<SessionRecord, StorageError>;
/// 确保指定 session_id 的会话存在(如果不存在则创建)
fn ensure_session(
&self,
session_id: &str,
channel_name: &str,
chat_id: &str,
title: &str,
) -> Result<SessionRecord, StorageError>;
fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError>; fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError>;
fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError>; fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError>;
@ -139,6 +148,16 @@ impl ConversationRepository for super::SessionStore {
super::SessionStore::ensure_channel_session(self, channel_name, chat_id) super::SessionStore::ensure_channel_session(self, channel_name, chat_id)
} }
fn ensure_session(
&self,
session_id: &str,
channel_name: &str,
chat_id: &str,
title: &str,
) -> Result<SessionRecord, StorageError> {
super::SessionStore::ensure_session(self, session_id, channel_name, chat_id, title)
}
fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError> { fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError> {
super::SessionStore::load_messages(self, session_id) super::SessionStore::load_messages(self, session_id)
} }

View File

@ -290,7 +290,18 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
task.subagent_type, task.subagent_type,
); );
// 3. 保存会话 // 3. 在 sessions 表中创建子智能体会话(确保外键约束满足)
let session_title = format!("Subagent: {}", task.description);
if let Err(e) = self.conversation_repository.ensure_session(
&session.session_id,
&session.parent_channel_name,
&session.parent_chat_id,
&session_title,
) {
tracing::warn!(error = %e, session_id = %session.session_id, "Failed to ensure subagent session");
}
// 4. 保存任务会话
self.task_repository.save_task_session(&session).await?; self.task_repository.save_task_session(&session).await?;
// 4. 构建子代理系统提示词 // 4. 构建子代理系统提示词
@ -354,21 +365,32 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
return Err(TaskError::InvalidParentSession); return Err(TaskError::InvalidParentSession);
} }
// 3. 构建恢复提示词 // 3. 确保 sessions 表中存在子智能体会话记录
let session_title = format!("Subagent: {}", session.description);
if let Err(e) = self.conversation_repository.ensure_session(
&session.session_id,
&session.parent_channel_name,
&session.parent_chat_id,
&session_title,
) {
tracing::warn!(error = %e, session_id = %session.session_id, "Failed to ensure subagent session on resume");
}
// 4. 构建恢复提示词
let system_prompt = SubagentPromptBuilder::build_resume_prompt( let system_prompt = SubagentPromptBuilder::build_resume_prompt(
&session.description, &session.description,
&additional_prompt, &additional_prompt,
); );
// 4. 创建子代理 // 5. 创建子代理
let agent = self.create_subagent(&session, system_prompt)?; let agent = self.create_subagent(&session, system_prompt)?;
// 5. 使用历史继续执行 // 6. 使用历史继续执行
let result = self let result = self
.execute_task_with_history(agent, &session, additional_prompt) .execute_task_with_history(agent, &session, additional_prompt)
.await; .await;
// 6. 更新会话状态 // 7. 更新会话状态
match result { match result {
Ok(tool_result) => { Ok(tool_result) => {
let mut session = session; let mut session = session;