Add default AI model selection to settings

Replaces the previous placeholder for default LLM selection with a working default AI model selector in settings. Updates SettingsModel and related providers to support storing and updating the default AI model as a JSON object. Integrates the selector UI and ensures new AI requests use the default model if set.
This commit is contained in:
Ankit Mahato
2025-08-29 01:27:32 +05:30
parent 7b7daa7dac
commit 9d50e3f09c
6 changed files with 41 additions and 48 deletions

View File

@@ -18,8 +18,7 @@ class SettingsModel {
this.workspaceFolderPath,
this.isSSLDisabled = false,
this.isDashBotEnabled = true,
// TODO: Fix it
// this.defaultLLMSaveObject,
this.defaultAIModel,
});
final bool isDark;
@@ -35,8 +34,7 @@ class SettingsModel {
final String? workspaceFolderPath;
final bool isSSLDisabled;
final bool isDashBotEnabled;
// TODO: Fix it
// final LLMSaveObject? defaultLLMSaveObject;
final Map<String, Object?>? defaultAIModel;
SettingsModel copyWith({
bool? isDark,
@@ -52,9 +50,7 @@ class SettingsModel {
String? workspaceFolderPath,
bool? isSSLDisabled,
bool? isDashBotEnabled,
// TODO: Fix it
// LLMSaveObject? def,
// LLMSaveObject? defaultLLMSaveObject,
Map<String, Object?>? defaultAIModel,
}) {
return SettingsModel(
isDark: isDark ?? this.isDark,
@@ -72,8 +68,7 @@ class SettingsModel {
workspaceFolderPath: workspaceFolderPath ?? this.workspaceFolderPath,
isSSLDisabled: isSSLDisabled ?? this.isSSLDisabled,
isDashBotEnabled: isDashBotEnabled ?? this.isDashBotEnabled,
// TODO: Fix it
// defaultLLMSaveObject: defaultLLMSaveObject ?? this.defaultLLMSaveObject,
defaultAIModel: defaultAIModel ?? this.defaultAIModel,
);
}
@@ -94,8 +89,7 @@ class SettingsModel {
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
isDashBotEnabled: isDashBotEnabled,
// TODO: Fix it
// defaultLLMSaveObject: defaultLLMSaveObject,
defaultAIModel: defaultAIModel,
);
}
@@ -151,14 +145,7 @@ class SettingsModel {
final workspaceFolderPath = data["workspaceFolderPath"] as String?;
final isSSLDisabled = data["isSSLDisabled"] as bool?;
final isDashBotEnabled = data["isDashBotEnabled"] as bool?;
// TODO: Fix it
// LLMSaveObject? defaultLLMSaveObject;
// if (data["defaultLLMSaveObject"] != null) {
// defaultLLMSaveObject =
// LLMSaveObject.fromJSON(data["defaultLLMSaveObject"]);
// }
final defaultAIModel = data["defaultAIModel"] as Map<String, Object?>?;
const sm = SettingsModel();
return sm.copyWith(
@@ -176,8 +163,7 @@ class SettingsModel {
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
isDashBotEnabled: isDashBotEnabled,
// TODO: Fix it
// defaultLLMSaveObject: defaultLLMSaveObject,
defaultAIModel: defaultAIModel,
);
}
@@ -198,8 +184,7 @@ class SettingsModel {
"workspaceFolderPath": workspaceFolderPath,
"isSSLDisabled": isSSLDisabled,
"isDashBotEnabled": isDashBotEnabled,
// TODO: Fix it
// 'defaultLLMSaveObject': defaultLLMSaveObject?.toJSON(),
'defaultLLMSaveObject': defaultAIModel,
};
}
@@ -225,10 +210,8 @@ class SettingsModel {
other.historyRetentionPeriod == historyRetentionPeriod &&
other.workspaceFolderPath == workspaceFolderPath &&
other.isSSLDisabled == isSSLDisabled &&
other.isDashBotEnabled == isDashBotEnabled;
// TODO: Fix it
// &&
// other.defaultLLMSaveObject == defaultLLMSaveObject;
other.isDashBotEnabled == isDashBotEnabled &&
other.defaultAIModel == defaultAIModel;
}
@override
@@ -248,8 +231,7 @@ class SettingsModel {
workspaceFolderPath,
isSSLDisabled,
isDashBotEnabled,
// TODO: Fix it
// defaultLLMSaveObject,
defaultAIModel,
);
}
}

