diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart index e68ad2eb8d..dcb9a78902 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -74,7 +74,7 @@ class ChatAIMessageBloc extends Bloc { chatId: chatId, messageId: questionId, ); - ChatEventGetAnswerForQuestion(payload).send().then((result) { + AIEventGetAnswerForQuestion(payload).send().then((result) { if (!isClosed) { result.fold( (answer) { diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart index 4a14608d50..9533a97b64 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart @@ -5,7 +5,7 @@ import 'dart:isolate'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; @@ -70,7 +70,7 @@ class ChatBloc extends Bloc { chatId: state.view.id, limit: Int64(10), ); - ChatEventLoadNextMessage(payload).send().then( + AIEventLoadNextMessage(payload).send().then( (result) { result.fold((list) { if (!isClosed) { @@ -202,7 +202,7 @@ class ChatBloc extends Bloc { } final payload = StopStreamPB(chatId: chatId); - await ChatEventStopStream(payload).send(); + await AIEventStopStream(payload).send(); final allMessages = _perminentMessages(); if (state.streamingStatus != const LoadingState.finish()) { // If the streaming is not started, remove the message from the list @@ -273,7 +273,7 @@ class ChatBloc extends Bloc { messageId: state.lastSentMessage!.messageId, ); // When user message was sent to the server, we start gettting related question - ChatEventGetRelatedQuestion(payload).send().then((result) { + AIEventGetRelatedQuestion(payload).send().then((result) { if (!isClosed) { result.fold( (list) { @@ -322,7 +322,7 @@ class ChatBloc extends Bloc { limit: Int64(10), beforeMessageId: beforeMessageId, ); - ChatEventLoadPrevMessage(payload).send(); + AIEventLoadPrevMessage(payload).send(); } Future _startStreamingMessage( @@ -344,7 +344,7 @@ class ChatBloc extends Bloc { ); // Stream message to the server - final result = await ChatEventStreamMessage(payload).send(); + final result = await AIEventStreamMessage(payload).send(); result.fold( (ChatMessagePB question) { if (!isClosed) { diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_file_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_file_bloc.dart index b2e1dd397d..703093a5eb 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_file_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_file_bloc.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:appflowy/workspace/application/settings/ai/local_llm_listener.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -31,7 +31,7 @@ class ChatFileBloc extends Bloc { (event, emit) async { await event.when( initial: () async { - final result = await ChatEventGetLocalAIChatState().send(); + final result = await AIEventGetLocalAIChatState().send(); result.fold( (chatState) { if (!isClosed) { @@ -53,7 +53,7 @@ class ChatFileBloc extends Bloc { ); final payload = ChatFilePB(filePath: filePath, chatId: chatId); unawaited( - ChatEventChatWithFile(payload).send().then((result) { + AIEventChatWithFile(payload).send().then((result) { if (!isClosed) { result.fold((_) { add( diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_input_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_input_bloc.dart index 51f4222c68..5a4244da15 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_input_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_input_bloc.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:appflowy/workspace/application/settings/ai/local_llm_listener.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'chat_input_bloc.freezed.dart'; @@ -37,7 +37,7 @@ class ChatInputBloc extends Bloc { ) async { await event.when( started: () async { - final result = await ChatEventGetLocalAIPluginState().send(); + final result = await AIEventGetLocalAIPluginState().send(); result.fold( (pluginState) { if (!isClosed) { diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart index a26acd916f..4667806286 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'dart:typed_data'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/notification.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/notification.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; import 'package:appflowy_backend/rust_stream.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart index 194748858b..7dc1b550c3 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:appflowy/core/notification/notification_helper.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/notification.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/notification.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart'; import 'package:appflowy_backend/rust_stream.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart index 02b77664e8..22c8fa90de 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart @@ -1,6 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/ai_client.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/ai_client.dart index 19d68f58ba..801f15a77f 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/ai_client.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/ai_client.dart @@ -1,6 +1,6 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/error.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/text_completion.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; abstract class AIRepository { diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart index b2115ff5d7..3b52963125 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/ai_client.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pbenum.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pbenum.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:http/http.dart' as http; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/auto_completion_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/auto_completion_node_widget.dart index 34850c982b..45875b2aa9 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/auto_completion_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/auto_completion_node_widget.dart @@ -7,7 +7,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/wid import 'package:appflowy/user/application/ai_service.dart'; import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/appflowy_flutter/lib/user/application/ai_service.dart b/frontend/appflowy_flutter/lib/user/application/ai_service.dart index 59f8bf5008..175cb6f1fe 100644 --- a/frontend/appflowy_flutter/lib/user/application/ai_service.dart +++ b/frontend/appflowy_flutter/lib/user/application/ai_service.dart @@ -8,7 +8,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/ser import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/text_completion.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/smart_edit_action.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:fixnum/fixnum.dart' as fixnum; @@ -59,7 +59,7 @@ class AppFlowyAIService implements AIRepository { ); // ignore: unawaited_futures - ChatEventCompleteText(payload).send(); + AIEventCompleteText(payload).send(); return stream; } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart index e53915e95d..fdc3e8e3cd 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart @@ -5,7 +5,7 @@ import 'dart:isolate'; import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:fixnum/fixnum.dart'; @@ -47,7 +47,7 @@ class DownloadModelBloc extends Bloc { final payload = DownloadLLMPB(progressStream: Int64(downloadStream.nativePort)); - final result = await ChatEventDownloadLLMResource(payload).send(); + final result = await AIEventDownloadLLMResource(payload).send(); result.fold((_) { emit( state.copyWith( diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_offline_ai_app_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_offline_ai_app_bloc.dart index 292de1d237..829bd2f62a 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_offline_ai_app_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_offline_ai_app_bloc.dart @@ -18,7 +18,7 @@ class DownloadOfflineAIBloc ) async { await event.when( started: () async { - final result = await ChatEventGetOfflineAIAppLink().send(); + final result = await AIEventGetOfflineAIAppLink().send(); await result.fold( (app) async { await launchUrl(Uri.parse(app.link)); diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_bloc.dart index 6159e5b5aa..3c3d20039d 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_bloc.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:bloc/bloc.dart'; @@ -19,7 +19,7 @@ class LocalAIToggleBloc extends Bloc { ) async { await event.when( started: () async { - final result = await ChatEventGetLocalAIState().send(); + final result = await AIEventGetLocalAIState().send(); _handleResult(emit, result); }, toggle: () async { @@ -29,7 +29,7 @@ class LocalAIToggleBloc extends Bloc { ), ); unawaited( - ChatEventToggleLocalAI().send().then( + AIEventToggleLocalAI().send().then( (result) { if (!isClosed) { add(LocalAIToggleEvent.handleResult(result)); diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_bloc.dart index 41da184498..03d4202027 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_bloc.dart @@ -4,7 +4,7 @@ import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; import 'package:appflowy/workspace/application/settings/ai/local_llm_listener.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:bloc/bloc.dart'; @@ -60,7 +60,7 @@ class LocalAIChatSettingBloc ); }, selectLLMConfig: (LLMModelPB llmModel) async { - final result = await ChatEventUpdateLocalLLM(llmModel).send(); + final result = await AIEventUpdateLocalLLM(llmModel).send(); result.fold( (llmResource) { // If all resources are downloaded, show reload plugin @@ -144,7 +144,7 @@ class LocalAIChatSettingBloc ); }, cancelDownload: () async { - final _ = await ChatEventCancelDownloadLLMResource().send(); + final _ = await AIEventCancelDownloadLLMResource().send(); _fetchCurremtLLMState(); }, finishDownload: () async { @@ -156,7 +156,7 @@ class LocalAIChatSettingBloc }, updatePluginState: (LocalAIPluginStatePB pluginState) { if (pluginState.offlineAiReady) { - ChatEventRefreshLocalAIModelInfo().send().then((result) { + AIEventRefreshLocalAIModelInfo().send().then((result) { if (!isClosed) { add(LocalAIChatSettingEvent.didLoadModelInfo(result)); } @@ -188,7 +188,7 @@ class LocalAIChatSettingBloc } void _fetchCurremtLLMState() async { - final result = await ChatEventGetLocalLLMState().send(); + final result = await AIEventGetLocalLLMState().send(); result.fold( (llmResource) { if (!isClosed) { @@ -203,13 +203,13 @@ class LocalAIChatSettingBloc /// Handles the event to fetch local AI settings when the application starts. Future _handleStarted() async { - final result = await ChatEventGetLocalAIPluginState().send(); + final result = await AIEventGetLocalAIPluginState().send(); result.fold( (pluginState) async { if (!isClosed) { add(LocalAIChatSettingEvent.updatePluginState(pluginState)); if (pluginState.offlineAiReady) { - final result = await ChatEventRefreshLocalAIModelInfo().send(); + final result = await AIEventRefreshLocalAIModelInfo().send(); if (!isClosed) { add(LocalAIChatSettingEvent.didLoadModelInfo(result)); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_toggle_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_toggle_bloc.dart index aea17c36cc..4feac1247a 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_toggle_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_chat_toggle_bloc.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:bloc/bloc.dart'; @@ -20,7 +20,7 @@ class LocalAIChatToggleBloc ) async { await event.when( started: () async { - final result = await ChatEventGetLocalAIChatState().send(); + final result = await AIEventGetLocalAIChatState().send(); _handleResult(emit, result); }, toggle: () async { @@ -30,7 +30,7 @@ class LocalAIChatToggleBloc ), ); unawaited( - ChatEventToggleLocalAIChat().send().then( + AIEventToggleLocalAIChat().send().then( (result) { if (!isClosed) { add(LocalAIChatToggleEvent.handleResult(result)); diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_llm_listener.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_llm_listener.dart index dfbe9cc771..a7778d7d99 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_llm_listener.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_llm_listener.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:appflowy/plugins/ai_chat/application/chat_notification.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; import 'package:appflowy_backend/rust_stream.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/plugin_state_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/plugin_state_bloc.dart index c1f504ab2b..41070e2fe4 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/plugin_state_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/plugin_state_bloc.dart @@ -4,7 +4,7 @@ import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/workspace/application/settings/ai/local_llm_listener.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:url_launcher/url_launcher.dart' show launchUrl; @@ -43,7 +43,7 @@ class PluginStateBloc extends Bloc { ) async { await event.when( started: () async { - final result = await ChatEventGetLocalAIPluginState().send(); + final result = await AIEventGetLocalAIPluginState().send(); result.fold( (pluginState) { if (!isClosed) { @@ -85,10 +85,10 @@ class PluginStateBloc extends Bloc { emit( const PluginStateState(action: PluginStateAction.loadingPlugin()), ); - unawaited(ChatEventRestartLocalAIChat().send()); + unawaited(AIEventRestartLocalAIChat().send()); }, openModelDirectory: () async { - final result = await ChatEventGetModelStorageDirectory().send(); + final result = await AIEventGetModelStorageDirectory().send(); result.fold( (data) { afLaunchUrl(Uri.file(data.filePath)); @@ -97,7 +97,7 @@ class PluginStateBloc extends Bloc { ); }, downloadOfflineAIApp: () async { - final result = await ChatEventGetOfflineAIAppLink().send(); + final result = await AIEventGetOfflineAIAppLink().send(); await result.fold( (app) async { await launchUrl(Uri.parse(app.link)); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart index a9bfb6d2d4..dccc01dcc8 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart @@ -1,6 +1,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/ai/download_model_bloc.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart index 9b10acddfa..d924b46825 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart @@ -1,7 +1,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/settings/ai/local_ai_chat_bloc.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_chat_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_chat_setting.dart index f7a61bd4f7..a87c0ddea7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_chat_setting.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_chat_setting.dart @@ -7,7 +7,7 @@ import 'package:appflowy/workspace/presentation/settings/pages/setting_ai_view/i import 'package:appflowy/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:expandable/expandable.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart index 67a7103503..bf601b6184 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart @@ -106,19 +106,28 @@ class _LocalAIReadyToUse extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const HSpace(8), - const FlowySvg( - FlowySvgs.download_success_s, - color: Color(0xFF2E7D32), + Flexible( + child: Row( + children: [ + const HSpace(8), + const FlowySvg( + FlowySvgs.download_success_s, + color: Color(0xFF2E7D32), + ), + const HSpace(6), + Flexible( + child: FlowyText( + LocaleKeys.settings_aiPage_keys_localAILoaded.tr(), + fontSize: 11, + color: const Color(0xFF1E4620), + maxLines: 3, + ), + ), + ], + ), ), - const HSpace(6), - FlowyText( - LocaleKeys.settings_aiPage_keys_localAILoaded.tr(), - fontSize: 11, - color: const Color(0xFF1E4620), - ), - const Spacer(), Padding( padding: const EdgeInsets.symmetric(horizontal: 6), child: FlowyButton( diff --git a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart index 621b0e3154..746e95fbd8 100644 --- a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart +++ b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart @@ -16,7 +16,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-search/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; -import 'package:appflowy_backend/protobuf/flowy-chat/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-ai/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:ffi/ffi.dart'; import 'package:isolates/isolates.dart'; @@ -37,7 +37,7 @@ part 'dart_event/flowy-document/dart_event.dart'; part 'dart_event/flowy-config/dart_event.dart'; part 'dart_event/flowy-date/dart_event.dart'; part 'dart_event/flowy-search/dart_event.dart'; -part 'dart_event/flowy-chat/dart_event.dart'; +part 'dart_event/flowy-ai/dart_event.dart'; enum FFIException { RequestIsEmpty, diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index df5be78b17..f594230085 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -172,7 +172,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -192,7 +192,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -206,7 +206,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "appflowy-plugin", @@ -225,7 +225,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "cfg-if", @@ -248,7 +248,7 @@ version = "0.0.0" dependencies = [ "bytes", "dotenv", - "flowy-chat", + "flowy-ai", "flowy-config", "flowy-core", "flowy-date", @@ -825,7 +825,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "again", "anyhow", @@ -875,7 +875,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "collab-entity", "collab-rt-entity", @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "futures-channel", "futures-util", @@ -1131,7 +1131,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -1156,7 +1156,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "async-trait", @@ -1531,7 +1531,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -1950,16 +1950,7 @@ dependencies = [ ] [[package]] -name = "flowy-ast" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "flowy-chat" +name = "flowy-ai" version = "0.1.0" dependencies = [ "allo-isolate", @@ -1969,7 +1960,7 @@ dependencies = [ "base64 0.21.5", "bytes", "dashmap", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-codegen", "flowy-derive", "flowy-error", @@ -2000,7 +1991,7 @@ dependencies = [ ] [[package]] -name = "flowy-chat-pub" +name = "flowy-ai-pub" version = "0.1.0" dependencies = [ "bytes", @@ -2010,6 +2001,15 @@ dependencies = [ "lib-infra", ] +[[package]] +name = "flowy-ast" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -2061,8 +2061,8 @@ dependencies = [ "collab-integrate", "collab-plugins", "diesel", - "flowy-chat", - "flowy-chat-pub", + "flowy-ai", + "flowy-ai-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -2407,7 +2407,7 @@ dependencies = [ "collab-entity", "collab-folder", "collab-plugins", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "futures-util", @@ -3064,7 +3064,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -3496,7 +3496,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -6094,7 +6094,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 4e890684df..add6956acc 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -53,7 +53,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0062c950677f7f633f5b7edabc827a35d3bc92c3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "8f61e6d03469aac73b9ad88e37ac6898a691289d" } [dependencies] serde_json.workspace = true @@ -76,7 +76,7 @@ flowy-core = { path = "../../rust-lib/flowy-core", features = [ flowy-user = { path = "../../rust-lib/flowy-user", features = ["tauri_ts"] } flowy-config = { path = "../../rust-lib/flowy-config", features = ["tauri_ts"] } flowy-date = { path = "../../rust-lib/flowy-date", features = ["tauri_ts"] } -flowy-chat = { path = "../../rust-lib/flowy-chat", features = ["tauri_ts"] } +flowy-ai = { path = "../../rust-lib/flowy-ai", features = ["tauri_ts"] } flowy-error = { path = "../../rust-lib/flowy-error", features = [ "impl_from_sqlite", "impl_from_dispatch_error", @@ -128,5 +128,5 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy- # To update the commit ID, run: # scripts/tool/update_local_ai_rev.sh new_rev_id # ⚠️⚠️⚠️️ -appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index ecc23d8566..028a347b69 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "appflowy-plugin", @@ -216,7 +216,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "cfg-if", @@ -239,7 +239,7 @@ version = "0.0.0" dependencies = [ "bytes", "dotenv", - "flowy-chat", + "flowy-ai", "flowy-config", "flowy-core", "flowy-date", @@ -799,7 +799,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "again", "anyhow", @@ -849,7 +849,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "collab-entity", "collab-rt-entity", @@ -861,7 +861,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "futures-channel", "futures-util", @@ -1114,7 +1114,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -1139,7 +1139,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "async-trait", @@ -1521,7 +1521,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -1980,16 +1980,7 @@ dependencies = [ ] [[package]] -name = "flowy-ast" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "flowy-chat" +name = "flowy-ai" version = "0.1.0" dependencies = [ "allo-isolate", @@ -1999,7 +1990,7 @@ dependencies = [ "base64 0.21.7", "bytes", "dashmap", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-codegen", "flowy-derive", "flowy-error", @@ -2030,7 +2021,7 @@ dependencies = [ ] [[package]] -name = "flowy-chat-pub" +name = "flowy-ai-pub" version = "0.1.0" dependencies = [ "bytes", @@ -2040,6 +2031,15 @@ dependencies = [ "lib-infra", ] +[[package]] +name = "flowy-ast" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -2091,8 +2091,8 @@ dependencies = [ "collab-integrate", "collab-plugins", "diesel", - "flowy-chat", - "flowy-chat-pub", + "flowy-ai", + "flowy-ai-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -2437,7 +2437,7 @@ dependencies = [ "collab-entity", "collab-folder", "collab-plugins", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "futures-util", @@ -3131,7 +3131,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -3568,7 +3568,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -6158,7 +6158,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index 43b6c4fb52..aae0b746fe 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0062c950677f7f633f5b7edabc827a35d3bc92c3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "8f61e6d03469aac73b9ad88e37ac6898a691289d" } [dependencies] serde_json.workspace = true @@ -89,7 +89,7 @@ flowy-document = { path = "../../rust-lib/flowy-document", features = [ flowy-notification = { path = "../../rust-lib/flowy-notification", features = [ "tauri_ts", ] } -flowy-chat = { path = "../../rust-lib/flowy-chat", features = [ +flowy-ai = { path = "../../rust-lib/flowy-ai", features = [ "tauri_ts", ] } @@ -128,6 +128,6 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy- # To update the commit ID, run: # scripts/tool/update_local_ai_rev.sh new_rev_id # ⚠️⚠️⚠️️ -appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index d36fec34eb..f496fecda5 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -657,7 +657,7 @@ "downloadLLMPrompt": "Download {}", "downloadAppFlowyOfflineAI": "Downloading AI offline package will enable AI to run on your device. Do you want to continue?", "downloadLLMPromptDetail": "Downloading {} local model will take up to {} of storage. Do you want to continue?", - "downloadAIModelButton": "Download AI model", + "downloadAIModelButton": "Download", "downloadingModel": "Downloading", "localAILoaded": "Local AI Model successfully added and ready to use", "localAIStart": "Local AI Chat is starting...", diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 9d69cad905..24b838922d 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "appflowy-plugin", @@ -216,7 +216,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec#8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=7dd879a6b9b3246e5cd06f1647e620553db9b960#7dd879a6b9b3246e5cd06f1647e620553db9b960" dependencies = [ "anyhow", "cfg-if", @@ -717,7 +717,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "again", "anyhow", @@ -767,7 +767,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "collab-entity", "collab-rt-entity", @@ -779,7 +779,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "futures-channel", "futures-util", @@ -992,7 +992,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bincode", @@ -1017,7 +1017,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "async-trait", @@ -1255,7 +1255,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1355,7 +1355,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -1624,8 +1624,8 @@ dependencies = [ "collab-folder", "collab-plugins", "dotenv", - "flowy-chat", - "flowy-chat-pub", + "flowy-ai", + "flowy-ai-pub", "flowy-core", "flowy-database-pub", "flowy-database2", @@ -1773,16 +1773,7 @@ dependencies = [ ] [[package]] -name = "flowy-ast" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "flowy-chat" +name = "flowy-ai" version = "0.1.0" dependencies = [ "allo-isolate", @@ -1793,7 +1784,7 @@ dependencies = [ "bytes", "dashmap", "dotenv", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-codegen", "flowy-derive", "flowy-error", @@ -1826,7 +1817,7 @@ dependencies = [ ] [[package]] -name = "flowy-chat-pub" +name = "flowy-ai-pub" version = "0.1.0" dependencies = [ "bytes", @@ -1836,6 +1827,15 @@ dependencies = [ "lib-infra", ] +[[package]] +name = "flowy-ast" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -1879,6 +1879,7 @@ name = "flowy-core" version = "0.1.0" dependencies = [ "anyhow", + "appflowy-local-ai", "base64 0.21.5", "bytes", "client-api", @@ -1888,8 +1889,8 @@ dependencies = [ "collab-plugins", "console-subscriber", "diesel", - "flowy-chat", - "flowy-chat-pub", + "flowy-ai", + "flowy-ai-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -2240,7 +2241,7 @@ dependencies = [ "collab-folder", "collab-plugins", "dotenv", - "flowy-chat-pub", + "flowy-ai-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -2726,7 +2727,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "futures-util", @@ -2743,7 +2744,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", @@ -3108,7 +3109,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "bytes", @@ -4064,7 +4065,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -4084,7 +4085,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -4152,19 +4152,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.47", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -5317,7 +5304,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=0062c950677f7f633f5b7edabc827a35d3bc92c3#0062c950677f7f633f5b7edabc827a35d3bc92c3" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=8f61e6d03469aac73b9ad88e37ac6898a691289d#8f61e6d03469aac73b9ad88e37ac6898a691289d" dependencies = [ "anyhow", "app-error", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 256f25bd31..ebf85f85c2 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -29,8 +29,8 @@ members = [ "build-tool/flowy-codegen", "build-tool/flowy-derive", "flowy-search-pub", - "flowy-chat", - "flowy-chat-pub", + "flowy-ai", + "flowy-ai-pub", "flowy-storage-pub", ] resolver = "2" @@ -65,8 +65,8 @@ flowy-search = { workspace = true, path = "flowy-search" } flowy-search-pub = { workspace = true, path = "flowy-search-pub" } collab-integrate = { workspace = true, path = "collab-integrate" } flowy-date = { workspace = true, path = "flowy-date" } -flowy-chat = { workspace = true, path = "flowy-chat" } -flowy-chat-pub = { workspace = true, path = "flowy-chat-pub" } +flowy-ai = { workspace = true, path = "flowy-ai" } +flowy-ai-pub = { workspace = true, path = "flowy-ai-pub" } anyhow = "1.0" tracing = "0.1.40" bytes = "1.5.0" @@ -99,8 +99,8 @@ zip = "2.1.3" # Run the script.add_workspace_members: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0062c950677f7f633f5b7edabc827a35d3bc92c3" } -client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "0062c950677f7f633f5b7edabc827a35d3bc92c3" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "8f61e6d03469aac73b9ad88e37ac6898a691289d" } +client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "8f61e6d03469aac73b9ad88e37ac6898a691289d" } [profile.dev] opt-level = 0 @@ -147,5 +147,5 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy- # To update the commit ID, run: # scripts/tool/update_local_ai_rev.sh new_rev_id # ⚠️⚠️⚠️️ -appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "8ef7d3e4c38fbf92ff9b3630fe79017e95a496ec" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "7dd879a6b9b3246e5cd06f1647e620553db9b960" } diff --git a/frontend/rust-lib/event-integration-test/Cargo.toml b/frontend/rust-lib/event-integration-test/Cargo.toml index b836e8a40c..01f2f2aad3 100644 --- a/frontend/rust-lib/event-integration-test/Cargo.toml +++ b/frontend/rust-lib/event-integration-test/Cargo.toml @@ -16,7 +16,7 @@ flowy-database-pub = { workspace = true } flowy-document = { path = "../flowy-document" } flowy-document-pub = { workspace = true } flowy-encrypt = { workspace = true } -flowy-chat = { workspace = true } +flowy-ai = { workspace = true } lib-dispatch = { workspace = true } lib-infra = { workspace = true } flowy-server = { path = "../flowy-server" } @@ -58,7 +58,7 @@ chrono = "0.4.31" zip.workspace = true walkdir = "2.5.0" futures = "0.3.30" -flowy-chat-pub = { workspace = true } +flowy-ai-pub = { workspace = true } [features] default = ["supabase_cloud_test"] diff --git a/frontend/rust-lib/event-integration-test/src/chat_event.rs b/frontend/rust-lib/event-integration-test/src/chat_event.rs index 2371820f84..f7ecf2d886 100644 --- a/frontend/rust-lib/event-integration-test/src/chat_event.rs +++ b/frontend/rust-lib/event-integration-test/src/chat_event.rs @@ -1,10 +1,10 @@ use crate::event_builder::EventBuilder; use crate::EventIntegrationTest; -use flowy_chat::entities::{ +use flowy_ai::entities::{ ChatMessageListPB, ChatMessageTypePB, CompleteTextPB, CompleteTextTaskPB, CompletionTypePB, LoadNextChatMessagePB, LoadPrevChatMessagePB, SendChatPayloadPB, }; -use flowy_chat::event_map::ChatEvent; +use flowy_ai::event_map::AIEvent; use flowy_folder::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB}; use flowy_folder::event_map::FolderEvent; @@ -45,7 +45,7 @@ impl EventIntegrationTest { }; EventBuilder::new(self.clone()) - .event(ChatEvent::StreamMessage) + .event(AIEvent::StreamMessage) .payload(payload) .async_send() .await; @@ -63,7 +63,7 @@ impl EventIntegrationTest { before_message_id, }; EventBuilder::new(self.clone()) - .event(ChatEvent::LoadPrevMessage) + .event(AIEvent::LoadPrevMessage) .payload(payload) .async_send() .await @@ -82,7 +82,7 @@ impl EventIntegrationTest { after_message_id, }; EventBuilder::new(self.clone()) - .event(ChatEvent::LoadNextMessage) + .event(AIEvent::LoadNextMessage) .payload(payload) .async_send() .await @@ -100,7 +100,7 @@ impl EventIntegrationTest { stream_port: 0, }; EventBuilder::new(self.clone()) - .event(ChatEvent::CompleteText) + .event(AIEvent::CompleteText) .payload(payload) .async_send() .await diff --git a/frontend/rust-lib/event-integration-test/tests/chat/ai_tool_test.rs b/frontend/rust-lib/event-integration-test/tests/chat/ai_tool_test.rs index 3bef3a81b0..51b6b05c0e 100644 --- a/frontend/rust-lib/event-integration-test/tests/chat/ai_tool_test.rs +++ b/frontend/rust-lib/event-integration-test/tests/chat/ai_tool_test.rs @@ -1,6 +1,6 @@ use event_integration_test::user_event::user_localhost_af_cloud; use event_integration_test::EventIntegrationTest; -use flowy_chat::entities::CompletionTypePB; +use flowy_ai::entities::CompletionTypePB; use std::time::Duration; diff --git a/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs index 8e84dfe827..5967cfec27 100644 --- a/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs +++ b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs @@ -1,10 +1,10 @@ use crate::util::receive_with_timeout; use event_integration_test::user_event::user_localhost_af_cloud; use event_integration_test::EventIntegrationTest; -use flowy_chat::entities::ChatMessageListPB; -use flowy_chat::notification::ChatNotification; +use flowy_ai::entities::ChatMessageListPB; +use flowy_ai::notification::ChatNotification; -use flowy_chat_pub::cloud::ChatMessageType; +use flowy_ai_pub::cloud::ChatMessageType; use std::time::Duration; diff --git a/frontend/rust-lib/flowy-chat-pub/Cargo.toml b/frontend/rust-lib/flowy-ai-pub/Cargo.toml similarity index 85% rename from frontend/rust-lib/flowy-chat-pub/Cargo.toml rename to frontend/rust-lib/flowy-ai-pub/Cargo.toml index f320fb2133..426ec7b5e0 100644 --- a/frontend/rust-lib/flowy-chat-pub/Cargo.toml +++ b/frontend/rust-lib/flowy-ai-pub/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "flowy-chat-pub" +name = "flowy-ai-pub" version = "0.1.0" edition = "2021" diff --git a/frontend/rust-lib/flowy-chat-pub/src/cloud.rs b/frontend/rust-lib/flowy-ai-pub/src/cloud.rs similarity index 100% rename from frontend/rust-lib/flowy-chat-pub/src/cloud.rs rename to frontend/rust-lib/flowy-ai-pub/src/cloud.rs diff --git a/frontend/rust-lib/flowy-chat-pub/src/lib.rs b/frontend/rust-lib/flowy-ai-pub/src/lib.rs similarity index 100% rename from frontend/rust-lib/flowy-chat-pub/src/lib.rs rename to frontend/rust-lib/flowy-ai-pub/src/lib.rs diff --git a/frontend/rust-lib/flowy-chat/Cargo.toml b/frontend/rust-lib/flowy-ai/Cargo.toml similarity index 97% rename from frontend/rust-lib/flowy-chat/Cargo.toml rename to frontend/rust-lib/flowy-ai/Cargo.toml index 955bc32e3d..750c912cf4 100644 --- a/frontend/rust-lib/flowy-chat/Cargo.toml +++ b/frontend/rust-lib/flowy-ai/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "flowy-chat" +name = "flowy-ai" version = "0.1.0" edition = "2021" @@ -21,7 +21,7 @@ protobuf.workspace = true bytes.workspace = true validator = { workspace = true, features = ["derive"] } lib-infra = { workspace = true, features = ["isolate_flutter"] } -flowy-chat-pub.workspace = true +flowy-ai-pub.workspace = true dashmap = "5.5" flowy-sqlite = { workspace = true } tokio.workspace = true diff --git a/frontend/rust-lib/flowy-chat/Flowy.toml b/frontend/rust-lib/flowy-ai/Flowy.toml similarity index 100% rename from frontend/rust-lib/flowy-chat/Flowy.toml rename to frontend/rust-lib/flowy-ai/Flowy.toml diff --git a/frontend/rust-lib/flowy-chat/build.rs b/frontend/rust-lib/flowy-ai/build.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/build.rs rename to frontend/rust-lib/flowy-ai/build.rs diff --git a/frontend/rust-lib/flowy-chat/dev.env b/frontend/rust-lib/flowy-ai/dev.env similarity index 100% rename from frontend/rust-lib/flowy-chat/dev.env rename to frontend/rust-lib/flowy-ai/dev.env diff --git a/frontend/rust-lib/flowy-chat/src/chat_manager.rs b/frontend/rust-lib/flowy-ai/src/ai_manager.rs similarity index 92% rename from frontend/rust-lib/flowy-chat/src/chat_manager.rs rename to frontend/rust-lib/flowy-ai/src/ai_manager.rs index 78a05496c4..f1c2fc4191 100644 --- a/frontend/rust-lib/flowy-chat/src/chat_manager.rs +++ b/frontend/rust-lib/flowy-ai/src/ai_manager.rs @@ -1,12 +1,12 @@ use crate::chat::Chat; use crate::entities::{ChatMessageListPB, ChatMessagePB, RepeatedRelatedQuestionPB}; use crate::local_ai::local_llm_chat::LocalAIController; -use crate::middleware::chat_service_mw::CloudServiceMiddleware; +use crate::middleware::chat_service_mw::AICloudServiceMiddleware; use crate::persistence::{insert_chat, ChatTable}; use appflowy_plugin::manager::PluginManager; use dashmap::DashMap; -use flowy_chat_pub::cloud::{ChatCloudService, ChatMessageType}; +use flowy_ai_pub::cloud::{ChatCloudService, ChatMessageType}; use flowy_error::{FlowyError, FlowyResult}; use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::DBConnection; @@ -16,7 +16,7 @@ use std::path::PathBuf; use std::sync::Arc; use tracing::{info, trace}; -pub trait ChatUserService: Send + Sync + 'static { +pub trait AIUserService: Send + Sync + 'static { fn user_id(&self) -> Result; fn device_id(&self) -> Result; fn workspace_id(&self) -> Result; @@ -24,32 +24,32 @@ pub trait ChatUserService: Send + Sync + 'static { fn data_root_dir(&self) -> Result; } -pub struct ChatManager { - pub cloud_service_wm: Arc, - pub user_service: Arc, +pub struct AIManager { + pub cloud_service_wm: Arc, + pub user_service: Arc, chats: Arc>>, pub local_ai_controller: Arc, } -impl ChatManager { +impl AIManager { pub fn new( - cloud_service: Arc, - user_service: impl ChatUserService, + chat_cloud_service: Arc, + user_service: impl AIUserService, store_preferences: Arc, - ) -> ChatManager { + ) -> AIManager { let user_service = Arc::new(user_service); let plugin_manager = Arc::new(PluginManager::new()); let local_ai_controller = Arc::new(LocalAIController::new( plugin_manager.clone(), store_preferences.clone(), user_service.clone(), - cloud_service.clone(), + chat_cloud_service.clone(), )); // setup local chat service - let cloud_service_wm = Arc::new(CloudServiceMiddleware::new( + let cloud_service_wm = Arc::new(AICloudServiceMiddleware::new( user_service.clone(), - cloud_service, + chat_cloud_service, local_ai_controller.clone(), )); diff --git a/frontend/rust-lib/flowy-chat/src/chat.rs b/frontend/rust-lib/flowy-ai/src/chat.rs similarity index 97% rename from frontend/rust-lib/flowy-chat/src/chat.rs rename to frontend/rust-lib/flowy-ai/src/chat.rs index b6e08a0339..af67d8ed83 100644 --- a/frontend/rust-lib/flowy-chat/src/chat.rs +++ b/frontend/rust-lib/flowy-ai/src/chat.rs @@ -1,12 +1,12 @@ -use crate::chat_manager::ChatUserService; +use crate::ai_manager::AIUserService; use crate::entities::{ ChatMessageErrorPB, ChatMessageListPB, ChatMessagePB, RepeatedRelatedQuestionPB, }; -use crate::middleware::chat_service_mw::CloudServiceMiddleware; +use crate::middleware::chat_service_mw::AICloudServiceMiddleware; use crate::notification::{make_notification, ChatNotification}; use crate::persistence::{insert_chat_messages, select_chat_messages, ChatMessageTable}; use allo_isolate::Isolate; -use flowy_chat_pub::cloud::{ChatCloudService, ChatMessage, ChatMessageType, MessageCursor}; +use flowy_ai_pub::cloud::{ChatCloudService, ChatMessage, ChatMessageType, MessageCursor}; use flowy_error::{FlowyError, FlowyResult}; use flowy_sqlite::DBConnection; use futures::{SinkExt, StreamExt}; @@ -26,8 +26,8 @@ enum PrevMessageState { pub struct Chat { chat_id: String, uid: i64, - user_service: Arc, - chat_service: Arc, + user_service: Arc, + chat_service: Arc, prev_message_state: Arc>, latest_message_id: Arc, stop_stream: Arc, @@ -38,8 +38,8 @@ impl Chat { pub fn new( uid: i64, chat_id: String, - user_service: Arc, - chat_service: Arc, + user_service: Arc, + chat_service: Arc, ) -> Chat { Chat { uid, @@ -189,7 +189,7 @@ impl Chat { fn save_answer( uid: i64, chat_id: &str, - user_service: &Arc, + user_service: &Arc, answer: ChatMessage, ) -> Result<(), FlowyError> { save_chat_message( diff --git a/frontend/rust-lib/flowy-chat/src/tools.rs b/frontend/rust-lib/flowy-ai/src/completion.rs similarity index 91% rename from frontend/rust-lib/flowy-chat/src/tools.rs rename to frontend/rust-lib/flowy-ai/src/completion.rs index 0219bbe230..ebb7f1f7a8 100644 --- a/frontend/rust-lib/flowy-chat/src/tools.rs +++ b/frontend/rust-lib/flowy-ai/src/completion.rs @@ -1,9 +1,9 @@ -use crate::chat_manager::ChatUserService; +use crate::ai_manager::AIUserService; use crate::entities::{CompleteTextPB, CompleteTextTaskPB, CompletionTypePB}; use allo_isolate::Isolate; use dashmap::DashMap; -use flowy_chat_pub::cloud::{ChatCloudService, CompletionType}; +use flowy_ai_pub::cloud::{ChatCloudService, CompletionType}; use flowy_error::{FlowyError, FlowyResult}; use futures::{SinkExt, StreamExt}; @@ -12,16 +12,16 @@ use lib_infra::isolate_stream::IsolateSink; use std::sync::{Arc, Weak}; use tokio::select; -pub struct AITools { +pub struct AICompletion { tasks: Arc>>, cloud_service: Weak, - user_service: Weak, + user_service: Weak, } -impl AITools { +impl AICompletion { pub fn new( cloud_service: Weak, - user_service: Weak, + user_service: Weak, ) -> Self { Self { tasks: Arc::new(DashMap::new()), @@ -40,7 +40,7 @@ impl AITools { .ok_or_else(FlowyError::internal)? .workspace_id()?; let (tx, rx) = tokio::sync::mpsc::channel(1); - let task = ToolTask::new(workspace_id, complete, self.cloud_service.clone(), rx); + let task = CompletionTask::new(workspace_id, complete, self.cloud_service.clone(), rx); let task_id = task.task_id.clone(); self.tasks.insert(task_id.clone(), tx); @@ -55,7 +55,7 @@ impl AITools { } } -pub struct ToolTask { +pub struct CompletionTask { workspace_id: String, task_id: String, stop_rx: tokio::sync::mpsc::Receiver<()>, @@ -63,7 +63,7 @@ pub struct ToolTask { cloud_service: Weak, } -impl ToolTask { +impl CompletionTask { pub fn new( workspace_id: String, context: CompleteTextPB, diff --git a/frontend/rust-lib/flowy-chat/src/entities.rs b/frontend/rust-lib/flowy-ai/src/entities.rs similarity index 99% rename from frontend/rust-lib/flowy-chat/src/entities.rs rename to frontend/rust-lib/flowy-ai/src/entities.rs index f96be7d9c8..05106ed99b 100644 --- a/frontend/rust-lib/flowy-chat/src/entities.rs +++ b/frontend/rust-lib/flowy-ai/src/entities.rs @@ -2,7 +2,7 @@ use crate::local_ai::local_llm_chat::LLMModelInfo; use appflowy_plugin::core::plugin::RunningState; use crate::local_ai::local_llm_resource::PendingResource; -use flowy_chat_pub::cloud::{ +use flowy_ai_pub::cloud::{ ChatMessage, LLMModel, RelatedQuestion, RepeatedChatMessage, RepeatedRelatedQuestion, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; diff --git a/frontend/rust-lib/flowy-chat/src/event_handler.rs b/frontend/rust-lib/flowy-ai/src/event_handler.rs similarity index 67% rename from frontend/rust-lib/flowy-chat/src/event_handler.rs rename to frontend/rust-lib/flowy-ai/src/event_handler.rs index cfacad115e..20ef4f9c03 100644 --- a/frontend/rust-lib/flowy-chat/src/event_handler.rs +++ b/frontend/rust-lib/flowy-ai/src/event_handler.rs @@ -1,4 +1,4 @@ -use flowy_chat_pub::cloud::ChatMessageType; +use flowy_ai_pub::cloud::ChatMessageType; use std::path::PathBuf; @@ -7,30 +7,28 @@ use std::sync::{Arc, Weak}; use tokio::sync::oneshot; use validator::Validate; -use crate::chat_manager::ChatManager; +use crate::ai_manager::AIManager; +use crate::completion::AICompletion; use crate::entities::*; use crate::local_ai::local_llm_chat::LLMModelInfo; use crate::notification::{make_notification, ChatNotification, APPFLOWY_AI_NOTIFICATION_KEY}; -use crate::tools::AITools; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; use lib_infra::isolate_stream::IsolateSink; -fn upgrade_chat_manager( - chat_manager: AFPluginState>, -) -> FlowyResult> { - let chat_manager = chat_manager +fn upgrade_ai_manager(ai_manager: AFPluginState>) -> FlowyResult> { + let ai_manager = ai_manager .upgrade() .ok_or(FlowyError::internal().with_context("The chat manager is already dropped"))?; - Ok(chat_manager) + Ok(ai_manager) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn stream_chat_message_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); data.validate()?; @@ -39,7 +37,7 @@ pub(crate) async fn stream_chat_message_handler( ChatMessageTypePB::User => ChatMessageType::User, }; - let question = chat_manager + let question = ai_manager .stream_chat_message( &data.chat_id, &data.message, @@ -53,13 +51,13 @@ pub(crate) async fn stream_chat_message_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn load_prev_message_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); data.validate()?; - let messages = chat_manager + let messages = ai_manager .load_prev_chat_messages(&data.chat_id, data.limit, data.before_message_id) .await?; data_result_ok(messages) @@ -68,13 +66,13 @@ pub(crate) async fn load_prev_message_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn load_next_message_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); data.validate()?; - let messages = chat_manager + let messages = ai_manager .load_latest_chat_messages(&data.chat_id, data.limit, data.after_message_id) .await?; data_result_ok(messages) @@ -83,13 +81,13 @@ pub(crate) async fn load_next_message_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_related_question_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); let (tx, rx) = tokio::sync::oneshot::channel(); tokio::spawn(async move { - let messages = chat_manager + let messages = ai_manager .get_related_questions(&data.chat_id, data.message_id) .await?; let _ = tx.send(messages); @@ -102,13 +100,13 @@ pub(crate) async fn get_related_question_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_answer_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let data = data.into_inner(); let (tx, rx) = tokio::sync::oneshot::channel(); tokio::spawn(async move { - let message = chat_manager + let message = ai_manager .generate_answer(&data.chat_id, data.message_id) .await?; let _ = tx.send(message); @@ -121,26 +119,26 @@ pub(crate) async fn get_answer_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn stop_stream_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> Result<(), FlowyError> { let data = data.into_inner(); data.validate()?; - let chat_manager = upgrade_chat_manager(chat_manager)?; - chat_manager.stop_stream(&data.chat_id).await?; + let ai_manager = upgrade_ai_manager(ai_manager)?; + ai_manager.stop_stream(&data.chat_id).await?; Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn refresh_local_ai_info_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let (tx, rx) = oneshot::channel::>(); tokio::spawn(async move { - let model_info = chat_manager.local_ai_controller.refresh().await; + let model_info = ai_manager.local_ai_controller.refresh().await; if model_info.is_err() { - if let Some(llm_model) = chat_manager.local_ai_controller.get_current_model() { + 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], @@ -160,11 +158,11 @@ pub(crate) async fn refresh_local_ai_info_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_local_llm_model_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { let data = data.into_inner(); - let chat_manager = upgrade_chat_manager(chat_manager)?; - let state = chat_manager + let ai_manager = upgrade_ai_manager(ai_manager)?; + let state = ai_manager .local_ai_controller .select_local_llm(data.llm_id) .await?; @@ -173,19 +171,16 @@ pub(crate) async fn update_local_llm_model_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_local_llm_state_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let state = chat_manager - .local_ai_controller - .get_local_llm_state() - .await?; + let ai_manager = upgrade_ai_manager(ai_manager)?; + let state = ai_manager.local_ai_controller.get_local_llm_state().await?; data_result_ok(state) } pub(crate) async fn start_complete_text_handler( data: AFPluginData, - tools: AFPluginState>, + tools: AFPluginState>, ) -> DataResult { let task = tools.create_complete_task(data.into_inner()).await?; data_result_ok(task) @@ -194,7 +189,7 @@ pub(crate) async fn start_complete_text_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn stop_complete_text_handler( data: AFPluginData, - tools: AFPluginState>, + tools: AFPluginState>, ) -> Result<(), FlowyError> { let data = data.into_inner(); tools.cancel_complete_task(&data.task_id).await; @@ -204,7 +199,7 @@ pub(crate) async fn stop_complete_text_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn chat_file_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> Result<(), FlowyError> { let data = data.try_into_inner()?; let file_path = PathBuf::from(&data.file_path); @@ -229,10 +224,8 @@ pub(crate) async fn chat_file_handler( let (tx, rx) = oneshot::channel::>(); tokio::spawn(async move { - let chat_manager = upgrade_chat_manager(chat_manager)?; - chat_manager - .chat_with_file(&data.chat_id, file_path) - .await?; + let ai_manager = upgrade_ai_manager(ai_manager)?; + ai_manager.chat_with_file(&data.chat_id, file_path).await?; let _ = tx.send(Ok(())); Ok::<_, FlowyError>(()) }); @@ -243,12 +236,12 @@ pub(crate) async fn chat_file_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn download_llm_resource_handler( data: AFPluginData, - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { let data = data.into_inner(); - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let text_sink = IsolateSink::new(Isolate::new(data.progress_stream)); - let task_id = chat_manager + let task_id = ai_manager .local_ai_controller .start_downloading(text_sink) .await?; @@ -257,32 +250,32 @@ pub(crate) async fn download_llm_resource_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn cancel_download_llm_resource_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> Result<(), FlowyError> { - let chat_manager = upgrade_chat_manager(chat_manager)?; - chat_manager.local_ai_controller.cancel_download()?; + let ai_manager = upgrade_ai_manager(ai_manager)?; + ai_manager.local_ai_controller.cancel_download()?; Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_plugin_state_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let state = chat_manager.local_ai_controller.get_chat_plugin_state(); + let ai_manager = upgrade_ai_manager(ai_manager)?; + let state = ai_manager.local_ai_controller.get_chat_plugin_state(); data_result_ok(state) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn toggle_local_ai_chat_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let enabled = chat_manager + let ai_manager = upgrade_ai_manager(ai_manager)?; + let enabled = ai_manager .local_ai_controller .toggle_local_ai_chat() .await?; - let file_enabled = chat_manager.local_ai_controller.is_rag_enabled(); - let plugin_state = chat_manager.local_ai_controller.get_chat_plugin_state(); + let file_enabled = ai_manager.local_ai_controller.is_rag_enabled(); + let plugin_state = ai_manager.local_ai_controller.get_chat_plugin_state(); let pb = LocalAIChatPB { enabled, file_enabled, @@ -299,15 +292,15 @@ pub(crate) async fn toggle_local_ai_chat_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn toggle_local_ai_chat_file_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let enabled = chat_manager.local_ai_controller.is_chat_enabled(); - let file_enabled = chat_manager + 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 .toggle_local_ai_chat_rag() .await?; - let plugin_state = chat_manager.local_ai_controller.get_chat_plugin_state(); + let plugin_state = ai_manager.local_ai_controller.get_chat_plugin_state(); let pb = LocalAIChatPB { enabled, file_enabled, @@ -325,12 +318,12 @@ pub(crate) async fn toggle_local_ai_chat_file_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_local_ai_chat_state_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let enabled = chat_manager.local_ai_controller.is_chat_enabled(); - let file_enabled = chat_manager.local_ai_controller.is_rag_enabled(); - let plugin_state = chat_manager.local_ai_controller.get_chat_plugin_state(); + 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(); data_result_ok(LocalAIChatPB { enabled, file_enabled, @@ -339,37 +332,37 @@ pub(crate) async fn get_local_ai_chat_state_handler( } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn restart_local_ai_chat_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> Result<(), FlowyError> { - let chat_manager = upgrade_chat_manager(chat_manager)?; - chat_manager.local_ai_controller.restart_chat_plugin(); + let ai_manager = upgrade_ai_manager(ai_manager)?; + ai_manager.local_ai_controller.restart_chat_plugin(); Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn toggle_local_ai_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let enabled = chat_manager.local_ai_controller.toggle_local_ai().await?; + let ai_manager = upgrade_ai_manager(ai_manager)?; + let enabled = ai_manager.local_ai_controller.toggle_local_ai().await?; data_result_ok(LocalAIPB { enabled }) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_local_ai_state_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let enabled = chat_manager.local_ai_controller.is_enabled(); + let ai_manager = upgrade_ai_manager(ai_manager)?; + let enabled = ai_manager.local_ai_controller.is_enabled(); data_result_ok(LocalAIPB { enabled }) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_model_storage_directory_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; - let file_path = chat_manager + let ai_manager = upgrade_ai_manager(ai_manager)?; + let file_path = ai_manager .local_ai_controller .get_model_storage_directory()?; data_result_ok(LocalModelStoragePB { file_path }) @@ -377,12 +370,12 @@ pub(crate) async fn get_model_storage_directory_handler( #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn get_offline_app_handler( - chat_manager: AFPluginState>, + ai_manager: AFPluginState>, ) -> DataResult { - let chat_manager = upgrade_chat_manager(chat_manager)?; + let ai_manager = upgrade_ai_manager(ai_manager)?; let (tx, rx) = oneshot::channel::>(); tokio::spawn(async move { - let link = chat_manager + let link = ai_manager .local_ai_controller .get_offline_ai_app_download_link() .await?; diff --git a/frontend/rust-lib/flowy-chat/src/event_map.rs b/frontend/rust-lib/flowy-ai/src/event_map.rs similarity index 58% rename from frontend/rust-lib/flowy-chat/src/event_map.rs rename to frontend/rust-lib/flowy-ai/src/event_map.rs index 834ef05466..7c56b7ed6e 100644 --- a/frontend/rust-lib/flowy-chat/src/event_map.rs +++ b/frontend/rust-lib/flowy-ai/src/event_map.rs @@ -2,67 +2,64 @@ use std::sync::{Arc, Weak}; use strum_macros::Display; -use crate::tools::AITools; +use crate::completion::AICompletion; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use lib_dispatch::prelude::*; -use crate::chat_manager::ChatManager; +use crate::ai_manager::AIManager; use crate::event_handler::*; -pub fn init(chat_manager: Weak) -> AFPlugin { - let user_service = Arc::downgrade(&chat_manager.upgrade().unwrap().user_service); - let cloud_service = Arc::downgrade(&chat_manager.upgrade().unwrap().cloud_service_wm); - let ai_tools = Arc::new(AITools::new(cloud_service, user_service)); +pub fn init(ai_manager: Weak) -> AFPlugin { + let user_service = Arc::downgrade(&ai_manager.upgrade().unwrap().user_service); + let cloud_service = Arc::downgrade(&ai_manager.upgrade().unwrap().cloud_service_wm); + let ai_tools = Arc::new(AICompletion::new(cloud_service, user_service)); AFPlugin::new() - .name("Flowy-Chat") - .state(chat_manager) + .name("flowy-ai") + .state(ai_manager) .state(ai_tools) - .event(ChatEvent::StreamMessage, stream_chat_message_handler) - .event(ChatEvent::LoadPrevMessage, load_prev_message_handler) - .event(ChatEvent::LoadNextMessage, load_next_message_handler) - .event(ChatEvent::GetRelatedQuestion, get_related_question_handler) - .event(ChatEvent::GetAnswerForQuestion, get_answer_handler) - .event(ChatEvent::StopStream, stop_stream_handler) + .event(AIEvent::StreamMessage, stream_chat_message_handler) + .event(AIEvent::LoadPrevMessage, load_prev_message_handler) + .event(AIEvent::LoadNextMessage, load_next_message_handler) + .event(AIEvent::GetRelatedQuestion, get_related_question_handler) + .event(AIEvent::GetAnswerForQuestion, get_answer_handler) + .event(AIEvent::StopStream, stop_stream_handler) .event( - ChatEvent::RefreshLocalAIModelInfo, + AIEvent::RefreshLocalAIModelInfo, refresh_local_ai_info_handler, ) - .event(ChatEvent::UpdateLocalLLM, update_local_llm_model_handler) - .event(ChatEvent::GetLocalLLMState, get_local_llm_state_handler) - .event(ChatEvent::CompleteText, start_complete_text_handler) - .event(ChatEvent::StopCompleteText, stop_complete_text_handler) - .event(ChatEvent::ChatWithFile, chat_file_handler) + .event(AIEvent::UpdateLocalLLM, update_local_llm_model_handler) + .event(AIEvent::GetLocalLLMState, get_local_llm_state_handler) + .event(AIEvent::CompleteText, start_complete_text_handler) + .event(AIEvent::StopCompleteText, stop_complete_text_handler) + .event(AIEvent::ChatWithFile, chat_file_handler) + .event(AIEvent::DownloadLLMResource, download_llm_resource_handler) .event( - ChatEvent::DownloadLLMResource, - download_llm_resource_handler, - ) - .event( - ChatEvent::CancelDownloadLLMResource, + AIEvent::CancelDownloadLLMResource, cancel_download_llm_resource_handler, ) - .event(ChatEvent::GetLocalAIPluginState, get_plugin_state_handler) - .event(ChatEvent::ToggleLocalAIChat, toggle_local_ai_chat_handler) + .event(AIEvent::GetLocalAIPluginState, get_plugin_state_handler) + .event(AIEvent::ToggleLocalAIChat, toggle_local_ai_chat_handler) .event( - ChatEvent::GetLocalAIChatState, + AIEvent::GetLocalAIChatState, get_local_ai_chat_state_handler, ) - .event(ChatEvent::RestartLocalAIChat, restart_local_ai_chat_handler) - .event(ChatEvent::ToggleLocalAI, toggle_local_ai_handler) - .event(ChatEvent::GetLocalAIState, get_local_ai_state_handler) + .event(AIEvent::RestartLocalAIChat, restart_local_ai_chat_handler) + .event(AIEvent::ToggleLocalAI, toggle_local_ai_handler) + .event(AIEvent::GetLocalAIState, get_local_ai_state_handler) .event( - ChatEvent::ToggleChatWithFile, + AIEvent::ToggleChatWithFile, toggle_local_ai_chat_file_handler, ) .event( - ChatEvent::GetModelStorageDirectory, + AIEvent::GetModelStorageDirectory, get_model_storage_directory_handler, ) - .event(ChatEvent::GetOfflineAIAppLink, get_offline_app_handler) + .event(AIEvent::GetOfflineAIAppLink, get_offline_app_handler) } #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[event_err = "FlowyError"] -pub enum ChatEvent { +pub enum AIEvent { /// Create a new workspace #[event(input = "LoadPrevChatMessagePB", output = "ChatMessageListPB")] LoadPrevMessage = 0, diff --git a/frontend/rust-lib/flowy-chat/src/lib.rs b/frontend/rust-lib/flowy-ai/src/lib.rs similarity index 80% rename from frontend/rust-lib/flowy-chat/src/lib.rs rename to frontend/rust-lib/flowy-ai/src/lib.rs index 2b4458d5ea..9ebcbf75bb 100644 --- a/frontend/rust-lib/flowy-chat/src/lib.rs +++ b/frontend/rust-lib/flowy-ai/src/lib.rs @@ -1,12 +1,12 @@ mod event_handler; pub mod event_map; +pub mod ai_manager; mod chat; -pub mod chat_manager; +mod completion; pub mod entities; mod local_ai; mod middleware; pub mod notification; mod persistence; mod protobuf; -mod tools; diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/local_llm_chat.rs b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs similarity index 77% rename from frontend/rust-lib/flowy-chat/src/local_ai/local_llm_chat.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs index c620d61dd4..9936ceba2f 100644 --- a/frontend/rust-lib/flowy-chat/src/local_ai/local_llm_chat.rs +++ b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs @@ -1,12 +1,12 @@ -use crate::chat_manager::ChatUserService; +use crate::ai_manager::AIUserService; use crate::entities::{LocalAIPluginStatePB, LocalModelResourcePB, RunningStatePB}; -use crate::local_ai::local_llm_resource::{LLMResourceController, LLMResourceService}; +use crate::local_ai::local_llm_resource::{LLMResourceService, LocalAIResourceController}; use crate::notification::{make_notification, ChatNotification, APPFLOWY_AI_NOTIFICATION_KEY}; use anyhow::Error; -use appflowy_local_ai::chat_plugin::{AIPluginConfig, LocalChatLLMChat}; +use appflowy_local_ai::chat_plugin::{AIPluginConfig, AppFlowyLocalAI}; use appflowy_plugin::manager::PluginManager; use appflowy_plugin::util::is_apple_silicon; -use flowy_chat_pub::cloud::{AppFlowyOfflineAI, ChatCloudService, LLMModel, LocalAIConfig}; +use flowy_ai_pub::cloud::{AppFlowyOfflineAI, ChatCloudService, LLMModel, LocalAIConfig}; use flowy_error::{FlowyError, FlowyResult}; use flowy_sqlite::kv::KVStorePreferences; use futures::Sink; @@ -18,7 +18,7 @@ use std::ops::Deref; use std::sync::Arc; use tokio::select; use tokio_stream::StreamExt; -use tracing::{debug, error, info, instrument, trace}; +use tracing::{debug, error, info, instrument}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct LLMSetting { @@ -37,17 +37,17 @@ const APPFLOWY_LOCAL_AI_CHAT_RAG_ENABLED: &str = "appflowy_local_ai_chat_rag_ena const LOCAL_AI_SETTING_KEY: &str = "appflowy_local_ai_setting:v0"; pub struct LocalAIController { - llm_chat: Arc, - llm_res: Arc, + local_ai: Arc, + local_ai_resource: Arc, current_chat_id: Mutex>, store_preferences: Arc, } impl Deref for LocalAIController { - type Target = Arc; + type Target = Arc; fn deref(&self) -> &Self::Target { - &self.llm_chat + &self.local_ai } } @@ -55,10 +55,10 @@ impl LocalAIController { pub fn new( plugin_manager: Arc, store_preferences: Arc, - user_service: Arc, + user_service: Arc, cloud_service: Arc, ) -> Self { - let llm_chat = Arc::new(LocalChatLLMChat::new(plugin_manager)); + let local_ai = Arc::new(AppFlowyLocalAI::new(plugin_manager)); let res_impl = LLMResourceServiceImpl { user_service: user_service.clone(), cloud_service, @@ -66,10 +66,10 @@ impl LocalAIController { }; let (tx, mut rx) = tokio::sync::mpsc::channel(1); - let llm_res = Arc::new(LLMResourceController::new(user_service, res_impl, tx)); + let llm_res = Arc::new(LocalAIResourceController::new(user_service, res_impl, tx)); let current_chat_id = Mutex::new(None); - let mut running_state_rx = llm_chat.subscribe_running_state(); + let mut running_state_rx = local_ai.subscribe_running_state(); let cloned_llm_res = llm_res.clone(); tokio::spawn(async move { while let Some(state) = running_state_rx.next().await { @@ -89,16 +89,16 @@ impl LocalAIController { }); let this = Self { - llm_chat, - llm_res, + local_ai, + local_ai_resource: llm_res, current_chat_id, store_preferences, }; let rag_enabled = this.is_rag_enabled(); - let cloned_llm_chat = this.llm_chat.clone(); - let cloned_llm_res = this.llm_res.clone(); - let mut offline_ai_watch = this.llm_res.subscribe_offline_app_state(); + let cloned_llm_chat = this.local_ai.clone(); + let cloned_llm_res = this.local_ai_resource.clone(); + let mut offline_ai_watch = this.local_ai_resource.subscribe_offline_app_state(); tokio::spawn(async move { let init_fn = || { if let Ok(chat_config) = cloned_llm_res.get_chat_config(rag_enabled) { @@ -122,9 +122,11 @@ impl LocalAIController { }); if this.can_init_plugin() { - let result = this.llm_res.get_chat_config(this.is_rag_enabled()); + let result = this + .local_ai_resource + .get_chat_config(this.is_rag_enabled()); if let Ok(chat_config) = result { - if let Err(err) = initialize_ai_plugin(&this.llm_chat, chat_config, None) { + if let Err(err) = initialize_ai_plugin(&this.local_ai, chat_config, None) { error!("[AI Plugin] failed to setup plugin: {:?}", err); } } @@ -133,17 +135,17 @@ impl LocalAIController { this } pub async fn refresh(&self) -> FlowyResult { - self.llm_res.refresh_llm_resource().await + self.local_ai_resource.refresh_llm_resource().await } /// Returns true if the local AI is enabled and ready to use. pub fn can_init_plugin(&self) -> bool { - self.is_enabled() && self.llm_res.is_resource_ready() + self.is_enabled() && self.local_ai_resource.is_resource_ready() } /// Indicate whether the local AI plugin is running. pub fn is_running(&self) -> bool { - self.llm_chat.get_plugin_running_state().is_ready() + self.local_ai.get_plugin_running_state().is_ready() } /// Indicate whether the local AI is enabled. @@ -184,7 +186,7 @@ impl LocalAIController { *self.current_chat_id.lock() = Some(chat_id.to_string()); let chat_id = chat_id.to_string(); - let weak_ctrl = Arc::downgrade(&self.llm_chat); + let weak_ctrl = Arc::downgrade(&self.local_ai); tokio::spawn(async move { if let Some(ctrl) = weak_ctrl.upgrade() { if let Err(err) = ctrl.create_chat(&chat_id).await { @@ -195,7 +197,7 @@ impl LocalAIController { } pub fn close_chat(&self, chat_id: &str) { - let weak_ctrl = Arc::downgrade(&self.llm_chat); + let weak_ctrl = Arc::downgrade(&self.local_ai); let chat_id = chat_id.to_string(); tokio::spawn(async move { if let Some(ctrl) = weak_ctrl.upgrade() { @@ -211,11 +213,19 @@ impl LocalAIController { return Err(FlowyError::local_ai_unavailable()); } - let state = self.llm_res.use_local_llm(llm_id)?; + if let Some(model) = self.local_ai_resource.get_selected_model() { + if model.llm_id == llm_id { + return self.local_ai_resource.get_local_llm_state(); + } + } + + let state = self.local_ai_resource.use_local_llm(llm_id)?; // Re-initialize the plugin if the setting is updated and ready to use - if self.llm_res.is_resource_ready() { - let chat_config = self.llm_res.get_chat_config(self.is_rag_enabled())?; - if let Err(err) = initialize_ai_plugin(&self.llm_chat, chat_config, None) { + if self.local_ai_resource.is_resource_ready() { + let chat_config = self + .local_ai_resource + .get_chat_config(self.is_rag_enabled())?; + if let Err(err) = initialize_ai_plugin(&self.local_ai, chat_config, None) { error!("failed to setup plugin: {:?}", err); } } @@ -223,29 +233,32 @@ impl LocalAIController { } pub async fn get_local_llm_state(&self) -> FlowyResult { - self.llm_res.get_local_llm_state() + self.local_ai_resource.get_local_llm_state() } pub fn get_current_model(&self) -> Option { - self.llm_res.get_selected_model() + self.local_ai_resource.get_selected_model() } pub async fn start_downloading(&self, progress_sink: T) -> FlowyResult where T: Sink + Unpin + Sync + Send + 'static, { - let task_id = self.llm_res.start_downloading(progress_sink).await?; + let task_id = self + .local_ai_resource + .start_downloading(progress_sink) + .await?; Ok(task_id) } pub fn cancel_download(&self) -> FlowyResult<()> { - self.llm_res.cancel_download()?; + self.local_ai_resource.cancel_download()?; Ok(()) } pub fn get_chat_plugin_state(&self) -> LocalAIPluginStatePB { - let offline_ai_ready = self.llm_res.is_offline_app_ready(); - let state = self.llm_chat.get_plugin_running_state(); + let offline_ai_ready = self.local_ai_resource.is_offline_app_ready(); + let state = self.local_ai.get_plugin_running_state(); LocalAIPluginStatePB { state: RunningStatePB::from(state), offline_ai_ready, @@ -254,8 +267,8 @@ impl LocalAIController { pub fn restart_chat_plugin(&self) { let rag_enabled = self.is_rag_enabled(); - if let Ok(chat_config) = self.llm_res.get_chat_config(rag_enabled) { - if let Err(err) = initialize_ai_plugin(&self.llm_chat, chat_config, None) { + if let Ok(chat_config) = self.local_ai_resource.get_chat_config(rag_enabled) { + if let Err(err) = initialize_ai_plugin(&self.local_ai, chat_config, None) { error!("[AI Plugin] failed to setup plugin: {:?}", err); } } @@ -263,13 +276,16 @@ impl LocalAIController { pub fn get_model_storage_directory(&self) -> FlowyResult { self - .llm_res + .local_ai_resource .user_model_folder() .map(|path| path.to_string_lossy().to_string()) } pub async fn get_offline_ai_app_download_link(&self) -> FlowyResult { - self.llm_res.get_offline_ai_app_download_link().await + self + .local_ai_resource + .get_offline_ai_app_download_link() + .await } pub async fn toggle_local_ai(&self) -> FlowyResult { @@ -322,12 +338,14 @@ impl LocalAIController { info!("[AI Plugin] enable chat plugin: {}", enabled); if enabled { let (tx, rx) = tokio::sync::oneshot::channel(); - let chat_config = self.llm_res.get_chat_config(self.is_rag_enabled())?; - if let Err(err) = initialize_ai_plugin(&self.llm_chat, chat_config, Some(tx)) { + let chat_config = self + .local_ai_resource + .get_chat_config(self.is_rag_enabled())?; + if let Err(err) = initialize_ai_plugin(&self.local_ai, chat_config, Some(tx)) { error!("[AI Plugin] failed to initialize local ai: {:?}", err); } let _ = rx.await; - } else if let Err(err) = self.llm_chat.destroy_chat_plugin().await { + } else if let Err(err) = self.local_ai.destroy_chat_plugin().await { error!("[AI Plugin] failed to destroy plugin: {:?}", err); } Ok(()) @@ -336,14 +354,14 @@ impl LocalAIController { #[instrument(level = "debug", skip_all, err)] fn initialize_ai_plugin( - llm_chat: &Arc, + llm_chat: &Arc, mut chat_config: AIPluginConfig, ret: Option>, ) -> FlowyResult<()> { let llm_chat = llm_chat.clone(); tokio::spawn(async move { - trace!("[AI Plugin] config: {:?}", chat_config); + info!("[AI Plugin] config: {:?}", chat_config); if is_apple_silicon().await.unwrap_or(false) { chat_config = chat_config.with_device("gpu"); } @@ -360,7 +378,7 @@ fn initialize_ai_plugin( } pub struct LLMResourceServiceImpl { - user_service: Arc, + user_service: Arc, cloud_service: Arc, store_preferences: Arc, } diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/local_llm_resource.rs b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs similarity index 98% rename from frontend/rust-lib/flowy-chat/src/local_ai/local_llm_resource.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs index e32f2ef86c..3dbf19e967 100644 --- a/frontend/rust-lib/flowy-chat/src/local_ai/local_llm_resource.rs +++ b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs @@ -1,10 +1,10 @@ -use crate::chat_manager::ChatUserService; +use crate::ai_manager::AIUserService; use crate::entities::{LocalModelResourcePB, PendingResourcePB, PendingResourceTypePB}; use crate::local_ai::local_llm_chat::{LLMModelInfo, LLMSetting}; use crate::local_ai::model_request::download_model; use appflowy_local_ai::chat_plugin::AIPluginConfig; -use flowy_chat_pub::cloud::{LLMModel, LocalAIConfig, ModelInfo}; +use flowy_ai_pub::cloud::{LLMModel, LocalAIConfig, ModelInfo}; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use futures::Sink; use futures_util::SinkExt; @@ -61,8 +61,8 @@ impl DownloadTask { } } -pub struct LLMResourceController { - user_service: Arc, +pub struct LocalAIResourceController { + user_service: Arc, resource_service: Arc, llm_setting: RwLock>, // The ai_config will be set when user try to get latest local ai config from server @@ -75,9 +75,9 @@ pub struct LLMResourceController { offline_app_state_sender: tokio::sync::broadcast::Sender, } -impl LLMResourceController { +impl LocalAIResourceController { pub fn new( - user_service: Arc, + user_service: Arc, resource_service: impl LLMResourceService, resource_notify: tokio::sync::mpsc::Sender<()>, ) -> Self { @@ -171,7 +171,7 @@ impl LLMResourceController { #[instrument(level = "info", skip_all, err)] pub fn use_local_llm(&self, llm_id: i64) -> FlowyResult { - let (package, llm_config) = self + let (app, llm_model) = self .ai_config .read() .as_ref() @@ -186,8 +186,8 @@ impl LLMResourceController { .ok_or_else(|| FlowyError::local_ai().with_context("No local ai config found"))?; let llm_setting = LLMSetting { - app: package, - llm_model: llm_config.clone(), + app, + llm_model: llm_model.clone(), }; trace!("[LLM Resource] Selected AI setting: {:?}", llm_setting); diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/mod.rs b/frontend/rust-lib/flowy-ai/src/local_ai/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/local_ai/mod.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/mod.rs diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/model_request.rs b/frontend/rust-lib/flowy-ai/src/local_ai/model_request.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/local_ai/model_request.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/model_request.rs diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/path.rs b/frontend/rust-lib/flowy-ai/src/local_ai/path.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/local_ai/path.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/path.rs diff --git a/frontend/rust-lib/flowy-chat/src/local_ai/watch.rs b/frontend/rust-lib/flowy-ai/src/local_ai/watch.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/local_ai/watch.rs rename to frontend/rust-lib/flowy-ai/src/local_ai/watch.rs diff --git a/frontend/rust-lib/flowy-chat/src/middleware/chat_service_mw.rs b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs similarity index 96% rename from frontend/rust-lib/flowy-chat/src/middleware/chat_service_mw.rs rename to frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs index b4c2a1710e..7c48283a1d 100644 --- a/frontend/rust-lib/flowy-chat/src/middleware/chat_service_mw.rs +++ b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs @@ -1,11 +1,11 @@ -use crate::chat_manager::ChatUserService; +use crate::ai_manager::AIUserService; use crate::entities::{ChatStatePB, ModelTypePB}; use crate::local_ai::local_llm_chat::LocalAIController; use crate::notification::{make_notification, ChatNotification, APPFLOWY_AI_NOTIFICATION_KEY}; use crate::persistence::select_single_message; use appflowy_plugin::error::PluginError; -use flowy_chat_pub::cloud::{ +use flowy_ai_pub::cloud::{ ChatCloudService, ChatMessage, ChatMessageType, CompletionType, LocalAIConfig, MessageCursor, RelatedQuestion, RepeatedChatMessage, RepeatedRelatedQuestion, StreamAnswer, StreamComplete, }; @@ -17,15 +17,15 @@ use lib_infra::future::FutureResult; use std::path::PathBuf; use std::sync::Arc; -pub struct CloudServiceMiddleware { +pub struct AICloudServiceMiddleware { cloud_service: Arc, - user_service: Arc, + user_service: Arc, local_llm_controller: Arc, } -impl CloudServiceMiddleware { +impl AICloudServiceMiddleware { pub fn new( - user_service: Arc, + user_service: Arc, cloud_service: Arc, local_llm_controller: Arc, ) -> Self { @@ -67,7 +67,7 @@ impl CloudServiceMiddleware { } #[async_trait] -impl ChatCloudService for CloudServiceMiddleware { +impl ChatCloudService for AICloudServiceMiddleware { fn create_chat( &self, uid: &i64, diff --git a/frontend/rust-lib/flowy-chat/src/middleware/mod.rs b/frontend/rust-lib/flowy-ai/src/middleware/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/middleware/mod.rs rename to frontend/rust-lib/flowy-ai/src/middleware/mod.rs diff --git a/frontend/rust-lib/flowy-chat/src/notification.rs b/frontend/rust-lib/flowy-ai/src/notification.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/notification.rs rename to frontend/rust-lib/flowy-ai/src/notification.rs diff --git a/frontend/rust-lib/flowy-chat/src/persistence/chat_message_sql.rs b/frontend/rust-lib/flowy-ai/src/persistence/chat_message_sql.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/persistence/chat_message_sql.rs rename to frontend/rust-lib/flowy-ai/src/persistence/chat_message_sql.rs diff --git a/frontend/rust-lib/flowy-chat/src/persistence/chat_sql.rs b/frontend/rust-lib/flowy-ai/src/persistence/chat_sql.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/persistence/chat_sql.rs rename to frontend/rust-lib/flowy-ai/src/persistence/chat_sql.rs diff --git a/frontend/rust-lib/flowy-chat/src/persistence/mod.rs b/frontend/rust-lib/flowy-ai/src/persistence/mod.rs similarity index 100% rename from frontend/rust-lib/flowy-chat/src/persistence/mod.rs rename to frontend/rust-lib/flowy-ai/src/persistence/mod.rs diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index bb5b69c269..8b24a615dc 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -33,8 +33,10 @@ uuid.workspace = true flowy-storage = { workspace = true } flowy-storage-pub = { workspace = true } client-api.workspace = true -flowy-chat = { workspace = true } -flowy-chat-pub = { workspace = true } +flowy-ai = { workspace = true } +flowy-ai-pub = { workspace = true } +appflowy-local-ai = { version = "0.1.0" } + tracing.workspace = true futures-core = { version = "0.3", default-features = false } @@ -65,7 +67,7 @@ dart = [ "flowy-search/dart", "flowy-folder/dart", "flowy-database2/dart", - "flowy-chat/dart", + "flowy-ai/dart", "flowy-storage/dart", ] ts = [ @@ -74,7 +76,7 @@ ts = [ "flowy-search/tauri_ts", "flowy-database2/ts", "flowy-config/tauri_ts", - "flowy-chat/tauri_ts", + "flowy-ai/tauri_ts", "flowy-storage/tauri_ts", ] openssl_vendored = ["flowy-sqlite/openssl_vendored"] diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs index 7fd2b66775..cb6975a7a0 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs @@ -1,5 +1,5 @@ -use flowy_chat::chat_manager::{ChatManager, ChatUserService}; -use flowy_chat_pub::cloud::ChatCloudService; +use flowy_ai::ai_manager::{AIManager, AIUserService}; +use flowy_ai_pub::cloud::ChatCloudService; use flowy_error::FlowyError; use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::DBConnection; @@ -14,9 +14,9 @@ impl ChatDepsResolver { authenticate_user: Weak, cloud_service: Arc, store_preferences: Arc, - ) -> Arc { + ) -> Arc { let user_service = ChatUserServiceImpl(authenticate_user); - Arc::new(ChatManager::new( + Arc::new(AIManager::new( cloud_service, user_service, store_preferences, @@ -35,7 +35,7 @@ impl ChatUserServiceImpl { } } -impl ChatUserService for ChatUserServiceImpl { +impl AIUserService for ChatUserServiceImpl { fn user_id(&self) -> Result { self.upgrade_user()?.user_id() } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/database_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/database_deps.rs index 2ef0046dc7..56ac310300 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/database_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/database_deps.rs @@ -1,12 +1,19 @@ +use appflowy_local_ai::ai_ops::{LocalAITranslateItem, LocalAITranslateRowData}; use collab_integrate::collab_builder::AppFlowyCollabBuilder; use collab_integrate::CollabKVDB; +use flowy_ai::ai_manager::AIManager; use flowy_database2::{DatabaseManager, DatabaseUser}; -use flowy_database_pub::cloud::DatabaseCloudService; +use flowy_database_pub::cloud::{ + DatabaseAIService, DatabaseCloudService, SummaryRowContent, TranslateRowContent, + TranslateRowResponse, +}; use flowy_error::FlowyError; use flowy_user::services::authenticate_user::AuthenticateUser; +use lib_infra::async_trait::async_trait; use lib_infra::priority_task::TaskDispatcher; use std::sync::{Arc, Weak}; use tokio::sync::RwLock; + pub struct DatabaseDepsResolver(); impl DatabaseDepsResolver { @@ -15,6 +22,8 @@ impl DatabaseDepsResolver { task_scheduler: Arc>, collab_builder: Arc, cloud_service: Arc, + ai_service: Arc, + ai_manager: Arc, ) -> Arc { let user = Arc::new(DatabaseUserImpl(authenticate_user)); Arc::new(DatabaseManager::new( @@ -22,10 +31,76 @@ impl DatabaseDepsResolver { task_scheduler, collab_builder, cloud_service, + Arc::new(DatabaseAIServiceMiddleware { + ai_manager, + ai_service, + }), )) } } +struct DatabaseAIServiceMiddleware { + ai_manager: Arc, + ai_service: Arc, +} +#[async_trait] +impl DatabaseAIService for DatabaseAIServiceMiddleware { + async fn summary_database_row( + &self, + workspace_id: &str, + object_id: &str, + summary_row: SummaryRowContent, + ) -> Result { + if self.ai_manager.local_ai_controller.is_running() { + self + .ai_manager + .local_ai_controller + .summary_database_row(summary_row) + .await + .map_err(|err| FlowyError::local_ai().with_context(err)) + } else { + self + .ai_service + .summary_database_row(workspace_id, object_id, summary_row) + .await + } + } + + async fn translate_database_row( + &self, + workspace_id: &str, + translate_row: TranslateRowContent, + language: &str, + ) -> Result { + if self.ai_manager.local_ai_controller.is_running() { + let data = LocalAITranslateRowData { + cells: translate_row + .into_iter() + .map(|row| LocalAITranslateItem { + title: row.title, + content: row.content, + }) + .collect(), + language: language.to_string(), + include_header: false, + }; + let resp = self + .ai_manager + .local_ai_controller + .translate_database_row(data) + .await + .map_err(|err| FlowyError::local_ai().with_context(err))?; + + Ok(TranslateRowResponse { items: resp.items }) + } else { + self + .ai_service + .translate_database_row(workspace_id, translate_row, language) + .await + } + } +} + struct DatabaseUserImpl(Weak); impl DatabaseUserImpl { fn upgrade_user(&self) -> Result, FlowyError> { diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index edc3a7ff85..6b6b22fa9d 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -3,7 +3,7 @@ use bytes::Bytes; use collab_entity::{CollabType, EncodedCollab}; use collab_integrate::collab_builder::AppFlowyCollabBuilder; use collab_integrate::CollabKVDB; -use flowy_chat::chat_manager::ChatManager; +use flowy_ai::ai_manager::AIManager; use flowy_database2::entities::DatabaseLayoutPB; use flowy_database2::services::share::csv::CSVFormat; use flowy_database2::template::{make_default_board, make_default_calendar, make_default_grid}; @@ -68,7 +68,7 @@ impl FolderDepsResolver { pub fn folder_operation_handlers( document_manager: Arc, database_manager: Arc, - chat_manager: Arc, + chat_manager: Arc, ) -> FolderOperationHandlers { let mut map: HashMap> = HashMap::new(); @@ -598,7 +598,7 @@ impl CreateDatabaseExtParams { } } -struct ChatFolderOperation(Arc); +struct ChatFolderOperation(Arc); impl FolderOperationHandler for ChatFolderOperation { fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { let manager = self.0.clone(); diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index f44dabce90..fa1c8e4e0a 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -18,13 +18,13 @@ use tracing::{debug, info}; use collab_integrate::collab_builder::{ CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType, }; -use flowy_chat_pub::cloud::{ +use flowy_ai_pub::cloud::{ ChatCloudService, ChatMessage, LocalAIConfig, MessageCursor, RepeatedChatMessage, StreamAnswer, StreamComplete, }; use flowy_database_pub::cloud::{ - CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, - TranslateRowContent, TranslateRowResponse, + CollabDocStateByOid, DatabaseAIService, DatabaseCloudService, DatabaseSnapshot, + SummaryRowContent, TranslateRowContent, TranslateRowResponse, }; use flowy_document::deps::DocumentData; use flowy_document_pub::cloud::{DocumentCloudService, DocumentSnapshot}; @@ -364,6 +364,7 @@ impl FolderCloudService for ServerProvider { } } +#[async_trait] impl DatabaseCloudService for ServerProvider { fn get_database_object_doc_state( &self, @@ -412,39 +413,36 @@ impl DatabaseCloudService for ServerProvider { .await }) } +} - fn summary_database_row( +#[async_trait] +impl DatabaseAIService for ServerProvider { + async fn summary_database_row( &self, workspace_id: &str, object_id: &str, summary_row: SummaryRowContent, - ) -> FutureResult { - let workspace_id = workspace_id.to_string(); - let server = self.get_server(); - let object_id = object_id.to_string(); - FutureResult::new(async move { - server? - .database_service() - .summary_database_row(&workspace_id, &object_id, summary_row) - .await - }) + ) -> Result { + self + .get_server()? + .database_ai_service() + .ok_or_else(FlowyError::not_support)? + .summary_database_row(workspace_id, object_id, summary_row) + .await } - fn translate_database_row( + async fn translate_database_row( &self, workspace_id: &str, translate_row: TranslateRowContent, language: &str, - ) -> FutureResult { - let workspace_id = workspace_id.to_string(); - let server = self.get_server(); - let language = language.to_string(); - FutureResult::new(async move { - server? - .database_service() - .translate_database_row(&workspace_id, translate_row, &language) - .await - }) + ) -> Result { + self + .get_server()? + .database_ai_service() + .ok_or_else(FlowyError::not_support)? + .translate_database_row(workspace_id, translate_row, language) + .await } } diff --git a/frontend/rust-lib/flowy-core/src/integrate/user.rs b/frontend/rust-lib/flowy-core/src/integrate/user.rs index 6e64fa7840..5cc5f787a4 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/user.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/user.rs @@ -6,7 +6,7 @@ use tracing::{event, trace}; use collab_entity::CollabType; use collab_integrate::collab_builder::AppFlowyCollabBuilder; -use flowy_chat::chat_manager::ChatManager; +use flowy_ai::ai_manager::AIManager; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; use flowy_error::{FlowyError, FlowyResult}; @@ -26,7 +26,7 @@ pub(crate) struct UserStatusCallbackImpl { pub(crate) document_manager: Arc, pub(crate) server_provider: Arc, pub(crate) storage_manager: Arc, - pub(crate) chat_manager: Arc, + pub(crate) ai_manager: Arc, } impl UserStatusCallback for UserStatusCallbackImpl { @@ -235,7 +235,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { } if local_ai_enabled { - self.chat_manager.local_ai_purchased(); + self.ai_manager.local_ai_purchased(); } } diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index 257882c1c7..2e72aa8469 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -9,7 +9,7 @@ use tokio::sync::RwLock; use tracing::{debug, error, event, info, instrument}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProviderType}; -use flowy_chat::chat_manager::ChatManager; +use flowy_ai::ai_manager::AIManager; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; use flowy_error::{FlowyError, FlowyResult}; @@ -59,7 +59,7 @@ pub struct AppFlowyCore { pub task_dispatcher: Arc>, pub store_preference: Arc, pub search_manager: Arc, - pub chat_manager: Arc, + pub ai_manager: Arc, pub storage_manager: Arc, } @@ -143,7 +143,7 @@ impl AppFlowyCore { document_manager, collab_builder, search_manager, - chat_manager, + ai_manager, storage_manager, ) = async { let storage_manager = FileStorageResolver::resolve( @@ -161,11 +161,19 @@ impl AppFlowyCore { collab_builder .set_snapshot_persistence(Arc::new(SnapshotDBImpl(Arc::downgrade(&authenticate_user)))); + let ai_manager = ChatDepsResolver::resolve( + Arc::downgrade(&authenticate_user), + server_provider.clone(), + store_preference.clone(), + ); + let database_manager = DatabaseDepsResolver::resolve( Arc::downgrade(&authenticate_user), task_dispatcher.clone(), collab_builder.clone(), server_provider.clone(), + server_provider.clone(), + ai_manager.clone(), ) .await; @@ -177,12 +185,6 @@ impl AppFlowyCore { Arc::downgrade(&storage_manager.storage_service), ); - let chat_manager = ChatDepsResolver::resolve( - Arc::downgrade(&authenticate_user), - server_provider.clone(), - store_preference.clone(), - ); - let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Some(Arc::downgrade( &authenticate_user, )))); @@ -190,7 +192,7 @@ impl AppFlowyCore { let folder_operation_handlers = folder_operation_handlers( document_manager.clone(), database_manager.clone(), - chat_manager.clone(), + ai_manager.clone(), ); let folder_manager = FolderDepsResolver::resolve( @@ -228,7 +230,7 @@ impl AppFlowyCore { document_manager, collab_builder, search_manager, - chat_manager, + ai_manager, storage_manager, ) } @@ -241,7 +243,7 @@ impl AppFlowyCore { document_manager: document_manager.clone(), server_provider: server_provider.clone(), storage_manager: storage_manager.clone(), - chat_manager: chat_manager.clone(), + ai_manager: ai_manager.clone(), }; let collab_interact_impl = CollabInteractImpl { @@ -266,7 +268,7 @@ impl AppFlowyCore { Arc::downgrade(&user_manager), Arc::downgrade(&document_manager), Arc::downgrade(&search_manager), - Arc::downgrade(&chat_manager), + Arc::downgrade(&ai_manager), ), )); @@ -281,7 +283,7 @@ impl AppFlowyCore { task_dispatcher, store_preference, search_manager, - chat_manager, + ai_manager, storage_manager, } } diff --git a/frontend/rust-lib/flowy-core/src/module.rs b/frontend/rust-lib/flowy-core/src/module.rs index 70e55bc559..2c75cb376e 100644 --- a/frontend/rust-lib/flowy-core/src/module.rs +++ b/frontend/rust-lib/flowy-core/src/module.rs @@ -1,4 +1,4 @@ -use flowy_chat::chat_manager::ChatManager; +use flowy_ai::ai_manager::AIManager; use std::sync::Weak; use flowy_database2::DatabaseManager; @@ -14,7 +14,7 @@ pub fn make_plugins( user_session: Weak, document_manager2: Weak, search_manager: Weak, - chat_manager: Weak, + ai_manager: Weak, ) -> Vec { let store_preferences = user_session .upgrade() @@ -27,7 +27,7 @@ pub fn make_plugins( let config_plugin = flowy_config::event_map::init(store_preferences); let date_plugin = flowy_date::event_map::init(); let search_plugin = flowy_search::event_map::init(search_manager); - let chat_plugin = flowy_chat::event_map::init(chat_manager); + let ai_plugin = flowy_ai::event_map::init(ai_manager); vec![ user_plugin, folder_plugin, @@ -36,6 +36,6 @@ pub fn make_plugins( config_plugin, date_plugin, search_plugin, - chat_plugin, + ai_plugin, ] } diff --git a/frontend/rust-lib/flowy-database-pub/src/cloud.rs b/frontend/rust-lib/flowy-database-pub/src/cloud.rs index 0ceecf8930..24da5c72a1 100644 --- a/frontend/rust-lib/flowy-database-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-database-pub/src/cloud.rs @@ -3,18 +3,43 @@ pub use client_api::entity::ai_dto::{TranslateItem, TranslateRowResponse}; use collab::core::collab::DataSource; use collab_entity::CollabType; use flowy_error::FlowyError; +use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; use std::collections::HashMap; pub type CollabDocStateByOid = HashMap; pub type SummaryRowContent = HashMap; pub type TranslateRowContent = Vec; + +#[async_trait] +pub trait DatabaseAIService: Send + Sync { + async fn summary_database_row( + &self, + _workspace_id: &str, + _object_id: &str, + _summary_row: SummaryRowContent, + ) -> Result { + Ok("".to_string()) + } + + async fn translate_database_row( + &self, + _workspace_id: &str, + _translate_row: TranslateRowContent, + _language: &str, + ) -> Result { + Ok(TranslateRowResponse::default()) + } +} + /// A trait for database cloud service. /// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of /// [flowy-server] crate for more information. /// /// returns the doc state of the object with the given object_id. /// None if the object is not found. +/// +#[async_trait] pub trait DatabaseCloudService: Send + Sync { fn get_database_object_doc_state( &self, @@ -35,20 +60,6 @@ pub trait DatabaseCloudService: Send + Sync { object_id: &str, limit: usize, ) -> FutureResult, Error>; - - fn summary_database_row( - &self, - workspace_id: &str, - object_id: &str, - summary_row: SummaryRowContent, - ) -> FutureResult; - - fn translate_database_row( - &self, - workspace_id: &str, - translate_row: TranslateRowContent, - language: &str, - ) -> FutureResult; } pub struct DatabaseSnapshot { diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index f9c4651e25..a051dcf63c 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -1099,9 +1099,15 @@ pub(crate) async fn summarize_row_handler( let manager = upgrade_manager(manager)?; let data = data.into_inner(); let row_id = RowId::from(data.row_id); - manager - .summarize_row(data.view_id, row_id, data.field_id) - .await?; + let (tx, rx) = oneshot::channel(); + af_spawn(async move { + let result = manager + .summarize_row(data.view_id, row_id, data.field_id) + .await; + let _ = tx.send(result); + }); + + rx.await??; Ok(()) } @@ -1112,8 +1118,14 @@ pub(crate) async fn translate_row_handler( let manager = upgrade_manager(manager)?; let data = data.try_into_inner()?; let row_id = RowId::from(data.row_id); - manager - .translate_row(data.view_id, row_id, data.field_id) - .await?; + let (tx, rx) = oneshot::channel(); + af_spawn(async move { + let result = manager + .translate_row(data.view_id, row_id, data.field_id) + .await; + let _ = tx.send(result); + }); + + rx.await??; Ok(()) } diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 5d9c6a8bc7..4aa3f643fc 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -18,7 +18,7 @@ use tracing::{event, instrument, trace}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; use collab_integrate::{CollabKVAction, CollabKVDB, CollabPersistenceConfig}; use flowy_database_pub::cloud::{ - DatabaseCloudService, SummaryRowContent, TranslateItem, TranslateRowContent, + DatabaseAIService, DatabaseCloudService, SummaryRowContent, TranslateItem, TranslateRowContent, }; use flowy_error::{internal_error, FlowyError, FlowyResult}; use lib_infra::box_any::BoxAny; @@ -47,6 +47,7 @@ pub struct DatabaseManager { editors: Mutex>>, collab_builder: Arc, cloud_service: Arc, + ai_service: Arc, } impl DatabaseManager { @@ -55,6 +56,7 @@ impl DatabaseManager { task_scheduler: Arc>, collab_builder: Arc, cloud_service: Arc, + ai_service: Arc, ) -> Self { Self { user: database_user, @@ -63,6 +65,7 @@ impl DatabaseManager { editors: Default::default(), collab_builder, cloud_service, + ai_service, } } @@ -479,7 +482,7 @@ impl DatabaseManager { summary_row_content ); let response = self - .cloud_service + .ai_service .summary_database_row(&self.user.workspace_id()?, &row_id, summary_row_content) .await?; trace!("[AI]:summarize row response: {}", response); @@ -540,7 +543,7 @@ impl DatabaseManager { translate_row_content ); let response = self - .cloud_service + .ai_service .translate_database_row(&self.user.workspace_id()?, translate_row_content, &language) .await?; diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index dabcef78e7..76fcd99a32 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -43,7 +43,7 @@ flowy-search-pub = { workspace = true } flowy-encrypt = { workspace = true } flowy-storage = { workspace = true } flowy-storage-pub = { workspace = true } -flowy-chat-pub = { workspace = true } +flowy-ai-pub = { workspace = true } mime_guess = "2.0" url = "2.4" tokio-util = "0.7" diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs index 80fce796ef..dc0f9173bd 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs @@ -4,7 +4,7 @@ use client_api::entity::{ CreateAnswerMessageParams, CreateChatMessageParams, CreateChatParams, MessageCursor, RepeatedChatMessage, }; -use flowy_chat_pub::cloud::{ +use flowy_ai_pub::cloud::{ ChatCloudService, ChatMessage, ChatMessageType, LocalAIConfig, StreamAnswer, StreamComplete, }; use flowy_error::FlowyError; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs index c26c8d262d..57c97a3a67 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs @@ -13,10 +13,11 @@ use std::sync::Arc; use tracing::{error, instrument}; use flowy_database_pub::cloud::{ - CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, - TranslateRowContent, TranslateRowResponse, + CollabDocStateByOid, DatabaseAIService, DatabaseCloudService, DatabaseSnapshot, + SummaryRowContent, TranslateRowContent, TranslateRowResponse, }; use flowy_error::FlowyError; +use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; use crate::af_cloud::define::ServerUser; @@ -28,6 +29,7 @@ pub(crate) struct AFCloudDatabaseCloudServiceImpl { pub user: Arc, } +#[async_trait] impl DatabaseCloudService for AFCloudDatabaseCloudServiceImpl where T: AFServer, @@ -121,48 +123,48 @@ where ) -> FutureResult, Error> { FutureResult::new(async move { Ok(vec![]) }) } +} - fn summary_database_row( +#[async_trait] +impl DatabaseAIService for AFCloudDatabaseCloudServiceImpl +where + T: AFServer, +{ + async fn summary_database_row( &self, workspace_id: &str, _object_id: &str, summary_row: SummaryRowContent, - ) -> FutureResult { - let workspace_id = workspace_id.to_string(); + ) -> Result { let try_get_client = self.inner.try_get_client(); - FutureResult::new(async move { - let map: Map = summary_row - .into_iter() - .map(|(key, value)| (key, Value::String(value))) - .collect(); - let params = SummarizeRowParams { - workspace_id, - data: SummarizeRowData::Content(map), - }; - let data = try_get_client?.summarize_row(params).await?; - Ok(data.text) - }) + let map: Map = summary_row + .into_iter() + .map(|(key, value)| (key, Value::String(value))) + .collect(); + let params = SummarizeRowParams { + workspace_id: workspace_id.to_string(), + data: SummarizeRowData::Content(map), + }; + let data = try_get_client?.summarize_row(params).await?; + Ok(data.text) } - fn translate_database_row( + async fn translate_database_row( &self, workspace_id: &str, translate_row: TranslateRowContent, language: &str, - ) -> FutureResult { - let language = language.to_string(); + ) -> Result { let workspace_id = workspace_id.to_string(); let try_get_client = self.inner.try_get_client(); - FutureResult::new(async move { - let data = TranslateRowData { - cells: translate_row, - language, - include_header: false, - }; + let data = TranslateRowData { + cells: translate_row, + language: language.to_string(), + include_header: false, + }; - let params = TranslateRowParams { workspace_id, data }; - let data = try_get_client?.translate_row(params).await?; - Ok(data) - }) + let params = TranslateRowParams { workspace_id, data }; + let data = try_get_client?.translate_row(params).await?; + Ok(data) } } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 7d78e6e979..0f755caedb 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -14,8 +14,8 @@ use client_api::ws::{ }; use client_api::{Client, ClientConfiguration}; -use flowy_chat_pub::cloud::ChatCloudService; -use flowy_database_pub::cloud::DatabaseCloudService; +use flowy_ai_pub::cloud::ChatCloudService; +use flowy_database_pub::cloud::{DatabaseAIService, DatabaseCloudService}; use flowy_document_pub::cloud::DocumentCloudService; use flowy_error::{ErrorCode, FlowyError}; use flowy_folder_pub::cloud::FolderCloudService; @@ -216,6 +216,16 @@ impl AppFlowyServer for AppFlowyCloudServer { }) } + fn database_ai_service(&self) -> Option> { + let server = AFServerImpl { + client: self.get_client(), + }; + Some(Arc::new(AFCloudDatabaseCloudServiceImpl { + inner: server, + user: self.user.clone(), + })) + } + fn document_service(&self) -> Arc { let server = AFServerImpl { client: self.get_client(), diff --git a/frontend/rust-lib/flowy-server/src/default_impl.rs b/frontend/rust-lib/flowy-server/src/default_impl.rs index 662853d854..dacb5fea36 100644 --- a/frontend/rust-lib/flowy-server/src/default_impl.rs +++ b/frontend/rust-lib/flowy-server/src/default_impl.rs @@ -1,6 +1,6 @@ use client_api::entity::ai_dto::{CompletionType, LocalAIConfig, RepeatedRelatedQuestion}; use client_api::entity::{ChatMessageType, MessageCursor, RepeatedChatMessage}; -use flowy_chat_pub::cloud::{ChatCloudService, ChatMessage, StreamAnswer, StreamComplete}; +use flowy_ai_pub::cloud::{ChatCloudService, ChatMessage, StreamAnswer, StreamComplete}; use flowy_error::FlowyError; use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs index 30cc6415d1..7195430a8f 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/database.rs @@ -4,15 +4,14 @@ use collab_entity::define::{DATABASE, DATABASE_ROW_DATA, WORKSPACE_DATABASES}; use collab_entity::CollabType; use yrs::MapPrelim; -use flowy_database_pub::cloud::{ - CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, - TranslateRowContent, TranslateRowResponse, -}; -use flowy_error::FlowyError; +use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; + +use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; pub(crate) struct LocalServerDatabaseCloudServiceImpl(); +#[async_trait] impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl { fn get_database_object_doc_state( &self, @@ -77,24 +76,4 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl { ) -> FutureResult, Error> { FutureResult::new(async move { Ok(vec![]) }) } - - fn summary_database_row( - &self, - _workspace_id: &str, - _object_id: &str, - _summary_row: SummaryRowContent, - ) -> FutureResult { - // TODO(lucas): local ai - FutureResult::new(async move { Ok("".to_string()) }) - } - - fn translate_database_row( - &self, - _workspace_id: &str, - _translate_row: TranslateRowContent, - _language: &str, - ) -> FutureResult { - // TODO(lucas): local ai - FutureResult::new(async move { Ok(TranslateRowResponse::default()) }) - } } diff --git a/frontend/rust-lib/flowy-server/src/local_server/server.rs b/frontend/rust-lib/flowy-server/src/local_server/server.rs index 5bb00d9c60..e0ab174f75 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/server.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use parking_lot::RwLock; use tokio::sync::mpsc; -use flowy_database_pub::cloud::DatabaseCloudService; +use flowy_database_pub::cloud::{DatabaseAIService, DatabaseCloudService}; use flowy_document_pub::cloud::DocumentCloudService; use flowy_error::FlowyError; use flowy_folder_pub::cloud::FolderCloudService; @@ -75,4 +75,8 @@ impl AppFlowyServer for LocalServer { fn search_service(&self) -> Option> { None } + + fn database_ai_service(&self) -> Option> { + None + } } diff --git a/frontend/rust-lib/flowy-server/src/server.rs b/frontend/rust-lib/flowy-server/src/server.rs index 8ad002910d..2c4ee66b03 100644 --- a/frontend/rust-lib/flowy-server/src/server.rs +++ b/frontend/rust-lib/flowy-server/src/server.rs @@ -6,14 +6,14 @@ use std::sync::Arc; use anyhow::Error; use client_api::collab_sync::ServerCollabMessage; -use flowy_chat_pub::cloud::ChatCloudService; +use flowy_ai_pub::cloud::ChatCloudService; use parking_lot::RwLock; use tokio_stream::wrappers::WatchStream; #[cfg(feature = "enable_supabase")] use {collab_entity::CollabObject, collab_plugins::cloud_storage::RemoteCollabStorage}; use crate::default_impl::DefaultChatCloudServiceImpl; -use flowy_database_pub::cloud::DatabaseCloudService; +use flowy_database_pub::cloud::{DatabaseAIService, DatabaseCloudService}; use flowy_document_pub::cloud::DocumentCloudService; use flowy_folder_pub::cloud::FolderCloudService; use flowy_storage_pub::cloud::StorageCloudService; @@ -93,6 +93,8 @@ pub trait AppFlowyServer: Send + Sync + 'static { /// An `Arc` wrapping the `DatabaseCloudService` interface. fn database_service(&self) -> Arc; + fn database_ai_service(&self) -> Option>; + /// Facilitates cloud-based document management. This service offers operations for updating documents, /// fetching snapshots, and accessing primary document data in an asynchronous manner. /// diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs index aed2be3adc..372aa35f3d 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/database.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/database.rs @@ -2,12 +2,10 @@ use anyhow::Error; use collab_entity::CollabType; use tokio::sync::oneshot::channel; -use flowy_database_pub::cloud::{ - CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, - TranslateRowContent, TranslateRowResponse, -}; -use flowy_error::FlowyError; +use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; + use lib_dispatch::prelude::af_spawn; +use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; use crate::supabase::api::request::{ @@ -25,6 +23,7 @@ impl SupabaseDatabaseServiceImpl { } } +#[async_trait] impl DatabaseCloudService for SupabaseDatabaseServiceImpl where T: SupabaseServerService, @@ -98,22 +97,4 @@ where Ok(snapshots) }) } - - fn summary_database_row( - &self, - _workspace_id: &str, - _object_id: &str, - _summary_row: SummaryRowContent, - ) -> FutureResult { - FutureResult::new(async move { Ok("".to_string()) }) - } - - fn translate_database_row( - &self, - _workspace_id: &str, - _translate_row: TranslateRowContent, - _language: &str, - ) -> FutureResult { - FutureResult::new(async move { Ok(TranslateRowResponse::default()) }) - } } diff --git a/frontend/rust-lib/flowy-server/src/supabase/server.rs b/frontend/rust-lib/flowy-server/src/supabase/server.rs index 7b88a80545..b02d7a9030 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/server.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/server.rs @@ -6,7 +6,7 @@ use collab_entity::CollabObject; use collab_plugins::cloud_storage::{RemoteCollabStorage, RemoteUpdateSender}; use parking_lot::RwLock; -use flowy_database_pub::cloud::DatabaseCloudService; +use flowy_database_pub::cloud::{DatabaseAIService, DatabaseCloudService}; use flowy_document_pub::cloud::DocumentCloudService; use flowy_folder_pub::cloud::FolderCloudService; use flowy_server_pub::supabase_config::SupabaseConfiguration; @@ -144,6 +144,10 @@ impl AppFlowyServer for SupabaseServer { ))) } + fn database_ai_service(&self) -> Option> { + None + } + fn document_service(&self) -> Arc { Arc::new(SupabaseDocumentServiceImpl::new(SupabaseServerServiceImpl( self.restful_postgres.clone(),