import 'dart:convert'; import 'package:http/http.dart' as http; import '../models/appconfig.dart'; import 'ai_service.dart'; class DeapsoundAIService implements AiService { late final String baseUrl; late final String apiKey; late final String model; DeapsoundAIService() { apiKey = AppConfig.env('OPENAI_API_KEY') ?? ''; baseUrl = AppConfig.env('OPENAI_BASE_URL') ?? ''; model = AppConfig.env('OPENAI_MODEL') ?? ''; } @override Future sendMessage({ required List> messages, String? systemPrompt, String? userProperties, }) async { final url = Uri.parse(baseUrl); final headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer $apiKey', }; final requestBody = { "model": model, "messages": messages, }; try { final response = await http.post( url, headers: headers, body: jsonEncode(requestBody), ); if (response.statusCode != 200) { throw Exception('Unknown error'); } final result = jsonDecode(response.body); return result['choices'].first['message']['content']; } catch (e) { throw Exception('Unknown error'); } } @override Stream sendMessageStream({ required List> messages, String? systemPrompt, String? userProperties, }) async* { final client = http.Client(); final url = Uri.parse(baseUrl); final headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer $apiKey', }; final requestBody = { "model": model, "messages": messages, "stream": true, }; try { final request = http.Request('POST', url) ..headers.addAll(headers) ..body = jsonEncode(requestBody); final response = await client.send(request); await for (final chunk in response.stream .transform(utf8.decoder) .transform(const LineSplitter())) { if (chunk.isEmpty) continue; if (chunk.startsWith('data:')) { final jsonStr = chunk.substring(5).trim(); if (jsonStr == '[DONE]') { break; } final data = jsonDecode(jsonStr); final content = data['choices'][0]['delta']['content'] ?? ''; if (content.isNotEmpty) { yield content; } } } } catch (e) { throw Exception('Unknown error'); } finally { client.close(); } } }