PicoBot/src/command/handlers/list_channels.rs
oudecheng e9e1439428 feat: 添加通道和话题管理功能
后端:
- 新增 ListChannels 命令,列出所有可用通道 (WebSocket/CLI)
- 新增 ListSessionsByChannel 命令,支持按通道筛选会话
- 新增 ListTopics 命令,列出 Session 的所有 Topics
- 添加 Channel 和 TopicSummary 数据结构
- 更新 WebSocket 协议,支持 channel_list 和 topic_list 消息

前端:
- 新增 ChannelSelector 组件用于通道选择
- 新增 SessionSelector 组件用于会话选择
- 更新 TopicList 组件支持话题展示
- 更新 useChat hook 和协议类型定义

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:55:09 +08:00

76 lines
2.2 KiB
Rust

use crate::command::context::CommandContext;
use crate::command::handler::{CommandHandler, CommandMetadata};
use crate::command::response::{CommandError, CommandResponse, MessageKind};
use crate::command::Command;
use crate::protocol::Channel;
use async_trait::async_trait;
/// 列出通道命令处理器
pub struct ListChannelsCommandHandler;
impl ListChannelsCommandHandler {
pub fn new() -> Self {
Self
}
/// 获取默认通道列表(公开供其他模块使用)
pub fn get_default_channels() -> Vec<Channel> {
vec![
Channel {
id: "websocket".to_string(),
name: "WebSocket".to_string(),
description: Some("Web 前端通道".to_string()),
is_writable: true,
},
Channel {
id: "cli".to_string(),
name: "命令行".to_string(),
description: Some("CLI 命令行通道".to_string()),
is_writable: false,
},
]
}
}
#[async_trait]
impl CommandHandler for ListChannelsCommandHandler {
fn can_handle(&self, cmd: &Command) -> bool {
matches!(cmd, Command::ListChannels)
}
fn metadata(&self) -> Option<CommandMetadata> {
Some(CommandMetadata {
name: "channels",
description: "列出所有可用通道",
usage: "/channels",
})
}
async fn handle(
&self,
cmd: Command,
ctx: CommandContext,
) -> Result<CommandResponse, CommandError> {
match cmd {
Command::ListChannels => handle_list_channels(ctx).await,
_ => unreachable!(),
}
}
}
async fn handle_list_channels(
ctx: CommandContext,
) -> Result<CommandResponse, CommandError> {
let channels = ListChannelsCommandHandler::get_default_channels();
let channels_json = serde_json::to_string(&channels)
.map_err(|e| CommandError::new("SERIALIZE_ERROR", e.to_string()))?;
let message = format!("Available channels: {}", channels.len());
Ok(CommandResponse::success(ctx.request_id)
.with_message(MessageKind::Notification, &message)
.with_metadata("channels", &channels_json)
.with_metadata("count", &channels.len().to_string()))
}