简化斜杠命令,移除不可用的命令
删除:sessions, switch, rename, archive 保留:new, delete, compact, info
This commit is contained in:
parent
8219e7c928
commit
7220e89a22
433
session_plan.md
Normal file
433
session_plan.md
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
# Session 管理详细设计
|
||||||
|
|
||||||
|
## 一、设计目标
|
||||||
|
|
||||||
|
1. Session 数据持久化到 SQLite,系统重启后可恢复
|
||||||
|
2. 支持 Dialog 的完整生命周期管理(创建/列表/切换/重命名/删除)
|
||||||
|
3. 基于 TTL 的自动内存清理(DB 保留所有数据)
|
||||||
|
4. LLM 自动生成会话标题(title),帮助用户和 AI 理解对话上下文
|
||||||
|
5. 每条消息实时写入 DB,失败后重试 + 告警
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、概念定义
|
||||||
|
|
||||||
|
### 2.1 层级结构
|
||||||
|
|
||||||
|
```
|
||||||
|
Channel (渠道)
|
||||||
|
└── Chat (聊天)
|
||||||
|
└── Dialog (对话)
|
||||||
|
└── Session (会话实例)
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Channel**:消息来源渠道(如 `cli_chat`、`feishu`)
|
||||||
|
- **Chat**:同一渠道下的一个聊天会话(如某个 CLI session ID 或飞书 open_conversation_id)
|
||||||
|
- **Dialog**:聊天内的多个独立对话线程(如 `/new` 创建的新对话)
|
||||||
|
- **Session**:一个 Dialog 的运行时实例,包含消息历史、LLM 配置、工具等
|
||||||
|
|
||||||
|
### 2.2 UnifiedSessionId
|
||||||
|
|
||||||
|
```
|
||||||
|
格式:{channel}:{chat_id}:{dialog_id}
|
||||||
|
示例:cli_chat:sid_abc123:dialog_xyz
|
||||||
|
feishu:oc_123456:default
|
||||||
|
```
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| channel | 渠道标识 |
|
||||||
|
| chat_id | 聊天标识 |
|
||||||
|
| dialog_id | 对话标识(默认 `default`) |
|
||||||
|
|
||||||
|
### 2.3 Session 与 Dialog 的关系
|
||||||
|
|
||||||
|
- 每个 Dialog 在运行时对应一个 `Session` 实例
|
||||||
|
- `Session` 存在于内存中,可通过 `UnifiedSessionId` 访问
|
||||||
|
- `Dialog` 是 Storage 中的持久化记录,`Session` 是其运行时投影
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、数据库 Schema
|
||||||
|
|
||||||
|
### 3.1 sessions 表
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
channel TEXT NOT NULL,
|
||||||
|
chat_id TEXT NOT NULL,
|
||||||
|
dialog_id TEXT NOT NULL,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
created_at INTEGER NOT NULL,
|
||||||
|
last_active_at INTEGER NOT NULL,
|
||||||
|
message_count INTEGER DEFAULT 0,
|
||||||
|
deleted_at INTEGER,
|
||||||
|
UNIQUE(channel, chat_id, dialog_id)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
> 注意:已删除 `archived_at` 字段,不保留归档概念。
|
||||||
|
|
||||||
|
### 3.2 messages 表
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE messages (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
session_id TEXT NOT NULL,
|
||||||
|
seq INTEGER NOT NULL,
|
||||||
|
role TEXT NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
media_refs TEXT,
|
||||||
|
tool_call_id TEXT,
|
||||||
|
tool_name TEXT,
|
||||||
|
tool_calls TEXT,
|
||||||
|
created_at INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_messages_session_seq ON messages(session_id, seq);
|
||||||
|
CREATE INDEX idx_sessions_chat ON sessions(channel, chat_id, deleted_at);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、Storage API
|
||||||
|
|
||||||
|
### 4.1 Storage 职责
|
||||||
|
|
||||||
|
- 唯一的持久化 source of truth
|
||||||
|
- 由调用方(GatewayState)构造,通过 `Arc<Storage>` 注入 `SessionManager`
|
||||||
|
- 所有写操作失败后重试 3 次(100ms, 200ms, 300ms 退避),仍失败则触发系统通知告警
|
||||||
|
|
||||||
|
### 4.2 Session 操作
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `new(db_path) -> Storage` | 打开/创建数据库 |
|
||||||
|
| `upsert_session(meta) -> Result<(), StorageError>` | 插入或更新 session 元数据 |
|
||||||
|
| `get_session(id) -> Result<SessionMeta, StorageError>` | 获取单个 session |
|
||||||
|
| `list_sessions(channel, chat_id, limit) -> Result<Vec<SessionMeta>>` | 最近 N 条(供 `/sessions`) |
|
||||||
|
| `delete_session(id) -> Result<(), StorageError>` | 物理删除 session 及关联消息 |
|
||||||
|
| `touch_session(id, message_count, last_active_at)` | 更新计数和最后活跃时间 |
|
||||||
|
|
||||||
|
### 4.3 Message 操作
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `append_message(session_id, msg) -> Result<i64, StorageError>` | 追加单条消息,返回 seq |
|
||||||
|
| `append_messages(session_id, msgs) -> Result<Vec<i64>, StorageError>` | 批量追加 |
|
||||||
|
| `load_messages(session_id, from_seq) -> Result<Vec<MessageMeta>>` | 从指定 seq 加载消息 |
|
||||||
|
| `clear_messages(session_id) -> Result<(), StorageError>` | 清除消息(保留 session) |
|
||||||
|
|
||||||
|
### 4.4 写入失败处理
|
||||||
|
|
||||||
|
```rust
|
||||||
|
async fn append_message_with_retry(&self, session_id: &str, msg: &MessageMeta) -> Result<i64, StorageError> {
|
||||||
|
let delays = [100, 200, 300];
|
||||||
|
for (i, delay) in delays.iter().enumerate() {
|
||||||
|
match self.append_message(session_id, msg) {
|
||||||
|
Ok(seq) => return Ok(seq),
|
||||||
|
Err(e) if i < delays.len() - 1 => {
|
||||||
|
sleep(Duration::from_millis(*delay)).await;
|
||||||
|
tracing::warn!("Storage write failed, retrying: {}", e);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// 全部重试失败后,通过 Session 发送系统通知
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Session 结构
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct Session {
|
||||||
|
pub id: UnifiedSessionId,
|
||||||
|
pub title: String, // 会话标题(用户指定或 LLM 自动生成)
|
||||||
|
pub created_at: i64, // 创建时间(ms)
|
||||||
|
pub last_active_at: i64, // 最后活跃时间(ms)
|
||||||
|
pub message_count: i64, // 用户消息计数(触发 title 自动生成)
|
||||||
|
pub total_message_count: i64, // 含系统消息的总数
|
||||||
|
|
||||||
|
messages: Vec<ChatMessage>, // 内存中的消息历史(压缩后)
|
||||||
|
seq_counter: i64, // 下一个消息的 seq
|
||||||
|
|
||||||
|
provider_config: LLMProviderConfig,
|
||||||
|
provider: Arc<dyn LLMProvider>,
|
||||||
|
tools: Arc<ToolRegistry>,
|
||||||
|
compressor: ContextCompressor,
|
||||||
|
user_tx: mpsc::Sender<WsOutbound>,
|
||||||
|
storage: Arc<Storage>, // 持久化 sink
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.1 初始化流程
|
||||||
|
|
||||||
|
```
|
||||||
|
new() 或 from_storage()
|
||||||
|
↓
|
||||||
|
注入 storage 引用
|
||||||
|
↓
|
||||||
|
创建 provider, tools, compressor
|
||||||
|
↓
|
||||||
|
从 Storage 加载 messages(from_seq = 0)
|
||||||
|
↓
|
||||||
|
设置 seq_counter = messages.len() + 1
|
||||||
|
↓
|
||||||
|
返回 Session 实例
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 消息管理
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub async fn add_message(&mut self, msg: ChatMessage) -> Result<(), StorageError> {
|
||||||
|
// 1. 分配序号: seq = seq_counter; seq_counter += 1
|
||||||
|
// 2. 转换为 MessageMeta
|
||||||
|
// 3. 写入 Storage(重试 + 告警)
|
||||||
|
// 4. 更新内存: messages.push(msg)
|
||||||
|
// 5. 更新计数: message_count / total_message_count += 1
|
||||||
|
// 6. 更新 last_active_at
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 系统通知接口(不记历史)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Session {
|
||||||
|
/// 发送系统通知(不记录进 session 历史)
|
||||||
|
pub async fn send_system_notification(&self, content: &str) {
|
||||||
|
let msg = WsOutbound::SystemNotification {
|
||||||
|
content: content.to_string(),
|
||||||
|
};
|
||||||
|
let _ = self.user_tx.send(msg).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 Title 自动生成
|
||||||
|
|
||||||
|
调用时机:
|
||||||
|
1. Session 首次创建时(初始 title = "Dialog {dialog_id}")
|
||||||
|
2. `message_count` 达到阈值(10 条)且 title 仍为默认值时,自动更新为 LLM 生成
|
||||||
|
3. 用户执行 `/rename` 命令手动更新
|
||||||
|
|
||||||
|
生成 Prompt:
|
||||||
|
```
|
||||||
|
给定以下对话历史,生成一个简短的会话标题(5-15 个中文字符),
|
||||||
|
概括这个对话的核心内容或用户的主要需求。只返回一个标题,不要解释。
|
||||||
|
|
||||||
|
历史:
|
||||||
|
{messages}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、SessionManager 设计
|
||||||
|
|
||||||
|
### 6.1 数据结构
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct SessionManager {
|
||||||
|
inner: Arc<Mutex<SessionManagerInner>>,
|
||||||
|
provider_config: LLMProviderConfig,
|
||||||
|
tools: Arc<ToolRegistry>,
|
||||||
|
skills_loader: Arc<SkillsLoader>,
|
||||||
|
storage: Arc<Storage>, // 由调用方注入
|
||||||
|
cleanup_interval: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SessionManagerInner {
|
||||||
|
sessions: HashMap<String, Arc<Mutex<Session>>>,
|
||||||
|
session_timestamps: HashMap<String, Instant>,
|
||||||
|
session_ttl: Duration,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 handle_message 完整流程
|
||||||
|
|
||||||
|
```
|
||||||
|
handle_message(channel, sender_id, chat_id, dialog_id, content, media)
|
||||||
|
│
|
||||||
|
├── 1. 确定 UnifiedSessionId
|
||||||
|
│ │
|
||||||
|
│ ├── dialog_id 有值 → 直接使用
|
||||||
|
│ │
|
||||||
|
│ └── dialog_id 无值 → 查找 channel:chat_id 下最近活跃的 session
|
||||||
|
│ ├── 找到且未过期 → 使用该 session
|
||||||
|
│ └── 未找到或已过期 → 创建新 session
|
||||||
|
│
|
||||||
|
├── 2. 获取或创建 Session
|
||||||
|
│ 有 → 更新 session_timestamps
|
||||||
|
│ 无 → 从 Storage 恢复 或 创建新 Session
|
||||||
|
│
|
||||||
|
├── 3. 添加用户消息并持久化
|
||||||
|
│ seq = seq_counter; seq_counter += 1
|
||||||
|
│ Storage.append_message()(失败重试 → 仍失败则 send_system_notification)
|
||||||
|
│ messages.push(user_msg)
|
||||||
|
│ message_count += 1
|
||||||
|
│
|
||||||
|
├── 4. 检查 title 自动生成条件
|
||||||
|
│ message_count == 10 → 调用 LLM 生成 → 更新 title → 写回 Storage
|
||||||
|
│
|
||||||
|
├── 5. 注入 skills_prompt(index 0 之后)
|
||||||
|
│
|
||||||
|
├── 6. 新 session 注入欢迎消息(作为系统消息,不计入 message_count)
|
||||||
|
│
|
||||||
|
├── 7. 上下文压缩(如需要)
|
||||||
|
│
|
||||||
|
├── 8. 调用 AgentLoop
|
||||||
|
│
|
||||||
|
├── 9. 保存 Agent 响应消息并持久化(同样流程)
|
||||||
|
│
|
||||||
|
└── 10. 返回最终响应
|
||||||
|
```
|
||||||
|
|
||||||
|
**欢迎消息**(仅新 session 创建时注入历史):
|
||||||
|
```
|
||||||
|
新对话已创建!会话 ID: {dialog_id}
|
||||||
|
使用 /sessions 查看所有对话,/switch <id> 切换对话。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 Dialog 生命周期
|
||||||
|
|
||||||
|
| 操作 | 方法 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 创建 | `create_dialog()` | 生成 dialog_id,创建 Session,写入 Storage |
|
||||||
|
| 列表 | `list_dialogs()` | 从 Storage 读取,limit=10 |
|
||||||
|
| 切换 | `switch_dialog()` | 从 Storage 加载 session,激活到内存 |
|
||||||
|
| 重命名 | `rename_dialog()` | 更新 Storage 和内存 title |
|
||||||
|
| 删除 | `delete_dialog()` | 删除内存 session + 删除 Storage 记录 |
|
||||||
|
| 软重置 | **已删除** | 用户直接 `/new` 开新 session |
|
||||||
|
|
||||||
|
### 6.4 TTL 清理
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn start_cleanup_task(&self) {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
sleep(cleanup_interval).await;
|
||||||
|
self.run_cleanup().await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_cleanup(&self) {
|
||||||
|
// 扫描 session_timestamps
|
||||||
|
// 超时的 session → 从内存 HashMap 移除
|
||||||
|
// Storage 中的 session 记录保留(用户切回可重新加载)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
清理策略:
|
||||||
|
- 内存 session 超时 → 仅释放内存,Storage 记录保留
|
||||||
|
- 用户切换回该 session → 从 Storage 重新加载到内存
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、斜杠命令
|
||||||
|
|
||||||
|
| 命令 | 触发词 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| new | `/new [标题]` | 创建新 dialog |
|
||||||
|
| sessions | `/sessions` | 列出当前 chat 最近 10 条 dialog |
|
||||||
|
| switch | `/switch <dialog_id>` | 切换到指定 dialog |
|
||||||
|
| rename | `/rename <新标题>` | 重命名当前 dialog |
|
||||||
|
| delete | `/delete` | 删除当前 dialog(内存 + Storage) |
|
||||||
|
| compact | `/compact` | 手动触发上下文压缩 |
|
||||||
|
| info | `/info` | 显示当前 dialog 信息 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、错误处理
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum StorageError {
|
||||||
|
NotFound(String),
|
||||||
|
AlreadyExists(String),
|
||||||
|
Database(String),
|
||||||
|
Serialization(String),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 场景 | 处理 |
|
||||||
|
|------|------|
|
||||||
|
| Storage 写入失败 | 重试 3 次 → 发送系统通知告警 |
|
||||||
|
| Storage 读取失败 | 若 session 在内存中,继续使用内存数据 |
|
||||||
|
| Session 不存在 | 创建新 session |
|
||||||
|
| 并发冲突 | SQLite transaction 保护 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、配置项
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"session": {
|
||||||
|
"ttl_hours": 24,
|
||||||
|
"cleanup_interval_minutes": 60,
|
||||||
|
"auto_title_after_n_messages": 10,
|
||||||
|
"storage_retry_delays_ms": [100, 200, 300]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── storage/
|
||||||
|
│ ├── mod.rs # Storage 主模块
|
||||||
|
│ ├── session.rs # Session CRUD
|
||||||
|
│ ├── message.rs # Message CRUD
|
||||||
|
│ └── error.rs # StorageError
|
||||||
|
│
|
||||||
|
└── session/
|
||||||
|
├── mod.rs # 导出 Session, SessionManager
|
||||||
|
├── session.rs # Session, SessionManager 实现
|
||||||
|
├── session_id.rs # UnifiedSessionId(已有)
|
||||||
|
├── commands.rs # SessionCommand(已有)
|
||||||
|
├── events.rs # SessionEvent, DialogInfo(已有)
|
||||||
|
└── error.rs # SessionError(已有)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、实现顺序
|
||||||
|
|
||||||
|
### Phase 1: Storage 基础
|
||||||
|
1. `Storage` 结构和数据库初始化
|
||||||
|
2. Session CRUD(upsert_session, get_session, list_sessions, delete_session)
|
||||||
|
3. Message CRUD(append_message, load_messages)
|
||||||
|
4. 写入失败重试逻辑
|
||||||
|
5. 单元测试
|
||||||
|
|
||||||
|
### Phase 2: Session 扩展
|
||||||
|
1. 扩展 `Session` 结构体(添加 storage 引用、计数字段、seq_counter)
|
||||||
|
2. `add_message` 持久化集成
|
||||||
|
3. `send_system_notification` 接口
|
||||||
|
4. `from_storage()` 恢复逻辑
|
||||||
|
5. Title 自动生成 LLM 调用
|
||||||
|
|
||||||
|
### Phase 3: SessionManager 完善
|
||||||
|
1. 将 `Arc<Storage>` 集成到 `SessionManager`
|
||||||
|
2. 实现 `list_dialogs()`(limit=10)
|
||||||
|
3. 实现 `switch_dialog()`(从 Storage 加载)
|
||||||
|
4. 实现 `delete_dialog()`(内存 + Storage)
|
||||||
|
5. 实现 `rename_dialog()`
|
||||||
|
6. 后台 TTL 清理任务
|
||||||
|
7. 集成测试
|
||||||
|
|
||||||
|
### Phase 4: 斜杠命令
|
||||||
|
1. 实现 `/sessions`(列出最近 10 条)
|
||||||
|
2. 实现 `/switch`
|
||||||
|
3. 实现 `/rename`
|
||||||
|
4. 实现 `/delete`
|
||||||
|
5. 端到端测试
|
||||||
@ -201,32 +201,12 @@ impl SlashCommand {
|
|||||||
pub static SLASH_COMMANDS: &[SlashCommand] = &[
|
pub static SLASH_COMMANDS: &[SlashCommand] = &[
|
||||||
SlashCommand {
|
SlashCommand {
|
||||||
name: "new",
|
name: "new",
|
||||||
description: "Archive current conversation and start a new one",
|
description: "Create a new conversation",
|
||||||
aliases: &["/new"],
|
aliases: &["/new"],
|
||||||
},
|
},
|
||||||
SlashCommand {
|
|
||||||
name: "sessions",
|
|
||||||
description: "List all conversations",
|
|
||||||
aliases: &["/sessions"],
|
|
||||||
},
|
|
||||||
SlashCommand {
|
|
||||||
name: "switch",
|
|
||||||
description: "Switch to a specific conversation by ID",
|
|
||||||
aliases: &["/switch"],
|
|
||||||
},
|
|
||||||
SlashCommand {
|
|
||||||
name: "rename",
|
|
||||||
description: "Rename current conversation",
|
|
||||||
aliases: &["/rename"],
|
|
||||||
},
|
|
||||||
SlashCommand {
|
|
||||||
name: "archive",
|
|
||||||
description: "Archive current conversation",
|
|
||||||
aliases: &["/archive"],
|
|
||||||
},
|
|
||||||
SlashCommand {
|
SlashCommand {
|
||||||
name: "delete",
|
name: "delete",
|
||||||
description: "Delete current conversation",
|
description: "Delete current conversation and start a new one",
|
||||||
aliases: &["/delete"],
|
aliases: &["/delete"],
|
||||||
},
|
},
|
||||||
SlashCommand {
|
SlashCommand {
|
||||||
@ -291,24 +271,6 @@ impl SessionManager {
|
|||||||
let (new_id, title) = self.create_session(channel, chat_id, title.as_deref()).await?;
|
let (new_id, title) = self.create_session(channel, chat_id, title.as_deref()).await?;
|
||||||
Ok((Some(new_id), format!("New conversation '{}' created.", title)))
|
Ok((Some(new_id), format!("New conversation '{}' created.", title)))
|
||||||
}
|
}
|
||||||
"sessions" => {
|
|
||||||
Ok((None, "Fetching sessions list...".to_string()))
|
|
||||||
}
|
|
||||||
"switch" => {
|
|
||||||
let target_id = args
|
|
||||||
.ok_or_else(|| AgentError::Other("Usage: /switch <session_id>".to_string()))?;
|
|
||||||
let unified_id = UnifiedSessionId::parse(target_id)
|
|
||||||
.ok_or_else(|| AgentError::Other("Invalid session ID format".to_string()))?;
|
|
||||||
Ok((Some(unified_id), format!("Switched to session {}", target_id)))
|
|
||||||
}
|
|
||||||
"rename" => {
|
|
||||||
let _title = args
|
|
||||||
.ok_or_else(|| AgentError::Other("Usage: /rename <title>".to_string()))?;
|
|
||||||
Ok((None, "Rename not available in this mode.".to_string()))
|
|
||||||
}
|
|
||||||
"archive" => {
|
|
||||||
Ok((None, "Archive not available in this mode.".to_string()))
|
|
||||||
}
|
|
||||||
"delete" => {
|
"delete" => {
|
||||||
let (new_id, _title) = self.create_session(channel, chat_id, None).await?;
|
let (new_id, _title) = self.create_session(channel, chat_id, None).await?;
|
||||||
Ok((Some(new_id), "Conversation deleted. New conversation created.".to_string()))
|
Ok((Some(new_id), "Conversation deleted. New conversation created.".to_string()))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user