diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_service.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_service.dart index c497cd6c23..1985e41242 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_service.dart @@ -10,6 +10,9 @@ import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:nanoid/nanoid.dart'; +/// Indicate file source from appflowy document +const appflowySoruce = "appflowy"; + List fileListFromMessageMetadata( Map? map, ) { @@ -75,6 +78,7 @@ List messageReferenceSource(String? s) { Log.warn("metadata is null"); return []; } + // [{"id":null,"name":"The Five Dysfunctions of a Team.pdf","source":"/Users/weidongfu/Desktop/The Five Dysfunctions of a Team.pdf"}] if (metadataJson is Map) { if (metadataJson.isNotEmpty) { @@ -115,7 +119,7 @@ Future> metadataPBFromMetadata( name: view.name, data: pb.text, dataType: ChatMessageMetaTypePB.Txt, - source: "appflowy", + source: appflowySoruce, ), ); }, (err) { diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart index 207d811b8b..c0a29c2453 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart @@ -19,7 +19,9 @@ class ChatUserMessageBloc event.when( initial: () { if (state.stream != null) { - add(ChatUserMessageEvent.updateText(state.stream!.text)); + if (!isClosed) { + add(ChatUserMessageEvent.updateText(state.stream!.text)); + } } state.stream?.listen( diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/message/ai_metadata.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/message/ai_metadata.dart index 9796a28a34..6d4f85d616 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/message/ai_metadata.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/message/ai_metadata.dart @@ -1,5 +1,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/ai_chat/application/chat_entity.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_message_service.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; @@ -53,7 +54,13 @@ class AIMessageMetadata extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - onTap: () => onSelectedMetadata(m), + disable: m.source != appflowySoruce, + onTap: () { + if (m.source != appflowySoruce) { + return; + } + onSelectedMetadata(m); + }, ), ), ) diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart index a14206e38e..0a1fce251b 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/ai/download_model_bloc.dart @@ -2,18 +2,20 @@ import 'dart:async'; import 'dart:ffi'; import 'dart:isolate'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/ai_chat/application/chat_entity.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:bloc/bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:fixnum/fixnum.dart'; part 'download_model_bloc.freezed.dart'; class DownloadModelBloc extends Bloc { DownloadModelBloc(LLMModelPB model) - : super(DownloadModelState(model: model)) { + : super(DownloadModelState.initial(model)) { on(_handleEvent); } @@ -99,8 +101,21 @@ class DownloadModelState with _$DownloadModelState { @Default("") String object, @Default(0) double percent, @Default(false) bool isFinish, + String? bigFileDownloadPrompt, @Default(ChatLoadingState.loading()) ChatLoadingState loadingState, }) = _DownloadModelState; + + factory DownloadModelState.initial(LLMModelPB model) { + // bigger than 1 GB then show download big file prompt + String? bigFileDownloadPrompt; + if (model.fileSize > 1 * 1024 * 1024 * 1024) { + bigFileDownloadPrompt = LocaleKeys.settings_aiPage_keys_downloadBigFilePrompt.tr(); + } + return DownloadModelState( + model: model, + bigFileDownloadPrompt: bigFileDownloadPrompt, + ); + } } class DownloadingStream { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart index dccc01dcc8..a7ed782aea 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/downloading_model.dart @@ -37,10 +37,23 @@ class DownloadingIndicator extends StatelessWidget { color: Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(8), ), - child: Column( - children: [ - DownloadingProgressBar(onCancel: onCancel), - ], + child: BlocBuilder( + builder: (context, state) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DownloadingProgressBar(onCancel: onCancel), + if (state.bigFileDownloadPrompt != null) ...[ + const VSpace(2), + Opacity( + opacity: 0.6, + child: + FlowyText(state.bigFileDownloadPrompt!, fontSize: 11), + ), + ], + ], + ); + }, ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart index ac1fd2ab09..135259a04e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_view.dart @@ -121,8 +121,8 @@ class _SettingsPlanViewState extends State { priceInfo: LocaleKeys .settings_planPage_planUsage_addons_aiMax_priceInfo .tr(), - billingInfo: LocaleKeys - .settings_planPage_planUsage_addons_aiMax_billingInfo + recommend: LocaleKeys + .settings_planPage_planUsage_addons_aiMax_recommend .tr( args: [SubscriptionPlanPB.AiMax.priceMonthBilling], ), @@ -160,8 +160,8 @@ class _SettingsPlanViewState extends State { priceInfo: LocaleKeys .settings_planPage_planUsage_addons_aiOnDevice_priceInfo .tr(), - billingInfo: LocaleKeys - .settings_planPage_planUsage_addons_aiOnDevice_billingInfo + recommend: LocaleKeys + .settings_planPage_planUsage_addons_aiOnDevice_recommend .tr( args: [ SubscriptionPlanPB.AiLocal.priceMonthBilling, @@ -654,7 +654,7 @@ class _AddOnBox extends StatelessWidget { required this.description, required this.price, required this.priceInfo, - required this.billingInfo, + required this.recommend, required this.buttonText, required this.isActive, required this.plan, @@ -664,7 +664,7 @@ class _AddOnBox extends StatelessWidget { final String description; final String price; final String priceInfo; - final String billingInfo; + final String recommend; final String buttonText; final bool isActive; final SubscriptionPlanPB plan; @@ -717,7 +717,7 @@ class _AddOnBox extends StatelessWidget { children: [ Expanded( child: FlowyText( - billingInfo, + recommend, color: AFThemeExtension.of(context).secondaryTextColor, fontSize: 11, maxLines: 2, diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 20ede978d8..5232879284 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -172,7 +172,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" 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=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -207,7 +207,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "appflowy-plugin", @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "cfg-if", @@ -826,7 +826,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "again", "anyhow", @@ -876,7 +876,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "collab-entity", "collab-rt-entity", @@ -888,7 +888,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "futures-channel", "futures-util", @@ -994,7 +994,7 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", - "dashmap", + "dashmap 5.5.3", "getrandom 0.2.10", "js-sys", "lazy_static", @@ -1132,7 +1132,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bincode", @@ -1157,7 +1157,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "async-trait", @@ -1421,7 +1421,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1523,6 +1523,20 @@ dependencies = [ "parking_lot_core 0.9.8", ] +[[package]] +name = "dashmap" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.8", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -1532,7 +1546,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -1960,13 +1974,14 @@ dependencies = [ "appflowy-plugin", "base64 0.21.5", "bytes", - "dashmap", + "dashmap 6.0.1", "flowy-ai-pub", "flowy-codegen", "flowy-derive", "flowy-error", "flowy-notification", "flowy-sqlite", + "flowy-storage-pub", "futures", "futures-util", "lib-dispatch", @@ -2131,7 +2146,7 @@ dependencies = [ "collab-integrate", "collab-plugins", "csv", - "dashmap", + "dashmap 6.0.1", "fancy-regex 0.11.0", "flowy-codegen", "flowy-database-pub", @@ -2181,7 +2196,7 @@ dependencies = [ name = "flowy-derive" version = "0.1.0" dependencies = [ - "dashmap", + "dashmap 6.0.1", "flowy-ast", "flowy-codegen", "lazy_static", @@ -2203,7 +2218,7 @@ dependencies = [ "collab-entity", "collab-integrate", "collab-plugins", - "dashmap", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "flowy-document-pub", @@ -2340,7 +2355,7 @@ name = "flowy-notification" version = "0.1.0" dependencies = [ "bytes", - "dashmap", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "lazy_static", @@ -2483,6 +2498,7 @@ dependencies = [ "async-trait", "bytes", "chrono", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "flowy-error", @@ -2515,6 +2531,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tracing", ] [[package]] @@ -3051,7 +3068,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "futures-util", @@ -3068,7 +3085,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -3500,7 +3517,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -6098,7 +6115,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 026dd6daf6..e1ea6f63ba 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -53,7 +53,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6a44490daccb101c8b855443d2d6ded0fb752016" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7878a018a18553e3d8201e572a0c066c14ba3b35" } [dependencies] serde_json.workspace = true @@ -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 = "65802795ad8778de11c45b5af65d05c973709613" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "65802795ad8778de11c45b5af65d05c973709613" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index e940bdd58a..d09880059e 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" 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=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -198,7 +198,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "appflowy-plugin", @@ -217,7 +217,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "cfg-if", @@ -800,7 +800,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "again", "anyhow", @@ -850,7 +850,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "collab-entity", "collab-rt-entity", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "futures-channel", "futures-util", @@ -977,7 +977,7 @@ dependencies = [ "collab", "collab-entity", "collab-plugins", - "dashmap", + "dashmap 5.5.3", "getrandom 0.2.12", "js-sys", "lazy_static", @@ -1115,7 +1115,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bincode", @@ -1140,7 +1140,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "async-trait", @@ -1411,7 +1411,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.10", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1513,6 +1513,20 @@ dependencies = [ "parking_lot_core 0.9.9", ] +[[package]] +name = "dashmap" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + [[package]] name = "data-encoding" version = "2.5.0" @@ -1522,7 +1536,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -1990,13 +2004,14 @@ dependencies = [ "appflowy-plugin", "base64 0.21.7", "bytes", - "dashmap", + "dashmap 6.0.1", "flowy-ai-pub", "flowy-codegen", "flowy-derive", "flowy-error", "flowy-notification", "flowy-sqlite", + "flowy-storage-pub", "futures", "futures-util", "lib-dispatch", @@ -2161,7 +2176,7 @@ dependencies = [ "collab-integrate", "collab-plugins", "csv", - "dashmap", + "dashmap 6.0.1", "fancy-regex 0.11.0", "flowy-codegen", "flowy-database-pub", @@ -2211,7 +2226,7 @@ dependencies = [ name = "flowy-derive" version = "0.1.0" dependencies = [ - "dashmap", + "dashmap 6.0.1", "flowy-ast", "flowy-codegen", "lazy_static", @@ -2233,7 +2248,7 @@ dependencies = [ "collab-entity", "collab-integrate", "collab-plugins", - "dashmap", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "flowy-document-pub", @@ -2370,7 +2385,7 @@ name = "flowy-notification" version = "0.1.0" dependencies = [ "bytes", - "dashmap", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "lazy_static", @@ -2513,6 +2528,7 @@ dependencies = [ "async-trait", "bytes", "chrono", + "dashmap 6.0.1", "flowy-codegen", "flowy-derive", "flowy-error", @@ -2545,6 +2561,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tracing", ] [[package]] @@ -3118,7 +3135,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "futures-util", @@ -3135,7 +3152,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -3572,7 +3589,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -6162,7 +6179,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index e2b61d6d39..b4db66e726 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6a44490daccb101c8b855443d2d6ded0fb752016" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7878a018a18553e3d8201e572a0c066c14ba3b35" } [dependencies] serde_json.workspace = true @@ -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 = "65802795ad8778de11c45b5af65d05c973709613" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "65802795ad8778de11c45b5af65d05c973709613" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index b1a3ebe11a..5994543413 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -666,6 +666,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?", + "downloadBigFilePrompt": "It may take around 10 minutes to complete the download", "downloadAIModelButton": "Download", "downloadingModel": "Downloading", "localAILoaded": "Local AI Model successfully added and ready to use", @@ -735,15 +736,15 @@ "title": "AI Max", "description": "Unlimited AI responses powered by GPT-4o, Claude 3.5 Sonnet, and more", "price": "{}", - "priceInfo": "per user per month", - "billingInfo": "billed annually or {} billed monthly" + "priceInfo": "per user per month billed annually", + "recommend": "" }, "aiOnDevice": { "title": "AI On-device for Mac", "description": "Run Mistral 7B, LLAMA 3, and more local models on your machine", "price": "{}", - "priceInfo": "per user per month", - "billingInfo": "billed annually or {} billed monthly" + "priceInfo": "per user per month billed annually", + "recommend": "Recommend M1 or newer" } }, "deal": { diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 9ff90f08e9..0785d7c68a 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" 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=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -198,7 +198,7 @@ dependencies = [ [[package]] name = "appflowy-local-ai" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "appflowy-plugin", @@ -217,7 +217,7 @@ dependencies = [ [[package]] name = "appflowy-plugin" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=65802795ad8778de11c45b5af65d05c973709613#65802795ad8778de11c45b5af65d05c973709613" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=6f064efe232268f8d396edbb4b84d57fbb640f13#6f064efe232268f8d396edbb4b84d57fbb640f13" dependencies = [ "anyhow", "cfg-if", @@ -718,7 +718,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "again", "anyhow", @@ -768,7 +768,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "collab-entity", "collab-rt-entity", @@ -780,7 +780,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "futures-channel", "futures-util", @@ -993,7 +993,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bincode", @@ -1018,7 +1018,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "async-trait", @@ -1370,7 +1370,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -2747,7 +2747,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "futures-util", @@ -2764,7 +2764,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", @@ -3129,7 +3129,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "bytes", @@ -5338,7 +5338,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6a44490daccb101c8b855443d2d6ded0fb752016#6a44490daccb101c8b855443d2d6ded0fb752016" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=7878a018a18553e3d8201e572a0c066c14ba3b35#7878a018a18553e3d8201e572a0c066c14ba3b35" dependencies = [ "anyhow", "app-error", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 54b2f1a187..1675bf3d7b 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -100,8 +100,8 @@ dashmap = "6.0.1" # 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 = "6a44490daccb101c8b855443d2d6ded0fb752016" } -client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6a44490daccb101c8b855443d2d6ded0fb752016" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7878a018a18553e3d8201e572a0c066c14ba3b35" } +client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "7878a018a18553e3d8201e572a0c066c14ba3b35" } [profile.dev] opt-level = 0 @@ -148,5 +148,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 = "65802795ad8778de11c45b5af65d05c973709613" } -appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "65802795ad8778de11c45b5af65d05c973709613" } +appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } +appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "6f064efe232268f8d396edbb4b84d57fbb640f13" } diff --git a/frontend/rust-lib/flowy-ai-pub/src/cloud.rs b/frontend/rust-lib/flowy-ai-pub/src/cloud.rs index e29ddae174..30f29d6c7f 100644 --- a/frontend/rust-lib/flowy-ai-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-ai-pub/src/cloud.rs @@ -12,6 +12,8 @@ use flowy_error::FlowyError; use futures::stream::BoxStream; use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; +use serde_json::Value; +use std::collections::HashMap; use std::path::Path; pub type ChatMessageStream = BoxStream<'static, Result>; @@ -85,6 +87,7 @@ pub trait ChatCloudService: Send + Sync + 'static { workspace_id: &str, file_path: &Path, chat_id: &str, + metadata: Option>, ) -> Result<(), FlowyError>; async fn get_local_ai_config(&self, workspace_id: &str) -> Result; diff --git a/frontend/rust-lib/flowy-ai/src/chat.rs b/frontend/rust-lib/flowy-ai/src/chat.rs index b0fd1c42d3..667e072ea2 100644 --- a/frontend/rust-lib/flowy-ai/src/chat.rs +++ b/frontend/rust-lib/flowy-ai/src/chat.rs @@ -513,6 +513,7 @@ impl Chat { &self.user_service.workspace_id()?, &file_path, &self.chat_id, + None, ) .await?; diff --git a/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs index 8ea17c1638..cf69120d80 100644 --- a/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs +++ b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_chat.rs @@ -357,6 +357,7 @@ impl LocalAIController { } let mut index_metadata = HashMap::new(); + index_metadata.insert("id".to_string(), json!(&metadata.id)); index_metadata.insert("name".to_string(), json!(&metadata.name)); index_metadata.insert("at_name".to_string(), json!(format!("@{}", &metadata.name))); index_metadata.insert("source".to_string(), json!(&metadata.source)); diff --git a/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs index 2b51ef7a61..5528a00ac5 100644 --- a/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs +++ b/frontend/rust-lib/flowy-ai/src/local_ai/local_llm_resource.rs @@ -359,6 +359,10 @@ impl LocalAIResourceController { let cloned_model_name = model_name.clone(); let progress = Arc::new(move |downloaded, total_size| { let progress = (downloaded as f64 / total_size as f64).clamp(0.0, 1.0); + if plugin_progress_tx.receiver_count() == 0 { + return; + } + if let Err(err) = plugin_progress_tx.send(format!("{}:progress:{}", cloned_model_name, progress)) { diff --git a/frontend/rust-lib/flowy-ai/src/local_ai/stream_util.rs b/frontend/rust-lib/flowy-ai/src/local_ai/stream_util.rs index 5f411a9130..76eb01ea6f 100644 --- a/frontend/rust-lib/flowy-ai/src/local_ai/stream_util.rs +++ b/frontend/rust-lib/flowy-ai/src/local_ai/stream_util.rs @@ -1,39 +1,62 @@ use appflowy_plugin::error::PluginError; -use bytes::Bytes; + use flowy_ai_pub::cloud::QuestionStreamValue; use flowy_error::FlowyError; use futures::{ready, Stream}; use pin_project::pin_project; +use serde_json::Value; use std::pin::Pin; use std::task::{Context, Poll}; +use tracing::error; + +pub const STEAM_METADATA_KEY: &str = "0"; +pub const STEAM_ANSWER_KEY: &str = "1"; #[pin_project] -pub struct LocalAIStreamAdaptor { - stream: Pin> + Send>>, +pub struct QuestionStream { + stream: Pin> + Send>>, buffer: Vec, } -impl LocalAIStreamAdaptor { +impl QuestionStream { pub fn new(stream: S) -> Self where - S: Stream> + Send + 'static, + S: Stream> + Send + 'static, { - LocalAIStreamAdaptor { + QuestionStream { stream: Box::pin(stream), buffer: Vec::new(), } } } -impl Stream for LocalAIStreamAdaptor { +impl Stream for QuestionStream { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); + match ready!(this.stream.as_mut().poll_next(cx)) { - Some(Ok(bytes)) => match String::from_utf8(bytes.to_vec()) { - Ok(s) => Poll::Ready(Some(Ok(QuestionStreamValue::Answer { value: s }))), - Err(err) => Poll::Ready(Some(Err(FlowyError::internal().with_context(err)))), + Some(Ok(value)) => match value { + Value::Object(mut value) => { + if let Some(metadata) = value.remove(STEAM_METADATA_KEY) { + return Poll::Ready(Some(Ok(QuestionStreamValue::Metadata { value: metadata }))); + } + + if let Some(answer) = value + .remove(STEAM_ANSWER_KEY) + .and_then(|s| s.as_str().map(ToString::to_string)) + { + return Poll::Ready(Some(Ok(QuestionStreamValue::Answer { value: answer }))); + } + + error!("Invalid streaming value: {:?}", value); + Poll::Ready(None) + }, + _ => { + error!("Unexpected JSON value type: {:?}", value); + Poll::Ready(None) + }, }, Some(Err(err)) => Poll::Ready(Some(Err(FlowyError::local_ai().with_context(err)))), None => Poll::Ready(None), diff --git a/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs index 2e7f4e54a2..598d5716c6 100644 --- a/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs +++ b/frontend/rust-lib/flowy-ai/src/middleware/chat_service_mw.rs @@ -4,6 +4,7 @@ use crate::local_ai::local_llm_chat::LocalAIController; use crate::notification::{make_notification, ChatNotification, APPFLOWY_AI_NOTIFICATION_KEY}; use crate::persistence::{select_single_message, ChatMessageTable}; use appflowy_plugin::error::PluginError; +use std::collections::HashMap; use flowy_ai_pub::cloud::{ ChatCloudService, ChatMessage, ChatMessageMetadata, ChatMessageType, CompletionType, @@ -15,11 +16,11 @@ use futures::{stream, Sink, StreamExt, TryStreamExt}; use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; -use crate::local_ai::stream_util::LocalAIStreamAdaptor; +use crate::local_ai::stream_util::QuestionStream; use crate::stream_message::StreamMessage; use flowy_storage_pub::storage::StorageService; use futures_util::SinkExt; -use serde_json::json; +use serde_json::{json, Value}; use std::path::Path; use std::sync::{Arc, Weak}; use tracing::trace; @@ -157,7 +158,7 @@ impl ChatCloudService for AICloudServiceMiddleware { .stream_question(chat_id, &row.content, json!([])) .await { - Ok(stream) => Ok(LocalAIStreamAdaptor::new(stream).boxed()), + Ok(stream) => Ok(QuestionStream::new(stream).boxed()), Err(err) => { self.handle_plugin_error(err); Ok(stream::once(async { Err(FlowyError::local_ai_unavailable()) }).boxed()) @@ -284,18 +285,19 @@ impl ChatCloudService for AICloudServiceMiddleware { workspace_id: &str, file_path: &Path, chat_id: &str, + metadata: Option>, ) -> Result<(), FlowyError> { if self.local_llm_controller.is_running() { self .local_llm_controller - .index_file(chat_id, Some(file_path.to_path_buf()), None, None) + .index_file(chat_id, Some(file_path.to_path_buf()), None, metadata) .await .map_err(|err| FlowyError::local_ai().with_context(err))?; Ok(()) } else { self .cloud_service - .index_file(workspace_id, file_path, chat_id) + .index_file(workspace_id, file_path, chat_id, metadata) .await } } diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index afb482d64a..f184b5a020 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -1,5 +1,6 @@ use client_api::entity::search_dto::SearchDocumentResponseItem; use flowy_search_pub::cloud::SearchCloudService; +use std::collections::HashMap; use std::path::Path; use std::sync::Arc; @@ -12,6 +13,7 @@ use collab::core::origin::{CollabClient, CollabOrigin}; use collab::preclude::CollabPlugin; use collab_entity::CollabType; use collab_plugins::cloud_storage::postgres::SupabaseDBPlugin; +use serde_json::Value; use tokio_stream::wrappers::WatchStream; use tracing::{debug, info}; @@ -719,11 +721,12 @@ impl ChatCloudService for ServerProvider { workspace_id: &str, file_path: &Path, chat_id: &str, + metadata: Option>, ) -> Result<(), FlowyError> { self .get_server()? .chat_service() - .index_file(workspace_id, file_path, chat_id) + .index_file(workspace_id, file_path, chat_id, metadata) .await } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs index 3bdaf7e1a6..2e8e1a8eab 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs @@ -15,7 +15,8 @@ use futures_util::{StreamExt, TryStreamExt}; use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; use lib_infra::util::{get_operating_system, OperatingSystem}; -use serde_json::json; +use serde_json::{json, Value}; +use std::collections::HashMap; use std::path::Path; pub(crate) struct AFCloudChatCloudServiceImpl { @@ -182,6 +183,7 @@ where _workspace_id: &str, _file_path: &Path, _chat_id: &str, + _metadata: Option>, ) -> Result<(), FlowyError> { return Err( FlowyError::not_support() diff --git a/frontend/rust-lib/flowy-server/src/default_impl.rs b/frontend/rust-lib/flowy-server/src/default_impl.rs index be0ce1092e..0e22a6313f 100644 --- a/frontend/rust-lib/flowy-server/src/default_impl.rs +++ b/frontend/rust-lib/flowy-server/src/default_impl.rs @@ -6,6 +6,8 @@ use flowy_ai_pub::cloud::{ use flowy_error::FlowyError; use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; +use serde_json::Value; +use std::collections::HashMap; use std::path::Path; pub(crate) struct DefaultChatCloudServiceImpl; @@ -96,6 +98,7 @@ impl ChatCloudService for DefaultChatCloudServiceImpl { _workspace_id: &str, _file_path: &Path, _chat_id: &str, + _metadata: Option>, ) -> Result<(), FlowyError> { Err(FlowyError::not_support().with_context("indexing file is not supported in local server.")) }