- Removed InputHandler and related input event handling code. - Updated GatewayState to handle new session commands for dialogs. - Introduced UnifiedSessionId for managing session identifiers across channels and chats. - Refactored Session and SessionManager to manage dialogs instead of sessions. - Added methods for creating, listing, switching, renaming, archiving, and deleting dialogs. - Updated storage functions to accommodate dialog IDs in persistent session management. - Enhanced tests to cover new dialog functionalities and ensure stability.
121 lines
3.5 KiB
Rust
121 lines
3.5 KiB
Rust
/// Unified session identifier composed of channel, chat_id, and dialog_id
|
|
///
|
|
/// Format: `channel:chat_id:dialog_id`
|
|
///
|
|
/// Examples:
|
|
/// - CLI: `"cli_chat:sid_abc123:dialog_xyz"`
|
|
/// - Feishu: `"feishu:oc_123456:dialog_xyz"`
|
|
///
|
|
/// For simple cases where only one dialog exists per chat:
|
|
/// - `dialog_id` defaults to `"default"`
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
pub const DEFAULT_DIALOG_ID: &str = "default";
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
pub struct UnifiedSessionId {
|
|
pub channel: String,
|
|
pub chat_id: String,
|
|
pub dialog_id: String,
|
|
}
|
|
|
|
impl UnifiedSessionId {
|
|
/// Create a new UnifiedSessionId
|
|
pub fn new(channel: impl Into<String>, chat_id: impl Into<String>, dialog_id: impl Into<String>) -> Self {
|
|
Self {
|
|
channel: channel.into(),
|
|
chat_id: chat_id.into(),
|
|
dialog_id: dialog_id.into(),
|
|
}
|
|
}
|
|
|
|
/// Create with default dialog_id ("default")
|
|
pub fn with_default_dialog(channel: impl Into<String>, chat_id: impl Into<String>) -> Self {
|
|
Self {
|
|
channel: channel.into(),
|
|
chat_id: chat_id.into(),
|
|
dialog_id: DEFAULT_DIALOG_ID.to_string(),
|
|
}
|
|
}
|
|
|
|
/// Parse from string format "channel:chat_id:dialog_id"
|
|
pub fn parse(s: &str) -> Option<Self> {
|
|
let parts: Vec<&str> = s.split(':').collect();
|
|
if parts.len() != 3 {
|
|
return None;
|
|
}
|
|
Some(Self {
|
|
channel: parts[0].to_string(),
|
|
chat_id: parts[1].to_string(),
|
|
dialog_id: parts[2].to_string(),
|
|
})
|
|
}
|
|
|
|
/// Convert to string format "channel:chat_id:dialog_id"
|
|
pub fn to_string(&self) -> String {
|
|
format!("{}:{}:{}", self.channel, self.chat_id, self.dialog_id)
|
|
}
|
|
|
|
/// Get the session key without dialog_id (channel:chat_id)
|
|
/// This is used to group all dialogs within a chat
|
|
pub fn chat_scope(&self) -> String {
|
|
format!("{}:{}", self.channel, self.chat_id)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for UnifiedSessionId {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.to_string())
|
|
}
|
|
}
|
|
|
|
// Note: No Deref implementation to avoid confusion between String and UnifiedSessionId
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_new() {
|
|
let id = UnifiedSessionId::new("cli_chat", "sid123", "dialog456");
|
|
assert_eq!(id.channel, "cli_chat");
|
|
assert_eq!(id.chat_id, "sid123");
|
|
assert_eq!(id.dialog_id, "dialog456");
|
|
}
|
|
|
|
#[test]
|
|
fn test_with_default_dialog() {
|
|
let id = UnifiedSessionId::with_default_dialog("feishu", "oc123");
|
|
assert_eq!(id.channel, "feishu");
|
|
assert_eq!(id.chat_id, "oc123");
|
|
assert_eq!(id.dialog_id, "default");
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse() {
|
|
let id = UnifiedSessionId::parse("cli_chat:sid123:dialog456").unwrap();
|
|
assert_eq!(id.channel, "cli_chat");
|
|
assert_eq!(id.chat_id, "sid123");
|
|
assert_eq!(id.dialog_id, "dialog456");
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_invalid() {
|
|
assert!(UnifiedSessionId::parse("invalid").is_none());
|
|
assert!(UnifiedSessionId::parse("only:two").is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_to_string() {
|
|
let id = UnifiedSessionId::new("feishu", "oc123", "dialog789");
|
|
assert_eq!(id.to_string(), "feishu:oc123:dialog789");
|
|
}
|
|
|
|
#[test]
|
|
fn test_chat_scope() {
|
|
let id = UnifiedSessionId::new("feishu", "oc123", "dialog789");
|
|
assert_eq!(id.chat_scope(), "feishu:oc123");
|
|
}
|
|
}
|