Some checks failed
BotServer CI / build (push) Failing after 1m34s
Split 20+ files over 1000 lines into focused subdirectories for better maintainability and code organization. All changes maintain backward compatibility through re-export wrappers. Major splits: - attendance/llm_assist.rs (2074→7 modules) - basic/keywords/face_api.rs → face_api/ (7 modules) - basic/keywords/file_operations.rs → file_ops/ (8 modules) - basic/keywords/hear_talk.rs → hearing/ (6 modules) - channels/wechat.rs → wechat/ (10 modules) - channels/youtube.rs → youtube/ (5 modules) - contacts/mod.rs → contacts_api/ (6 modules) - core/bootstrap/mod.rs → bootstrap/ (5 modules) - core/shared/admin.rs → admin_*.rs (5 modules) - designer/canvas.rs → canvas_api/ (6 modules) - designer/mod.rs → designer_api/ (6 modules) - docs/handlers.rs → handlers_api/ (11 modules) - drive/mod.rs → drive_handlers.rs, drive_types.rs - learn/mod.rs → types.rs - main.rs → main_module/ (7 modules) - meet/webinar.rs → webinar_api/ (8 modules) - paper/mod.rs → (10 modules) - security/auth.rs → auth_api/ (7 modules) - security/passkey.rs → (4 modules) - sources/mod.rs → sources_api/ (5 modules) - tasks/mod.rs → task_api/ (5 modules) Stats: 38,040 deletions, 1,315 additions across 318 files Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
123 lines
4.8 KiB
Rust
123 lines
4.8 KiB
Rust
use crate::core::shared::message_types::MessageType;
|
|
use crate::core::shared::models::BotResponse;
|
|
use crate::core::shared::state::AppState;
|
|
use color_eyre::Result;
|
|
use std::sync::Arc;
|
|
use tokio::sync::mpsc;
|
|
use uuid::Uuid;
|
|
pub struct ChatPanel {
|
|
pub messages: Vec<String>,
|
|
pub input_buffer: String,
|
|
pub session_id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub response_rx: Option<mpsc::Receiver<BotResponse>>,
|
|
}
|
|
|
|
impl std::fmt::Debug for ChatPanel {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.debug_struct("ChatPanel")
|
|
.field("messages_count", &self.messages.len())
|
|
.field("input_buffer_len", &self.input_buffer.len())
|
|
.field("session_id", &self.session_id)
|
|
.field("user_id", &self.user_id)
|
|
.field("has_response_rx", &self.response_rx.is_some())
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl ChatPanel {
|
|
pub fn new(_app_state: Arc<AppState>) -> Self {
|
|
Self {
|
|
messages: vec!["Welcome to General Bots Console Chat!".to_string()],
|
|
input_buffer: String::new(),
|
|
session_id: Uuid::new_v4(),
|
|
user_id: Uuid::new_v4(),
|
|
response_rx: None,
|
|
}
|
|
}
|
|
pub fn add_char(&mut self, c: char) {
|
|
self.input_buffer.push(c);
|
|
}
|
|
pub fn backspace(&mut self) {
|
|
self.input_buffer.pop();
|
|
}
|
|
pub async fn send_message(&mut self, bot_name: &str, app_state: &Arc<AppState>) -> Result<()> {
|
|
if self.input_buffer.trim().is_empty() {
|
|
return Ok(());
|
|
}
|
|
let message = self.input_buffer.clone();
|
|
self.messages.push(format!("You: {}", message));
|
|
self.input_buffer.clear();
|
|
let bot_id = Self::get_bot_id(bot_name, app_state)?;
|
|
let user_message = crate::core::shared::models::UserMessage {
|
|
bot_id: bot_id.to_string(),
|
|
user_id: self.user_id.to_string(),
|
|
session_id: self.session_id.to_string(),
|
|
channel: "console".to_string(),
|
|
content: message,
|
|
message_type: MessageType::USER,
|
|
media_url: None,
|
|
timestamp: chrono::Utc::now(),
|
|
context_name: None,
|
|
};
|
|
let (tx, rx) = mpsc::channel::<BotResponse>(100);
|
|
self.response_rx = Some(rx);
|
|
let orchestrator = crate::core::bot::BotOrchestrator::new(app_state.clone());
|
|
let _ = orchestrator.stream_response(user_message, tx).await;
|
|
Ok(())
|
|
}
|
|
pub fn poll_response(&mut self, _bot_name: &str) -> Result<()> {
|
|
if let Some(rx) = &mut self.response_rx {
|
|
while let Ok(response) = rx.try_recv() {
|
|
if !response.content.is_empty() && !response.is_complete {
|
|
if let Some(last_msg) = self.messages.last_mut() {
|
|
if last_msg.starts_with("Bot: ") {
|
|
last_msg.push_str(&response.content);
|
|
} else {
|
|
self.messages.push(format!("Bot: {}", response.content));
|
|
}
|
|
} else {
|
|
self.messages.push(format!("Bot: {}", response.content));
|
|
}
|
|
}
|
|
if response.is_complete && response.content.is_empty() {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
fn get_bot_id(bot_name: &str, app_state: &Arc<AppState>) -> Result<Uuid> {
|
|
use crate::core::shared::models::schema::bots::dsl::*;
|
|
use diesel::prelude::*;
|
|
let mut conn = app_state.conn.get()
|
|
.map_err(|e| color_eyre::eyre::eyre!("Failed to get db connection: {e}"))?;
|
|
let bot_id = bots
|
|
.filter(name.eq(bot_name))
|
|
.select(id)
|
|
.first::<Uuid>(&mut *conn)?;
|
|
Ok(bot_id)
|
|
}
|
|
pub fn render(&self) -> String {
|
|
let mut lines = vec![
|
|
"╔═══════════════════════════════════════╗".to_string(),
|
|
"║ CONVERSATION ║".to_string(),
|
|
"╚═══════════════════════════════════════╝".to_string(),
|
|
String::new(),
|
|
];
|
|
let visible_start = if self.messages.len() > 15 {
|
|
self.messages.len() - 15
|
|
} else {
|
|
0
|
|
};
|
|
for msg in &self.messages[visible_start..] {
|
|
lines.push(format!(" {}", msg));
|
|
}
|
|
lines.push("".to_string());
|
|
lines.push("─────────────────────────────────────────".to_string());
|
|
lines.push(format!(" > {}_", self.input_buffer));
|
|
lines.push("".to_string());
|
|
lines.push(" Enter: Send | Tab: Switch Panel".to_string());
|
|
lines.join("\n")
|
|
}
|
|
}
|