View File

@@ -245,6 +245,7 @@ class CollectionStateNotifier
RequestModel newModel;
if (apiType != null && currentModel.apiType != apiType) {
final defaultModel = ref.read(settingsProvider).defaultAIModel;
newModel = switch (apiType) {
APIType.rest || APIType.graphql => currentModel.copyWith(
apiType: apiType,
@@ -257,7 +258,9 @@ class CollectionStateNotifier
name: name ?? currentModel.name,
description: description ?? currentModel.description,
httpRequestModel: null,
aiRequestModel: const AIRequestModel()),
aiRequestModel: defaultModel == null
? const AIRequestModel()
: AIRequestModel.fromJson(defaultModel)),
};
} else {
newModel = currentModel.copyWith(

View File

@@ -34,8 +34,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
String? workspaceFolderPath,
bool? isSSLDisabled,
bool? isDashBotEnabled,
// TODO: Fix it
// LLMSaveObject? defaultLLMSaveObject,
Map<String, Object?>? defaultAIModel,
}) async {
state = state.copyWith(
isDark: isDark,
@@ -51,8 +50,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
workspaceFolderPath: workspaceFolderPath,
isSSLDisabled: isSSLDisabled,
isDashBotEnabled: isDashBotEnabled,
// TODO: Fix it
// defaultLLMSaveObject: defaultLLMSaveObject,
defaultAIModel: defaultAIModel,
);
await setSettingsToSharedPrefs(state);
}

View File

@@ -22,6 +22,10 @@ class _AIModelSelectorDialogState extends ConsumerState<AIModelSelectorDialog> {
@override
void initState() {
super.initState();
selectedProvider = widget.aiRequestModel?.modelApiProvider;
if (selectedProvider != null && widget.aiRequestModel?.model != null) {
newAIRequestModel = widget.aiRequestModel?.copyWith();
}
aM = ModelManager.fetchAvailableModels();
}

View File

@@ -29,7 +29,8 @@ class CodePane extends ConsumerWidget {
? getRequestModelFromHistoryModel(selectedHistoryRequestModel!)
: ref.watch(selectedRequestModelProvider);
if (selectedRequestModel!.apiType == APIType.ai) {
// TODO: Add AI Request Codegen
if (selectedRequestModel?.apiType == APIType.ai) {
return const ErrorMessage(
message: "Code generation for AI Requests is currently not available.",
);

View File

@@ -1,3 +1,4 @@
import 'package:apidash_core/apidash_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -7,6 +8,7 @@ import '../services/services.dart';
import '../utils/utils.dart';
import '../widgets/widgets.dart';
import '../consts.dart';
import 'common_widgets/common_widgets.dart';
class SettingsPage extends ConsumerWidget {
const SettingsPage({super.key});
@@ -114,19 +116,22 @@ class SettingsPage extends ConsumerWidget {
},
),
),
// TODO: Fix it
// ListTile(
// hoverColor: kColorTransparent,
// title: const Text('Default Large Language Model (LLM)'),
// trailing: DefaultLLMSelectorButton(
// defaultLLM: settings.defaultLLMSaveObject,
// onDefaultLLMUpdated: (d) {
// ref
// .read(settingsProvider.notifier)
// .update(defaultLLMSaveObject: d);
// },
// ),
// ),
ListTile(
hoverColor: kColorTransparent,
title: const Text('Default Large Language Model (LLM)'),
trailing: AIModelSelectorButton(
aiRequestModel:
AIRequestModel.fromJson(settings.defaultAIModel ?? {}),
onModelUpdated: (d) {
ref.read(settingsProvider.notifier).update(
defaultAIModel: d.copyWith(
modelConfigs: [],
stream: null,
systemPrompt: '',
userPrompt: '').toJson());
},
),
),
CheckboxListTile(
title: const Text("Save Responses"),
subtitle: