You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.5 KiB

import 'dart:convert';
import 'package:http/http.dart' as http;
import '../../core/utils/logger.dart';
import 'ai_service.dart';
class KouziAIService implements AiService {
final String apiKey =
'pat_QGDh6UGm3PaeL9GRS95JxrJ9aoU92ehMLQQ2NCre1TeBC5YeTcjpDmlz3efsJ8lh';
final String modelId = '7481292724306657316';
@override
Future<String> sendMessage({
required List<Map<String, String>> messages,
required String systemPrompt,
}) async {
return '';
}
@override
Stream<String> sendMessageStream({
required List<Map<String, String>> messages,
required String systemPrompt,
}) async* {
final client = http.Client();
final url = Uri.parse('https://api.coze.cn/v3/chat');
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $apiKey',
};
final requestBody = {
"bot_id": modelId,
"user_id": "3422",
"additional_messages": [
{
"content": messages.last['content'],
"content_type": "text",
"role": "user",
"type": "question",
},
],
"shortcut_command": {"command_id": "0"},
"stream": true,
};
try {
final request = http.Request('POST', url)
..headers.addAll(headers)
..body = jsonEncode(requestBody);
final response = await client.send(request);
final regex = RegExp(r'(?<=[。!?;:.:;?!\n])');
String allContent = '';
//流式处理响应数据
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;
}
try {
final data = jsonDecode(jsonStr);
if (data['type'] == 'answer') {
String content = data['content'] ?? '';
if (content.isNotEmpty && allContent != content) {
allContent += content;
List splitText =
content.split(regex).where((s) => s.isNotEmpty).toList();
for (var element in splitText) {
yield element;
}
}
}
} catch (e) {
Logger.error('JSON解析错误: $e');
}
}
}
} catch (e) {
Logger.error('请求异常: $e');
} finally {
client.close();
}
}
}