optimize: Enhanced session command processing logic

This commit is contained in:
xintaofei
2026-04-01 17:22:56 +08:00
parent adb5829613
commit d76dc716e4
15 changed files with 106 additions and 344 deletions

View File

@@ -170,7 +170,6 @@ async fn dispatch_command(
match command.as_str() {
// Existing commands
"recent" => command_handlers::handle_recent(db, lang).await,
"search" => {
if args.is_empty() {
super::types::RichMessage::info(i18n::search_usage(lang, prefix))
@@ -179,14 +178,6 @@ async fn dispatch_command(
command_handlers::handle_search(db, args, lang).await
}
}
"detail" => {
if let Ok(id) = args.parse::<i32>() {
command_handlers::handle_detail(db, id, lang).await
} else {
super::types::RichMessage::info(i18n::detail_usage(lang, prefix))
.with_title(i18n::invalid_args_title(lang))
}
}
"today" => command_handlers::handle_today(db, lang).await,
"status" => command_handlers::handle_status(manager, lang).await,
"help" | "start" => command_handlers::handle_help(prefix, lang),

View File

@@ -6,48 +6,6 @@ use super::manager::ChatChannelManager;
use super::types::{MessageLevel, RichMessage};
use crate::db::entities::conversation;
pub async fn handle_recent(db: &DatabaseConnection, lang: Lang) -> RichMessage {
let recent = match conversation::Entity::find()
.filter(conversation::Column::DeletedAt.is_null())
.order_by_desc(conversation::Column::CreatedAt)
.limit(5)
.all(db)
.await
{
Ok(rows) => rows,
Err(e) => {
return RichMessage {
title: Some(i18n::query_failed_title(lang).to_string()),
body: e.to_string(),
fields: Vec::new(),
level: MessageLevel::Error,
};
}
};
if recent.is_empty() {
return RichMessage::info(i18n::no_conversations(lang))
.with_title(i18n::recent_conversations_title(lang));
}
let mut body = String::new();
for (i, conv) in recent.iter().enumerate() {
let title = conv.title.as_deref().unwrap_or(i18n::untitled(lang));
let agent = &conv.agent_type;
let time = conv.created_at.format("%m-%d %H:%M");
body.push_str(&format!(
"{}. [{}] {} ({})\n",
i + 1,
agent,
title,
time
));
}
RichMessage::info(body.trim_end())
.with_title(i18n::recent_n_conversations_title(lang, recent.len()))
}
pub async fn handle_search(
db: &DatabaseConnection,
keyword: &str,
@@ -78,15 +36,13 @@ pub async fn handle_search(
}
let mut body = String::new();
for (i, conv) in matched.iter().enumerate() {
for conv in &matched {
let title = conv.title.as_deref().unwrap_or(i18n::untitled(lang));
let agent = &conv.agent_type;
let time = conv.created_at.format("%m-%d %H:%M");
body.push_str(&format!(
"{}. [{}] {} (ID:{})\n",
i + 1,
agent,
title,
conv.id
"#{} [{}] {} ({})\n",
conv.id, agent, title, time,
));
}
@@ -97,46 +53,6 @@ pub async fn handle_search(
))
}
pub async fn handle_detail(
db: &DatabaseConnection,
conversation_id: i32,
lang: Lang,
) -> RichMessage {
let conv = match conversation::Entity::find_by_id(conversation_id)
.filter(conversation::Column::DeletedAt.is_null())
.one(db)
.await
{
Ok(Some(c)) => c,
Ok(None) => {
return RichMessage::info(i18n::conversation_not_found(lang, conversation_id))
.with_title(i18n::not_found_title(lang));
}
Err(e) => {
return RichMessage {
title: Some(i18n::query_failed_title(lang).to_string()),
body: e.to_string(),
fields: Vec::new(),
level: MessageLevel::Error,
};
}
};
let title = conv.title.as_deref().unwrap_or(i18n::untitled(lang));
RichMessage::info(title)
.with_title(i18n::conversation_detail_title(lang, conv.id))
.with_field(i18n::field_agent(lang), &conv.agent_type)
.with_field(i18n::field_status(lang), format!("{:?}", conv.status))
.with_field(
i18n::field_message_count(lang),
conv.message_count.to_string(),
)
.with_field(
i18n::field_created_at(lang),
conv.created_at.format("%Y-%m-%d %H:%M").to_string(),
)
}
pub async fn handle_today(db: &DatabaseConnection, lang: Lang) -> RichMessage {
let now = Utc::now();
let today_start = now

View File

@@ -280,36 +280,6 @@ pub fn query_failed_title(lang: Lang) -> &'static str {
}
}
pub fn no_conversations(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "暂无会话记录",
Lang::ZhTw => "暫無對話記錄",
Lang::Ja => "セッション履歴なし",
Lang::Ko => "대화 기록 없음",
Lang::Es => "Sin conversaciones",
Lang::De => "Keine Sitzungen",
Lang::Fr => "Aucune session",
Lang::Pt => "Nenhuma sessão",
Lang::Ar => "لا توجد جلسات",
Lang::En => "No conversations found",
}
}
pub fn recent_conversations_title(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "最近会话",
Lang::ZhTw => "最近對話",
Lang::Ja => "最近のセッション",
Lang::Ko => "최근 대화",
Lang::Es => "Conversaciones recientes",
Lang::De => "Letzte Sitzungen",
Lang::Fr => "Sessions récentes",
Lang::Pt => "Sessões recentes",
Lang::Ar => "الجلسات الأخيرة",
Lang::En => "Recent Conversations",
}
}
pub fn untitled(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "(无标题)",
@@ -325,21 +295,6 @@ pub fn untitled(lang: Lang) -> &'static str {
}
}
pub fn recent_n_conversations_title(lang: Lang, n: usize) -> String {
match lang {
Lang::ZhCn => format!("最近 {n} 条会话"),
Lang::ZhTw => format!("最近 {n} 條對話"),
Lang::Ja => format!("最新 {n} セッション"),
Lang::Ko => format!("최근 {n}개 대화"),
Lang::Es => format!("{n} conversaciones más recientes"),
Lang::De => format!("Letzte {n} Sitzungen"),
Lang::Fr => format!("{n} dernières sessions"),
Lang::Pt => format!("{n} sessões mais recentes"),
Lang::Ar => format!("أحدث {n} جلسات"),
Lang::En => format!("{n} Most Recent Conversations"),
}
}
pub fn search_no_results(lang: Lang, keyword: &str) -> String {
match lang {
Lang::ZhCn => format!("未找到包含 \"{keyword}\" 的会话"),
@@ -385,110 +340,6 @@ pub fn search_results_count_title(lang: Lang, keyword: &str, count: usize) -> St
}
}
pub fn conversation_not_found(lang: Lang, id: i32) -> String {
match lang {
Lang::ZhCn => format!("会话 {id} 不存在"),
Lang::ZhTw => format!("對話 {id} 不存在"),
Lang::Ja => format!("セッション {id} が見つかりません"),
Lang::Ko => format!("대화 {id}를 찾을 수 없습니다"),
Lang::Es => format!("Conversación {id} no encontrada"),
Lang::De => format!("Sitzung {id} nicht gefunden"),
Lang::Fr => format!("Session {id} introuvable"),
Lang::Pt => format!("Sessão {id} não encontrada"),
Lang::Ar => format!("الجلسة {id} غير موجودة"),
Lang::En => format!("Conversation {id} not found"),
}
}
pub fn not_found_title(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "未找到",
Lang::ZhTw => "未找到",
Lang::Ja => "見つかりません",
Lang::Ko => "찾을 수 없음",
Lang::Es => "No encontrado",
Lang::De => "Nicht gefunden",
Lang::Fr => "Introuvable",
Lang::Pt => "Não encontrado",
Lang::Ar => "غير موجود",
Lang::En => "Not Found",
}
}
pub fn conversation_detail_title(lang: Lang, id: i32) -> String {
match lang {
Lang::ZhCn => format!("会话详情 #{id}"),
Lang::ZhTw => format!("對話詳情 #{id}"),
Lang::Ja => format!("セッション詳細 #{id}"),
Lang::Ko => format!("대화 상세 #{id}"),
Lang::Es => format!("Detalles #{id}"),
Lang::De => format!("Sitzungsdetails #{id}"),
Lang::Fr => format!("Détails #{id}"),
Lang::Pt => format!("Detalhes #{id}"),
Lang::Ar => format!("تفاصيل الجلسة #{id}"),
Lang::En => format!("Conversation Details #{id}"),
}
}
pub fn field_agent(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "代理",
Lang::ZhTw => "代理",
Lang::Ja => "エージェント",
Lang::Ko => "에이전트",
Lang::Es => "Agente",
Lang::De => "Agent",
Lang::Fr => "Agent",
Lang::Pt => "Agente",
Lang::Ar => "الوكيل",
Lang::En => "Agent",
}
}
pub fn field_status(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "状态",
Lang::ZhTw => "狀態",
Lang::Ja => "ステータス",
Lang::Ko => "상태",
Lang::Es => "Estado",
Lang::De => "Status",
Lang::Fr => "Statut",
Lang::Pt => "Status",
Lang::Ar => "الحالة",
Lang::En => "Status",
}
}
pub fn field_message_count(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "消息数",
Lang::ZhTw => "訊息數",
Lang::Ja => "メッセージ数",
Lang::Ko => "메시지 수",
Lang::Es => "Mensajes",
Lang::De => "Nachrichten",
Lang::Fr => "Messages",
Lang::Pt => "Mensagens",
Lang::Ar => "عدد الرسائل",
Lang::En => "Messages",
}
}
pub fn field_created_at(lang: Lang) -> &'static str {
match lang {
Lang::ZhCn => "创建时间",
Lang::ZhTw => "建立時間",
Lang::Ja => "作成日時",
Lang::Ko => "생성 시간",
Lang::Es => "Creado",
Lang::De => "Erstellt",
Lang::Fr => "Créé",
Lang::Pt => "Criado",
Lang::Ar => "تاريخ الإنشاء",
Lang::En => "Created",
}
}
pub fn no_activity_today(lang: Lang) -> &'static str {
match lang {
@@ -614,14 +465,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - 选择 Agent\n\
{prefix}task <描述> - 创建会话并执行任务\n\
{prefix}sessions - 当前目录的活跃会话\n\
{prefix}resume <ID> - 恢复已有会话\n\
{prefix}resume [ID] - 最近会话 / 恢复指定会话\n\
{prefix}cancel - 取消当前任务\n\
{prefix}approve [always] - 批准权限请求\n\
{prefix}deny - 拒绝权限请求\n\
\n\
{prefix}recent - 最近 5 条会话\n\
{prefix}search <关键词> - 搜索会话\n\
{prefix}detail <ID> - 会话详情\n\
{prefix}today - 今日活动汇总\n\
{prefix}status - 渠道连接状态\n\
{prefix}help - 显示帮助\n\
@@ -633,14 +482,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - 選擇 Agent\n\
{prefix}task <描述> - 建立對話並執行任務\n\
{prefix}sessions - 當前目錄的活躍對話\n\
{prefix}resume <ID> - 恢復已有對話\n\
{prefix}resume [ID] - 最近對話 / 恢復指定對話\n\
{prefix}cancel - 取消當前任務\n\
{prefix}approve [always] - 批准權限請求\n\
{prefix}deny - 拒絕權限請求\n\
\n\
{prefix}recent - 最近 5 條對話\n\
{prefix}search <關鍵字> - 搜尋對話\n\
{prefix}detail <ID> - 對話詳情\n\
{prefix}today - 今日活動匯總\n\
{prefix}status - 頻道連線狀態\n\
{prefix}help - 顯示幫助\n\
@@ -652,14 +499,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - エージェントを選択\n\
{prefix}task <説明> - セッションを作成してタスクを実行\n\
{prefix}sessions - フォルダ内のアクティブセッション\n\
{prefix}resume <ID> - セッションを再開\n\
{prefix}resume [ID] - 最近のセッション / セッションを再開\n\
{prefix}cancel - 現在のタスクをキャンセル\n\
{prefix}approve [always] - 権限を承認\n\
{prefix}deny - 権限を拒否\n\
\n\
{prefix}recent - 最新5件のセッション\n\
{prefix}search <キーワード> - セッション検索\n\
{prefix}detail <ID> - セッション詳細\n\
{prefix}today - 本日の活動まとめ\n\
{prefix}status - チャンネル接続状況\n\
{prefix}help - ヘルプを表示\n\
@@ -671,14 +516,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - 에이전트 선택\n\
{prefix}task <설명> - 세션 생성 및 작업 실행\n\
{prefix}sessions - 폴더 내 활성 세션\n\
{prefix}resume <ID> - 세션 재개\n\
{prefix}resume [ID] - 최근 대화 / 세션 재개\n\
{prefix}cancel - 현재 작업 취소\n\
{prefix}approve [always] - 권한 승인\n\
{prefix}deny - 권한 거부\n\
\n\
{prefix}recent - 최근 5개 대화\n\
{prefix}search <키워드> - 대화 검색\n\
{prefix}detail <ID> - 대화 상세\n\
{prefix}today - 오늘의 활동 요약\n\
{prefix}status - 채널 연결 상태\n\
{prefix}help - 도움말 표시\n\
@@ -690,14 +533,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - Seleccionar agente\n\
{prefix}task <desc> - Crear sesion y ejecutar tarea\n\
{prefix}sessions - Sesiones activas en la carpeta\n\
{prefix}resume <ID> - Reanudar una sesion\n\
{prefix}resume [ID] - Recientes / reanudar una sesion\n\
{prefix}cancel - Cancelar tarea actual\n\
{prefix}approve [always] - Aprobar permiso\n\
{prefix}deny - Denegar permiso\n\
\n\
{prefix}recent - 5 conversaciones mas recientes\n\
{prefix}search <palabra> - Buscar conversaciones\n\
{prefix}detail <ID> - Detalles de conversacion\n\
{prefix}today - Resumen de hoy\n\
{prefix}status - Estado de canales\n\
{prefix}help - Mostrar ayuda\n\
@@ -709,14 +550,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - Agent auswahlen\n\
{prefix}task <Beschreibung> - Sitzung erstellen und Aufgabe ausfuhren\n\
{prefix}sessions - Aktive Sitzungen im Ordner\n\
{prefix}resume <ID> - Sitzung fortsetzen\n\
{prefix}resume [ID] - Neueste Sitzungen / Sitzung fortsetzen\n\
{prefix}cancel - Aktuelle Aufgabe abbrechen\n\
{prefix}approve [always] - Berechtigung genehmigen\n\
{prefix}deny - Berechtigung verweigern\n\
\n\
{prefix}recent - 5 neueste Sitzungen\n\
{prefix}search <Stichwort> - Sitzungen suchen\n\
{prefix}detail <ID> - Sitzungsdetails\n\
{prefix}today - Heutige Zusammenfassung\n\
{prefix}status - Kanalstatus\n\
{prefix}help - Hilfe anzeigen\n\
@@ -728,14 +567,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - Selectionner l'agent\n\
{prefix}task <desc> - Creer une session et executer une tache\n\
{prefix}sessions - Sessions actives dans le dossier\n\
{prefix}resume <ID> - Reprendre une session\n\
{prefix}resume [ID] - Sessions recentes / reprendre une session\n\
{prefix}cancel - Annuler la tache en cours\n\
{prefix}approve [always] - Approuver la permission\n\
{prefix}deny - Refuser la permission\n\
\n\
{prefix}recent - 5 dernieres sessions\n\
{prefix}search <mot-cle> - Rechercher des sessions\n\
{prefix}detail <ID> - Details de la session\n\
{prefix}today - Resume du jour\n\
{prefix}status - Statut des canaux\n\
{prefix}help - Afficher l'aide\n\
@@ -747,14 +584,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - Selecionar agente\n\
{prefix}task <desc> - Criar sessao e executar tarefa\n\
{prefix}sessions - Sessoes ativas na pasta\n\
{prefix}resume <ID> - Retomar uma sessao\n\
{prefix}resume [ID] - Recentes / retomar uma sessao\n\
{prefix}cancel - Cancelar tarefa atual\n\
{prefix}approve [always] - Aprovar permissao\n\
{prefix}deny - Negar permissao\n\
\n\
{prefix}recent - 5 sessoes mais recentes\n\
{prefix}search <palavra> - Buscar sessoes\n\
{prefix}detail <ID> - Detalhes da sessao\n\
{prefix}today - Resumo de hoje\n\
{prefix}status - Status dos canais\n\
{prefix}help - Mostrar ajuda\n\
@@ -766,14 +601,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - اختيار الوكيل\n\
{prefix}task <وصف> - انشاء جلسة وتنفيذ مهمة\n\
{prefix}sessions - الجلسات النشطة في المجلد\n\
{prefix}resume <ID> - استئناف جلسة\n\
{prefix}resume [ID] - الجلسات الاخيرة / استئناف جلسة\n\
{prefix}cancel - الغاء المهمة الحالية\n\
{prefix}approve [always] - الموافقة على الاذن\n\
{prefix}deny - رفض الاذن\n\
\n\
{prefix}recent - احدث 5 جلسات\n\
{prefix}search <كلمة> - البحث في الجلسات\n\
{prefix}detail <ID> - تفاصيل الجلسة\n\
{prefix}today - ملخص اليوم\n\
{prefix}status - حالة القنوات\n\
{prefix}help - عرض المساعدة\n\
@@ -785,14 +618,12 @@ pub fn help_body(lang: Lang, prefix: &str) -> String {
{prefix}agent - Select agent\n\
{prefix}task <desc> - Create session & run task\n\
{prefix}sessions - Active sessions in folder\n\
{prefix}resume <ID> - Resume a session\n\
{prefix}resume [ID] - Recent conversations / resume a session\n\
{prefix}cancel - Cancel current task\n\
{prefix}approve [always] - Approve permission\n\
{prefix}deny - Deny permission\n\
\n\
{prefix}recent - 5 most recent conversations\n\
{prefix}search <keyword> - Search conversations\n\
{prefix}detail <ID> - Conversation details\n\
{prefix}today - Today's activity summary\n\
{prefix}status - Channel connection status\n\
{prefix}help - Show help\n\
@@ -834,21 +665,6 @@ pub fn search_usage(lang: Lang, prefix: &str) -> String {
}
}
pub fn detail_usage(lang: Lang, prefix: &str) -> String {
match lang {
Lang::ZhCn => format!("用法: {prefix}detail <会话ID>"),
Lang::ZhTw => format!("用法: {prefix}detail <對話ID>"),
Lang::Ja => format!("使い方: {prefix}detail <セッションID>"),
Lang::Ko => format!("사용법: {prefix}detail <대화ID>"),
Lang::Es => format!("Uso: {prefix}detail <ID>"),
Lang::De => format!("Verwendung: {prefix}detail <ID>"),
Lang::Fr => format!("Utilisation : {prefix}detail <ID>"),
Lang::Pt => format!("Uso: {prefix}detail <ID>"),
Lang::Ar => format!("الاستخدام: {prefix}detail <ID>"),
Lang::En => format!("Usage: {prefix}detail <ID>"),
}
}
pub fn unknown_command(lang: Lang, prefix: &str, command: &str) -> String {
match lang {
Lang::ZhCn => format!(

View File

@@ -2,12 +2,12 @@ use std::collections::BTreeMap;
use std::sync::Arc;
use std::time::Instant;
use sea_orm::DatabaseConnection;
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
use tokio::sync::Mutex;
use super::i18n::Lang;
use super::i18n::{self, Lang};
use super::session_bridge::{ActiveSession, SessionBridge};
use super::types::RichMessage;
use super::types::{MessageLevel, RichMessage};
use crate::acp::manager::ConnectionManager;
use crate::acp::registry::all_acp_agents;
use crate::acp::types::PromptInputBlock;
@@ -476,7 +476,7 @@ pub async fn handle_sessions(
lang,
prefix,
"Reply {prefix}resume <id> to continue.",
"回复 {prefix}resume <ID> 继续会话。"
"回复 {prefix}resume <会话ID> 继续会话。"
)
));
@@ -501,15 +501,14 @@ pub async fn handle_resume(
lang: Lang,
prefix: &str,
) -> RichMessage {
if args.is_empty() {
return list_recent_sessions(db, lang, prefix).await;
}
let conversation_id: i32 = match args.parse() {
Ok(id) => id,
Err(_) => {
return RichMessage::info(tp(
lang,
prefix,
"Usage: {prefix}resume <conversation_id>",
"用法: {prefix}resume <会话ID>",
));
return list_recent_sessions(db, lang, prefix).await;
}
};
@@ -825,6 +824,68 @@ pub async fn handle_followup(
RichMessage::info(t(lang, "Message sent.", "消息已发送。"))
}
// ── /resume (list recent) ──
async fn list_recent_sessions(
db: &DatabaseConnection,
lang: Lang,
prefix: &str,
) -> RichMessage {
let recent = match conversation::Entity::find()
.filter(conversation::Column::DeletedAt.is_null())
.order_by_desc(conversation::Column::CreatedAt)
.limit(10)
.all(db)
.await
{
Ok(rows) => rows,
Err(e) => {
return RichMessage {
title: Some(i18n::query_failed_title(lang).to_string()),
body: e.to_string(),
fields: Vec::new(),
level: MessageLevel::Error,
};
}
};
if recent.is_empty() {
return RichMessage::info(t(
lang,
"No conversations found.",
"暂无会话记录。",
))
.with_title(t(lang, "Recent Conversations", "最近会话"));
}
let mut body = String::new();
for conv in &recent {
let title = conv.title.as_deref().unwrap_or(i18n::untitled(lang));
let agent = &conv.agent_type;
let time = conv.created_at.format("%m-%d %H:%M");
body.push_str(&format!(
"#{} [{}] {} ({})\n",
conv.id, agent, title, time,
));
}
body.push_str(&format!(
"\n{}",
tp(
lang,
prefix,
"Reply {prefix}resume <id> to resume a session.",
"回复 {prefix}resume <会话ID> 恢复会话。"
)
));
RichMessage::info(body.trim_end()).with_title(t(
lang,
"Recent Conversations",
"最近会话",
))
}
// ── Helpers ──
fn t(lang: Lang, en: &str, zh: &str) -> String {