143 lines
4.2 KiB
Dart
143 lines
4.2 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:social_app/core/chat/chat_api.dart';
|
|
import 'package:social_app/data/network/i_api_client.dart';
|
|
|
|
class ChatApiImpl implements ChatApi {
|
|
ChatApiImpl(this._apiClient);
|
|
|
|
final IApiClient _apiClient;
|
|
|
|
@override
|
|
Future<Map<String, dynamic>> createRun(Map<String, dynamic> runInput) async {
|
|
final response = await _apiClient.post<Map<String, dynamic>>(
|
|
'/api/v1/agent/runs',
|
|
data: runInput,
|
|
);
|
|
final payload = response.data;
|
|
if (payload is! Map<String, dynamic>) {
|
|
throw StateError('Invalid /agent/runs response');
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
@override
|
|
Future<Stream<String>> streamRunEvents(
|
|
String threadId, {
|
|
required String runId,
|
|
String? lastEventId,
|
|
}) {
|
|
final headers = <String, String>{'Accept': 'text/event-stream'};
|
|
if (lastEventId != null && lastEventId.isNotEmpty) {
|
|
headers['Last-Event-ID'] = lastEventId;
|
|
}
|
|
final encodedRunId = Uri.encodeQueryComponent(runId);
|
|
final path = '/api/v1/agent/runs/$threadId/events?runId=$encodedRunId';
|
|
return _apiClient.getSseLines(path, headers: headers);
|
|
}
|
|
|
|
@override
|
|
Future<Map<String, dynamic>> fetchHistory({
|
|
String? threadId,
|
|
DateTime? beforeDate,
|
|
}) async {
|
|
final path = _buildHistoryPath(threadId: threadId, beforeDate: beforeDate);
|
|
final response = await _apiClient.get<Map<String, dynamic>>(path);
|
|
final payload = response.data;
|
|
if (payload is! Map<String, dynamic>) {
|
|
throw StateError('Invalid /agent/history response');
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
@override
|
|
Future<Map<String, dynamic>> uploadAttachment({
|
|
required String threadId,
|
|
required String filename,
|
|
required String mimeType,
|
|
required Uint8List bytes,
|
|
}) async {
|
|
final formData = FormData.fromMap({
|
|
'threadId': threadId,
|
|
'file': MultipartFile.fromBytes(
|
|
bytes,
|
|
filename: filename,
|
|
contentType: DioMediaType.parse(mimeType),
|
|
),
|
|
});
|
|
final response = await _apiClient.post<Map<String, dynamic>>(
|
|
'/api/v1/agent/attachments',
|
|
data: formData,
|
|
);
|
|
final payload = response.data;
|
|
if (payload is! Map<String, dynamic>) {
|
|
throw StateError('Invalid /agent/attachments response');
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
@override
|
|
Future<Uint8List> fetchAttachmentPreview(String previewPath) async {
|
|
final response = await _apiClient.get<List<int>>(
|
|
previewPath,
|
|
options: Options(responseType: ResponseType.bytes),
|
|
);
|
|
final payload = response.data;
|
|
if (payload is! List<int>) {
|
|
throw StateError('Invalid attachment payload');
|
|
}
|
|
return Uint8List.fromList(payload);
|
|
}
|
|
|
|
@override
|
|
Future<String> transcribeAudio(String filePath) async {
|
|
final formData = FormData.fromMap({
|
|
'audio': await MultipartFile.fromFile(
|
|
filePath,
|
|
filename: 'recording.wav',
|
|
contentType: DioMediaType('audio', 'wav'),
|
|
),
|
|
});
|
|
final response = await _apiClient.post<Map<String, dynamic>>(
|
|
'/api/v1/agent/transcribe',
|
|
data: formData,
|
|
);
|
|
final payload = response.data;
|
|
if (payload is! Map<String, dynamic>) {
|
|
throw StateError('Invalid /agent/transcribe response');
|
|
}
|
|
final transcript = payload['transcript'];
|
|
if (transcript is! String) {
|
|
throw StateError('Missing transcript in /agent/transcribe response');
|
|
}
|
|
return transcript;
|
|
}
|
|
|
|
@override
|
|
Future<void> cancelRun({
|
|
required String threadId,
|
|
required String runId,
|
|
}) async {
|
|
final encodedRunId = Uri.encodeQueryComponent(runId);
|
|
await _apiClient.post<Map<String, dynamic>>(
|
|
'/api/v1/agent/runs/$threadId/cancel?runId=$encodedRunId',
|
|
);
|
|
}
|
|
|
|
static String _buildHistoryPath({String? threadId, DateTime? beforeDate}) {
|
|
final query = <String>[];
|
|
if (threadId != null && threadId.isNotEmpty) {
|
|
query.add('threadId=${Uri.encodeQueryComponent(threadId)}');
|
|
}
|
|
if (beforeDate != null) {
|
|
final day = DateTime(beforeDate.year, beforeDate.month, beforeDate.day);
|
|
query.add('before=${day.toIso8601String().substring(0, 10)}');
|
|
}
|
|
if (query.isEmpty) {
|
|
return '/api/v1/agent/history';
|
|
}
|
|
return '/api/v1/agent/history?${query.join('&')}';
|
|
}
|
|
}
|