listModels method
override
Fetch available models from the provider's API.
Implementation
@override
Future<List<AiModel>> listModels() async {
final apiKey = await _getApiKey();
if (apiKey == null || apiKey.isEmpty) {
return _provider.availableModels
.map((m) => AiModel(id: m.id, name: m.name))
.toList();
}
// Web: api.anthropic.com blocks browser requests at the CORS preflight.
// Route through the ai-proxy Edge Function instead.
if (kIsWeb) {
final models = await listModelsViaProxy(
dio: _dio,
provider: 'claude',
credential: apiKey,
);
if (models.isNotEmpty) return models;
return _provider.availableModels
.map((m) => AiModel(id: m.id, name: m.name))
.toList();
}
try {
final response = await _dio.get(
'https://api.anthropic.com/v1/models',
options: Options(
headers: {
'x-api-key': apiKey,
'anthropic-version': AiProviderConfig.claudeApiVersion,
},
),
);
final data = response.data as Map<String, dynamic>;
final models = data['data'] as List<dynamic>;
final result = <AiModel>[];
for (final model in models) {
final m = model as Map<String, dynamic>;
final id = m['id'] as String;
final name = m['display_name'] as String? ?? id;
result.add(AiModel(id: id, name: name));
}
// Sort by name for consistent display.
result.sort((a, b) => a.name.compareTo(b.name));
return result;
} catch (e) {
dev.log('Failed to list Claude models: $e', name: 'ClaudeDatasource');
// Fall back to static list.
return _provider.availableModels
.map((m) => AiModel(id: m.id, name: m.name))
.toList();
}
}