mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-09-11 11:15:53 +03:00
feat: suppport translate and summary using local ai (#5858)
* chore: fix ui * chore: fix ui * chore: rename * chore: rename * chore: rename * chore: refactor database ai interface * chore: support local ai for database * chore: clippy
This commit is contained in:
parent
b9fd3701cd
commit
73421e0d58
@ -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<ChatAIMessageEvent, ChatAIMessageState> {
|
||||
chatId: chatId,
|
||||
messageId: questionId,
|
||||
);
|
||||
ChatEventGetAnswerForQuestion(payload).send().then((result) {
|
||||
AIEventGetAnswerForQuestion(payload).send().then((result) {
|
||||
if (!isClosed) {
|
||||
result.fold(
|
||||
(answer) {
|
||||
|
@ -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<ChatEvent, ChatState> {
|
||||
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<ChatEvent, ChatState> {
|
||||
}
|
||||
|
||||
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<ChatEvent, ChatState> {
|
||||
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<ChatEvent, ChatState> {
|
||||
limit: Int64(10),
|
||||
beforeMessageId: beforeMessageId,
|
||||
);
|
||||
ChatEventLoadPrevMessage(payload).send();
|
||||
AIEventLoadPrevMessage(payload).send();
|
||||
}
|
||||
|
||||
Future<void> _startStreamingMessage(
|
||||
@ -344,7 +344,7 @@ class ChatBloc extends Bloc<ChatEvent, ChatState> {
|
||||
);
|
||||
|
||||
// Stream message to the server
|
||||
final result = await ChatEventStreamMessage(payload).send();
|
||||
final result = await AIEventStreamMessage(payload).send();
|
||||
result.fold(
|
||||
(ChatMessagePB question) {
|
||||
if (!isClosed) {
|
||||
|
@ -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<ChatFileEvent, ChatFileState> {
|
||||
(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<ChatFileEvent, ChatFileState> {
|
||||
);
|
||||
final payload = ChatFilePB(filePath: filePath, chatId: chatId);
|
||||
unawaited(
|
||||
ChatEventChatWithFile(payload).send().then((result) {
|
||||
AIEventChatWithFile(payload).send().then((result) {
|
||||
if (!isClosed) {
|
||||
result.fold((_) {
|
||||
add(
|
||||
|
@ -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<ChatInputEvent, ChatInputState> {
|
||||
) async {
|
||||
await event.when(
|
||||
started: () async {
|
||||
final result = await ChatEventGetLocalAIPluginState().send();
|
||||
final result = await AIEventGetLocalAIPluginState().send();
|
||||
result.fold(
|
||||
(pluginState) {
|
||||
if (!isClosed) {
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<DownloadModelEvent, DownloadModelState> {
|
||||
|
||||
final payload =
|
||||
DownloadLLMPB(progressStream: Int64(downloadStream.nativePort));
|
||||
final result = await ChatEventDownloadLLMResource(payload).send();
|
||||
final result = await AIEventDownloadLLMResource(payload).send();
|
||||
result.fold((_) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
|
@ -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));
|
||||
|
@ -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<LocalAIToggleEvent, LocalAIToggleState> {
|
||||
) 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<LocalAIToggleEvent, LocalAIToggleState> {
|
||||
),
|
||||
);
|
||||
unawaited(
|
||||
ChatEventToggleLocalAI().send().then(
|
||||
AIEventToggleLocalAI().send().then(
|
||||
(result) {
|
||||
if (!isClosed) {
|
||||
add(LocalAIToggleEvent.handleResult(result));
|
||||
|
@ -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<void> _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));
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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';
|
||||
|
@ -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<PluginStateEvent, PluginStateState> {
|
||||
) 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<PluginStateEvent, PluginStateState> {
|
||||
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<PluginStateEvent, PluginStateState> {
|
||||
);
|
||||
},
|
||||
downloadOfflineAIApp: () async {
|
||||
final result = await ChatEventGetOfflineAIAppLink().send();
|
||||
final result = await AIEventGetOfflineAIAppLink().send();
|
||||
await result.fold(
|
||||
(app) async {
|
||||
await launchUrl(Uri.parse(app.link));
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
60
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
60
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -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",
|
||||
|
@ -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" }
|
||||
|
60
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
60
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
@ -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",
|
||||
|
@ -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" }
|
||||
|
||||
|
@ -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...",
|
||||
|
81
frontend/rust-lib/Cargo.lock
generated
81
frontend/rust-lib/Cargo.lock
generated
@ -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",
|
||||
|
@ -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" }
|
||||
|
@ -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"]
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "flowy-chat-pub"
|
||||
name = "flowy-ai-pub"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
@ -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
|
@ -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<i64, FlowyError>;
|
||||
fn device_id(&self) -> Result<String, FlowyError>;
|
||||
fn workspace_id(&self) -> Result<String, FlowyError>;
|
||||
@ -24,32 +24,32 @@ pub trait ChatUserService: Send + Sync + 'static {
|
||||
fn data_root_dir(&self) -> Result<PathBuf, FlowyError>;
|
||||
}
|
||||
|
||||
pub struct ChatManager {
|
||||
pub cloud_service_wm: Arc<CloudServiceMiddleware>,
|
||||
pub user_service: Arc<dyn ChatUserService>,
|
||||
pub struct AIManager {
|
||||
pub cloud_service_wm: Arc<AICloudServiceMiddleware>,
|
||||
pub user_service: Arc<dyn AIUserService>,
|
||||
chats: Arc<DashMap<String, Arc<Chat>>>,
|
||||
pub local_ai_controller: Arc<LocalAIController>,
|
||||
}
|
||||
|
||||
impl ChatManager {
|
||||
impl AIManager {
|
||||
pub fn new(
|
||||
cloud_service: Arc<dyn ChatCloudService>,
|
||||
user_service: impl ChatUserService,
|
||||
chat_cloud_service: Arc<dyn ChatCloudService>,
|
||||
user_service: impl AIUserService,
|
||||
store_preferences: Arc<KVStorePreferences>,
|
||||
) -> 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(),
|
||||
));
|
||||
|
@ -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<dyn ChatUserService>,
|
||||
chat_service: Arc<CloudServiceMiddleware>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
chat_service: Arc<AICloudServiceMiddleware>,
|
||||
prev_message_state: Arc<RwLock<PrevMessageState>>,
|
||||
latest_message_id: Arc<AtomicI64>,
|
||||
stop_stream: Arc<AtomicBool>,
|
||||
@ -38,8 +38,8 @@ impl Chat {
|
||||
pub fn new(
|
||||
uid: i64,
|
||||
chat_id: String,
|
||||
user_service: Arc<dyn ChatUserService>,
|
||||
chat_service: Arc<CloudServiceMiddleware>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
chat_service: Arc<AICloudServiceMiddleware>,
|
||||
) -> Chat {
|
||||
Chat {
|
||||
uid,
|
||||
@ -189,7 +189,7 @@ impl Chat {
|
||||
fn save_answer(
|
||||
uid: i64,
|
||||
chat_id: &str,
|
||||
user_service: &Arc<dyn ChatUserService>,
|
||||
user_service: &Arc<dyn AIUserService>,
|
||||
answer: ChatMessage,
|
||||
) -> Result<(), FlowyError> {
|
||||
save_chat_message(
|
@ -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<DashMap<String, tokio::sync::mpsc::Sender<()>>>,
|
||||
cloud_service: Weak<dyn ChatCloudService>,
|
||||
user_service: Weak<dyn ChatUserService>,
|
||||
user_service: Weak<dyn AIUserService>,
|
||||
}
|
||||
|
||||
impl AITools {
|
||||
impl AICompletion {
|
||||
pub fn new(
|
||||
cloud_service: Weak<dyn ChatCloudService>,
|
||||
user_service: Weak<dyn ChatUserService>,
|
||||
user_service: Weak<dyn AIUserService>,
|
||||
) -> 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<dyn ChatCloudService>,
|
||||
}
|
||||
|
||||
impl ToolTask {
|
||||
impl CompletionTask {
|
||||
pub fn new(
|
||||
workspace_id: String,
|
||||
context: CompleteTextPB,
|
@ -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};
|
@ -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<Weak<ChatManager>>,
|
||||
) -> FlowyResult<Arc<ChatManager>> {
|
||||
let chat_manager = chat_manager
|
||||
fn upgrade_ai_manager(ai_manager: AFPluginState<Weak<AIManager>>) -> FlowyResult<Arc<AIManager>> {
|
||||
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<StreamChatPayloadPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<ChatMessagePB, FlowyError> {
|
||||
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<LoadPrevChatMessagePB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<ChatMessageListPB, FlowyError> {
|
||||
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<LoadNextChatMessagePB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<ChatMessageListPB, FlowyError> {
|
||||
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<ChatMessageIdPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<RepeatedRelatedQuestionPB, FlowyError> {
|
||||
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<ChatMessageIdPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<ChatMessagePB, FlowyError> {
|
||||
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<StopStreamPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> 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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LLMModelInfoPB, FlowyError> {
|
||||
let chat_manager = upgrade_chat_manager(chat_manager)?;
|
||||
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
||||
let (tx, rx) = oneshot::channel::<Result<LLMModelInfo, FlowyError>>();
|
||||
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<LLMModelPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalModelResourcePB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalModelResourcePB, FlowyError> {
|
||||
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<CompleteTextPB>,
|
||||
tools: AFPluginState<Arc<AITools>>,
|
||||
tools: AFPluginState<Arc<AICompletion>>,
|
||||
) -> DataResult<CompleteTextTaskPB, FlowyError> {
|
||||
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<CompleteTextTaskPB>,
|
||||
tools: AFPluginState<Arc<AITools>>,
|
||||
tools: AFPluginState<Arc<AICompletion>>,
|
||||
) -> 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<ChatFilePB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> 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::<Result<(), FlowyError>>();
|
||||
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<DownloadLLMPB>,
|
||||
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<DownloadTaskPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> 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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIPluginStatePB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIChatPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIChatPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIChatPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> 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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIPB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalModelStoragePB, FlowyError> {
|
||||
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<Weak<ChatManager>>,
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<OfflineAIPB, FlowyError> {
|
||||
let chat_manager = upgrade_chat_manager(chat_manager)?;
|
||||
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
||||
let (tx, rx) = oneshot::channel::<Result<String, FlowyError>>();
|
||||
tokio::spawn(async move {
|
||||
let link = chat_manager
|
||||
let link = ai_manager
|
||||
.local_ai_controller
|
||||
.get_offline_ai_app_download_link()
|
||||
.await?;
|
@ -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<ChatManager>) -> 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<AIManager>) -> 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,
|
@ -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;
|
@ -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<LocalChatLLMChat>,
|
||||
llm_res: Arc<LLMResourceController>,
|
||||
local_ai: Arc<AppFlowyLocalAI>,
|
||||
local_ai_resource: Arc<LocalAIResourceController>,
|
||||
current_chat_id: Mutex<Option<String>>,
|
||||
store_preferences: Arc<KVStorePreferences>,
|
||||
}
|
||||
|
||||
impl Deref for LocalAIController {
|
||||
type Target = Arc<LocalChatLLMChat>;
|
||||
type Target = Arc<AppFlowyLocalAI>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.llm_chat
|
||||
&self.local_ai
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,10 +55,10 @@ impl LocalAIController {
|
||||
pub fn new(
|
||||
plugin_manager: Arc<PluginManager>,
|
||||
store_preferences: Arc<KVStorePreferences>,
|
||||
user_service: Arc<dyn ChatUserService>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
cloud_service: Arc<dyn ChatCloudService>,
|
||||
) -> 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<LLMModelInfo> {
|
||||
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<LocalModelResourcePB> {
|
||||
self.llm_res.get_local_llm_state()
|
||||
self.local_ai_resource.get_local_llm_state()
|
||||
}
|
||||
|
||||
pub fn get_current_model(&self) -> Option<LLMModel> {
|
||||
self.llm_res.get_selected_model()
|
||||
self.local_ai_resource.get_selected_model()
|
||||
}
|
||||
|
||||
pub async fn start_downloading<T>(&self, progress_sink: T) -> FlowyResult<String>
|
||||
where
|
||||
T: Sink<String, Error = anyhow::Error> + 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<String> {
|
||||
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<String> {
|
||||
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<bool> {
|
||||
@ -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<LocalChatLLMChat>,
|
||||
llm_chat: &Arc<AppFlowyLocalAI>,
|
||||
mut chat_config: AIPluginConfig,
|
||||
ret: Option<tokio::sync::oneshot::Sender<()>>,
|
||||
) -> 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<dyn ChatUserService>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
cloud_service: Arc<dyn ChatCloudService>,
|
||||
store_preferences: Arc<KVStorePreferences>,
|
||||
}
|
@ -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<dyn ChatUserService>,
|
||||
pub struct LocalAIResourceController {
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
resource_service: Arc<dyn LLMResourceService>,
|
||||
llm_setting: RwLock<Option<LLMSetting>>,
|
||||
// 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<WatchDiskEvent>,
|
||||
}
|
||||
|
||||
impl LLMResourceController {
|
||||
impl LocalAIResourceController {
|
||||
pub fn new(
|
||||
user_service: Arc<dyn ChatUserService>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
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<LocalModelResourcePB> {
|
||||
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);
|
@ -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<dyn ChatCloudService>,
|
||||
user_service: Arc<dyn ChatUserService>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
local_llm_controller: Arc<LocalAIController>,
|
||||
}
|
||||
|
||||
impl CloudServiceMiddleware {
|
||||
impl AICloudServiceMiddleware {
|
||||
pub fn new(
|
||||
user_service: Arc<dyn ChatUserService>,
|
||||
user_service: Arc<dyn AIUserService>,
|
||||
cloud_service: Arc<dyn ChatCloudService>,
|
||||
local_llm_controller: Arc<LocalAIController>,
|
||||
) -> Self {
|
||||
@ -67,7 +67,7 @@ impl CloudServiceMiddleware {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ChatCloudService for CloudServiceMiddleware {
|
||||
impl ChatCloudService for AICloudServiceMiddleware {
|
||||
fn create_chat(
|
||||
&self,
|
||||
uid: &i64,
|
@ -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"]
|
||||
|
@ -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<AuthenticateUser>,
|
||||
cloud_service: Arc<dyn ChatCloudService>,
|
||||
store_preferences: Arc<KVStorePreferences>,
|
||||
) -> Arc<ChatManager> {
|
||||
) -> Arc<AIManager> {
|
||||
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<i64, FlowyError> {
|
||||
self.upgrade_user()?.user_id()
|
||||
}
|
||||
|
@ -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<RwLock<TaskDispatcher>>,
|
||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
cloud_service: Arc<dyn DatabaseCloudService>,
|
||||
ai_service: Arc<dyn DatabaseAIService>,
|
||||
ai_manager: Arc<AIManager>,
|
||||
) -> Arc<DatabaseManager> {
|
||||
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<AIManager>,
|
||||
ai_service: Arc<dyn DatabaseAIService>,
|
||||
}
|
||||
#[async_trait]
|
||||
impl DatabaseAIService for DatabaseAIServiceMiddleware {
|
||||
async fn summary_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
object_id: &str,
|
||||
summary_row: SummaryRowContent,
|
||||
) -> Result<String, FlowyError> {
|
||||
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<TranslateRowResponse, FlowyError> {
|
||||
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<AuthenticateUser>);
|
||||
impl DatabaseUserImpl {
|
||||
fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> {
|
||||
|
@ -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<DocumentManager>,
|
||||
database_manager: Arc<DatabaseManager>,
|
||||
chat_manager: Arc<ChatManager>,
|
||||
chat_manager: Arc<AIManager>,
|
||||
) -> FolderOperationHandlers {
|
||||
let mut map: HashMap<ViewLayout, Arc<dyn FolderOperationHandler + Send + Sync>> = HashMap::new();
|
||||
|
||||
@ -598,7 +598,7 @@ impl CreateDatabaseExtParams {
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatFolderOperation(Arc<ChatManager>);
|
||||
struct ChatFolderOperation(Arc<AIManager>);
|
||||
impl FolderOperationHandler for ChatFolderOperation {
|
||||
fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
|
||||
let manager = self.0.clone();
|
||||
|
@ -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<String, FlowyError> {
|
||||
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<String, FlowyError> {
|
||||
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<TranslateRowResponse, FlowyError> {
|
||||
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<TranslateRowResponse, FlowyError> {
|
||||
self
|
||||
.get_server()?
|
||||
.database_ai_service()
|
||||
.ok_or_else(FlowyError::not_support)?
|
||||
.translate_database_row(workspace_id, translate_row, language)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<DocumentManager>,
|
||||
pub(crate) server_provider: Arc<ServerProvider>,
|
||||
pub(crate) storage_manager: Arc<StorageManager>,
|
||||
pub(crate) chat_manager: Arc<ChatManager>,
|
||||
pub(crate) ai_manager: Arc<AIManager>,
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<RwLock<TaskDispatcher>>,
|
||||
pub store_preference: Arc<KVStorePreferences>,
|
||||
pub search_manager: Arc<SearchManager>,
|
||||
pub chat_manager: Arc<ChatManager>,
|
||||
pub ai_manager: Arc<AIManager>,
|
||||
pub storage_manager: Arc<StorageManager>,
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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<UserManager>,
|
||||
document_manager2: Weak<DocumentManager2>,
|
||||
search_manager: Weak<SearchManager>,
|
||||
chat_manager: Weak<ChatManager>,
|
||||
ai_manager: Weak<AIManager>,
|
||||
) -> Vec<AFPlugin> {
|
||||
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,
|
||||
]
|
||||
}
|
||||
|
@ -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<String, DataSource>;
|
||||
pub type SummaryRowContent = HashMap<String, String>;
|
||||
pub type TranslateRowContent = Vec<TranslateItem>;
|
||||
|
||||
#[async_trait]
|
||||
pub trait DatabaseAIService: Send + Sync {
|
||||
async fn summary_database_row(
|
||||
&self,
|
||||
_workspace_id: &str,
|
||||
_object_id: &str,
|
||||
_summary_row: SummaryRowContent,
|
||||
) -> Result<String, FlowyError> {
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
async fn translate_database_row(
|
||||
&self,
|
||||
_workspace_id: &str,
|
||||
_translate_row: TranslateRowContent,
|
||||
_language: &str,
|
||||
) -> Result<TranslateRowResponse, FlowyError> {
|
||||
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<Vec<DatabaseSnapshot>, Error>;
|
||||
|
||||
fn summary_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
object_id: &str,
|
||||
summary_row: SummaryRowContent,
|
||||
) -> FutureResult<String, FlowyError>;
|
||||
|
||||
fn translate_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
translate_row: TranslateRowContent,
|
||||
language: &str,
|
||||
) -> FutureResult<TranslateRowResponse, FlowyError>;
|
||||
}
|
||||
|
||||
pub struct DatabaseSnapshot {
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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<HashMap<String, Arc<DatabaseEditor>>>,
|
||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
cloud_service: Arc<dyn DatabaseCloudService>,
|
||||
ai_service: Arc<dyn DatabaseAIService>,
|
||||
}
|
||||
|
||||
impl DatabaseManager {
|
||||
@ -55,6 +56,7 @@ impl DatabaseManager {
|
||||
task_scheduler: Arc<RwLock<TaskDispatcher>>,
|
||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||
cloud_service: Arc<dyn DatabaseCloudService>,
|
||||
ai_service: Arc<dyn DatabaseAIService>,
|
||||
) -> 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?;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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<T> {
|
||||
pub user: Arc<dyn ServerUser>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T> DatabaseCloudService for AFCloudDatabaseCloudServiceImpl<T>
|
||||
where
|
||||
T: AFServer,
|
||||
@ -121,48 +123,48 @@ where
|
||||
) -> FutureResult<Vec<DatabaseSnapshot>, Error> {
|
||||
FutureResult::new(async move { Ok(vec![]) })
|
||||
}
|
||||
}
|
||||
|
||||
fn summary_database_row(
|
||||
#[async_trait]
|
||||
impl<T> DatabaseAIService for AFCloudDatabaseCloudServiceImpl<T>
|
||||
where
|
||||
T: AFServer,
|
||||
{
|
||||
async fn summary_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
_object_id: &str,
|
||||
summary_row: SummaryRowContent,
|
||||
) -> FutureResult<String, FlowyError> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
) -> Result<String, FlowyError> {
|
||||
let try_get_client = self.inner.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let map: Map<String, Value> = 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<String, Value> = 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<TranslateRowResponse, FlowyError> {
|
||||
let language = language.to_string();
|
||||
) -> Result<TranslateRowResponse, FlowyError> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<Arc<dyn DatabaseAIService>> {
|
||||
let server = AFServerImpl {
|
||||
client: self.get_client(),
|
||||
};
|
||||
Some(Arc::new(AFCloudDatabaseCloudServiceImpl {
|
||||
inner: server,
|
||||
user: self.user.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn document_service(&self) -> Arc<dyn DocumentCloudService> {
|
||||
let server = AFServerImpl {
|
||||
client: self.get_client(),
|
||||
|
@ -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;
|
||||
|
@ -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<Vec<DatabaseSnapshot>, Error> {
|
||||
FutureResult::new(async move { Ok(vec![]) })
|
||||
}
|
||||
|
||||
fn summary_database_row(
|
||||
&self,
|
||||
_workspace_id: &str,
|
||||
_object_id: &str,
|
||||
_summary_row: SummaryRowContent,
|
||||
) -> FutureResult<String, FlowyError> {
|
||||
// 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<TranslateRowResponse, FlowyError> {
|
||||
// TODO(lucas): local ai
|
||||
FutureResult::new(async move { Ok(TranslateRowResponse::default()) })
|
||||
}
|
||||
}
|
||||
|
@ -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<Arc<dyn SearchCloudService>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn database_ai_service(&self) -> Option<Arc<dyn DatabaseAIService>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -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<dyn DatabaseCloudService>;
|
||||
|
||||
fn database_ai_service(&self) -> Option<Arc<dyn DatabaseAIService>>;
|
||||
|
||||
/// Facilitates cloud-based document management. This service offers operations for updating documents,
|
||||
/// fetching snapshots, and accessing primary document data in an asynchronous manner.
|
||||
///
|
||||
|
@ -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<T> SupabaseDatabaseServiceImpl<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T> DatabaseCloudService for SupabaseDatabaseServiceImpl<T>
|
||||
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<String, FlowyError> {
|
||||
FutureResult::new(async move { Ok("".to_string()) })
|
||||
}
|
||||
|
||||
fn translate_database_row(
|
||||
&self,
|
||||
_workspace_id: &str,
|
||||
_translate_row: TranslateRowContent,
|
||||
_language: &str,
|
||||
) -> FutureResult<TranslateRowResponse, FlowyError> {
|
||||
FutureResult::new(async move { Ok(TranslateRowResponse::default()) })
|
||||
}
|
||||
}
|
||||
|
@ -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<Arc<dyn DatabaseAIService>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn document_service(&self) -> Arc<dyn DocumentCloudService> {
|
||||
Arc::new(SupabaseDocumentServiceImpl::new(SupabaseServerServiceImpl(
|
||||
self.restful_postgres.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user