1 file changed
+29
-3
lib/features/chat/data/chat_service.dart
+29
-3
@@ -1,5 +1,6 @@
1
import 'dart:async';
2
import 'dart:convert';
3
+import 'dart:io';
4
import 'package:dio/dio.dart';
5
import '../../servers/data/models/server.dart';
6
import 'models/message.dart';
@@ -149,9 +150,11 @@ class LMStudioChatService implements ChatService {
150
}) async* {
151
_cancelToken = CancelToken();
152
153
+ final formattedInput = await _formatInputWithImages(messages);
154
+
155
final body = <String, dynamic>{
156
'model': modelId,
154
- 'input': _formatInput(messages),
157
+ 'input': formattedInput,
158
'temperature': params.temperature,
159
'top_p': params.topP,
160
'max_output_tokens': params.maxTokens,
@@ -390,11 +393,34 @@ class LMStudioChatService implements ChatService {
393
}
394
}
395
393
- dynamic _formatInput(List<Message> messages) {
396
+ Future<dynamic> _formatInputWithImages(List<Message> messages) async {
397
final formattedInputs = <Map<String, dynamic>>[];
398
for (final m in messages) {
399
if (m.role != MessageRole.system) {
397
- formattedInputs.add({'type': 'text', 'content': m.content});
400
+ if (m.attachmentPaths != null && m.attachmentPaths!.isNotEmpty) {
401
+ formattedInputs.add({'type': 'text', 'content': m.content});
402
+ for (final path in m.attachmentPaths!) {
403
+ try {
404
+ final file = File(path);
405
+ if (await file.exists()) {
406
+ final bytes = await file.readAsBytes();
407
+ final base64Image = base64Encode(bytes);
408
+ final ext = path.split('.').last.toLowerCase();
409
+ final mimeType = (ext == 'png')
410
+ ? 'image/png'
411
+ : (ext == 'webp' ? 'image/webp' : 'image/jpeg');
412
+ formattedInputs.add({
413
+ 'type': 'image',
414
+ 'data_url': 'data:$mimeType;base64,$base64Image',
415
+ });
416
+ }
417
+ } catch (e) {
418
+ Log.error('Failed to read attachment for LMStudio format: $e');
419
+ }
420
+ }
421
+ } else {
422
+ formattedInputs.add({'type': 'text', 'content': m.content});
423
+ }
424
}
425
}
426
return formattedInputs;