feat: generation defaults moved to model management
This commit is contained in:
@@ -84,11 +84,15 @@ struct ModelManagementView: View {
|
|||||||
baselineModel: modelManager.baselineModel(repoId: model.repoId) ?? model,
|
baselineModel: modelManager.baselineModel(repoId: model.repoId) ?? model,
|
||||||
detectedLocalModel: modelManager.discoveredLocalModelInfo(repoId: model.repoId),
|
detectedLocalModel: modelManager.discoveredLocalModelInfo(repoId: model.repoId),
|
||||||
hasSavedOverride: Preferences.hasModelMetadataOverride(forRepoId: model.repoId),
|
hasSavedOverride: Preferences.hasModelMetadataOverride(forRepoId: model.repoId),
|
||||||
|
hasSavedGenerationDefaults: Preferences.hasGenerationSettings(forModelId: model.id),
|
||||||
onSave: { override in
|
onSave: { override in
|
||||||
modelManager.saveMetadataOverride(override, for: model)
|
modelManager.saveMetadataOverride(override, for: model)
|
||||||
},
|
},
|
||||||
onReset: {
|
onReset: {
|
||||||
modelManager.clearMetadataOverride(for: model)
|
modelManager.clearMetadataOverride(for: model)
|
||||||
|
},
|
||||||
|
onSaveGenerationSettings: { settings in
|
||||||
|
Preferences.setGenerationSettings(settings, forModelId: model.id)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -241,32 +245,40 @@ private struct ModelMetadataEditorView: View {
|
|||||||
let baselineModel: ModelConfig
|
let baselineModel: ModelConfig
|
||||||
let detectedLocalModel: LocalModelResolver.LocalModelInfo?
|
let detectedLocalModel: LocalModelResolver.LocalModelInfo?
|
||||||
let hasSavedOverride: Bool
|
let hasSavedOverride: Bool
|
||||||
|
let hasSavedGenerationDefaults: Bool
|
||||||
let onSave: (ModelMetadataOverride) -> Void
|
let onSave: (ModelMetadataOverride) -> Void
|
||||||
let onReset: () -> Void
|
let onReset: () -> Void
|
||||||
|
let onSaveGenerationSettings: (GenerationSettings) -> Void
|
||||||
|
|
||||||
@State private var contextLengthText: String
|
@State private var contextLengthText: String
|
||||||
@State private var primaryLoaderKind: ModelConfig.LoaderKind
|
@State private var primaryLoaderKind: ModelConfig.LoaderKind
|
||||||
@State private var supportsImages: Bool
|
@State private var supportsImages: Bool
|
||||||
@State private var supportsTools: Bool
|
@State private var supportsTools: Bool
|
||||||
|
@State private var generationSettings: GenerationSettings
|
||||||
|
|
||||||
init(
|
init(
|
||||||
model: ModelConfig,
|
model: ModelConfig,
|
||||||
baselineModel: ModelConfig,
|
baselineModel: ModelConfig,
|
||||||
detectedLocalModel: LocalModelResolver.LocalModelInfo?,
|
detectedLocalModel: LocalModelResolver.LocalModelInfo?,
|
||||||
hasSavedOverride: Bool,
|
hasSavedOverride: Bool,
|
||||||
|
hasSavedGenerationDefaults: Bool,
|
||||||
onSave: @escaping (ModelMetadataOverride) -> Void,
|
onSave: @escaping (ModelMetadataOverride) -> Void,
|
||||||
onReset: @escaping () -> Void
|
onReset: @escaping () -> Void,
|
||||||
|
onSaveGenerationSettings: @escaping (GenerationSettings) -> Void
|
||||||
) {
|
) {
|
||||||
self.model = model
|
self.model = model
|
||||||
self.baselineModel = baselineModel
|
self.baselineModel = baselineModel
|
||||||
self.detectedLocalModel = detectedLocalModel
|
self.detectedLocalModel = detectedLocalModel
|
||||||
self.hasSavedOverride = hasSavedOverride
|
self.hasSavedOverride = hasSavedOverride
|
||||||
|
self.hasSavedGenerationDefaults = hasSavedGenerationDefaults
|
||||||
self.onSave = onSave
|
self.onSave = onSave
|
||||||
self.onReset = onReset
|
self.onReset = onReset
|
||||||
|
self.onSaveGenerationSettings = onSaveGenerationSettings
|
||||||
_contextLengthText = State(initialValue: String(model.contextLength))
|
_contextLengthText = State(initialValue: String(model.contextLength))
|
||||||
_primaryLoaderKind = State(initialValue: model.primaryLoaderKind)
|
_primaryLoaderKind = State(initialValue: model.primaryLoaderKind)
|
||||||
_supportsImages = State(initialValue: model.supportsImages)
|
_supportsImages = State(initialValue: model.supportsImages)
|
||||||
_supportsTools = State(initialValue: model.supportsTools)
|
_supportsTools = State(initialValue: model.supportsTools)
|
||||||
|
_generationSettings = State(initialValue: Preferences.generationSettings(forModelId: model.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -337,10 +349,18 @@ private struct ModelMetadataEditorView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Section("Generation Defaults") {
|
||||||
|
GenerationDefaultsEditor(settings: $generationSettings)
|
||||||
|
|
||||||
|
Text(generationDefaultsSummary)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.formStyle(.grouped)
|
.formStyle(.grouped)
|
||||||
.navigationTitle(model.displayName)
|
.navigationTitle(model.displayName)
|
||||||
.frame(minWidth: 520, minHeight: 380)
|
.frame(minWidth: 560, minHeight: 620)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .cancellationAction) {
|
ToolbarItem(placement: .cancellationAction) {
|
||||||
Button("Cancel") {
|
Button("Cancel") {
|
||||||
@@ -352,6 +372,7 @@ private struct ModelMetadataEditorView: View {
|
|||||||
Button("Save") {
|
Button("Save") {
|
||||||
guard let currentOverride else { return }
|
guard let currentOverride else { return }
|
||||||
onSave(currentOverride)
|
onSave(currentOverride)
|
||||||
|
onSaveGenerationSettings(generationSettings.normalized())
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
.disabled(currentOverride == nil)
|
.disabled(currentOverride == nil)
|
||||||
@@ -428,4 +449,16 @@ private struct ModelMetadataEditorView: View {
|
|||||||
private func yesNo(_ value: Bool) -> String {
|
private func yesNo(_ value: Bool) -> String {
|
||||||
value ? "Yes" : "No"
|
value ? "Yes" : "No"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var generationDefaultsSummary: String {
|
||||||
|
if hasSavedGenerationDefaults {
|
||||||
|
return "These saved generation defaults apply to new chats and to API requests that omit generation parameters for this model."
|
||||||
|
}
|
||||||
|
|
||||||
|
if model.isCurated {
|
||||||
|
return "These defaults currently match the model's built-in defaults. Save to store a custom per-model default for chats and API requests."
|
||||||
|
}
|
||||||
|
|
||||||
|
return "These defaults currently match the general fallback defaults for this model. Save to store a custom per-model default for chats and API requests."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,6 @@ struct SettingsView: View {
|
|||||||
@State private var apiAutoStart: Bool = Preferences.apiAutoStart
|
@State private var apiAutoStart: Bool = Preferences.apiAutoStart
|
||||||
@State private var idleUnloadMinutes: String = String(Preferences.idleUnloadMinutes)
|
@State private var idleUnloadMinutes: String = String(Preferences.idleUnloadMinutes)
|
||||||
@State private var defaultModelId: String = Preferences.defaultModelId ?? ModelConfig.default.id
|
@State private var defaultModelId: String = Preferences.defaultModelId ?? ModelConfig.default.id
|
||||||
@State private var generationDefaultsModelId: String = Preferences.defaultModelId ?? ModelConfig.default.id
|
|
||||||
@State private var kvQuantizationEnabled: Bool = Preferences.kvQuantizationEnabled
|
@State private var kvQuantizationEnabled: Bool = Preferences.kvQuantizationEnabled
|
||||||
@State private var kvQuantizationBits: Int = Preferences.kvQuantizationBits
|
@State private var kvQuantizationBits: Int = Preferences.kvQuantizationBits
|
||||||
|
|
||||||
@@ -43,20 +42,6 @@ struct SettingsView: View {
|
|||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("Generation Defaults") {
|
|
||||||
Picker("Defaults for model", selection: $generationDefaultsModelId) {
|
|
||||||
ForEach(modelManager.availableModels) { model in
|
|
||||||
Text(model.displayName).tag(model.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerationDefaultsEditor(settings: generationDefaultsBinding)
|
|
||||||
|
|
||||||
Text("These are the per-model defaults used by chat sessions and by the API server whenever a request omits a generation parameter. Lower temperature and stronger repetition penalties are usually better for technical work; higher temperature is usually better for improvisation and roleplay.")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
|
|
||||||
Section("System Prompt") {
|
Section("System Prompt") {
|
||||||
TextEditor(text: $systemPrompt)
|
TextEditor(text: $systemPrompt)
|
||||||
.font(.body.monospaced())
|
.font(.body.monospaced())
|
||||||
@@ -170,16 +155,6 @@ struct SettingsView: View {
|
|||||||
if !modelManager.availableModels.contains(where: { $0.id == defaultModelId }) {
|
if !modelManager.availableModels.contains(where: { $0.id == defaultModelId }) {
|
||||||
defaultModelId = modelManager.availableModels.first?.id ?? ModelConfig.default.id
|
defaultModelId = modelManager.availableModels.first?.id ?? ModelConfig.default.id
|
||||||
}
|
}
|
||||||
if !modelManager.availableModels.contains(where: { $0.id == generationDefaultsModelId }) {
|
|
||||||
generationDefaultsModelId = defaultModelId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private var generationDefaultsBinding: Binding<GenerationSettings> {
|
|
||||||
Binding(
|
|
||||||
get: { Preferences.generationSettings(forModelId: generationDefaultsModelId) },
|
|
||||||
set: { Preferences.setGenerationSettings($0, forModelId: generationDefaultsModelId) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user