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 new file mode 100644 index 000000000..db0efa4f6 --- /dev/null +++ b/scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart @@ -0,0 +1,40 @@ +import 'package:dio/dio.dart'; +import '../datasource/ai_datasource.dart'; +import '../model/ai_message.dart'; +import '../model/ai_api_request.dart'; +import '../network/ai_api.dart'; +import '../../domain/model/ai_response.dart'; +import 'package:tmail_ui_user/main/utils/app_config.dart'; + +class AIDataSourceImpl implements AIDataSource { + final AIApi _aiApi; + + AIDataSourceImpl({ + required Dio dio, + }) : _aiApi = AIApi( + dio: dio, + apiKey: AppConfig.aiApiKey, + baseUrl: AppConfig.aiApiUrl, + ); + + @override + Future request(String prompt) async { + try { + final aiRequest = AIAPIRequest( + messages: [ + AIMessage( + role: 'user', + content: prompt, + ), + ], + ); + + final apiResponse = await _aiApi.chatCompletion(aiRequest); + return AIResponse(result: apiResponse.content); + } on DioError catch (e) { + throw Exception('Failed to generate AI text: ${e.message}'); + } catch (e) { + throw Exception('Failed to generate AI text: $e'); + } + } +} diff --git a/scribe/lib/scribe/ai/data/network/ai_api.dart b/scribe/lib/scribe/ai/data/network/ai_api.dart new file mode 100644 index 000000000..a210ac914 --- /dev/null +++ b/scribe/lib/scribe/ai/data/network/ai_api.dart @@ -0,0 +1,41 @@ +import 'package:dio/dio.dart'; +import '../model/ai_api_response.dart'; +import '../model/ai_api_request.dart'; + +class AIApi { + final Dio _dio; + final String _apiKey; + final String _baseUrl; + + AIApi({ + required Dio dio, + required String apiKey, + required String baseUrl, + }) : _dio = dio, + _apiKey = apiKey, + _baseUrl = baseUrl; + + Future chatCompletion(AIAPIRequest request) async { + final response = await _dio.post( + '$_baseUrl/chat/completions', + options: Options( + headers: { + 'Authorization': 'Bearer $_apiKey', + 'Content-Type': 'application/json', + }, + ), + data: request.toJson(), + ); + + if (response.statusCode == 200) { + final parsedResponse = AIApiResponse.parse(response.data); + if (parsedResponse != null) { + return parsedResponse; + } else { + throw Exception('Empty response from AI service'); + } + } else { + throw Exception('AI API returned status code: ${response.statusCode}'); + } + } +}