From 2c364ea08add3093245ac325515258aa3431f82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Poizat?= Date: Thu, 11 Dec 2025 16:45:52 +0100 Subject: [PATCH] Use endpoint from AI capability instead of direct call to LLM --- .../mailbox_dashboard_controller.dart | 39 +++++++++++++++++++ .../datasource_impl/ai_datasource_impl.dart | 5 +-- scribe/lib/scribe/ai/data/network/ai_api.dart | 29 +++++++------- .../bindings/ai_scribe_bindings.dart | 7 +++- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index 67ebc8012..925dee928 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -78,8 +78,15 @@ import 'package:tmail_ui_user/features/email/presentation/model/composer_argumen import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_arguments.dart'; import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; +import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import 'package:tmail_ui_user/features/home/domain/state/auto_sign_in_via_deep_link_state.dart'; import 'package:tmail_ui_user/features/home/domain/usecases/store_session_interactor.dart'; +import 'package:scribe/scribe/ai/data/datasource/ai_datasource.dart'; +import 'package:scribe/scribe/ai/data/datasource_impl/ai_datasource_impl.dart'; +import 'package:scribe/scribe/ai/data/repository/ai_repository_impl.dart'; +import 'package:scribe/scribe/ai/domain/repository/ai_scribe_repository.dart'; +import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; +import 'package:scribe/scribe/ai/presentation/bindings/ai_scribe_bindings.dart'; import 'package:tmail_ui_user/features/identity_creator/domain/state/get_identity_cache_on_web_state.dart'; import 'package:tmail_ui_user/features/identity_creator/domain/usecase/get_identity_cache_on_web_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/logout_exception.dart'; @@ -818,6 +825,37 @@ class MailboxDashBoardController extends ReloadableController } } + void injectAIScribeBindings(Session? session, AccountId? accountId) { + try { + if (session == null || accountId == null) return; + + final aiCapability = session.getAICapability(accountId); + final scribeEndpoint = aiCapability?.scribeEndpoint; + + // Delete existing AI bindings if they exist + if (Get.isRegistered()) { + Get.delete(force: true); + } + if (Get.isRegistered()) { + Get.delete(force: true); + } + if (Get.isRegistered()) { + Get.delete(force: true); + } + if (Get.isRegistered()) { + Get.delete(force: true); + } + if (Get.isRegistered()) { + Get.delete(force: true); + } + + // Reinitialize with the correct endpoint + AIScribeBindings(scribeEndpoint: scribeEndpoint).dependencies(); + } catch (e) { + logError('MailboxDashBoardController::injectAIScribeBindings(): $e'); + } + } + @override Future injectFCMBindings(Session? session, AccountId? accountId) async { try { @@ -857,6 +895,7 @@ class MailboxDashBoardController extends ReloadableController injectVacationBindings(session, currentAccountId); injectWebSocket(session, currentAccountId); injectPreferencesBindings(); + injectAIScribeBindings(session, currentAccountId); if (PlatformInfo.isMobile) { injectFCMBindings(session, currentAccountId); } diff --git a/scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart b/scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart index b3bc0c553..c65951a26 100644 --- a/scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart +++ b/scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart @@ -1,5 +1,4 @@ import 'package:dio/dio.dart'; -import 'package:scribe/scribe/ai/data/config/ai_config.dart'; import 'package:scribe/scribe/ai/data/datasource/ai_datasource.dart'; import 'package:scribe/scribe/ai/data/model/ai_message.dart'; import 'package:scribe/scribe/ai/data/model/ai_api_request.dart'; @@ -11,10 +10,10 @@ class AIDataSourceImpl implements AIDataSource { AIDataSourceImpl({ required Dio dio, + String? endpoint, }) : _aiApi = AIApi( dio: dio, - apiKey: AIConfig.aiApiKey, - baseUrl: AIConfig.aiApiUrl, + endpoint: endpoint, ); @override diff --git a/scribe/lib/scribe/ai/data/network/ai_api.dart b/scribe/lib/scribe/ai/data/network/ai_api.dart index f89ff7181..d9845ff77 100644 --- a/scribe/lib/scribe/ai/data/network/ai_api.dart +++ b/scribe/lib/scribe/ai/data/network/ai_api.dart @@ -4,26 +4,25 @@ import 'package:scribe/scribe/ai/data/model/ai_api_request.dart'; class AIApi { final Dio _dio; - final String _apiKey; - final String _baseUrl; + final String? _endpoint; AIApi({ required Dio dio, - required String apiKey, - required String baseUrl, - }) : _dio = dio, - _apiKey = apiKey, - _baseUrl = baseUrl; + String? endpoint, + }) : _dio = dio, + _endpoint = endpoint; + + Future chatCompletion( + AIAPIRequest request + ) async { + final url = _endpoint; + + if (url == null) { + throw Exception('AI API is not available'); + } - Future chatCompletion(AIAPIRequest request) async { final response = await _dio.post( - '$_baseUrl/chat/completions', - options: Options( - headers: { - 'Authorization': 'Bearer $_apiKey', - 'Content-Type': 'application/json', - }, - ), + url, data: request.toJson(), ); diff --git a/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart b/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart index 90c0ea233..4f938bb92 100644 --- a/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart +++ b/scribe/lib/scribe/ai/presentation/bindings/ai_scribe_bindings.dart @@ -7,6 +7,10 @@ import 'package:scribe/scribe/ai/domain/repository/ai_scribe_repository.dart'; import 'package:scribe/scribe/ai/domain/usecases/generate_ai_text_interactor.dart'; class AIScribeBindings extends Bindings { + final String? scribeEndpoint; + + AIScribeBindings({this.scribeEndpoint}); + @override void dependencies() { _bindingsDataSourceImpl(); @@ -18,7 +22,8 @@ class AIScribeBindings extends Bindings { void _bindingsDataSourceImpl() { Get.lazyPut(() => AIDataSourceImpl( - dio: Dio(), // Dedicated Dio instance without authorization interceptors + dio: Get.find(), + endpoint: scribeEndpoint, )); }