This commit is contained in:
Slavi Pantaleev
2025-02-27 07:46:16 +02:00
parent c051da2f4a
commit 406141cd7d
72 changed files with 259 additions and 209 deletions

View File

@@ -1,6 +1,6 @@
use super::{
provider::{self, ControllerType},
AgentDefinition, AgentProvider, PublicIdentifier,
provider::{self, ControllerType},
};
// Dead-code is allowed. We do not use these enum struct payloads directly,

View File

@@ -1,7 +1,7 @@
use super::instantiation;
use super::instantiation::AgentInstance;
use super::AgentDefinition;
use super::PublicIdentifier;
use super::instantiation;
use super::instantiation::AgentInstance;
use crate::entity::RoomConfigContext;
#[derive(Debug)]

View File

@@ -11,11 +11,11 @@ pub use manager::Manager;
pub use definition::AgentDefinition;
pub use instantiation::create_from_provider_and_yaml_value_config;
pub use instantiation::default_config_for_provider;
pub use instantiation::AgentInstance;
pub use instantiation::Error as AgentInstantiationError;
pub use instantiation::Result as AgentInstantiationResult;
pub use instantiation::create_from_provider_and_yaml_value_config;
pub use instantiation::default_config_for_provider;
pub use provider::{AgentProvider, AgentProviderInfo, ControllerTrait};
pub use purpose::AgentPurpose;

View File

@@ -9,15 +9,15 @@ use anthropic_rs::{
};
use super::super::ControllerTrait;
use crate::agent::AgentPurpose;
use crate::agent::provider::entity::{
ImageGenerationResult, PingResult, TextGenerationParams, TextGenerationResult,
TextToSpeechParams, TextToSpeechResult,
};
use crate::agent::provider::{ImageGenerationParams, SpeechToTextParams, SpeechToTextResult};
use crate::agent::AgentPurpose;
use crate::conversation::llm::{
shorten_messages_list_to_context_size, Author as LLMAuthor, Conversation as LLMConversation,
Message as LLMMessage,
Author as LLMAuthor, Conversation as LLMConversation, Message as LLMMessage,
shorten_messages_list_to_context_size,
};
use crate::strings;

View File

