listModels method
override
Fetch available models from the provider's API.
Implementation
@override
Future<List<AiModel>> listModels() async {
try {
final token = await _auth.getAccessToken();
// Web: the Gemini REST endpoint blocks browser requests at the CORS
// preflight. Route through the ai-proxy Edge Function instead.
if (kIsWeb) {
if (token.isEmpty) return const [];
final models = await listModelsViaProxy(
dio: _dio,
provider: 'gemini',
credential: token,
);
if (models.isNotEmpty) return models;
return _provider.availableModels
.map((m) => AiModel(id: m.id, name: m.name))
.toList();
}
final response = await _dio.get(
'${_provider.apiUrl}/models',
options: Options(headers: {'Authorization': 'Bearer $token'}),
);
final data = response.data as Map<String, dynamic>;
final models = data['models'] as List<dynamic>;
final result = <AiModel>[];
for (final model in models) {
final m = model as Map<String, dynamic>;
final fullName = m['name'] as String; // e.g. "models/gemini-2.5-pro"
final id = fullName.replaceFirst('models/', '');
final displayName = m['displayName'] as String? ?? id;
// Only include models that support generateContent.
final methods =
(m['supportedGenerationMethods'] as List<dynamic>?)
?.cast<String>() ??
[];
if (!methods.contains('generateContent')) continue;
result.add(AiModel(id: id, name: displayName));
}
result.sort((a, b) => a.name.compareTo(b.name));
return result;
} catch (e) {
dev.log('Failed to list Gemini models: $e', name: 'GeminiDatasource');
return _provider.availableModels
.map((m) => AiModel(id: m.id, name: m.name))
.toList();
}
}