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.
95 lines
2.6 KiB
95 lines
2.6 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,
|
|
String? systemPrompt,
|
|
String? userProperties,
|
|
}) async {
|
|
return '';
|
|
}
|
|
|
|
@override
|
|
Stream<String> sendMessageStream({
|
|
required List<Map<String, String>> messages,
|
|
String? systemPrompt,
|
|
String? userProperties,
|
|
}) 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.toString()}');
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Logger.error('请求异常: ${e.toString()}');
|
|
} finally {
|
|
client.close();
|
|
}
|
|
}
|
|
}
|