getVertexAICompletion function
Implementation
Future<String> getVertexAICompletion(
String textPrompt, {
Uint8List? imageData,
String? imagePath,
String? mimeType,
}) async {
if (_cactusToken == null) {
throw Exception('CactusToken not set. Please call CactusVLM.init with cactusToken parameter.');
}
const String projectId = 'cactus-v1-452518';
const String location = 'global';
const String modelId = 'gemini-2.5-flash-lite-preview-06-17';
final String endpoint =
'https://aiplatform.googleapis.com/v1/projects/$projectId/locations/$location/publishers/google/models/$modelId:generateContent';
final Map<String, String> headers = {
'Authorization': 'Bearer $_cactusToken',
'Content-Type': 'application/json',
};
List<Map<String, dynamic>> parts = [
{'text': textPrompt}
];
if (imageData != null || imagePath != null) {
Uint8List? finalImageData = imageData;
String? finalMimeType = mimeType;
if (imagePath != null && finalImageData == null) {
final file = File(imagePath);
if (await file.exists()) {
finalImageData = await file.readAsBytes();
if (finalMimeType == null) {
final extension = imagePath.toLowerCase().split('.').last;
switch (extension) {
case 'jpg':
case 'jpeg':
finalMimeType = 'image/jpeg';
break;
case 'png':
finalMimeType = 'image/png';
break;
case 'gif':
finalMimeType = 'image/gif';
break;
case 'webp':
finalMimeType = 'image/webp';
break;
default:
finalMimeType = 'image/jpeg';
}
}
} else {
throw Exception('Image file not found: $imagePath');
}
}
if (finalImageData != null) {
final base64Image = base64Encode(finalImageData);
parts.add({
'inline_data': {
'mime_type': finalMimeType ?? 'image/jpeg',
'data': base64Image,
}
});
}
}
final Map<String, dynamic> requestBody = {
'contents': {
'role': 'user',
'parts': parts,
}
};
try {
final response = await http.post(
Uri.parse(endpoint),
headers: headers,
body: json.encode(requestBody),
);
if (response.statusCode == 200) {
final dynamic responseBody = json.decode(response.body);
if (responseBody is Map && responseBody.containsKey('error')) {
throw Exception('API Error: ${responseBody['error']['message']}');
}
dynamic candidates;
if (responseBody is List) {
candidates = responseBody;
} else if (responseBody is Map && responseBody.containsKey('candidates')) {
candidates = responseBody['candidates'];
} else {
throw Exception('Unexpected response format: ${response.body}');
}
if (candidates == null || candidates.isEmpty) {
throw Exception('No candidates in response');
}
final content = candidates[0]['content'];
final parts = content['parts'] as List;
if (parts.isEmpty) {
throw Exception('No parts in response');
}
final String modelOutput = parts[0]['text'] ?? '';
return modelOutput;
} else {
throw Exception(
'Failed to call Vertex AI. Status code: ${response.statusCode}\nBody: ${response.body}');
}
} catch (e) {
throw Exception('An error occurred: $e');
}
}