2024-09-12 13:44:06 +03:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests;
|
|
|
|
|
|
|
|
|
|
use super::chat_completion::ChatCompletionControllerType;
|
|
|
|
|
use crate::{
|
|
|
|
|
entity::{
|
2025-02-27 07:46:16 +02:00
|
|
|
InteractionTrigger, MessageContext, MessagePayload,
|
|
|
|
|
roomconfig::TextGenerationPrefixRequirementType,
|
2024-09-12 13:44:06 +03:00
|
|
|
},
|
|
|
|
|
strings,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use super::ControllerType;
|
|
|
|
|
|
|
|
|
|
pub fn determine_controller(
|
|
|
|
|
command_prefix: &str,
|
2024-10-01 21:06:54 +03:00
|
|
|
first_thread_message: &InteractionTrigger,
|
2024-09-12 13:44:06 +03:00
|
|
|
message_context: &MessageContext,
|
|
|
|
|
) -> ControllerType {
|
|
|
|
|
match &first_thread_message.payload {
|
2024-10-01 21:06:54 +03:00
|
|
|
MessagePayload::SynthethicChatCompletionTriggerInThread => {
|
|
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::ThreadMention)
|
|
|
|
|
}
|
|
|
|
|
MessagePayload::SynthethicChatCompletionTriggerForReply => {
|
|
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::ReplyMention)
|
|
|
|
|
}
|
2024-09-12 13:44:06 +03:00
|
|
|
MessagePayload::Text(text_message_content) => {
|
|
|
|
|
let prefix_requirement_type = message_context
|
|
|
|
|
.room_config_context()
|
|
|
|
|
.text_generation_prefix_requirement_type();
|
|
|
|
|
|
|
|
|
|
determine_text_controller(
|
|
|
|
|
command_prefix,
|
|
|
|
|
&text_message_content.body,
|
|
|
|
|
prefix_requirement_type,
|
|
|
|
|
first_thread_message.is_mentioning_bot,
|
|
|
|
|
)
|
|
|
|
|
}
|
2025-05-10 09:18:01 +03:00
|
|
|
MessagePayload::Image(_image_message_content) => {
|
|
|
|
|
let prefix_requirement_type = message_context
|
|
|
|
|
.room_config_context()
|
|
|
|
|
.text_generation_prefix_requirement_type();
|
|
|
|
|
|
|
|
|
|
match prefix_requirement_type {
|
2025-05-10 11:47:50 +03:00
|
|
|
TextGenerationPrefixRequirementType::CommandPrefix => ControllerType::Ignore,
|
2025-05-10 09:18:01 +03:00
|
|
|
TextGenerationPrefixRequirementType::No => {
|
|
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::Image)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-12 13:44:06 +03:00
|
|
|
MessagePayload::Encrypted(thread_info) => {
|
|
|
|
|
if thread_info.is_thread_root_only() {
|
|
|
|
|
ControllerType::Error(strings::error::message_is_encrypted().to_owned())
|
|
|
|
|
} else {
|
|
|
|
|
ControllerType::ErrorInThread(
|
|
|
|
|
strings::error::first_message_in_thread_is_encrypted().to_owned(),
|
|
|
|
|
thread_info.clone(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-20 12:07:15 +02:00
|
|
|
MessagePayload::File(_file_message_content) => {
|
|
|
|
|
let prefix_requirement_type = message_context
|
|
|
|
|
.room_config_context()
|
|
|
|
|
.text_generation_prefix_requirement_type();
|
|
|
|
|
|
|
|
|
|
match prefix_requirement_type {
|
|
|
|
|
TextGenerationPrefixRequirementType::CommandPrefix => ControllerType::Ignore,
|
|
|
|
|
TextGenerationPrefixRequirementType::No => {
|
|
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::File)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-12 13:44:06 +03:00
|
|
|
MessagePayload::Audio(_) => {
|
2024-10-01 21:06:54 +03:00
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::Audio)
|
2024-09-12 13:44:06 +03:00
|
|
|
}
|
|
|
|
|
MessagePayload::Reaction { .. } => {
|
|
|
|
|
panic!("Handling reaction as first message in thread does not make sense")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn determine_text_controller(
|
|
|
|
|
command_prefix: &str,
|
|
|
|
|
text: &str,
|
|
|
|
|
room_text_generation_prefix_requirement_type: TextGenerationPrefixRequirementType,
|
|
|
|
|
is_mentioning_bot: bool,
|
|
|
|
|
) -> ControllerType {
|
|
|
|
|
let text = text.trim();
|
|
|
|
|
|
|
|
|
|
if text.starts_with(&format!("{command_prefix} help")) || text == command_prefix {
|
|
|
|
|
return ControllerType::Help;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(remaining) = text.strip_prefix(&format!("{command_prefix} access")) {
|
|
|
|
|
return super::access::determine_controller(remaining.trim());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(remaining) = text.strip_prefix(&format!("{command_prefix} provider")) {
|
|
|
|
|
return super::provider::determine_controller(remaining.trim());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(remaining) = text.strip_prefix(&format!("{command_prefix} agent")) {
|
|
|
|
|
return super::agent::determine_controller(command_prefix, remaining.trim());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(remaining) = text.strip_prefix(&format!("{command_prefix} config")) {
|
|
|
|
|
return super::cfg::determine_controller(remaining.trim());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(prompt) = text.strip_prefix(&format!("{command_prefix} image")) {
|
2025-05-10 09:18:01 +03:00
|
|
|
return super::image::determine_controller(prompt.trim());
|
2024-09-12 13:44:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(prompt) = text.strip_prefix(&format!("{command_prefix} sticker")) {
|
|
|
|
|
return ControllerType::StickerGeneration(prompt.trim().to_owned());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(remaining) = text.strip_prefix(&format!("{command_prefix} usage")) {
|
|
|
|
|
return super::usage::determine_controller(remaining.trim());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Regular text message that does not match any command.
|
|
|
|
|
// If it mentions the bot, it's a chat completion.
|
|
|
|
|
// Otherwise, it depends on the prefix requirement for text generation - it may be routed for chat completion or ignored.
|
|
|
|
|
|
|
|
|
|
if is_mentioning_bot {
|
2024-10-01 21:06:54 +03:00
|
|
|
return ControllerType::ChatCompletion(ChatCompletionControllerType::TextMention);
|
|
|
|
|
}
|
2024-09-12 13:44:06 +03:00
|
|
|
|
2024-10-01 21:06:54 +03:00
|
|
|
// Regardless of what the prefix requirement is, if we encounter a command prefix, we'll consider it a chat completion via command prefix invokation.
|
|
|
|
|
// This is to correctly indicate to the chat completion controller that a command prefix was used,
|
|
|
|
|
// so that it can be stripped from the beginning of the message.
|
|
|
|
|
if text.starts_with(command_prefix) {
|
|
|
|
|
return ControllerType::ChatCompletion(ChatCompletionControllerType::TextCommand);
|
2024-09-12 13:44:06 +03:00
|
|
|
}
|
|
|
|
|
|
2024-10-01 21:06:54 +03:00
|
|
|
// We're dealing with a regular message that does not start with a command prefix.
|
|
|
|
|
|
2024-09-12 13:44:06 +03:00
|
|
|
match room_text_generation_prefix_requirement_type {
|
|
|
|
|
TextGenerationPrefixRequirementType::CommandPrefix => {
|
2024-10-01 21:06:54 +03:00
|
|
|
// A prefix is required, but we've already checked (above) that the message does not start with a command prefix.
|
|
|
|
|
// It's to be ignored.
|
|
|
|
|
ControllerType::Ignore
|
2024-09-12 13:44:06 +03:00
|
|
|
}
|
|
|
|
|
TextGenerationPrefixRequirementType::No => {
|
2024-10-01 21:06:54 +03:00
|
|
|
ControllerType::ChatCompletion(ChatCompletionControllerType::TextDirect)
|
2024-09-12 13:44:06 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|