mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2026-01-06 04:11:53 +00:00
Merge pull request #7650 from AppFlowy-IO/display_plugin_version
chore: show plugin version
This commit is contained in:
commit
3c74208ab9
@ -1,41 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:url_launcher/url_launcher.dart' show launchUrl;
|
||||
part 'download_offline_ai_app_bloc.freezed.dart';
|
||||
|
||||
class DownloadOfflineAIBloc
|
||||
extends Bloc<DownloadOfflineAIEvent, DownloadOfflineAIState> {
|
||||
DownloadOfflineAIBloc() : super(const DownloadOfflineAIState()) {
|
||||
on<DownloadOfflineAIEvent>(_handleEvent);
|
||||
}
|
||||
|
||||
Future<void> _handleEvent(
|
||||
DownloadOfflineAIEvent event,
|
||||
Emitter<DownloadOfflineAIState> emit,
|
||||
) async {
|
||||
await event.when(
|
||||
started: () async {
|
||||
final result = await AIEventGetLocalAIDownloadLink().send();
|
||||
await result.fold(
|
||||
(app) async {
|
||||
await launchUrl(Uri.parse(app.link));
|
||||
},
|
||||
(err) {},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DownloadOfflineAIEvent with _$DownloadOfflineAIEvent {
|
||||
const factory DownloadOfflineAIEvent.started() = _Started;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DownloadOfflineAIState with _$DownloadOfflineAIState {
|
||||
const factory DownloadOfflineAIState() = _DownloadOfflineAIState;
|
||||
}
|
||||
@ -44,7 +44,7 @@ class LocalAISettingPanelBloc
|
||||
) async {
|
||||
event.when(
|
||||
updateAIState: (LocalAIPB pluginState) {
|
||||
if (pluginState.isPluginExecutableReady) {
|
||||
if (pluginState.pluginDownloaded) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
runningState: pluginState.state,
|
||||
|
||||
@ -91,7 +91,11 @@ class PluginStateBloc extends Bloc<PluginStateEvent, PluginStateState> {
|
||||
);
|
||||
break;
|
||||
case RunningStatePB.Running:
|
||||
emit(const PluginStateState(action: PluginStateAction.running()));
|
||||
emit(
|
||||
PluginStateState(
|
||||
action: PluginStateAction.running(aiState.pluginVersion),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case RunningStatePB.Stopped:
|
||||
emit(
|
||||
@ -140,7 +144,7 @@ class PluginStateAction with _$PluginStateAction {
|
||||
const factory PluginStateAction.unknown() = _Unknown;
|
||||
const factory PluginStateAction.readToRun() = _ReadyToRun;
|
||||
const factory PluginStateAction.initializingPlugin() = _InitializingPlugin;
|
||||
const factory PluginStateAction.running() = _PluginRunning;
|
||||
const factory PluginStateAction.running(String version) = _PluginRunning;
|
||||
const factory PluginStateAction.restartPlugin() = _RestartPlugin;
|
||||
const factory PluginStateAction.lackOfResource(String desc) = _LackOfResource;
|
||||
}
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import 'package:appflowy/core/helpers/url_launcher.dart';
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/settings/ai/download_offline_ai_app_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/settings/ai/plugin_state_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
@ -27,7 +23,10 @@ class PluginStateIndicator extends StatelessWidget {
|
||||
unknown: () => const SizedBox.shrink(),
|
||||
readToRun: () => const _PrepareRunning(),
|
||||
initializingPlugin: () => const InitLocalAIIndicator(),
|
||||
running: () => const _LocalAIRunning(),
|
||||
running: (version) => _LocalAIRunning(
|
||||
key: ValueKey(version),
|
||||
version: version,
|
||||
),
|
||||
restartPlugin: () => const _RestartPluginButton(),
|
||||
lackOfResource: (desc) => _LackOfResource(desc: desc),
|
||||
);
|
||||
@ -88,7 +87,9 @@ class _RestartPluginButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _LocalAIRunning extends StatelessWidget {
|
||||
const _LocalAIRunning();
|
||||
const _LocalAIRunning({required this.version, super.key});
|
||||
|
||||
final String version;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -113,6 +114,14 @@ class _LocalAIRunning extends StatelessWidget {
|
||||
color: Color(0xFF2E7D32),
|
||||
),
|
||||
const HSpace(6),
|
||||
if (version.isNotEmpty)
|
||||
Flexible(
|
||||
child: FlowyText(
|
||||
"($version) ",
|
||||
fontSize: 11,
|
||||
color: const Color(0xFF1E4620),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: FlowyText(
|
||||
LocaleKeys.settings_aiPage_keys_localAIRunning.tr(),
|
||||
@ -131,95 +140,6 @@ class _LocalAIRunning extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class OpenOrDownloadOfflineAIApp extends StatelessWidget {
|
||||
const OpenOrDownloadOfflineAIApp({required this.onRetry, super.key});
|
||||
|
||||
final VoidCallback onRetry;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => DownloadOfflineAIBloc(),
|
||||
child: BlocBuilder<DownloadOfflineAIBloc, DownloadOfflineAIState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RichText(
|
||||
maxLines: 3,
|
||||
textAlign: TextAlign.left,
|
||||
text: TextSpan(
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text:
|
||||
"${LocaleKeys.settings_aiPage_keys_offlineAIInstruction1.tr()} ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(height: 1.5),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
" ${LocaleKeys.settings_aiPage_keys_offlineAIInstruction2.tr()} ",
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: FontSizes.s14,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
height: 1.5,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => afLaunchUrlString(
|
||||
"https://docs.appflowy.io/docs/appflowy/product/appflowy-ai-offline",
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
" ${LocaleKeys.settings_aiPage_keys_offlineAIInstruction3.tr()} ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(height: 1.5),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
"${LocaleKeys.settings_aiPage_keys_offlineAIDownload1.tr()} ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(height: 1.5),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
" ${LocaleKeys.settings_aiPage_keys_offlineAIDownload2.tr()} ",
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: FontSizes.s14,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
height: 1.5,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap =
|
||||
() => context.read<DownloadOfflineAIBloc>().add(
|
||||
const DownloadOfflineAIEvent.started(),
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
" ${LocaleKeys.settings_aiPage_keys_offlineAIDownload3.tr()} ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _LackOfResource extends StatelessWidget {
|
||||
const _LackOfResource({required this.desc});
|
||||
|
||||
|
||||
@ -3217,4 +3217,4 @@
|
||||
"rewrite": "إعادة كتابة",
|
||||
"insertBelow": "أدخل أدناه"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3202,4 +3202,4 @@
|
||||
"rewrite": "Rewrite",
|
||||
"insertBelow": "Insert below"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3185,4 +3185,4 @@
|
||||
"rewrite": "다시 작성",
|
||||
"insertBelow": "아래에 삽입"
|
||||
}
|
||||
}
|
||||
}
|
||||
6
frontend/rust-lib/Cargo.lock
generated
6
frontend/rust-lib/Cargo.lock
generated
@ -345,7 +345,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "af-local-ai"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=a7d4ca96ec30cad941b67acb1e0e426d689c1270#a7d4ca96ec30cad941b67acb1e0e426d689c1270"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=4b3d50cbec2f58be2ac385231b8f585f1555e282#4b3d50cbec2f58be2ac385231b8f585f1555e282"
|
||||
dependencies = [
|
||||
"af-plugin",
|
||||
"anyhow",
|
||||
@ -365,7 +365,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "af-mcp"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=a7d4ca96ec30cad941b67acb1e0e426d689c1270#a7d4ca96ec30cad941b67acb1e0e426d689c1270"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=4b3d50cbec2f58be2ac385231b8f585f1555e282#4b3d50cbec2f58be2ac385231b8f585f1555e282"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -379,7 +379,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "af-plugin"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=a7d4ca96ec30cad941b67acb1e0e426d689c1270#a7d4ca96ec30cad941b67acb1e0e426d689c1270"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-LocalAI?rev=4b3d50cbec2f58be2ac385231b8f585f1555e282#4b3d50cbec2f58be2ac385231b8f585f1555e282"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
|
||||
@ -152,6 +152,6 @@ collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFl
|
||||
# To update the commit ID, run:
|
||||
# scripts/tool/update_local_ai_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
af-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "a7d4ca96ec30cad941b67acb1e0e426d689c1270" }
|
||||
af-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "a7d4ca96ec30cad941b67acb1e0e426d689c1270" }
|
||||
af-mcp = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "a7d4ca96ec30cad941b67acb1e0e426d689c1270" }
|
||||
af-local-ai = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "4b3d50cbec2f58be2ac385231b8f585f1555e282" }
|
||||
af-plugin = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "4b3d50cbec2f58be2ac385231b8f585f1555e282" }
|
||||
af-mcp = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-LocalAI", rev = "4b3d50cbec2f58be2ac385231b8f585f1555e282" }
|
||||
|
||||
@ -585,20 +585,17 @@ pub struct LocalAIPB {
|
||||
#[pb(index = 1)]
|
||||
pub enabled: bool,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub is_plugin_executable_ready: bool,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
#[pb(index = 2, one_of)]
|
||||
pub lack_of_resource: Option<String>,
|
||||
|
||||
#[pb(index = 4)]
|
||||
#[pb(index = 3)]
|
||||
pub state: RunningStatePB,
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf, Clone, Debug)]
|
||||
pub struct LocalAIAppLinkPB {
|
||||
#[pb(index = 1)]
|
||||
pub link: String,
|
||||
#[pb(index = 4, one_of)]
|
||||
pub plugin_version: Option<String>,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub plugin_downloaded: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf, Validate, Clone, Debug)]
|
||||
|
||||
@ -301,15 +301,6 @@ pub(crate) async fn get_local_ai_state_handler(
|
||||
data_result_ok(state)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn get_offline_app_handler(
|
||||
ai_manager: AFPluginState<Weak<AIManager>>,
|
||||
) -> DataResult<LocalAIAppLinkPB, FlowyError> {
|
||||
let ai_manager = upgrade_ai_manager(ai_manager)?;
|
||||
let link = ai_manager.local_ai.get_plugin_download_link().await?;
|
||||
data_result_ok(LocalAIAppLinkPB { link })
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn create_chat_context_handler(
|
||||
data: AFPluginData<CreateChatContextPB>,
|
||||
|
||||
@ -34,7 +34,6 @@ pub fn init(ai_manager: Weak<AIManager>) -> AFPlugin {
|
||||
.event(AIEvent::RestartLocalAI, restart_local_ai_handler)
|
||||
.event(AIEvent::ToggleLocalAI, toggle_local_ai_handler)
|
||||
.event(AIEvent::GetLocalAIState, get_local_ai_state_handler)
|
||||
.event(AIEvent::GetLocalAIDownloadLink, get_offline_app_handler)
|
||||
.event(AIEvent::GetLocalAISetting, get_local_ai_setting_handler)
|
||||
.event(
|
||||
AIEvent::UpdateLocalAISetting,
|
||||
@ -97,9 +96,6 @@ pub enum AIEvent {
|
||||
#[event(output = "LocalAIPB")]
|
||||
GetLocalAIState = 19,
|
||||
|
||||
#[event(output = "LocalAIAppLinkPB")]
|
||||
GetLocalAIDownloadLink = 22,
|
||||
|
||||
#[event(input = "CreateChatContextPB")]
|
||||
CreateChatContext = 23,
|
||||
|
||||
|
||||
@ -77,61 +77,88 @@ impl LocalAIController {
|
||||
"[AI Plugin] init local ai controller, thread: {:?}",
|
||||
std::thread::current().id()
|
||||
);
|
||||
|
||||
// Create the core plugin and resource controller
|
||||
let local_ai = Arc::new(OllamaAIPlugin::new(plugin_manager));
|
||||
let res_impl = LLMResourceServiceImpl {
|
||||
user_service: user_service.clone(),
|
||||
cloud_service: cloud_service.clone(),
|
||||
store_preferences: store_preferences.clone(),
|
||||
};
|
||||
|
||||
let local_ai_resource = Arc::new(LocalAIResourceController::new(
|
||||
user_service.clone(),
|
||||
res_impl,
|
||||
));
|
||||
let current_chat_id = ArcSwapOption::default();
|
||||
// Subscribe to state changes
|
||||
let mut running_state_rx = local_ai.subscribe_running_state();
|
||||
let cloned_llm_res = local_ai_resource.clone();
|
||||
let cloned_store_preferences = store_preferences.clone();
|
||||
let cloned_user_service = user_service.clone();
|
||||
|
||||
let cloned_llm_res = Arc::clone(&local_ai_resource);
|
||||
let cloned_store_preferences = Arc::clone(&store_preferences);
|
||||
let cloned_local_ai = Arc::clone(&local_ai);
|
||||
let cloned_user_service = Arc::clone(&user_service);
|
||||
|
||||
// Spawn a background task to listen for plugin state changes
|
||||
tokio::spawn(async move {
|
||||
while let Some(state) = running_state_rx.next().await {
|
||||
if let Ok(workspace_id) = cloned_user_service.workspace_id() {
|
||||
let key = local_ai_enabled_key(&workspace_id);
|
||||
info!("[AI Plugin] state: {:?}", state);
|
||||
let mut ready = false;
|
||||
let mut lack_of_resource = None;
|
||||
let enabled = cloned_store_preferences.get_bool(&key).unwrap_or(true);
|
||||
if !matches!(state, RunningState::UnexpectedStop { .. }) && enabled {
|
||||
ready = is_plugin_ready();
|
||||
lack_of_resource = cloned_llm_res.get_lack_of_resource().await;
|
||||
}
|
||||
// Skip if we can’t get workspace_id
|
||||
let Ok(workspace_id) = cloned_user_service.workspace_id() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let new_state = RunningStatePB::from(state);
|
||||
chat_notification_builder(
|
||||
APPFLOWY_AI_NOTIFICATION_KEY,
|
||||
ChatNotification::UpdateLocalAIState,
|
||||
)
|
||||
.payload(LocalAIPB {
|
||||
enabled,
|
||||
is_plugin_executable_ready: ready,
|
||||
lack_of_resource,
|
||||
state: new_state,
|
||||
})
|
||||
.send();
|
||||
}
|
||||
let key = local_ai_enabled_key(&workspace_id);
|
||||
info!("[AI Plugin] state: {:?}", state);
|
||||
|
||||
// Read whether plugin is enabled from store; default to true
|
||||
let enabled = cloned_store_preferences.get_bool(&key).unwrap_or(true);
|
||||
|
||||
// Only check resource status if the plugin isn’t in "UnexpectedStop" and is enabled
|
||||
let (plugin_downloaded, lack_of_resource) =
|
||||
if !matches!(state, RunningState::UnexpectedStop { .. }) && enabled {
|
||||
// Possibly check plugin readiness and resource concurrency in parallel,
|
||||
// but here we do it sequentially for clarity.
|
||||
let downloaded = is_plugin_ready();
|
||||
let resource_lack = cloned_llm_res.get_lack_of_resource().await;
|
||||
(downloaded, resource_lack)
|
||||
} else {
|
||||
(false, None)
|
||||
};
|
||||
|
||||
// If plugin is running, retrieve version
|
||||
let plugin_version = if matches!(state, RunningState::Running { .. }) {
|
||||
match cloned_local_ai.plugin_info().await {
|
||||
Ok(info) => Some(info.version),
|
||||
Err(_) => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Broadcast the new local AI state
|
||||
let new_state = RunningStatePB::from(state);
|
||||
chat_notification_builder(
|
||||
APPFLOWY_AI_NOTIFICATION_KEY,
|
||||
ChatNotification::UpdateLocalAIState,
|
||||
)
|
||||
.payload(LocalAIPB {
|
||||
enabled,
|
||||
plugin_downloaded,
|
||||
lack_of_resource,
|
||||
state: new_state,
|
||||
plugin_version,
|
||||
})
|
||||
.send();
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
ai_plugin: local_ai,
|
||||
resource: local_ai_resource,
|
||||
current_chat_id,
|
||||
current_chat_id: ArcSwapOption::default(),
|
||||
store_preferences,
|
||||
user_service,
|
||||
cloud_service,
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub async fn observe_plugin_resource(&self) {
|
||||
debug!(
|
||||
@ -274,28 +301,56 @@ impl LocalAIController {
|
||||
pub async fn get_local_ai_state(&self) -> LocalAIPB {
|
||||
let start = std::time::Instant::now();
|
||||
let enabled = self.is_enabled();
|
||||
let mut is_plugin_executable_ready = false;
|
||||
let mut state = RunningState::ReadyToConnect;
|
||||
let mut lack_of_resource = None;
|
||||
if enabled {
|
||||
is_plugin_executable_ready = is_plugin_ready();
|
||||
state = self.ai_plugin.get_plugin_running_state();
|
||||
lack_of_resource = self.resource.get_lack_of_resource().await;
|
||||
|
||||
// If not enabled, return immediately.
|
||||
if !enabled {
|
||||
debug!(
|
||||
"[AI Plugin] get local ai state, elapsed: {:?}, thread: {:?}",
|
||||
start.elapsed(),
|
||||
std::thread::current().id()
|
||||
);
|
||||
return LocalAIPB {
|
||||
enabled: false,
|
||||
plugin_downloaded: false,
|
||||
state: RunningStatePB::from(RunningState::ReadyToConnect),
|
||||
lack_of_resource: None,
|
||||
plugin_version: None,
|
||||
};
|
||||
}
|
||||
|
||||
let plugin_downloaded = is_plugin_ready();
|
||||
let state = self.ai_plugin.get_plugin_running_state();
|
||||
|
||||
// If the plugin is running, run both requests in parallel.
|
||||
// Otherwise, only fetch the resource info.
|
||||
let (plugin_version, lack_of_resource) = if matches!(state, RunningState::Running { .. }) {
|
||||
// Launch both futures at once
|
||||
let plugin_info_fut = self.ai_plugin.plugin_info();
|
||||
let resource_fut = self.resource.get_lack_of_resource();
|
||||
|
||||
let (plugin_info_res, resource_res) = tokio::join!(plugin_info_fut, resource_fut);
|
||||
let plugin_version = plugin_info_res.ok().map(|info| info.version);
|
||||
(plugin_version, resource_res)
|
||||
} else {
|
||||
let resource_res = self.resource.get_lack_of_resource().await;
|
||||
(None, resource_res)
|
||||
};
|
||||
|
||||
let elapsed = start.elapsed();
|
||||
debug!(
|
||||
"[AI Plugin] get local ai state, elapsed: {:?}, thread: {:?}",
|
||||
elapsed,
|
||||
std::thread::current().id()
|
||||
);
|
||||
|
||||
LocalAIPB {
|
||||
enabled,
|
||||
is_plugin_executable_ready,
|
||||
plugin_downloaded,
|
||||
state: RunningStatePB::from(state),
|
||||
lack_of_resource,
|
||||
plugin_version,
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub async fn restart_plugin(&self) {
|
||||
if let Err(err) = initialize_ai_plugin(&self.ai_plugin, &self.resource, None).await {
|
||||
@ -442,9 +497,10 @@ impl LocalAIController {
|
||||
)
|
||||
.payload(LocalAIPB {
|
||||
enabled,
|
||||
is_plugin_executable_ready: true,
|
||||
plugin_downloaded: true,
|
||||
state: RunningStatePB::Stopped,
|
||||
lack_of_resource: None,
|
||||
plugin_version: None,
|
||||
})
|
||||
.send();
|
||||
}
|
||||
@ -466,9 +522,10 @@ async fn initialize_ai_plugin(
|
||||
)
|
||||
.payload(LocalAIPB {
|
||||
enabled: true,
|
||||
is_plugin_executable_ready: true,
|
||||
plugin_downloaded: true,
|
||||
state: RunningStatePB::ReadyToRun,
|
||||
lack_of_resource: lack_of_resource.clone(),
|
||||
plugin_version: None,
|
||||
})
|
||||
.send();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user