diff --git a/server/src/chat/transport/matrix/bot/messages.rs b/server/src/chat/transport/matrix/bot/messages.rs index 26dc17d3..f0cde960 100644 --- a/server/src/chat/transport/matrix/bot/messages.rs +++ b/server/src/chat/transport/matrix/bot/messages.rs @@ -201,7 +201,16 @@ pub(super) async fn on_room_message( None => (stripped.to_ascii_lowercase(), String::new()), }; - if !cmd.is_empty() && !GATEWAY_LOCAL_COMMANDS.contains(&cmd.as_str()) { + // Only proxy if the first word is a known bot command (sync or async). + let is_known_command = !cmd.is_empty() + && !GATEWAY_LOCAL_COMMANDS.contains(&cmd.as_str()) + && (crate::chat::commands::commands() + .iter() + .any(|c| c.name == cmd) + || ["assign", "start", "delete", "rebuild", "rmtree", "htop", "timer"] + .contains(&cmd.as_str())); + + if is_known_command { // Proxy to the active project server. let response = match ctx.proxy_bot_command(&cmd, &args).await { Some(r) => r, @@ -216,16 +225,7 @@ pub(super) async fn on_room_message( { ctx.bot_sent_event_ids.lock().await.insert(event_id); } - // If the command was recognized by the project server, we're done. - // If it was not a command at all (freeform text), fall through to the LLM. - if crate::chat::commands::commands() - .iter() - .any(|c| c.name == cmd) - || ["assign", "start", "delete", "rebuild", "rmtree", "htop", "timer"] - .contains(&cmd.as_str()) - { - return; - } + return; } // Gateway-local commands and freeform text fall through to normal handling below. }