huskies: merge 558_story_matrix_bot_can_run_on_the_gateway_to_manage_multiple_projects_from_one_chat
This commit is contained in:
@@ -450,6 +450,47 @@ pub(super) async fn on_room_message(
|
||||
return;
|
||||
}
|
||||
|
||||
// In gateway mode, handle the "switch <project>" command to change the
|
||||
// active project without invoking the LLM.
|
||||
if let Some(ref active_project) = ctx.gateway_active_project {
|
||||
let stripped = crate::chat::util::strip_bot_mention(
|
||||
&user_message,
|
||||
&ctx.bot_name,
|
||||
ctx.bot_user_id.as_str(),
|
||||
)
|
||||
.trim()
|
||||
.trim_start_matches(|c: char| !c.is_alphanumeric())
|
||||
.to_string();
|
||||
|
||||
let (cmd, arg) = match stripped.split_once(char::is_whitespace) {
|
||||
Some((c, a)) => (c.to_string(), a.trim().to_string()),
|
||||
None => (stripped.clone(), String::new()),
|
||||
};
|
||||
|
||||
if cmd.eq_ignore_ascii_case("switch") {
|
||||
let response = if arg.is_empty() {
|
||||
let available = ctx.gateway_projects.join(", ");
|
||||
format!("Usage: `switch <project>`. Available projects: {available}")
|
||||
} else if ctx.gateway_projects.iter().any(|p| p == &arg) {
|
||||
*active_project.write().await = arg.clone();
|
||||
format!("Switched to project **{arg}**.")
|
||||
} else {
|
||||
let available = ctx.gateway_projects.join(", ");
|
||||
format!("Unknown project `{arg}`. Available: {available}")
|
||||
};
|
||||
let html = markdown_to_html(&response);
|
||||
if let Ok(msg_id) = ctx
|
||||
.transport
|
||||
.send_message(&room_id_str, &response, &html)
|
||||
.await
|
||||
&& let Ok(event_id) = msg_id.parse()
|
||||
{
|
||||
ctx.bot_sent_event_ids.lock().await.insert(event_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the timer command, which requires async file I/O and cannot
|
||||
// be handled by the sync command registry.
|
||||
if let Some(timer_cmd) = crate::chat::timer::extract_timer_command(
|
||||
@@ -501,8 +542,14 @@ pub(super) async fn handle_message(
|
||||
// The prompt is just the current message with sender attribution.
|
||||
// Prior conversation context is carried by the Claude Code session.
|
||||
let bot_name = &ctx.bot_name;
|
||||
let active_project_ctx = if let Some(ref ap) = ctx.gateway_active_project {
|
||||
let name = ap.read().await.clone();
|
||||
format!("[Active project: {name}]\n")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let prompt = format!(
|
||||
"[Your name is {bot_name}. Refer to yourself as {bot_name}, not Claude.]\n\n{}",
|
||||
"[Your name is {bot_name}. Refer to yourself as {bot_name}, not Claude.]\n{active_project_ctx}\n{}",
|
||||
format_user_prompt(&sender, &user_message)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user