1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:get/get.dart'; import 'package:logger/logger.dart'; import 'package:onote/main.dart'; import 'package:onote/model/prompt_message.dart'; import 'package:onote/service/auth/auth_service.dart'; import 'package:onote/service/logger_factory.dart'; import 'package:onote/util/http_util.dart';
class AiCompletionsService {
static final Logger logger = LoggerFactory.instance;
static MainController get mainController => Get.find<MainController>();
static Stream<String> completions({required List<PromptMessage> messages, CancelToken? cancelToken}) async* { if (messages.isEmpty || AuthService.currentSession==null) { yield "[DONE]"; return; }
final stream = HttpUtil.streamStringPost( mainController.mcpConfig.aiApi, headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ${AuthService.currentSession?.accessToken}' }, data: { 'model': mainController.mcpConfig.aiModel, 'stream': true, 'messages': PromptMessage.toMapList(messages) }, cancelToken: cancelToken );
try { await for (final response in stream) { List<String> dataline = response.toString().split("\n"); for (String line in dataline) { if (line.trim().startsWith("data:")) { String lineJson = line.trim().substring(5).trim(); if (lineJson=="[DONE]") { yield "[DONE]"; } else if (lineJson.contains("assistant")) { dynamic dyn = JsonDecoder().convert(lineJson); if (dyn!=null && dyn["choices"]!=null && dyn["choices"].length>0 && dyn["choices"][0]["delta"]!=null && dyn["choices"][0]["delta"]["content"]!=null) { yield dyn["choices"][0]["delta"]["content"]; } } } } } } catch(e) { logger.i(e); yield "[ERROR]"; } }
static Stream<String> streamStringPost(String url, {CancelToken? cancelToken, Map<String, String>? headers, dynamic data}) async* { try { final response = await getDioInstance().post(url, data: data, options: Options( headers: buildHeaders(headers), responseType: ResponseType.stream ), cancelToken: cancelToken ); if (response.data!=null) { await for (final line in response.data.stream) { yield utf8.decode(line); } } } catch(e) { logger.i(e); } } }
|