@tduncan / Cortana / commits / fc4c3f8

fix #5: image attachment support to chat input formatting for lmstudio endpoint

abdulmominsakib committed May 10, 2026 at 16:41 UTC fc4c3f8696fe825df77948c59165887efee55f26
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;