diff --git a/src/basic/mod.rs b/src/basic/mod.rs index 74cb7345..b345f0ec 100644 --- a/src/basic/mod.rs +++ b/src/basic/mod.rs @@ -331,8 +331,12 @@ impl ScriptService { pub fn run(&mut self, ast_content: &str) -> Result> { let ast = match self.engine.compile(ast_content) { Ok(ast) => ast, - Err(e) => return Err(Box::new(e.into())), + Err(e) => { + log::error!("[BASIC_EXEC] Failed to compile AST: {}", e); + return Err(Box::new(e.into())); + } }; + log::trace!("[BASIC_EXEC] Executing compiled AST ({} chars)", ast_content.len()); self.engine.eval_ast_with_scope(&mut self.scope, &ast) } diff --git a/src/core/bot/tool_executor.rs b/src/core/bot/tool_executor.rs index 58831fcf..e6c59678 100644 --- a/src/core/bot/tool_executor.rs +++ b/src/core/bot/tool_executor.rs @@ -257,6 +257,7 @@ impl ToolExecutor { arguments: &Value, ) -> ToolExecutionResult { let tool_call_id = format!("tool_{}", uuid::Uuid::new_v4()); + log::info!("[BASIC_EXEC] Tool '{}' starting execution (bot={}, session={})", tool_name, bot_name, session.id); // Create ScriptService let mut script_service = ScriptService::new(state.clone(), session.clone()); @@ -276,15 +277,17 @@ impl ToolExecutor { // Set variable in script scope if let Err(e) = script_service.set_variable(key, &value_str) { - warn!("Failed to set variable '{}': {}", key, e); + log::warn!("[BASIC_EXEC] Failed to set variable '{}': {}", key, e); } } } + log::trace!("[BASIC_EXEC] Tool '{}' running .ast ({} chars)", tool_name, ast_content.len()); + // Run the pre-compiled .ast content (compilation happens only in Drive Monitor) match script_service.run(ast_content) { Ok(result) => { - trace!("Tool '{}' executed successfully", tool_name); + log::info!("[BASIC_EXEC] Tool '{}' completed successfully", tool_name); // Convert result to string let result_str = result.to_string(); @@ -297,6 +300,7 @@ impl ToolExecutor { } } Err(e) => { + log::error!("[BASIC_EXEC] Tool '{}' execution error: {}", tool_name, e); let error_msg = format!("Execution error: {}", e); Self::log_tool_error(bot_name, tool_name, &error_msg); let user_message = Self::format_user_friendly_error(tool_name, &error_msg); diff --git a/src/llm/glm.rs b/src/llm/glm.rs index 67cb4225..e6aa7bb9 100644 --- a/src/llm/glm.rs +++ b/src/llm/glm.rs @@ -316,14 +316,12 @@ impl LLMProvider for GLMClient { } } - // GLM-4.7 on NVIDIA sends text via reasoning_content when thinking is enabled - // content may be null; we accept both fields - let content = delta.get("content").and_then(|c| c.as_str()) - .or_else(|| delta.get("reasoning_content").and_then(|c| c.as_str())); - - if let Some(text) = content { - if !text.is_empty() { - match tx.send(text.to_string()).await { + // GLM-4.7 on NVIDIA sends thinking text via reasoning_content + // The actual user-facing response is in content field + // We ONLY send content — never reasoning_content (internal thinking) + if let Some(content) = delta.get("content").and_then(|c| c.as_str()) { + if !content.is_empty() { + match tx.send(content.to_string()).await { Ok(_) => {}, Err(e) => { error!("Failed to send to channel: {}", e); diff --git a/src/llm/kimi.rs b/src/llm/kimi.rs index 20b60bf3..a282e6e8 100644 --- a/src/llm/kimi.rs +++ b/src/llm/kimi.rs @@ -312,12 +312,10 @@ impl LLMProvider for KimiClient { } } - // Kimi K2.5 sends text via reasoning_content (thinking mode) - // content may be null; we accept both fields - let text = delta.get("content").and_then(|c| c.as_str()) - .or_else(|| delta.get("reasoning_content").and_then(|c| c.as_str())); - - if let Some(text) = text { + // Kimi K2.5 sends thinking via reasoning_content + // The actual user-facing response is in content field + // We ONLY send content — never reasoning_content (internal thinking) + if let Some(text) = delta.get("content").and_then(|c| c.as_str()) { if !text.is_empty() { let _ = tx.send(text.to_string()).await; } diff --git a/src/tasks/scheduler.rs b/src/tasks/scheduler.rs index 68967135..955e4283 100644 --- a/src/tasks/scheduler.rs +++ b/src/tasks/scheduler.rs @@ -335,10 +335,14 @@ impl TaskScheduler { let registry = self.task_registry.clone(); let running_tasks = self.running_tasks.clone(); + log::info!("[BASIC_EXEC] Scheduled task '{}' starting execution (task_id={}, type={})", task.name, task_id, task.task_type); + let handle = tokio::spawn(async move { let execution_id = Uuid::new_v4(); let started_at = Utc::now(); + log::trace!("[BASIC_EXEC] Task '{}' execution_id={}, started_at={}", task.name, execution_id, started_at); + let _execution = TaskExecution { id: execution_id, scheduled_task_id: task_id, diff --git a/src/whatsapp/mod.rs b/src/whatsapp/mod.rs index 5216cbc7..4c315da3 100644 --- a/src/whatsapp/mod.rs +++ b/src/whatsapp/mod.rs @@ -254,6 +254,7 @@ pub async fn handle_webhook( Err(err) => return err.0, }; + log::info!("[BASIC_EXEC] WhatsApp webhook received for bot_id={}", bot_id); debug!("Raw webhook body: {}", String::from_utf8_lossy(&body)); let payload: WhatsAppWebhook = match serde_json::from_slice(&body) {