Files
baibot-withmcp/src/controller/agent/delete/mod.rs
Slavi Pantaleev 406141cd7d fmt
2025-02-27 07:46:16 +02:00

196 lines
6.2 KiB
Rust

use mxlink::MessageResponseType;
use crate::entity::{
MessageContext, globalconfig::GlobalConfigurationManager, roomconfig::RoomConfigurationManager,
};
use crate::{Bot, agent::PublicIdentifier, strings};
pub async fn handle(
bot: &Bot,
room_config_manager: &tokio::sync::Mutex<RoomConfigurationManager>,
global_config_manager: &tokio::sync::Mutex<GlobalConfigurationManager>,
message_context: &MessageContext,
agent_identifier: &PublicIdentifier,
) -> anyhow::Result<()> {
let agents = bot
.agent_manager()
.available_room_agents_by_room_config_context(message_context.room_config_context());
let agent = agents.iter().find(|a| a.identifier() == agent_identifier);
let Some(_) = agent else {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
&strings::agent::agent_with_given_identifier_missing(agent_identifier),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
return Ok(());
};
match &agent_identifier {
PublicIdentifier::DynamicRoomLocal(_) => {
if !message_context.sender_can_manage_room_local_agents()? {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
&strings::agent::not_allowed_to_manage_room_local_agents_in_room(),
MessageResponseType::Reply(
message_context.thread_info().root_event_id.clone(),
),
)
.await;
return Ok(());
}
delete_room_local_agent(bot, room_config_manager, message_context, agent_identifier)
.await
}
PublicIdentifier::DynamicGlobal(_) => {
if !message_context.sender_can_manage_global_config() {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
strings::global_config::no_permissions_to_administrate(),
MessageResponseType::Reply(
message_context.thread_info().root_event_id.clone(),
),
)
.await;
return Ok(());
}
delete_global_agent(
bot,
global_config_manager,
message_context,
agent_identifier,
)
.await
}
PublicIdentifier::Static(_) => {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
&strings::agent::not_allowed_to_manage_static_agents(),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
Ok(())
}
}
}
async fn delete_room_local_agent(
bot: &Bot,
room_config_manager: &tokio::sync::Mutex<RoomConfigurationManager>,
message_context: &MessageContext,
agent_id: &PublicIdentifier,
) -> anyhow::Result<()> {
let mut room_config = message_context.room_config().clone();
let mut was_deleted = false;
let agent_id_prefixless = agent_id.prefixless();
let mut agents = Vec::new();
for agent_config in room_config.agents {
if agent_config.id == agent_id_prefixless {
was_deleted = true;
} else {
agents.push(agent_config.clone());
}
}
if !was_deleted {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
&strings::agent::agent_with_given_identifier_missing(agent_id),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
return Ok(());
}
room_config.agents = agents;
let room_config_manager = room_config_manager.lock().await;
// We may unset all handlers in the room config which refer to this agent.
// We intentionally do not do this, because we do not support "agent edit" yet and ask people to do "agent delete" and "agent create" instead.
// We'd rather not magically reconfigure the room on agent deletion and obstruct this use case.
room_config_manager
.persist(message_context.room(), &room_config)
.await?;
bot.messaging()
.send_success_markdown_no_fail(
message_context.room(),
&strings::agent::removed_room_local(agent_id, bot.command_prefix()),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
Ok(())
}
async fn delete_global_agent(
bot: &Bot,
global_config_manager: &tokio::sync::Mutex<GlobalConfigurationManager>,
message_context: &MessageContext,
agent_id: &PublicIdentifier,
) -> anyhow::Result<()> {
let mut global_config = message_context.global_config().clone();
let mut was_deleted = false;
let agent_id_prefixless = agent_id.prefixless();
let mut agents = Vec::new();
for agent_config in global_config.agents {
if agent_config.id == agent_id_prefixless {
was_deleted = true;
} else {
agents.push(agent_config.clone());
}
}
if !was_deleted {
bot.messaging()
.send_error_markdown_no_fail(
message_context.room(),
&strings::agent::agent_with_given_identifier_missing(agent_id),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
return Ok(());
}
global_config.agents = agents;
global_config_manager
.lock()
.await
.persist(&global_config)
.await?;
bot.messaging()
.send_success_markdown_no_fail(
message_context.room(),
&strings::agent::removed_global(agent_id, bot.command_prefix()),
MessageResponseType::Reply(message_context.thread_info().root_event_id.clone()),
)
.await;
Ok(())
}