import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; class AiService { static const _baseUrl = 'https://api.featherless.ai/v1'; static const _apiKey = 'rc_e10f49aaa4f7af03dcd9da115cfc12cc1988665e895955c11f77788ee5ad93c6'; static const _model = 'Qwen/Qwen2.5-7B-Instruct'; AiService._(); static final instance = AiService._(); Stream streamChat({ required String systemPrompt, required List> messages, }) async* { final client = http.Client(); try { final request = http.Request( 'POST', Uri.parse('$_baseUrl/chat/completions'), ); request.headers.addAll({ 'Authorization': 'Bearer $_apiKey', 'Content-Type': 'application/json', }); request.body = jsonEncode({ 'model': _model, 'messages': [ {'role': 'system', 'content': systemPrompt}, ...messages, ], 'stream': true, 'max_tokens': 2048, 'temperature': 0.7, }); final response = await client.send(request); if (response.statusCode != 200) { final body = await response.stream.bytesToString(); String msg = 'API hatası ${response.statusCode}'; try { final j = jsonDecode(body) as Map; msg = (j['error'] as Map?)?['message'] as String? ?? msg; } catch (_) {} throw Exception(msg); } final lines = response.stream .transform(utf8.decoder) .transform(const LineSplitter()); await for (final line in lines) { if (!line.startsWith('data: ')) continue; final payload = line.substring(6).trim(); if (payload == '[DONE]') break; try { final j = jsonDecode(payload) as Map; final choices = j['choices'] as List?; if (choices == null || choices.isEmpty) continue; final delta = choices.first['delta'] as Map?; final content = delta?['content'] as String?; if (content != null && content.isNotEmpty) yield content; } catch (_) {} } } finally { client.close(); } } }