添加 /dump 命令,导出 session 为 markdown 文档

/dump 命令会输出当前 session 的完整信息:
- Session 元信息 (ID, channel, chat_id, model 等)
- 所有对话历史 (system, user, assistant, tool)
- 每条消息包含角色、时间戳、内容、工具调用等
This commit is contained in:
xiaoxixi 2026-04-28 20:54:54 +08:00
parent 84bb06cc76
commit a3d8ebb534

View File

@ -142,6 +142,71 @@ impl Session {
format!("{}\n\n## Skills\n\n{}\n\nUse the `get_skill` tool to load a skill's full content when needed.", base_prompt, skills_prompt) format!("{}\n\n## Skills\n\n{}\n\nUse the `get_skill` tool to load a skill's full content when needed.", base_prompt, skills_prompt)
} }
} }
/// 将当前 session 导出为 markdown 文档
pub fn dump_as_markdown(&self) -> String {
use chrono::{DateTime, Local};
let now = Local::now().format("%Y-%m-%d %H:%M:%S");
let mut md = String::new();
md.push_str(&format!("# Session Dump\n\n"));
md.push_str(&format!("- **Session ID**: `{}`\n", self.id));
md.push_str(&format!("- **Channel**: `{}`\n", self.id.channel));
md.push_str(&format!("- **Chat ID**: `{}`\n", self.id.chat_id));
md.push_str(&format!("- **Dialog ID**: `{}`\n", self.id.dialog_id));
md.push_str(&format!("- **Message Count**: {}\n", self.messages.len()));
md.push_str(&format!("- **Model**: `{}`\n", self.provider_config.model_id));
md.push_str(&format!("- **Exported At**: {}\n", now));
md.push_str("\n---\n\n");
md.push_str("## Conversation History\n\n");
for (i, msg) in self.messages.iter().enumerate() {
let role = match msg.role.as_str() {
"system" => "System",
"user" => "User",
"assistant" => "Assistant",
"tool" => "Tool",
r => r,
};
let timestamp = if msg.timestamp > 0 {
DateTime::from_timestamp_millis(msg.timestamp)
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S").to_string())
.unwrap_or_default()
} else {
String::new()
};
md.push_str(&format!("### [{:03}] {} {}\n\n", i + 1, role, timestamp));
md.push_str("```\n");
if let Some(ref tool_calls) = msg.tool_calls {
md.push_str(&format!("[Tool Calls]\n"));
for tc in tool_calls {
md.push_str(&format!("- {}: {:?}\n", tc.name, tc.arguments));
}
}
if let Some(ref tool_name) = msg.tool_name {
md.push_str(&format!("[Tool: {}]\n", tool_name));
}
if let Some(ref tool_call_id) = msg.tool_call_id {
md.push_str(&format!("[Tool Call ID: {}]\n", tool_call_id));
}
md.push_str(&msg.content);
md.push_str("\n```\n\n");
if !msg.media_refs.is_empty() {
md.push_str(&format!("**Media**: {:?}\n\n", msg.media_refs));
}
}
md
}
} }
/// SessionManager 管理所有 Session按 channel_name 路由 /// SessionManager 管理所有 Session按 channel_name 路由
@ -219,6 +284,11 @@ pub static SLASH_COMMANDS: &[SlashCommand] = &[
description: "Print current session information", description: "Print current session information",
aliases: &["/info"], aliases: &["/info"],
}, },
SlashCommand {
name: "dump",
description: "Save current session as markdown document",
aliases: &["/dump"],
},
]; ];
impl SessionManager { impl SessionManager {
@ -313,6 +383,16 @@ impl SessionManager {
Ok((None, "No active session.".to_string())) Ok((None, "No active session.".to_string()))
} }
} }
"dump" => {
if let Some(sid) = current_session_id {
let session = self.get_or_create_session(sid).await?;
let session_guard = session.lock().await;
let md = session_guard.dump_as_markdown();
Ok((None, md))
} else {
Ok((None, "No active session.".to_string()))
}
}
_ => Err(AgentError::Other(format!("Command not implemented: {}", cmd.name))), _ => Err(AgentError::Other(format!("Command not implemented: {}", cmd.name))),
} }
} }