2024-08-08 12:07:00 +08:00
|
|
|
use std::fs;
|
2024-07-15 15:23:23 +08:00
|
|
|
use std::path::PathBuf;
|
2024-06-30 17:38:39 +08:00
|
|
|
|
2024-08-01 23:13:35 +08:00
|
|
|
use crate::ai_manager::AIManager;
|
|
|
|
use crate::completion::AICompletion;
|
2024-07-15 15:23:23 +08:00
|
|
|
use crate::entities::*;
|
|
|
|
use crate::local_ai::local_llm_chat::LLMModelInfo;
|
2024-12-08 18:25:25 +08:00
|
|
|
use crate::notification::{
|
|
|
|
chat_notification_builder, ChatNotification, APPFLOWY_AI_NOTIFICATION_KEY,
|
|
|
|
};
|
2024-08-06 07:56:13 +08:00
|
|
|
use allo_isolate::Isolate;
|
2024-11-14 00:51:07 +08:00
|
|
|
use flowy_ai_pub::cloud::{ChatMessageMetadata, ChatMessageType, ChatRAGData, ContextLoader};
|
2024-07-26 07:58:54 +08:00
|
|
|
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
2024-06-03 14:27:28 +08:00
|
|
|
use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
|
2024-07-15 15:23:23 +08:00
|
|
|
use lib_infra::isolate_stream::IsolateSink;
|
2024-08-06 07:56:13 +08:00
|
|
|
use std::sync::{Arc, Weak};
|
2024-08-09 21:55:20 +08:00
|
|
|
use tracing::trace;
|
2024-08-06 07:56:13 +08:00
|
|
|
use validator::Validate;
|
2024-06-03 14:27:28 +08:00
|
|
|
|
2024-08-01 23:13:35 +08:00
|
|
|
fn upgrade_ai_manager(ai_manager: AFPluginState<Weak<AIManager>>) -> FlowyResult<Arc<AIManager>> {
|
|
|
|
let ai_manager = ai_manager
|
2024-06-03 14:27:28 +08:00
|
|
|
.upgrade()
|
|
|
|
.ok_or(FlowyError::internal().with_context("The chat manager is already dropped"))?;
|
2024-08-01 23:13:35 +08:00
|
|
|
Ok(ai_manager)
|
2024-06-03 14:27:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
2024-06-09 14:02:32 +08:00
|
|
|
pub(crate) async fn stream_chat_message_handler(
|
|
|
|
data: AFPluginData<StreamChatPayloadPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-09 14:02:32 +08:00
|
|
|
) -> DataResult<ChatMessagePB, FlowyError> {
|
2024-06-03 14:27:28 +08:00
|
|
|
let data = data.into_inner();
|
|
|
|
data.validate()?;
|
|
|
|
|
|
|
|
let message_type = match data.message_type {
|
|
|
|
ChatMessageTypePB::System => ChatMessageType::System,
|
|
|
|
ChatMessageTypePB::User => ChatMessageType::User,
|
|
|
|
};
|
2024-12-08 18:25:25 +08:00
|
|
|
|
2024-08-06 07:56:13 +08:00
|
|
|
let metadata = data
|
|
|
|
.metadata
|
|
|
|
.into_iter()
|
2024-08-09 07:40:24 +08:00
|
|
|
.map(|metadata| {
|
2024-12-08 18:25:25 +08:00
|
|
|
let (content_type, content_len) = match metadata.loader_type {
|
|
|
|
ContextLoaderTypePB::Txt => (ContextLoader::Text, metadata.data.len()),
|
|
|
|
ContextLoaderTypePB::Markdown => (ContextLoader::Markdown, metadata.data.len()),
|
|
|
|
ContextLoaderTypePB::PDF => (ContextLoader::PDF, 0),
|
|
|
|
ContextLoaderTypePB::UnknownLoaderType => (ContextLoader::Unknown, 0),
|
2024-08-09 07:40:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
ChatMessageMetadata {
|
2024-11-14 00:51:07 +08:00
|
|
|
data: ChatRAGData {
|
2024-08-09 07:40:24 +08:00
|
|
|
content: metadata.data,
|
|
|
|
content_type,
|
|
|
|
size: content_len as i64,
|
|
|
|
},
|
|
|
|
id: metadata.id,
|
|
|
|
name: metadata.name.clone(),
|
|
|
|
source: metadata.source,
|
2024-11-14 00:51:07 +08:00
|
|
|
extra: None,
|
2024-08-09 07:40:24 +08:00
|
|
|
}
|
2024-08-06 07:56:13 +08:00
|
|
|
})
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
2024-08-09 21:55:20 +08:00
|
|
|
trace!("Stream chat message with metadata: {:?}", metadata);
|
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-08-13 23:36:44 +08:00
|
|
|
let result = ai_manager
|
|
|
|
.stream_chat_message(
|
|
|
|
&data.chat_id,
|
|
|
|
&data.message,
|
|
|
|
message_type,
|
|
|
|
data.answer_stream_port,
|
|
|
|
data.question_stream_port,
|
|
|
|
metadata,
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
data_result_ok(result)
|
2024-06-03 14:27:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn load_prev_message_handler(
|
|
|
|
data: AFPluginData<LoadPrevChatMessagePB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-03 14:27:28 +08:00
|
|
|
) -> DataResult<ChatMessageListPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-06-03 14:27:28 +08:00
|
|
|
let data = data.into_inner();
|
|
|
|
data.validate()?;
|
|
|
|
|
2024-08-01 23:13:35 +08:00
|
|
|
let messages = ai_manager
|
2024-06-03 14:27:28 +08:00
|
|
|
.load_prev_chat_messages(&data.chat_id, data.limit, data.before_message_id)
|
|
|
|
.await?;
|
|
|
|
data_result_ok(messages)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn load_next_message_handler(
|
|
|
|
data: AFPluginData<LoadNextChatMessagePB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-03 14:27:28 +08:00
|
|
|
) -> DataResult<ChatMessageListPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-06-03 14:27:28 +08:00
|
|
|
let data = data.into_inner();
|
|
|
|
data.validate()?;
|
|
|
|
|
2024-08-01 23:13:35 +08:00
|
|
|
let messages = ai_manager
|
2024-06-03 14:27:28 +08:00
|
|
|
.load_latest_chat_messages(&data.chat_id, data.limit, data.after_message_id)
|
|
|
|
.await?;
|
|
|
|
data_result_ok(messages)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_related_question_handler(
|
|
|
|
data: AFPluginData<ChatMessageIdPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-03 14:27:28 +08:00
|
|
|
) -> DataResult<RepeatedRelatedQuestionPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-06-03 14:27:28 +08:00
|
|
|
let data = data.into_inner();
|
2024-08-14 10:33:23 +08:00
|
|
|
let messages = ai_manager
|
|
|
|
.get_related_questions(&data.chat_id, data.message_id)
|
|
|
|
.await?;
|
2024-06-03 14:27:28 +08:00
|
|
|
data_result_ok(messages)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_answer_handler(
|
|
|
|
data: AFPluginData<ChatMessageIdPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-03 14:27:28 +08:00
|
|
|
) -> DataResult<ChatMessagePB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-06-03 14:27:28 +08:00
|
|
|
let data = data.into_inner();
|
2024-08-14 10:33:23 +08:00
|
|
|
let message = ai_manager
|
|
|
|
.generate_answer(&data.chat_id, data.message_id)
|
|
|
|
.await?;
|
2024-06-03 14:27:28 +08:00
|
|
|
data_result_ok(message)
|
|
|
|
}
|
2024-06-09 14:02:32 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn stop_stream_handler(
|
|
|
|
data: AFPluginData<StopStreamPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-06-09 14:02:32 +08:00
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let data = data.into_inner();
|
|
|
|
data.validate()?;
|
|
|
|
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
ai_manager.stop_stream(&data.chat_id).await?;
|
2024-06-09 14:02:32 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
2024-06-25 01:59:38 +02:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
2024-07-15 15:23:23 +08:00
|
|
|
pub(crate) async fn refresh_local_ai_info_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> DataResult<LLMModelInfoPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-08-14 16:58:56 +08:00
|
|
|
let model_info = ai_manager.local_ai_controller.refresh_model_info().await;
|
2024-08-14 10:33:23 +08:00
|
|
|
if model_info.is_err() {
|
|
|
|
if let Some(llm_model) = ai_manager.local_ai_controller.get_current_model() {
|
|
|
|
let model_info = LLMModelInfo {
|
|
|
|
selected_model: llm_model.clone(),
|
|
|
|
models: vec![llm_model],
|
|
|
|
};
|
|
|
|
return data_result_ok(model_info.into());
|
2024-07-18 20:54:35 +08:00
|
|
|
}
|
2024-08-14 10:33:23 +08:00
|
|
|
}
|
|
|
|
data_result_ok(model_info?.into())
|
2024-06-30 17:38:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
2024-07-15 15:23:23 +08:00
|
|
|
pub(crate) async fn update_local_llm_model_handler(
|
|
|
|
data: AFPluginData<LLMModelPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> DataResult<LocalModelResourcePB, FlowyError> {
|
2024-06-30 17:38:39 +08:00
|
|
|
let data = data.into_inner();
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let state = ai_manager
|
2024-07-15 15:23:23 +08:00
|
|
|
.local_ai_controller
|
2024-07-18 20:54:35 +08:00
|
|
|
.select_local_llm(data.llm_id)
|
2024-07-15 15:23:23 +08:00
|
|
|
.await?;
|
|
|
|
data_result_ok(state)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_local_llm_state_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> DataResult<LocalModelResourcePB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let state = ai_manager.local_ai_controller.get_local_llm_state().await?;
|
2024-07-15 15:23:23 +08:00
|
|
|
data_result_ok(state)
|
2024-06-30 17:38:39 +08:00
|
|
|
}
|
|
|
|
|
2024-06-25 01:59:38 +02:00
|
|
|
pub(crate) async fn start_complete_text_handler(
|
|
|
|
data: AFPluginData<CompleteTextPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
tools: AFPluginState<Arc<AICompletion>>,
|
2024-06-25 01:59:38 +02:00
|
|
|
) -> DataResult<CompleteTextTaskPB, FlowyError> {
|
|
|
|
let task = tools.create_complete_task(data.into_inner()).await?;
|
|
|
|
data_result_ok(task)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn stop_complete_text_handler(
|
|
|
|
data: AFPluginData<CompleteTextTaskPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
tools: AFPluginState<Arc<AICompletion>>,
|
2024-06-25 01:59:38 +02:00
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let data = data.into_inner();
|
|
|
|
tools.cancel_complete_task(&data.task_id).await;
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-07-15 15:23:23 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn chat_file_handler(
|
|
|
|
data: AFPluginData<ChatFilePB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let data = data.try_into_inner()?;
|
|
|
|
let file_path = PathBuf::from(&data.file_path);
|
2024-07-26 07:58:54 +08:00
|
|
|
|
|
|
|
let allowed_extensions = ["pdf", "md", "txt"];
|
|
|
|
let extension = file_path
|
|
|
|
.extension()
|
|
|
|
.and_then(|ext| ext.to_str())
|
|
|
|
.ok_or_else(|| {
|
|
|
|
FlowyError::new(
|
|
|
|
ErrorCode::UnsupportedFileFormat,
|
|
|
|
"Can't find file extension",
|
|
|
|
)
|
|
|
|
})?;
|
|
|
|
|
|
|
|
if !allowed_extensions.contains(&extension) {
|
|
|
|
return Err(FlowyError::new(
|
|
|
|
ErrorCode::UnsupportedFileFormat,
|
|
|
|
"Only support pdf,md and txt",
|
|
|
|
));
|
|
|
|
}
|
2024-08-08 12:07:00 +08:00
|
|
|
let file_size = fs::metadata(&file_path)
|
|
|
|
.map_err(|_| {
|
|
|
|
FlowyError::new(
|
|
|
|
ErrorCode::UnsupportedFileFormat,
|
|
|
|
"Failed to get file metadata",
|
|
|
|
)
|
|
|
|
})?
|
|
|
|
.len();
|
|
|
|
|
|
|
|
const MAX_FILE_SIZE: u64 = 10 * 1024 * 1024;
|
|
|
|
if file_size > MAX_FILE_SIZE {
|
|
|
|
return Err(FlowyError::new(
|
|
|
|
ErrorCode::PayloadTooLarge,
|
|
|
|
"File size is too large. Max file size is 10MB",
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
tracing::debug!("File size: {} bytes", file_size);
|
2024-08-14 10:33:23 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
ai_manager.chat_with_file(&data.chat_id, file_path).await?;
|
|
|
|
Ok(())
|
2024-07-15 15:23:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn download_llm_resource_handler(
|
|
|
|
data: AFPluginData<DownloadLLMPB>,
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> DataResult<DownloadTaskPB, FlowyError> {
|
|
|
|
let data = data.into_inner();
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-07-15 15:23:23 +08:00
|
|
|
let text_sink = IsolateSink::new(Isolate::new(data.progress_stream));
|
2024-08-01 23:13:35 +08:00
|
|
|
let task_id = ai_manager
|
2024-07-15 15:23:23 +08:00
|
|
|
.local_ai_controller
|
|
|
|
.start_downloading(text_sink)
|
|
|
|
.await?;
|
|
|
|
data_result_ok(DownloadTaskPB { task_id })
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn cancel_download_llm_resource_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 15:23:23 +08:00
|
|
|
) -> Result<(), FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
ai_manager.local_ai_controller.cancel_download()?;
|
2024-07-15 15:23:23 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_plugin_state_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIPluginStatePB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let state = ai_manager.local_ai_controller.get_chat_plugin_state();
|
2024-07-15 15:23:23 +08:00
|
|
|
data_result_ok(state)
|
|
|
|
}
|
2024-07-18 20:54:35 +08:00
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn toggle_local_ai_chat_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIChatPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let enabled = ai_manager
|
2024-07-18 20:54:35 +08:00
|
|
|
.local_ai_controller
|
|
|
|
.toggle_local_ai_chat()
|
|
|
|
.await?;
|
2024-08-01 23:13:35 +08:00
|
|
|
let file_enabled = ai_manager.local_ai_controller.is_rag_enabled();
|
|
|
|
let plugin_state = ai_manager.local_ai_controller.get_chat_plugin_state();
|
2024-07-18 20:54:35 +08:00
|
|
|
let pb = LocalAIChatPB {
|
|
|
|
enabled,
|
|
|
|
file_enabled,
|
|
|
|
plugin_state,
|
|
|
|
};
|
2024-12-08 18:25:25 +08:00
|
|
|
chat_notification_builder(
|
2024-07-18 20:54:35 +08:00
|
|
|
APPFLOWY_AI_NOTIFICATION_KEY,
|
|
|
|
ChatNotification::UpdateLocalChatAI,
|
|
|
|
)
|
|
|
|
.payload(pb.clone())
|
|
|
|
.send();
|
|
|
|
data_result_ok(pb)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn toggle_local_ai_chat_file_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIChatPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let enabled = ai_manager.local_ai_controller.is_chat_enabled();
|
|
|
|
let file_enabled = ai_manager
|
2024-07-18 20:54:35 +08:00
|
|
|
.local_ai_controller
|
|
|
|
.toggle_local_ai_chat_rag()
|
|
|
|
.await?;
|
2024-08-01 23:13:35 +08:00
|
|
|
let plugin_state = ai_manager.local_ai_controller.get_chat_plugin_state();
|
2024-07-18 20:54:35 +08:00
|
|
|
let pb = LocalAIChatPB {
|
|
|
|
enabled,
|
|
|
|
file_enabled,
|
|
|
|
plugin_state,
|
|
|
|
};
|
2024-12-08 18:25:25 +08:00
|
|
|
chat_notification_builder(
|
2024-07-18 20:54:35 +08:00
|
|
|
APPFLOWY_AI_NOTIFICATION_KEY,
|
|
|
|
ChatNotification::UpdateLocalChatAI,
|
|
|
|
)
|
|
|
|
.payload(pb.clone())
|
|
|
|
.send();
|
|
|
|
|
|
|
|
data_result_ok(pb)
|
|
|
|
}
|
2024-07-15 22:45:53 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
2024-07-18 20:54:35 +08:00
|
|
|
pub(crate) async fn get_local_ai_chat_state_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIChatPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let enabled = ai_manager.local_ai_controller.is_chat_enabled();
|
|
|
|
let file_enabled = ai_manager.local_ai_controller.is_rag_enabled();
|
|
|
|
let plugin_state = ai_manager.local_ai_controller.get_chat_plugin_state();
|
2024-07-18 20:54:35 +08:00
|
|
|
data_result_ok(LocalAIChatPB {
|
|
|
|
enabled,
|
|
|
|
file_enabled,
|
|
|
|
plugin_state,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn restart_local_ai_chat_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-15 22:45:53 +08:00
|
|
|
) -> Result<(), FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
ai_manager.local_ai_controller.restart_chat_plugin();
|
2024-07-15 22:45:53 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
2024-07-18 20:54:35 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn toggle_local_ai_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let enabled = ai_manager.local_ai_controller.toggle_local_ai().await?;
|
2024-07-18 20:54:35 +08:00
|
|
|
data_result_ok(LocalAIPB { enabled })
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_local_ai_state_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-18 20:54:35 +08:00
|
|
|
) -> DataResult<LocalAIPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let enabled = ai_manager.local_ai_controller.is_enabled();
|
2024-07-18 20:54:35 +08:00
|
|
|
data_result_ok(LocalAIPB { enabled })
|
|
|
|
}
|
2024-07-25 19:41:16 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_model_storage_directory_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-25 19:41:16 +08:00
|
|
|
) -> DataResult<LocalModelStoragePB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let file_path = ai_manager
|
2024-07-25 19:41:16 +08:00
|
|
|
.local_ai_controller
|
|
|
|
.get_model_storage_directory()?;
|
|
|
|
data_result_ok(LocalModelStoragePB { file_path })
|
|
|
|
}
|
2024-07-30 17:32:30 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_offline_app_handler(
|
2024-08-01 23:13:35 +08:00
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
2024-07-30 17:32:30 +08:00
|
|
|
) -> DataResult<OfflineAIPB, FlowyError> {
|
2024-08-01 23:13:35 +08:00
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
2024-08-14 10:33:23 +08:00
|
|
|
let link = ai_manager
|
|
|
|
.local_ai_controller
|
|
|
|
.get_offline_ai_app_download_link()
|
|
|
|
.await?;
|
2024-07-30 17:32:30 +08:00
|
|
|
data_result_ok(OfflineAIPB { link })
|
|
|
|
}
|
2024-08-06 07:56:13 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn create_chat_context_handler(
|
|
|
|
data: AFPluginData<CreateChatContextPB>,
|
|
|
|
_ai_manager: AFPluginState<Weak<AIManager>>,
|
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let _data = data.try_into_inner()?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-08-08 12:07:00 +08:00
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
|
|
|
pub(crate) async fn get_chat_info_handler(
|
|
|
|
data: AFPluginData<ChatId>,
|
|
|
|
ai_manager: AFPluginState<Weak<AIManager>>,
|
|
|
|
) -> DataResult<ChatInfoPB, FlowyError> {
|
|
|
|
let chat_id = data.try_into_inner()?.value;
|
|
|
|
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
|
|
|
let pb = ai_manager.get_chat_info(&chat_id).await?;
|
|
|
|
data_result_ok(pb)
|
|
|
|
}
|