@@ -7,8 +7,8 @@ pub use controller::Controller;
use super::super::AgentInstantiationError;
use super::super::AgentInstantiationResult;
use super::controller::ControllerType;
use super::ConfigTrait;
use super::controller::ControllerType;
pub fn create_controller_from_yaml_value_config(
agent_id: &str,

View File

@@ -1,11 +1,11 @@
use crate::{agent::AgentPurpose, conversation::llm::Conversation};
use super::{
ImageGenerationParams, SpeechToTextParams, SpeechToTextResult,
entity::{
ImageGenerationResult, PingResult, TextGenerationParams, TextGenerationResult,
TextToSpeechParams, TextToSpeechResult,
},
ImageGenerationParams, SpeechToTextParams, SpeechToTextResult,
};
pub trait ControllerTrait {

View File

@@ -67,9 +67,7 @@ impl AgentProvider {
wiki_url: Some("https://en.wikipedia.org/wiki/Anthropic"),
sign_up_url: Some("https://console.anthropic.com/"),
models_list_url: Some("https://docs.anthropic.com/en/docs/about-claude/models"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
],
supported_purposes: vec![AgentPurpose::TextGeneration],
},
Self::Groq => AgentProviderInfo {
id: Self::Groq.to_static_str(),
@@ -79,10 +77,7 @@ impl AgentProvider {
wiki_url: Some("https://en.wikipedia.org/wiki/Groq"),
sign_up_url: Some("https://console.groq.com/login"),
models_list_url: Some("https://console.groq.com/docs/models"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
AgentPurpose::SpeechToText,
],
supported_purposes: vec![AgentPurpose::TextGeneration, AgentPurpose::SpeechToText],
},
Self::LocalAI => AgentProviderInfo {
id: Self::LocalAI.to_static_str(),
@@ -106,9 +101,7 @@ impl AgentProvider {
wiki_url: Some("https://en.wikipedia.org/wiki/Mistral_AI"),
sign_up_url: Some("https://auth.mistral.ai/ui/registration"),
models_list_url: Some("https://docs.mistral.ai/getting-started/models/"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
],
supported_purposes: vec![AgentPurpose::TextGeneration],
},
Self::Ollama => AgentProviderInfo {
id: Self::Ollama.to_static_str(),
@@ -118,9 +111,7 @@ impl AgentProvider {
wiki_url: None,
sign_up_url: None,
models_list_url: Some("https://ollama.com/library"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
],
supported_purposes: vec![AgentPurpose::TextGeneration],
},
Self::OpenAI => AgentProviderInfo {
id: Self::OpenAI.to_static_str(),
@@ -160,9 +151,7 @@ impl AgentProvider {
wiki_url: None,
sign_up_url: Some("https://openrouter.ai/"),
models_list_url: Some("https://openrouter.ai/models"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
],
supported_purposes: vec![AgentPurpose::TextGeneration],
},
Self::TogetherAI => AgentProviderInfo {
id: Self::TogetherAI.to_static_str(),
@@ -172,9 +161,7 @@ impl AgentProvider {
wiki_url: None,
sign_up_url: Some("https://api.together.ai/signup"),
models_list_url: Some("https://api.together.xyz/models"),
supported_purposes: vec![
AgentPurpose::TextGeneration,
],
supported_purposes: vec![AgentPurpose::TextGeneration],
},
}
}

View File

@@ -1,36 +1,36 @@
use std::ops::Deref;
use async_openai::{
Client as OpenAIClient,
config::OpenAIConfig,
types::{
ChatCompletionRequestMessage, CreateChatCompletionRequestArgs, CreateImageRequestArgs,
CreateSpeechRequestArgs, CreateTranscriptionRequestArgs,
},
Client as OpenAIClient,
};
use super::super::ControllerTrait;
use crate::{
agent::{
AgentPurpose,
provider::{
entity::{ImageGenerationResult, PingResult, TextToSpeechParams, TextToSpeechResult},
openai::utils::convert_string_to_enum,
},
AgentPurpose,
},
strings,
};
use crate::{
agent::{
provider::{
entity::{TextGenerationParams, TextGenerationResult},
ImageGenerationParams, SpeechToTextParams, SpeechToTextResult,
entity::{TextGenerationParams, TextGenerationResult},
},
utils::base64_decode,
},
conversation::llm::{
shorten_messages_list_to_context_size, Author as LLMAuthor,
Conversation as LLMConversation, Message as LLMMessage,
Author as LLMAuthor, Conversation as LLMConversation, Message as LLMMessage,
shorten_messages_list_to_context_size,
},
};

View File

@@ -13,8 +13,8 @@ pub(super) use config::TextToSpeechConfig;
use super::super::AgentInstantiationError;
use super::super::AgentInstantiationResult;
use super::controller::ControllerType;
use super::ConfigTrait;
use super::controller::ControllerType;
pub fn create_controller_from_yaml_value_config(
agent_id: &str,

View File

@@ -7,20 +7,20 @@ use super::super::ControllerTrait;
use crate::agent::utils::base64_decode;
use crate::{
agent::provider::{
entity::{TextGenerationParams, TextGenerationResult},
ImageGenerationParams, SpeechToTextParams, SpeechToTextResult,
entity::{TextGenerationParams, TextGenerationResult},
},
conversation::llm::{
shorten_messages_list_to_context_size, Author as LLMAuthor,
Conversation as LLMConversation, Message as LLMMessage,
Author as LLMAuthor, Conversation as LLMConversation, Message as LLMMessage,
shorten_messages_list_to_context_size,
},
};
use crate::{
agent::{
AgentPurpose,
provider::entity::{
ImageGenerationResult, PingResult, TextToSpeechParams, TextToSpeechResult,
},
AgentPurpose,
},
strings,
};

View File

@@ -21,8 +21,8 @@ pub use controller::Controller;
use super::super::AgentInstantiationError;
use super::super::AgentInstantiationResult;
use super::controller::ControllerType;
use super::ConfigTrait;
use super::controller::ControllerType;
pub fn create_controller_from_yaml_value_config(
agent_id: &str,

View File

@@ -1,4 +1,4 @@
use base64::{engine::general_purpose::STANDARD, Engine as _};
use base64::{Engine as _, engine::general_purpose::STANDARD};
use crate::{
agent::{

View File

@@ -1,11 +1,11 @@
use std::sync::Arc;
use std::{future::Future, pin::Pin};
use mxlink::matrix_sdk::Room;
use mxlink::matrix_sdk::media::{MediaFormat, MediaRequestParameters};
use mxlink::matrix_sdk::ruma::{
events::room::MediaSource, MilliSecondsSinceUnixEpoch, OwnedUserId,
MilliSecondsSinceUnixEpoch, OwnedUserId, events::room::MediaSource,
};
use mxlink::matrix_sdk::Room;
use mxlink::{
InitConfig, LoginConfig, LoginCredentials, LoginEncryption, MatrixLink, PersistenceConfig,

View File

@@ -5,7 +5,7 @@ use anyhow::anyhow;
use crate::agent::AgentPurpose;
pub use crate::entity::cfg::{defaults as cfg_defaults, env as cfg_env, Config};
pub use crate::entity::cfg::{Config, defaults as cfg_defaults, env as cfg_env};
pub fn load() -> anyhow::Result<Config> {
let config_file_path = env::var(cfg_env::BAIBOT_CONFIG_FILE_PATH)

View File

@@ -1,9 +1,9 @@
use mxlink::matrix_sdk::{
ruma::{
api::client::receipt::create_receipt::v3::ReceiptType,
events::room::message::OriginalSyncRoomMessageEvent, OwnedEventId,
},
Room,
ruma::{
OwnedEventId, api::client::receipt::create_receipt::v3::ReceiptType,
events::room::message::OriginalSyncRoomMessageEvent,
},
};
use mxlink::{CallbackError, MessageResponseType};

View File

@@ -1,12 +1,12 @@
use mxlink::matrix_sdk::{
ruma::{
events::{
room::message::Relation, AnySyncMessageLikeEvent, AnySyncTimelineEvent,
SyncMessageLikeEvent,
},
OwnedEventId, OwnedUserId,
},
Room,
ruma::{
OwnedEventId, OwnedUserId,
events::{
AnySyncMessageLikeEvent, AnySyncTimelineEvent, SyncMessageLikeEvent,
room::message::Relation,
},
},
};
use mxlink::CallbackError;

View File

@@ -1,9 +1,9 @@
use mxlink::{
matrix_sdk::{
ruma::events::{room::member::StrippedRoomMemberEvent, AnySyncTimelineEvent},
Room,
},
InvitationDecision,
matrix_sdk::{
Room,
ruma::events::{AnySyncTimelineEvent, room::member::StrippedRoomMemberEvent},
},
};
use mxlink::CallbackError;

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
use super::AccessControllerType;

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
let mut message = String::new();

View File

@@ -4,5 +4,5 @@ pub mod help;
mod room_local_agent_managers;
mod users;
pub use determination::{determine_controller, AccessControllerType};
pub use determination::{AccessControllerType, determine_controller};
pub use dispatching::dispatch_controller;

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle_get(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
let message = match &message_context

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle_get(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
let message = match &message_context.global_config().access.user_patterns {

View File

@@ -3,15 +3,15 @@ mod tests;
use mxlink::MessageResponseType;
use crate::agent::provider::{ControllerTrait, PingResult};
use crate::agent::PublicIdentifier;
use crate::agent::{create_from_provider_and_yaml_value_config, AgentDefinition};
use crate::agent::provider::{ControllerTrait, PingResult};
use crate::agent::{AgentDefinition, create_from_provider_and_yaml_value_config};
use crate::agent::{AgentInstance, AgentProvider};
use crate::controller::utils::get_text_body_or_complain;
use crate::entity::globalconfig::GlobalConfigurationManager;
use crate::entity::roomconfig::RoomConfigurationManager;
use crate::strings;
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
struct ParsedAgentConfig {
agent: AgentInstance,

View File

@@ -1,9 +1,9 @@
use mxlink::MessageResponseType;
use crate::entity::{
globalconfig::GlobalConfigurationManager, roomconfig::RoomConfigurationManager, MessageContext,
MessageContext, globalconfig::GlobalConfigurationManager, roomconfig::RoomConfigurationManager,
};
use crate::{agent::PublicIdentifier, strings, Bot};
use crate::{Bot, agent::PublicIdentifier, strings};
pub async fn handle(
bot: &Bot,

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{agent::PublicIdentifier, entity::MessageContext, strings, Bot};
use crate::{Bot, agent::PublicIdentifier, entity::MessageContext, strings};
pub async fn handle(
bot: &Bot,

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
// Anyone can access this help command, because certain subcommands ("list")

View File

@@ -2,7 +2,7 @@ use mxlink::MessageResponseType;
use crate::agent::AgentPurpose;
use crate::strings;
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
let agents = bot

View File

@@ -1,4 +1,4 @@
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
pub mod create;
pub mod delete;
@@ -7,7 +7,7 @@ pub mod determination;
pub mod help;
pub mod list;
pub use determination::{determine_controller, AgentControllerType};
pub use determination::{AgentControllerType, determine_controller};
pub async fn dispatch_controller(
handler: &AgentControllerType,

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle_get<T>(
bot: &Bot,

View File

@@ -1,5 +1,5 @@
use crate::strings;
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
use mxlink::MessageResponseType;
use super::controller_type::{

View File

@@ -2,7 +2,7 @@ use crate::entity::roomconfig::{
RoomSettings, SpeechToTextFlowType,
SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages,
};
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
use super::super::controller_type::{
ConfigSpeechToTextSettingRelatedControllerType, SettingsStorageSource,

View File

@@ -1,7 +1,7 @@
use crate::entity::roomconfig::{
RoomSettings, TextGenerationAutoUsage, TextGenerationPrefixRequirementType,
};
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
use super::super::controller_type::{
ConfigTextGenerationSettingRelatedControllerType, SettingsStorageSource,

View File

@@ -1,7 +1,7 @@
use crate::entity::roomconfig::{
RoomSettings, TextToSpeechBotMessagesFlowType, TextToSpeechUserMessagesFlowType,
};
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
use super::super::controller_type::{
ConfigTextToSpeechSettingRelatedControllerType, SettingsStorageSource,

View File

@@ -1,7 +1,7 @@
use mxlink::MessageResponseType;
use crate::entity::{roomconfig::RoomSettings, MessageContext};
use crate::{strings, Bot};
use crate::entity::{MessageContext, roomconfig::RoomSettings};
use crate::{Bot, strings};
pub async fn handle_set<T>(
bot: &Bot,

View File

@@ -1,9 +1,10 @@
use mxlink::MessageResponseType;
use crate::{
Bot,
agent::{AgentPurpose, PublicIdentifier},
entity::{globalconfig::GlobalConfigurationManager, MessageContext},
strings, Bot,
entity::{MessageContext, globalconfig::GlobalConfigurationManager},
strings,
};
pub async fn handle_get(

View File

@@ -1,15 +1,16 @@
use mxlink::MessageResponseType;
use crate::{
Bot,
entity::{
MessageContext,
roomconfig::{
SpeechToTextFlowType, SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages,
TextGenerationAutoUsage, TextGenerationPrefixRequirementType,
TextToSpeechBotMessagesFlowType, TextToSpeechUserMessagesFlowType,
},
MessageContext,
},
strings, Bot,
strings,
};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {

View File

@@ -1,7 +1,7 @@
use mxlink::MessageResponseType;
use crate::entity::{roomconfig::RoomSettings, MessageContext};
use crate::{strings, Bot};
use crate::entity::{MessageContext, roomconfig::RoomSettings};
use crate::{Bot, strings};
pub async fn handle_set<T>(
bot: &Bot,

View File

@@ -1,9 +1,10 @@
use mxlink::MessageResponseType;
use crate::{
Bot,
agent::{AgentPurpose, PublicIdentifier},
entity::MessageContext,
strings, Bot,
strings,
};
use crate::entity::roomconfig::RoomConfigurationManager;

View File

@@ -1,15 +1,16 @@
use mxlink::MessageResponseType;
use crate::{
Bot,
agent::{
utils::get_effective_agent_for_purpose, AgentInstance, AgentPurpose, ControllerTrait,
Manager as AgentManager, PublicIdentifier,
AgentInstance, AgentPurpose, ControllerTrait, Manager as AgentManager, PublicIdentifier,
utils::get_effective_agent_for_purpose,
},
entity::{
roomconfig::{RoomConfig, RoomSettingsHandler},
MessageContext, RoomConfigContext,
roomconfig::{RoomConfig, RoomSettingsHandler},
},
strings, Bot,
strings,
};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {

View File

@@ -1,31 +1,31 @@
use mxlink::matrix_sdk::ruma::events::room::message::AudioMessageEventContent;
use mxlink::matrix_sdk::ruma::OwnedEventId;
use mxlink::matrix_sdk::ruma::events::room::message::AudioMessageEventContent;
use mxlink::{MatrixLink, MessageResponseType};
use tracing::Instrument;
use crate::agent::provider::{
SpeechToTextParams, TextGenerationParams, TextGenerationPromptVariables,
};
use crate::agent::AgentInstance;
use crate::agent::AgentPurpose;
use crate::agent::ControllerTrait;
use crate::agent::provider::{
SpeechToTextParams, TextGenerationParams, TextGenerationPromptVariables,
};
use crate::controller::utils::agent::get_effective_agent_for_purpose_or_complain;
use crate::conversation::matrix::MatrixMessageProcessingParams;
use crate::entity::MessagePayload;
use crate::entity::roomconfig::{
SpeechToTextFlowType, SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages,
TextToSpeechBotMessagesFlowType, TextToSpeechUserMessagesFlowType,
};
use crate::entity::MessagePayload;
use crate::strings;
use crate::utils::text_to_speech::create_transcribed_message_text;
use crate::{
Bot,
conversation::{
create_llm_conversation_for_matrix_reply_chain, create_llm_conversation_for_matrix_thread,
matrix::create_list_of_bot_user_prefixes_to_strip,
},
entity::MessageContext,
Bot,
};
#[derive(Debug, PartialEq)]

View File

@@ -4,8 +4,8 @@ mod tests;
use super::chat_completion::ChatCompletionControllerType;
use crate::{
entity::{
roomconfig::TextGenerationPrefixRequirementType, InteractionTrigger, MessageContext,
MessagePayload,
InteractionTrigger, MessageContext, MessagePayload,
roomconfig::TextGenerationPrefixRequirementType,
},
strings,
};

View File

@@ -142,8 +142,7 @@ fn determine_text_controller() {
// This test case is the same as the one above, just with a different prefix requirement setting.
// We expect the same result.
TestCase {
name:
"Regular message with bot mention triggers completion (command prefix requirement)",
name: "Regular message with bot mention triggers completion (command prefix requirement)",
input: "Regular text goes here",
is_mentioning_bot: true,
room_text_generation_prefix_requirement_type:

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
use super::ControllerType;

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
pub async fn handle(bot: &Bot, message_context: &MessageContext) -> anyhow::Result<()> {
let sender_can_manage_global_config = message_context.sender_can_manage_global_config();

View File

@@ -2,15 +2,15 @@ use mxlink::{MatrixLink, MessageResponseType};
use tracing::Instrument;
use crate::agent::provider::ImageGenerationParams;
use crate::agent::AgentPurpose;
use crate::agent::ControllerTrait;
use crate::agent::provider::ImageGenerationParams;
use crate::controller::utils::agent::get_effective_agent_for_purpose_or_complain;
use crate::controller::utils::mime::get_file_extension;
use crate::conversation::create_llm_conversation_for_matrix_thread;
use crate::conversation::matrix::MatrixMessageProcessingParams;
use crate::strings;
use crate::{entity::MessageContext, Bot};
use crate::{Bot, entity::MessageContext};
// We may make this configurable (per room, etc.) in the future, but for now it's hardcoded.
const STICKER_SIZE: &str = "256x256";

View File

@@ -68,46 +68,50 @@ mod tests {
// Multiple complex user messages dispersed with assistant messages
TestCase {
original_prompt: "Generate a picture of an elephant",
messages: vec![Message {
author: Author::User,
message_text: "Must be blue".to_owned(),
timestamp,
},
Message {
author: Author::Assistant,
message_text: "Whatever".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "Must be 3-legged.\nMust be flying.".to_owned(),
timestamp,
}],
messages: vec![
Message {
author: Author::User,
message_text: "Must be blue".to_owned(),
timestamp,
},
Message {
author: Author::Assistant,
message_text: "Whatever".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "Must be 3-legged.\nMust be flying.".to_owned(),
timestamp,
},
],
expected_prompt: "Generate a picture of an elephant\nOther criteria:\n- Must be blue\n- Must be 3-legged.. Must be flying.",
},
// "Again" is ignored.
TestCase {
original_prompt: "Generate a picture of a grizzly bear",
messages: vec![Message {
author: Author::User,
message_text: "Must be blue".to_owned(),
timestamp,
},
Message {
author: Author::Assistant,
message_text: "Whatever".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "Again".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "again".to_owned(),
timestamp,
}],
messages: vec![
Message {
author: Author::User,
message_text: "Must be blue".to_owned(),
timestamp,
},
Message {
author: Author::Assistant,
message_text: "Whatever".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "Again".to_owned(),
timestamp,
},
Message {
author: Author::User,
message_text: "again".to_owned(),
timestamp,
},
],
expected_prompt: "Generate a picture of a grizzly bear\nOther criteria:\n- Must be blue",
},
];

View File

@@ -1,7 +1,7 @@
use mxlink::MessageResponseType;
use crate::entity::RoomConfigContext;
use crate::{strings, Bot};
use crate::{Bot, strings};
pub async fn handle(
bot: &Bot,
@@ -9,7 +9,9 @@ pub async fn handle(
room_config_context: &RoomConfigContext,
) -> anyhow::Result<()> {
if !bot.post_join_self_introduction_enabled() {
tracing::debug!("Post-join self-introduction is disabled - not sending introduction message");
tracing::debug!(
"Post-join self-introduction is disabled - not sending introduction message"
);
return Ok(());
}

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{agent::AgentProvider, entity::MessageContext, strings, Bot};
use crate::{Bot, agent::AgentProvider, entity::MessageContext, strings};
use super::ControllerType;

View File

@@ -3,9 +3,9 @@ use std::ops::Deref;
use mxlink::MatrixLink;
use crate::{
Bot,
agent::AgentPurpose,
entity::{MessageContext, MessagePayload},
Bot,
};
mod text_to_speech;

View File

@@ -1,7 +1,7 @@
use mxlink::{MatrixLink, MessageResponseType};
use mxlink::matrix_sdk::ruma::{
events::room::message::TextMessageEventContent, OwnedEventId, OwnedUserId,
OwnedEventId, OwnedUserId, events::room::message::TextMessageEventContent,
};
use crate::entity::roomconfig::{
@@ -9,8 +9,8 @@ use crate::entity::roomconfig::{
};
use crate::{
agent::AgentPurpose, controller::utils::agent::get_effective_agent_for_purpose_or_complain,
entity::MessageContext, Bot,
Bot, agent::AgentPurpose,
controller::utils::agent::get_effective_agent_for_purpose_or_complain, entity::MessageContext,
};
pub(super) async fn handle(
@@ -34,7 +34,9 @@ pub(super) async fn handle(
reacted_to_event_sender_id,
matrix_link.user_id(),
) {
tracing::debug!("Ignoring request for on-demand text-to-speech (via reaction) due to room configuration");
tracing::debug!(
"Ignoring request for on-demand text-to-speech (via reaction) due to room configuration"
);
return Ok(());
}

View File

@@ -1,6 +1,6 @@
use mxlink::MessageResponseType;
use crate::{entity::MessageContext, strings, Bot};
use crate::{Bot, entity::MessageContext, strings};
use super::ControllerType;

View File

@@ -1,12 +1,13 @@
use mxlink::MessageResponseType;
use crate::{
Bot,
agent::{
utils::{get_effective_agent_for_purpose, AgentForPurposeDeterminationError},
AgentInstance, AgentPurpose,
utils::{AgentForPurposeDeterminationError, get_effective_agent_for_purpose},
},
entity::MessageContext,
strings, Bot,
strings,
};
pub async fn get_effective_agent_for_purpose_or_complain<'a>(

View File

@@ -1,8 +1,8 @@
use mxlink::MessageResponseType;
use crate::{
entity::{MessageContext, MessagePayload},
Bot,
entity::{MessageContext, MessagePayload},
};
pub mod agent;

View File

@@ -5,9 +5,10 @@ use tracing::Instrument;
use crate::controller::utils::mime::get_file_extension;
use crate::{
agent::{provider::TextToSpeechParams, AgentInstance, AgentPurpose, ControllerTrait},
Bot,
agent::{AgentInstance, AgentPurpose, ControllerTrait, provider::TextToSpeechParams},
entity::MessageContext,
strings, Bot,
strings,
};
pub async fn generate_and_send_tts_for_message(

View File

@@ -25,8 +25,8 @@ fn test_messages_by_the_bot_are_identified_correctly() {
}
#[test]
fn test_notice_messages_by_bot_with_speech_to_text_prefix_are_cleaned_up_and_considered_sent_by_user(
) {
fn test_notice_messages_by_bot_with_speech_to_text_prefix_are_cleaned_up_and_considered_sent_by_user()
{
let bot_user_id =
OwnedUserId::try_from("@bot:example.com").expect("Failed to parse bot user ID");

View File

@@ -1,6 +1,6 @@
use tiktoken_rs::CoreBPE;
use tiktoken_rs::get_bpe_from_tokenizer;
use tiktoken_rs::tokenizer;
use tiktoken_rs::CoreBPE;
use super::{Author, Message};

View File

@@ -1,5 +1,5 @@
use mxlink::matrix_sdk::ruma::OwnedRoomId;
use mxlink::matrix_sdk::Room;
use mxlink::matrix_sdk::ruma::OwnedRoomId;
use mxlink::MatrixLink;
use quick_cache::sync::Cache;

View File

@@ -1,6 +1,6 @@
use mxlink::matrix_sdk::Room;
use mxlink::matrix_sdk::deserialized_responses::TimelineEvent;
use mxlink::matrix_sdk::ruma::OwnedEventId;
use mxlink::matrix_sdk::Room;
use quick_cache::sync::Cache;

View File

@@ -5,17 +5,17 @@ use std::sync::Arc;
use mxlink::matrix_sdk::ruma::{OwnedEventId, OwnedUserId};
use mxlink::matrix_sdk::{
Room,
deserialized_responses::TimelineEvent,
ruma::events::{
relation::Thread,
room::message::{
sanitize::remove_plain_reply_fallback, MessageType, OriginalSyncRoomMessageEvent,
Relation, RoomMessageEventContent,
},
AnyMessageLikeEventContent, AnySyncMessageLikeEvent, AnySyncTimelineEvent,
SyncMessageLikeEvent,
relation::Thread,
room::message::{
MessageType, OriginalSyncRoomMessageEvent, Relation, RoomMessageEventContent,
sanitize::remove_plain_reply_fallback,
},
},
Room,
};
use mxlink::{MatrixLink, ThreadGetMessagesParams, ThreadInfo};

View File

@@ -1,14 +1,14 @@
use std::sync::Arc;
use mxlink::matrix_sdk::ruma::OwnedEventId;
use mxlink::MatrixLink;
use mxlink::matrix_sdk::ruma::OwnedEventId;
use crate::conversation::matrix::MatrixMessage;
use super::llm::{convert_matrix_message_to_llm_message, Conversation, Message};
use super::llm::{Conversation, Message, convert_matrix_message_to_llm_message};
use super::matrix::{
get_matrix_messages_in_reply_chain, get_matrix_messages_in_thread, process_matrix_messages,
MatrixMessageProcessingParams, RoomEventFetcher,
MatrixMessageProcessingParams, RoomEventFetcher, get_matrix_messages_in_reply_chain,
get_matrix_messages_in_thread, process_matrix_messages,
};
pub async fn create_llm_conversation_for_matrix_thread(

View File

@@ -247,7 +247,6 @@ impl PersistenceConfig {
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ConfigRoom {
#[serde(default = "super::defaults::room_post_join_self_introduction_enabled")]
@@ -263,7 +262,8 @@ impl ConfigRoom {
impl Default for ConfigRoom {
fn default() -> Self {
Self {
post_join_self_introduction_enabled: super::defaults::room_post_join_self_introduction_enabled(),
post_join_self_introduction_enabled:
super::defaults::room_post_join_self_introduction_enabled(),
}
}
}

View File

@@ -1,11 +1,11 @@
use mxlink::matrix_sdk::ruma::{OwnedEventId, OwnedUserId, RoomId};
use mxlink::matrix_sdk::Room;
use mxlink::matrix_sdk::ruma::{OwnedEventId, OwnedUserId, RoomId};
use mxlink::ThreadInfo;
use super::{
globalconfig::GlobalConfig, roomconfig::RoomConfig, MessagePayload, RoomConfigContext,
TriggerEventInfo,
MessagePayload, RoomConfigContext, TriggerEventInfo, globalconfig::GlobalConfig,
roomconfig::RoomConfig,
};
#[derive(Debug)]

View File

@@ -4,10 +4,9 @@ use super::globalconfig::GlobalConfig;
use super::roomconfig::RoomConfig;
use crate::entity::roomconfig::{
defaults as roomconfig_defaults, SpeechToTextFlowType,
SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages, TextGenerationAutoUsage,
TextGenerationPrefixRequirementType, TextToSpeechBotMessagesFlowType,
TextToSpeechUserMessagesFlowType,
SpeechToTextFlowType, SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages,
TextGenerationAutoUsage, TextGenerationPrefixRequirementType, TextToSpeechBotMessagesFlowType,
TextToSpeechUserMessagesFlowType, defaults as roomconfig_defaults,
};
#[derive(Debug)]

View File

@@ -46,7 +46,9 @@ impl RoomConfigTrait for RoomConfig {}
impl RoomConfig {
pub async fn with_room(mut self, room: Room) -> Self {
tracing::trace!("Determining room members count to decide on a suitable text-generation/prefix-requirement-type default");
tracing::trace!(
"Determining room members count to decide on a suitable text-generation/prefix-requirement-type default"
);
let members = room.members(RoomMemberships::ACTIVE).await;
@@ -60,12 +62,19 @@ impl RoomConfig {
text_generation::TextGenerationPrefixRequirementType::No
};
tracing::info!(?members_count, ?prefix_requirement_type, "Determined text-generation/prefix-requirement-type based on room members count");
tracing::info!(
?members_count,
?prefix_requirement_type,
"Determined text-generation/prefix-requirement-type based on room members count"
);
prefix_requirement_type
}
Err(err) => {
tracing::error!(?err, "Failed to get members of room - will default text-generation/prefix-requirement-type to No");
tracing::error!(
?err,
"Failed to get members of room - will default text-generation/prefix-requirement-type to No"
);
text_generation::TextGenerationPrefixRequirementType::No
}
};

View File

@@ -6,5 +6,5 @@ mod entity;
mod strings;
mod utils;
pub use bot::{load_config, Bot};
pub use bot::{Bot, load_config};
pub use entity::cfg::Config;

View File

@@ -1,7 +1,7 @@
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::fmt::format::FmtSpan;
use baibot::{load_config, Bot, Config};
use baibot::{Bot, Config, load_config};
#[tokio::main]
async fn main() -> anyhow::Result<()> {

View File

@@ -1,7 +1,7 @@
use crate::{
agent::{
utils::AgentForPurposeDeterminationInfoConfigurationSource, AgentInstance, AgentPurpose,
PublicIdentifier,
AgentInstance, AgentPurpose, PublicIdentifier,
utils::AgentForPurposeDeterminationInfoConfigurationSource,
},
entity::roomconfig::{
SpeechToTextFlowType, SpeechToTextMessageTypeForNonThreadedOnlyTranscribedMessages,
@@ -45,7 +45,9 @@ pub fn configuration_getter_used_with_extra_text(
getter_name: &str,
remaining_text: &str,
) -> String {
format!("You're invoking a getter command (`{getter_name}`), but passing additional text (`{remaining_text}`) as if you're invoking a setter.\n\nPerhaps you meant to invoke `set-{getter_name}`?")
format!(
"You're invoking a getter command (`{getter_name}`), but passing additional text (`{remaining_text}`) as if you're invoking a setter.\n\nPerhaps you meant to invoke `set-{getter_name}`?"
)
}
pub fn configuration_value_unrecognized(value: &str) -> String {
@@ -53,7 +55,10 @@ pub fn configuration_value_unrecognized(value: &str) -> String {
}
pub fn configuration_value_not_f32(value: &str) -> String {
format!("The value `{}` could not be converted to a [floating point number](https://en.wikipedia.org/wiki/Floating-point_arithmetic).", value)
format!(
"The value `{}` could not be converted to a [floating point number](https://en.wikipedia.org/wiki/Floating-point_arithmetic).",
value
)
}
pub fn status_room_config_handlers_heading() -> &'static str {

View File

@@ -32,7 +32,9 @@ pub fn users_command_get(command_prefix: &str) -> String {
}
pub fn users_command_set(command_prefix: &str) -> String {
format!("- **Set** the list of allowed users: `{command_prefix} access set-users SPACE_SEPARATED_PATTERNS`")
format!(
"- **Set** the list of allowed users: `{command_prefix} access set-users SPACE_SEPARATED_PATTERNS`"
)
}
pub fn example_user_patterns(own_server_name: &str) -> String {
@@ -64,7 +66,9 @@ pub fn room_local_agent_managers_heading() -> String {
}
pub fn room_local_agent_managers_intro(command_prefix: &str) -> String {
format!("Room-local agent managers are users privileged to **create their own agents** (see `{command_prefix} agent`) in rooms.")
format!(
"Room-local agent managers are users privileged to **create their own agents** (see `{command_prefix} agent`) in rooms."
)
}
pub fn room_local_agent_managers_security_warning() -> String {
@@ -72,9 +76,13 @@ pub fn room_local_agent_managers_security_warning() -> String {
}
pub fn room_local_agent_managers_command_get(command_prefix: &str) -> String {
format!("- **Show** the currently allowed users: `{command_prefix} access room-local-agent-managers`")
format!(
"- **Show** the currently allowed users: `{command_prefix} access room-local-agent-managers`"
)
}
pub fn room_local_agent_managers_command_set(command_prefix: &str) -> String {
format!("- **Set** the list of allowed users: `{command_prefix} access set-room-local-agent-managers SPACE_SEPARATED_PATTERNS`")
format!(
"- **Set** the list of allowed users: `{command_prefix} access set-room-local-agent-managers SPACE_SEPARATED_PATTERNS`"
)
}

View File

@@ -3,7 +3,9 @@ pub fn heading() -> String {
}
pub fn intro(command_prefix: &str) -> String {
format!("An agent is an instantiation and configuration of some **☁️ provider** (see `{command_prefix} provider`).")
format!(
"An agent is an instantiation and configuration of some **☁️ provider** (see `{command_prefix} provider`)."
)
}
pub fn intro_handler_relation(command_prefix: &str) -> String {
@@ -25,7 +27,9 @@ pub fn list_agents(command_prefix: &str) -> String {
}
pub fn show_agent_details(command_prefix: &str) -> String {
format!("- **Show** full details for a given agent: `{command_prefix} agent details FULL_AGENT_IDENTIFIER`")
format!(
"- **Show** full details for a given agent: `{command_prefix} agent details FULL_AGENT_IDENTIFIER`"
)
}
pub fn create_agent_intro() -> &'static str {
@@ -33,11 +37,15 @@ pub fn create_agent_intro() -> &'static str {
}
pub fn create_agent_room_local(command_prefix: &str) -> String {
format!("\t- (Accessible in **this room only**) `{command_prefix} agent create-room-local PROVIDER_ID AGENT_ID`")
format!(
"\t- (Accessible in **this room only**) `{command_prefix} agent create-room-local PROVIDER_ID AGENT_ID`"
)
}
pub fn create_agent_global(command_prefix: &str) -> String {
format!("\t- (Accessible in **all rooms**) `{command_prefix} agent create-global PROVIDER_ID AGENT_ID`")
format!(
"\t- (Accessible in **all rooms**) `{command_prefix} agent create-global PROVIDER_ID AGENT_ID`"
)
}
pub fn create_agent_example(command_prefix: &str) -> String {

View File

@@ -23,7 +23,9 @@ pub fn status_heading() -> String {
}
pub fn status_intro(command_prefix: &str) -> String {
format!("To **show a summary** of the configuration affecting the current room: `{command_prefix} config status`")
format!(
"To **show a summary** of the configuration affecting the current room: `{command_prefix} config status`"
)
}
pub fn handlers_heading() -> String {
@@ -57,15 +59,21 @@ pub fn handlers_intro_purposes() -> String {
}
pub fn handlers_show(command_prefix: &str) -> String {
format!("**Show** the currently configured agent for the given purpose: `{command_prefix} config CONFIG_TYPE handler PURPOSE`")
format!(
"**Show** the currently configured agent for the given purpose: `{command_prefix} config CONFIG_TYPE handler PURPOSE`"
)
}
pub fn handlers_set(command_prefix: &str) -> String {
format!("**Set** the agent to be used for the given purpose: `{command_prefix} config CONFIG_TYPE set-handler PURPOSE AGENT_ID`")
format!(
"**Set** the agent to be used for the given purpose: `{command_prefix} config CONFIG_TYPE set-handler PURPOSE AGENT_ID`"
)
}
pub fn handlers_unset(command_prefix: &str) -> String {
format!("**Unset** the agent to be used for the given purpose: `{command_prefix} config CONFIG_TYPE set-handler PURPOSE`")
format!(
"**Unset** the agent to be used for the given purpose: `{command_prefix} config CONFIG_TYPE set-handler PURPOSE`"
)
}
pub fn text_generation_heading() -> String {
@@ -99,7 +107,9 @@ pub fn text_generation_prefix_requirement_type_intro() -> String {
}
pub fn text_generation_prefix_requirement_type_outro(bot_username: &str) -> String {
format!("Regardless of the setting, the bot will always respond to **direct mentions** (e.g. `@{bot_username}`).")
format!(
"Regardless of the setting, the bot will always respond to **direct mentions** (e.g. `@{bot_username}`)."
)
}
pub fn text_generation_auto_usage_heading() -> &'static str {

View File

@@ -1,15 +1,17 @@
use crate::agent::utils::get_effective_agent_for_purpose;
use crate::agent::utils::AgentForPurposeDeterminationError;
use crate::agent::utils::get_effective_agent_for_purpose;
use crate::agent::{AgentPurpose, Manager as AgentManager};
use crate::entity::roomconfig::TextGenerationPrefixRequirementType;
use crate::entity::RoomConfigContext;
use crate::entity::roomconfig::TextGenerationPrefixRequirementType;
fn hello() -> &'static str {
"Hello! 👋"
}
pub fn its_me(name: &str) -> String {
let mut message = format!("I'm {name} - a bot exposing the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) ([Large Language Models](https://en.wikipedia.org/wiki/Large_language_model)) to you. 🤖");
let mut message = format!(
"I'm {name} - a bot exposing the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) ([Large Language Models](https://en.wikipedia.org/wiki/Large_language_model)) to you. 🤖"
);
if name == crate::entity::cfg::defaults::name() {
message.push('\n');
@@ -179,7 +181,9 @@ fn send_a_text_message(
"**Send a text message** in this room (e.g. `Hello!`) and see me reply.".to_owned()
}
TextGenerationPrefixRequirementType::CommandPrefix => {
format!("In this room, I'm configured to require the command prefix (`{command_prefix}`) for text messages. **Send a prefixed text message** (e.g. `{command_prefix} Hello!`) and see me reply.")
format!(
"In this room, I'm configured to require the command prefix (`{command_prefix}`) for text messages. **Send a prefixed text message** (e.g. `{command_prefix} Hello!`) and see me reply."
)
}
}
}
@@ -191,9 +195,13 @@ fn learn_more_from_usage_or_help(command_prefix: &str) -> String {
}
pub fn create_one_or_more_agents(command_prefix: &str) -> String {
format!("**Create one or more agents** in this room or globally. The provider help message will show you **🗲 Quick start** commands, but you may also send a `{command_prefix} agent` command to see the guide.")
format!(
"**Create one or more agents** in this room or globally. The provider help message will show you **🗲 Quick start** commands, but you may also send a `{command_prefix} agent` command to see the guide."
)
}
pub fn set_new_agent_as_handler(command_prefix: &str) -> String {
format!("**Set the new agent as a handler** for a given use-purpose like text-generation, image-generation, etc. The agent-creation wizard will tell you how, but you may also send a `{command_prefix} config` command to see the guide (in the 🤖 *Handler Agents* section).")
format!(
"**Set the new agent as a handler** for a given use-purpose like text-generation, image-generation, etc. The agent-creation wizard will tell you how, but you may also send a `{command_prefix} config` command to see the guide (in the 🤖 *Handler Agents* section)."
)
}

View File

@@ -7,5 +7,8 @@ pub fn redaction_reason_failed() -> &'static str {
}
pub fn language_code_invalid(value: &str) -> String {
format!("The value `{}` is not a valid 2-letter language code as per [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes).", value)
format!(
"The value `{}` is not a valid 2-letter language code as per [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes).",
value
)
}