Save verified Mithqal AI project progress
This commit is contained in:
@@ -29,6 +29,15 @@ class ApiRepository {
|
||||
return data['model'] as String? ?? 'نموذج غير معروف';
|
||||
}
|
||||
|
||||
Future<List<String>> getAvailableModels() async {
|
||||
final response = await http.get(Uri.parse('$_baseUrl/v1/models'));
|
||||
_checkStatus(response);
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
return (data['data'] as List<dynamic>)
|
||||
.map((model) => (model as Map<String, dynamic>)['id'] as String)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<String> _userId() async {
|
||||
final cached = _cachedUserId;
|
||||
if (cached != null) return cached;
|
||||
@@ -145,7 +154,26 @@ class ApiRepository {
|
||||
return message['content'] as String? ?? 'لم يصل نص في الإجابة.';
|
||||
}
|
||||
|
||||
Stream<String> completeStream(List<ChatMessage> messages) async* {
|
||||
Future<String> askWorkspaceAgent(String task, {String? model}) async {
|
||||
final response = await http
|
||||
.post(
|
||||
Uri.parse('$_baseUrl/v1/agent/workspace'),
|
||||
headers: const {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'task': task, if (model != null) 'model': model}),
|
||||
)
|
||||
.timeout(const Duration(minutes: 10));
|
||||
_checkStatus(response);
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final result = data['result'] as String? ?? '';
|
||||
final files = (data['files'] as List<dynamic>? ?? const []).cast<String>();
|
||||
if (files.isEmpty) return result;
|
||||
return '$result\n\nالمصادر المقروءة: ${files.join('، ')}';
|
||||
}
|
||||
|
||||
Stream<String> completeStream(
|
||||
List<ChatMessage> messages, {
|
||||
String? model,
|
||||
}) async* {
|
||||
final client = http.Client();
|
||||
try {
|
||||
final request =
|
||||
@@ -155,6 +183,7 @@ class ApiRepository {
|
||||
'Accept': 'application/x-ndjson',
|
||||
})
|
||||
..body = jsonEncode({
|
||||
if (model != null && model.isNotEmpty) 'model': model,
|
||||
'messages':
|
||||
messages
|
||||
.map(
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:local_notifier/local_notifier.dart';
|
||||
|
||||
class CompletionNotificationService {
|
||||
CompletionNotificationService._();
|
||||
|
||||
static final instance = CompletionNotificationService._();
|
||||
final _plugin = FlutterLocalNotificationsPlugin();
|
||||
bool _initialized = false;
|
||||
|
||||
Future<void> initialize() async {
|
||||
if (kIsWeb || _initialized) return;
|
||||
if (_isDesktop) {
|
||||
await localNotifier.setup(appName: 'Mithqal AI');
|
||||
_initialized = true;
|
||||
return;
|
||||
}
|
||||
const settings = InitializationSettings(
|
||||
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
|
||||
iOS: DarwinInitializationSettings(
|
||||
requestAlertPermission: false,
|
||||
requestBadgePermission: false,
|
||||
requestSoundPermission: false,
|
||||
),
|
||||
);
|
||||
await _plugin.initialize(settings);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
Future<bool> requestPermission() async {
|
||||
if (kIsWeb) return false;
|
||||
await initialize();
|
||||
if (_isDesktop) return true;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return await _plugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin
|
||||
>()
|
||||
?.requestNotificationsPermission() ??
|
||||
true;
|
||||
case TargetPlatform.iOS:
|
||||
return await _plugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
IOSFlutterLocalNotificationsPlugin
|
||||
>()
|
||||
?.requestPermissions(alert: true, badge: true, sound: true) ??
|
||||
false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> showFinished({required bool succeeded}) async {
|
||||
if (kIsWeb || !_initialized) return;
|
||||
final title = succeeded ? 'اكتملت الإجابة' : 'تعذر إكمال الطلب';
|
||||
final body = succeeded
|
||||
? 'انتهى النموذج من معالجة طلبك.'
|
||||
: 'افتح التطبيق لمراجعة الخطأ.';
|
||||
if (_isDesktop) {
|
||||
LocalNotification(title: title, body: body).show();
|
||||
return;
|
||||
}
|
||||
const android = AndroidNotificationDetails(
|
||||
'generation_complete',
|
||||
'اكتملت المهام',
|
||||
channelDescription: 'تنبيه عند انتهاء توليد الإجابة أو مهمة الوكيل',
|
||||
importance: Importance.defaultImportance,
|
||||
priority: Priority.defaultPriority,
|
||||
);
|
||||
const details = NotificationDetails(
|
||||
android: android,
|
||||
iOS: DarwinNotificationDetails(),
|
||||
);
|
||||
await _plugin.show(
|
||||
1001,
|
||||
title,
|
||||
body,
|
||||
details,
|
||||
);
|
||||
}
|
||||
|
||||
bool get _isDesktop =>
|
||||
defaultTargetPlatform == TargetPlatform.windows ||
|
||||
defaultTargetPlatform == TargetPlatform.linux ||
|
||||
defaultTargetPlatform == TargetPlatform.macOS;
|
||||
}
|
||||
Reference in New Issue
Block a user