15 changed files with 152 additions and 78 deletions
|
Before Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 423 KiB |
|
Before Width: | Height: | Size: 537 KiB After Width: | Height: | Size: 110 KiB |
@ -0,0 +1,83 @@ |
|||||
|
import 'dart:convert'; |
||||
|
|
||||
|
import 'package:http/http.dart' as http; |
||||
|
|
||||
|
import '../../core/utils/logger.dart'; |
||||
|
|
||||
|
class KouziAIService { |
||||
|
final String apiKey = |
||||
|
'pat_QGDh6UGm3PaeL9GRS95JxrJ9aoU92ehMLQQ2NCre1TeBC5YeTcjpDmlz3efsJ8lh'; |
||||
|
final String modelId = '7481292724306657316'; |
||||
|
|
||||
|
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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue