feat: enhance model and tools integration with auto-selection functionality
- Added a new `toolIds` field to the `Model` class to support tool identification. - Implemented `modelToolsAutoSelectionProvider` to automatically apply model-specific tools when the selected model changes. - Enhanced the logic to filter and set valid tool IDs based on available tools, improving user experience by ensuring relevant tools are automatically selected. - Updated the default model auto-selection provider to initialize the new tools auto-selection feature, ensuring seamless integration within the app's lifecycle.
This commit is contained in:
@@ -16,6 +16,7 @@ sealed class Model with _$Model {
|
|||||||
Map<String, dynamic>? capabilities,
|
Map<String, dynamic>? capabilities,
|
||||||
Map<String, dynamic>? metadata,
|
Map<String, dynamic>? metadata,
|
||||||
List<String>? supportedParameters,
|
List<String>? supportedParameters,
|
||||||
|
List<String>? toolIds,
|
||||||
}) = _Model;
|
}) = _Model;
|
||||||
|
|
||||||
factory Model.fromJson(Map<String, dynamic> json) {
|
factory Model.fromJson(Map<String, dynamic> json) {
|
||||||
@@ -111,6 +112,18 @@ sealed class Model with _$Model {
|
|||||||
mergedMetadata['info'] = {...existingInfo, ...infoSection};
|
mergedMetadata['info'] = {...existingInfo, ...infoSection};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract toolIds from info.meta.toolIds (OpenWebUI format)
|
||||||
|
List<String>? toolIds;
|
||||||
|
final infoMeta = (infoSection?['meta'] as Map<String, dynamic>?) ??
|
||||||
|
(metaSection) ??
|
||||||
|
(mergedMetadata['meta'] as Map<String, dynamic>?);
|
||||||
|
if (infoMeta != null) {
|
||||||
|
final toolIdsData = infoMeta['toolIds'];
|
||||||
|
if (toolIdsData is List) {
|
||||||
|
toolIds = toolIdsData.map((e) => e.toString()).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Model(
|
return Model(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
@@ -126,6 +139,7 @@ sealed class Model with _$Model {
|
|||||||
'supported_parameters': supportedParamsList ?? supportedParams,
|
'supported_parameters': supportedParamsList ?? supportedParams,
|
||||||
},
|
},
|
||||||
metadata: mergedMetadata,
|
metadata: mergedMetadata,
|
||||||
|
toolIds: toolIds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import '../utils/debug_logger.dart';
|
|||||||
import '../models/socket_event.dart';
|
import '../models/socket_event.dart';
|
||||||
import '../../shared/theme/color_palettes.dart';
|
import '../../shared/theme/color_palettes.dart';
|
||||||
import '../../shared/theme/app_theme.dart';
|
import '../../shared/theme/app_theme.dart';
|
||||||
|
import '../../features/tools/providers/tools_providers.dart';
|
||||||
|
|
||||||
part 'app_providers.g.dart';
|
part 'app_providers.g.dart';
|
||||||
|
|
||||||
@@ -645,9 +646,45 @@ final _settingsWatcherProvider = Provider<void>((ref) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Auto-apply model-specific tools when model changes
|
||||||
|
final modelToolsAutoSelectionProvider = Provider<void>((ref) {
|
||||||
|
ref.listen<Model?>(selectedModelProvider, (previous, next) {
|
||||||
|
// Only react when the model actually changes
|
||||||
|
if (previous?.id == next?.id) return;
|
||||||
|
if (next == null) return;
|
||||||
|
|
||||||
|
// Load tools configured for this model
|
||||||
|
final modelToolIds = next.toolIds ?? [];
|
||||||
|
if (modelToolIds.isNotEmpty) {
|
||||||
|
// Filter to only include tools that are actually available
|
||||||
|
final toolsAsync = ref.read(toolsListProvider);
|
||||||
|
toolsAsync.whenData((availableTools) {
|
||||||
|
final validToolIds = modelToolIds
|
||||||
|
.where((id) => availableTools.any((t) => t.id == id))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (validToolIds.isNotEmpty) {
|
||||||
|
ref.read(selectedToolIdsProvider.notifier).set(validToolIds);
|
||||||
|
DebugLogger.log(
|
||||||
|
'auto-apply-tools',
|
||||||
|
scope: 'models/tools',
|
||||||
|
data: {'modelId': next.id, 'toolCount': validToolIds.length},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Clear tools if model has no configured tools
|
||||||
|
ref.read(selectedToolIdsProvider.notifier).set([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Auto-apply default model from settings when it changes (and not manually overridden)
|
// Auto-apply default model from settings when it changes (and not manually overridden)
|
||||||
// keepAlive to maintain listener throughout app lifecycle
|
// keepAlive to maintain listener throughout app lifecycle
|
||||||
final defaultModelAutoSelectionProvider = Provider<void>((ref) {
|
final defaultModelAutoSelectionProvider = Provider<void>((ref) {
|
||||||
|
// Initialize the model tools auto-selection
|
||||||
|
ref.watch(modelToolsAutoSelectionProvider);
|
||||||
|
|
||||||
ref.listen<AppSettings>(appSettingsProvider, (previous, next) {
|
ref.listen<AppSettings>(appSettingsProvider, (previous, next) {
|
||||||
// Only react when default model value changes
|
// Only react when default model value changes
|
||||||
if (previous?.defaultModel == next.defaultModel) return;
|
if (previous?.defaultModel == next.defaultModel) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user