feat(api): improve model parsing with robust error handling
This commit is contained in:
@@ -339,17 +339,64 @@ class ApiService {
|
|||||||
Future<List<Model>> getModels() async {
|
Future<List<Model>> getModels() async {
|
||||||
final response = await _dio.get('/api/models');
|
final response = await _dio.get('/api/models');
|
||||||
|
|
||||||
// Handle different response formats
|
// Normalize common response formats:
|
||||||
List<dynamic> models;
|
// - {"data": [...]} (OpenAI)
|
||||||
if (response.data is Map && response.data['data'] != null) {
|
// - {"models": [...]} (some proxies)
|
||||||
// Response is wrapped in a 'data' field
|
// - [...] (raw array)
|
||||||
models = response.data['data'] as List;
|
// - String payloads that need JSON decoding
|
||||||
} else if (response.data is List) {
|
dynamic payload = response.data;
|
||||||
// Response is a direct array
|
if (payload is String) {
|
||||||
models = response.data as List;
|
try {
|
||||||
} else {
|
payload = json.decode(payload);
|
||||||
DebugLogger.error('models-format', scope: 'api/models');
|
} catch (_) {}
|
||||||
return [];
|
}
|
||||||
|
|
||||||
|
List<dynamic>? rawModels;
|
||||||
|
if (payload is Map && payload['data'] is List) {
|
||||||
|
rawModels = payload['data'] as List;
|
||||||
|
} else if (payload is Map && payload['models'] is List) {
|
||||||
|
rawModels = payload['models'] as List;
|
||||||
|
} else if (payload is List) {
|
||||||
|
rawModels = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawModels == null) {
|
||||||
|
DebugLogger.error(
|
||||||
|
'models-format',
|
||||||
|
scope: 'api/models',
|
||||||
|
data: {'type': payload.runtimeType},
|
||||||
|
);
|
||||||
|
return const [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final models = <Model>[];
|
||||||
|
for (final raw in rawModels) {
|
||||||
|
try {
|
||||||
|
if (raw is String) {
|
||||||
|
models.add(Model(id: raw, name: raw, supportsStreaming: true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (raw is Map) {
|
||||||
|
final normalized = raw.map(
|
||||||
|
(key, value) => MapEntry(key.toString(), value),
|
||||||
|
);
|
||||||
|
models.add(Model.fromJson(normalized));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DebugLogger.warning(
|
||||||
|
'models-entry-unknown',
|
||||||
|
scope: 'api/models',
|
||||||
|
data: {'type': raw.runtimeType},
|
||||||
|
);
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
DebugLogger.error(
|
||||||
|
'model-parse-failed',
|
||||||
|
scope: 'api/models',
|
||||||
|
error: error,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
data: {'type': raw.runtimeType},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugLogger.log(
|
DebugLogger.log(
|
||||||
@@ -357,7 +404,7 @@ class ApiService {
|
|||||||
scope: 'api/models',
|
scope: 'api/models',
|
||||||
data: {'count': models.length},
|
data: {'count': models.length},
|
||||||
);
|
);
|
||||||
return models.map((m) => Model.fromJson(m)).toList();
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get default model configuration from OpenWebUI user settings
|
// Get default model configuration from OpenWebUI user settings
|
||||||
|
|||||||
Reference in New Issue
Block a user