fix: repair recognition — migrate vision model and fix XFile handling
- Replace decommissioned llama-3.2-11b-vision-preview with meta-llama/llama-4-scout-17b-16e-instruct (Groq deprecation) - Use XFile.readAsBytes() instead of File(path).readAsBytes() so Android content URIs (from gallery picks) are read correctly - Add maxWidth/maxHeight constraints to image picker calls to reduce payload size - Increase receiveTimeout from 30s to 120s to accommodate slow vision AI - Log recognition errors via debugPrint instead of swallowing them Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
import '../../core/api/api_client.dart';
|
||||
|
||||
@@ -108,7 +109,7 @@ class RecognitionService {
|
||||
final ApiClient _client;
|
||||
|
||||
/// Recognizes food items from a receipt photo.
|
||||
Future<ReceiptResult> recognizeReceipt(File image) async {
|
||||
Future<ReceiptResult> recognizeReceipt(XFile image) async {
|
||||
final payload = await _buildImagePayload(image);
|
||||
final data = await _client.post('/ai/recognize-receipt', data: payload);
|
||||
return ReceiptResult(
|
||||
@@ -122,7 +123,7 @@ class RecognitionService {
|
||||
}
|
||||
|
||||
/// Recognizes food items from 1–3 product photos.
|
||||
Future<List<RecognizedItem>> recognizeProducts(List<File> images) async {
|
||||
Future<List<RecognizedItem>> recognizeProducts(List<XFile> images) async {
|
||||
final imageList = await Future.wait(images.map(_buildImagePayload));
|
||||
final data = await _client.post(
|
||||
'/ai/recognize-products',
|
||||
@@ -134,17 +135,18 @@ class RecognitionService {
|
||||
}
|
||||
|
||||
/// Recognizes a dish and estimates its nutritional content.
|
||||
Future<DishResult> recognizeDish(File image) async {
|
||||
Future<DishResult> recognizeDish(XFile image) async {
|
||||
final payload = await _buildImagePayload(image);
|
||||
final data = await _client.post('/ai/recognize-dish', data: payload);
|
||||
return DishResult.fromJson(data);
|
||||
}
|
||||
|
||||
Future<Map<String, String>> _buildImagePayload(File image) async {
|
||||
Future<Map<String, String>> _buildImagePayload(XFile image) async {
|
||||
final bytes = await image.readAsBytes();
|
||||
final base64Data = base64Encode(bytes);
|
||||
final ext = image.path.split('.').last.toLowerCase();
|
||||
final mimeType = ext == 'png' ? 'image/png' : 'image/jpeg';
|
||||
// XFile.mimeType may be null on some platforms; fall back to path extension.
|
||||
final mimeType = image.mimeType ??
|
||||
(image.path.toLowerCase().endsWith('.png') ? 'image/png' : 'image/jpeg');
|
||||
return {'image_base64': base64Data, 'mime_type': mimeType};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user