mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: show plugin state (#5740)
* chore: show plugin state * chore: flutter analyzer * chore: update
This commit is contained in:
parent
ff23165d3e
commit
c6ad57f11d
@ -15,7 +15,6 @@ extension AppFlowyAuthTest on WidgetTester {
|
|||||||
Future<void> tapGoogleLoginInButton() async {
|
Future<void> tapGoogleLoginInButton() async {
|
||||||
await tapButton(
|
await tapButton(
|
||||||
find.byKey(const Key('signInWithGoogleButton')),
|
find.byKey(const Key('signInWithGoogleButton')),
|
||||||
milliseconds: 3000,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:appflowy/workspace/application/settings/ai/local_llm_listener.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -9,31 +10,69 @@ class ChatFileBloc extends Bloc<ChatFileEvent, ChatFileState> {
|
|||||||
ChatFileBloc({
|
ChatFileBloc({
|
||||||
required String chatId,
|
required String chatId,
|
||||||
dynamic message,
|
dynamic message,
|
||||||
}) : super(ChatFileState.initial(message)) {
|
}) : listener = LocalLLMListener(),
|
||||||
|
super(ChatFileState.initial(message)) {
|
||||||
|
listener.start(
|
||||||
|
stateCallback: (pluginState) {
|
||||||
|
if (!isClosed) {
|
||||||
|
add(ChatFileEvent.updateLocalAIState(pluginState));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
on<ChatFileEvent>(
|
on<ChatFileEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.when(
|
await event.when(
|
||||||
initial: () async {},
|
initial: () async {
|
||||||
|
final result = await ChatEventGetPluginState().send();
|
||||||
|
result.fold(
|
||||||
|
(pluginState) {
|
||||||
|
if (!isClosed) {
|
||||||
|
add(ChatFileEvent.updateLocalAIState(pluginState));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) {},
|
||||||
|
);
|
||||||
|
},
|
||||||
newFile: (String filePath) {
|
newFile: (String filePath) {
|
||||||
final payload = ChatFilePB(filePath: filePath, chatId: chatId);
|
final payload = ChatFilePB(filePath: filePath, chatId: chatId);
|
||||||
ChatEventChatWithFile(payload).send();
|
ChatEventChatWithFile(payload).send();
|
||||||
},
|
},
|
||||||
|
updateLocalAIState: (PluginStatePB pluginState) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
supportChatWithFile:
|
||||||
|
pluginState.state == RunningStatePB.Running,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final LocalLLMListener listener;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
await listener.stop();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ChatFileEvent with _$ChatFileEvent {
|
class ChatFileEvent with _$ChatFileEvent {
|
||||||
const factory ChatFileEvent.initial() = Initial;
|
const factory ChatFileEvent.initial() = Initial;
|
||||||
const factory ChatFileEvent.newFile(String filePath) = _NewFile;
|
const factory ChatFileEvent.newFile(String filePath) = _NewFile;
|
||||||
|
const factory ChatFileEvent.updateLocalAIState(PluginStatePB pluginState) =
|
||||||
|
_UpdateLocalAIState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ChatFileState with _$ChatFileState {
|
class ChatFileState with _$ChatFileState {
|
||||||
const factory ChatFileState({
|
const factory ChatFileState({
|
||||||
required String text,
|
required String text,
|
||||||
|
@Default(false) bool supportChatWithFile,
|
||||||
}) = _ChatFileState;
|
}) = _ChatFileState;
|
||||||
|
|
||||||
factory ChatFileState.initial(dynamic text) {
|
factory ChatFileState.initial(dynamic text) {
|
||||||
|
@ -71,19 +71,24 @@ class AIChatPage extends StatelessWidget {
|
|||||||
create: (context) => ChatFileBloc(chatId: view.id.toString()),
|
create: (context) => ChatFileBloc(chatId: view.id.toString()),
|
||||||
child: BlocBuilder<ChatFileBloc, ChatFileState>(
|
child: BlocBuilder<ChatFileBloc, ChatFileState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return DropTarget(
|
return state.supportChatWithFile
|
||||||
onDragDone: (DropDoneDetails detail) async {
|
? DropTarget(
|
||||||
for (final file in detail.files) {
|
onDragDone: (DropDoneDetails detail) async {
|
||||||
context
|
for (final file in detail.files) {
|
||||||
.read<ChatFileBloc>()
|
context
|
||||||
.add(ChatFileEvent.newFile(file.path));
|
.read<ChatFileBloc>()
|
||||||
}
|
.add(ChatFileEvent.newFile(file.path));
|
||||||
},
|
}
|
||||||
child: _ChatContentPage(
|
},
|
||||||
view: view,
|
child: _ChatContentPage(
|
||||||
userProfile: userProfile,
|
view: view,
|
||||||
),
|
userProfile: userProfile,
|
||||||
);
|
),
|
||||||
|
)
|
||||||
|
: _ChatContentPage(
|
||||||
|
view: view,
|
||||||
|
userProfile: userProfile,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -20,7 +20,7 @@ class LocalAISettingBloc
|
|||||||
listener.start(
|
listener.start(
|
||||||
stateCallback: (newState) {
|
stateCallback: (newState) {
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
add(LocalAISettingEvent.updateLLMRunningState(newState));
|
add(LocalAISettingEvent.updateLLMRunningState(newState.state));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -51,7 +51,11 @@ class LocalAISettingBloc
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
(err) {
|
(err) {
|
||||||
emit(state.copyWith(fetchModelInfoState: LoadingState.finish(error: err)));
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
fetchModelInfoState: LoadingState.finish(error: err),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -184,6 +188,12 @@ class LocalAISettingBloc
|
|||||||
add(LocalAISettingEvent.didLoadModelInfo(result));
|
add(LocalAISettingEvent.didLoadModelInfo(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
await listener.stop();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -9,7 +9,7 @@ import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart';
|
|||||||
import 'package:appflowy_backend/rust_stream.dart';
|
import 'package:appflowy_backend/rust_stream.dart';
|
||||||
import 'package:appflowy_result/appflowy_result.dart';
|
import 'package:appflowy_result/appflowy_result.dart';
|
||||||
|
|
||||||
typedef PluginStateCallback = void Function(RunningStatePB state);
|
typedef PluginStateCallback = void Function(PluginStatePB state);
|
||||||
|
|
||||||
class LocalLLMListener {
|
class LocalLLMListener {
|
||||||
LocalLLMListener() {
|
LocalLLMListener() {
|
||||||
@ -39,7 +39,7 @@ class LocalLLMListener {
|
|||||||
result.map((r) {
|
result.map((r) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case ChatNotification.UpdateChatPluginState:
|
case ChatNotification.UpdateChatPluginState:
|
||||||
stateCallback?.call(PluginStatePB.fromBuffer(r).state);
|
stateCallback?.call(PluginStatePB.fromBuffer(r));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1,24 +1,67 @@
|
|||||||
import 'dart:async';
|
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-chat/entities.pb.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
part 'plugin_state_bloc.freezed.dart';
|
part 'plugin_state_bloc.freezed.dart';
|
||||||
|
|
||||||
class PluginStateBloc extends Bloc<PluginStateEvent, PluginState> {
|
class PluginStateBloc extends Bloc<PluginStateEvent, PluginStateState> {
|
||||||
PluginStateBloc()
|
PluginStateBloc()
|
||||||
: super(
|
: listener = LocalLLMListener(),
|
||||||
const PluginState(runningState: RunningStatePB.Connecting),
|
super(const PluginStateState(action: PluginStateAction.init())) {
|
||||||
) {
|
listener.start(
|
||||||
|
stateCallback: (pluginState) {
|
||||||
|
if (!isClosed) {
|
||||||
|
add(PluginStateEvent.updateState(pluginState));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
on<PluginStateEvent>(_handleEvent);
|
on<PluginStateEvent>(_handleEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final LocalLLMListener listener;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
await listener.stop();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _handleEvent(
|
Future<void> _handleEvent(
|
||||||
PluginStateEvent event,
|
PluginStateEvent event,
|
||||||
Emitter<PluginState> emit,
|
Emitter<PluginStateState> emit,
|
||||||
) async {
|
) async {
|
||||||
await event.when(
|
await event.when(
|
||||||
started: () async {},
|
started: () async {
|
||||||
|
final result = await ChatEventGetPluginState().send();
|
||||||
|
result.fold(
|
||||||
|
(pluginState) {
|
||||||
|
if (!isClosed) {
|
||||||
|
add(PluginStateEvent.updateState(pluginState));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => Log.error(err.toString()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
updateState: (PluginStatePB pluginState) {
|
||||||
|
switch (pluginState.state) {
|
||||||
|
case RunningStatePB.Running:
|
||||||
|
emit(const PluginStateState(action: PluginStateAction.ready()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
emit(
|
||||||
|
state.copyWith(action: const PluginStateAction.reloadRequired()),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
restartLocalAI: () {
|
||||||
|
ChatEventRestartLocalAI().send();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,11 +69,20 @@ class PluginStateBloc extends Bloc<PluginStateEvent, PluginState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class PluginStateEvent with _$PluginStateEvent {
|
class PluginStateEvent with _$PluginStateEvent {
|
||||||
const factory PluginStateEvent.started() = _Started;
|
const factory PluginStateEvent.started() = _Started;
|
||||||
|
const factory PluginStateEvent.updateState(PluginStatePB pluginState) =
|
||||||
|
_UpdatePluginState;
|
||||||
|
const factory PluginStateEvent.restartLocalAI() = _RestartLocalAI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class PluginState with _$PluginState {
|
class PluginStateState with _$PluginStateState {
|
||||||
const factory PluginState({
|
const factory PluginStateState({required PluginStateAction action}) =
|
||||||
required RunningStatePB runningState,
|
_PluginStateState;
|
||||||
}) = _PluginState;
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class PluginStateAction with _$PluginStateAction {
|
||||||
|
const factory PluginStateAction.init() = _Init;
|
||||||
|
const factory PluginStateAction.ready() = _Ready;
|
||||||
|
const factory PluginStateAction.reloadRequired() = _ReloadRequired;
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/ai/plugin_state_bloc.dart';
|
import 'package:appflowy/workspace/application/settings/ai/plugin_state_bloc.dart';
|
||||||
import 'package:easy_localization/easy_localization.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';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class CheckPluginStateIndicator extends StatelessWidget {
|
class CheckPluginStateIndicator extends StatelessWidget {
|
||||||
@ -12,17 +13,82 @@ class CheckPluginStateIndicator extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DecoratedBox(
|
return BlocProvider(
|
||||||
decoration: const BoxDecoration(
|
create: (context) =>
|
||||||
color: Color(0xFFEDF7ED),
|
PluginStateBloc()..add(const PluginStateEvent.started()),
|
||||||
borderRadius: BorderRadius.all(
|
child: BlocBuilder<PluginStateBloc, PluginStateState>(
|
||||||
Radius.circular(4),
|
builder: (context, state) {
|
||||||
),
|
return state.action.when(
|
||||||
|
init: () => const _InitPlugin(),
|
||||||
|
ready: () => const _ReadyToUse(),
|
||||||
|
reloadRequired: () => const _ReloadButton(),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
child: Padding(
|
);
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
}
|
||||||
child: BlocProvider(
|
}
|
||||||
create: (context) => PluginStateBloc(),
|
|
||||||
|
class _InitPlugin extends StatelessWidget {
|
||||||
|
const _InitPlugin();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator.adaptive(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReloadButton extends StatelessWidget {
|
||||||
|
const _ReloadButton();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const FlowySvg(
|
||||||
|
FlowySvgs.download_warn_s,
|
||||||
|
color: Color(0xFFC62828),
|
||||||
|
),
|
||||||
|
const HSpace(6),
|
||||||
|
FlowyText(LocaleKeys.settings_aiPage_keys_failToLoadLocalAI.tr()),
|
||||||
|
const Spacer(),
|
||||||
|
SizedBox(
|
||||||
|
height: 30,
|
||||||
|
child: FlowyButton(
|
||||||
|
useIntrinsicWidth: true,
|
||||||
|
text:
|
||||||
|
FlowyText(LocaleKeys.settings_aiPage_keys_restartLocalAI.tr()),
|
||||||
|
onTap: () {
|
||||||
|
context.read<PluginStateBloc>().add(
|
||||||
|
const PluginStateEvent.restartLocalAI(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReadyToUse extends StatelessWidget {
|
||||||
|
const _ReadyToUse();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Color(0xFFEDF7ED),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const HSpace(8),
|
const HSpace(8),
|
||||||
|
4
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
4
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -206,7 +206,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-local-ai"
|
name = "appflowy-local-ai"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"appflowy-plugin",
|
"appflowy-plugin",
|
||||||
@ -225,7 +225,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-plugin"
|
name = "appflowy-plugin"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -128,5 +128,5 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-
|
|||||||
# To update the commit ID, run:
|
# To update the commit ID, run:
|
||||||
# scripts/tool/update_local_ai_rev.sh new_rev_id
|
# 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 = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
|
4
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
4
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
@ -197,7 +197,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-local-ai"
|
name = "appflowy-local-ai"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"appflowy-plugin",
|
"appflowy-plugin",
|
||||||
@ -216,7 +216,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-plugin"
|
name = "appflowy-plugin"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -128,6 +128,6 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-
|
|||||||
# To update the commit ID, run:
|
# To update the commit ID, run:
|
||||||
# scripts/tool/update_local_ai_rev.sh new_rev_id
|
# 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 = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
|
|
||||||
|
@ -632,6 +632,8 @@
|
|||||||
"localAILoaded": "Local AI Model successfully added and ready to use",
|
"localAILoaded": "Local AI Model successfully added and ready to use",
|
||||||
"localAILoading": "Local AI Model is loading...",
|
"localAILoading": "Local AI Model is loading...",
|
||||||
"localAIStopped": "Local AI Model stopped",
|
"localAIStopped": "Local AI Model stopped",
|
||||||
|
"failToLoadLocalAI": "Failed to start local AI",
|
||||||
|
"restartLocalAI": "Restart Local AI",
|
||||||
"title": "AI API Keys",
|
"title": "AI API Keys",
|
||||||
"openAILabel": "OpenAI API key",
|
"openAILabel": "OpenAI API key",
|
||||||
"openAITooltip": "You can find your Secret API key on the API key page",
|
"openAITooltip": "You can find your Secret API key on the API key page",
|
||||||
|
4
frontend/rust-lib/Cargo.lock
generated
4
frontend/rust-lib/Cargo.lock
generated
@ -197,7 +197,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-local-ai"
|
name = "appflowy-local-ai"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"appflowy-plugin",
|
"appflowy-plugin",
|
||||||
@ -216,7 +216,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-plugin"
|
name = "appflowy-plugin"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=b803d8a8fd6b1587449e869b3a7a1ac687cf630b#b803d8a8fd6b1587449e869b3a7a1ac687cf630b"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=346020270a0a3d3c82a60b545cd3f52144d56beb#346020270a0a3d3c82a60b545cd3f52144d56beb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -151,5 +151,5 @@ collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-
|
|||||||
# To update the commit ID, run:
|
# To update the commit ID, run:
|
||||||
# scripts/tool/update_local_ai_rev.sh new_rev_id
|
# 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 = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "b803d8a8fd6b1587449e869b3a7a1ac687cf630b" }
|
appflowy-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "346020270a0a3d3c82a60b545cd3f52144d56beb" }
|
||||||
|
@ -234,3 +234,12 @@ pub(crate) async fn get_plugin_state_handler(
|
|||||||
let state = chat_manager.local_ai_controller.get_plugin_state();
|
let state = chat_manager.local_ai_controller.get_plugin_state();
|
||||||
data_result_ok(state)
|
data_result_ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
|
pub(crate) async fn restart_local_ai_handler(
|
||||||
|
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||||
|
) -> Result<(), FlowyError> {
|
||||||
|
let chat_manager = upgrade_chat_manager(chat_manager)?;
|
||||||
|
chat_manager.local_ai_controller.restart();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -41,6 +41,7 @@ pub fn init(chat_manager: Weak<ChatManager>) -> AFPlugin {
|
|||||||
cancel_download_llm_resource_handler,
|
cancel_download_llm_resource_handler,
|
||||||
)
|
)
|
||||||
.event(ChatEvent::GetPluginState, get_plugin_state_handler)
|
.event(ChatEvent::GetPluginState, get_plugin_state_handler)
|
||||||
|
.event(ChatEvent::RestartLocalAI, restart_local_ai_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||||
@ -91,4 +92,7 @@ pub enum ChatEvent {
|
|||||||
|
|
||||||
#[event(output = "PluginStatePB")]
|
#[event(output = "PluginStatePB")]
|
||||||
GetPluginState = 14,
|
GetPluginState = 14,
|
||||||
|
|
||||||
|
#[event()]
|
||||||
|
RestartLocalAI = 15,
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ impl LocalAIController {
|
|||||||
let mut rx = llm_chat.subscribe_running_state();
|
let mut rx = llm_chat.subscribe_running_state();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Some(state) = rx.next().await {
|
while let Some(state) = rx.next().await {
|
||||||
|
info!("[AI Plugin] state: {:?}", state);
|
||||||
let new_state = RunningStatePB::from(state);
|
let new_state = RunningStatePB::from(state);
|
||||||
info!("[AI Plugin] state: {:?}", new_state);
|
|
||||||
send_notification(
|
send_notification(
|
||||||
"appflowy_chat_plugin",
|
"appflowy_chat_plugin",
|
||||||
ChatNotification::UpdateChatPluginState,
|
ChatNotification::UpdateChatPluginState,
|
||||||
@ -84,7 +84,9 @@ impl LocalAIController {
|
|||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while rx.recv().await.is_some() {
|
while rx.recv().await.is_some() {
|
||||||
if let Ok(chat_config) = cloned_llm_res.get_ai_plugin_config() {
|
if let Ok(chat_config) = cloned_llm_res.get_ai_plugin_config() {
|
||||||
initialize_chat_plugin(&cloned_llm_chat, chat_config).unwrap();
|
if let Err(err) = initialize_chat_plugin(&cloned_llm_chat, chat_config) {
|
||||||
|
error!("[AI Plugin] failed to setup plugin: {:?}", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -184,6 +186,14 @@ impl LocalAIController {
|
|||||||
state: RunningStatePB::from(state),
|
state: RunningStatePB::from(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn restart(&self) {
|
||||||
|
if let Ok(chat_config) = self.llm_res.get_ai_plugin_config() {
|
||||||
|
if let Err(err) = initialize_chat_plugin(&self.llm_chat, chat_config) {
|
||||||
|
error!("[AI Plugin] failed to setup plugin: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_chat_plugin(
|
fn initialize_chat_plugin(
|
||||||
|
Loading…
Reference in New Issue
Block a user