Skip to content

Commit f1cb526

Browse files
committed
Update model format picker styles
1 parent be47c9a commit f1cb526

4 files changed

Lines changed: 160 additions & 32 deletions

File tree

Core/Sources/HostApp/AccountSettings/ChatModelManagement/ChatModelEdit.swift

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,41 @@ struct ChatModelEdit {
4545
case testSucceeded(String)
4646
case testFailed(String)
4747
case checkSuggestedMaxTokens
48+
case selectModelFormat(ModelFormat)
4849
case apiKeySelection(APIKeySelection.Action)
4950
case baseURLSelection(BaseURLSelection.Action)
5051
}
5152

53+
enum ModelFormat: CaseIterable {
54+
case openAI
55+
case azureOpenAI
56+
case googleAI
57+
case ollama
58+
case claude
59+
case openAICompatible
60+
case deepSeekOpenAICompatible
61+
case openRouterOpenAICompatible
62+
case grokOpenAICompatible
63+
case mistralOpenAICompatible
64+
65+
init(_ format: ChatModel.Format) {
66+
switch format {
67+
case .openAI:
68+
self = .openAI
69+
case .azureOpenAI:
70+
self = .azureOpenAI
71+
case .googleAI:
72+
self = .googleAI
73+
case .ollama:
74+
self = .ollama
75+
case .claude:
76+
self = .claude
77+
case .openAICompatible:
78+
self = .openAICompatible
79+
}
80+
}
81+
}
82+
5283
var toast: (String, ToastType) -> Void {
5384
@Dependency(\.namespacedToast) var toast
5485
return {
@@ -169,6 +200,39 @@ struct ChatModelEdit {
169200
return .none
170201
}
171202

203+
case let .selectModelFormat(format):
204+
switch format {
205+
case .openAI:
206+
state.format = .openAI
207+
case .azureOpenAI:
208+
state.format = .azureOpenAI
209+
case .googleAI:
210+
state.format = .googleAI
211+
case .ollama:
212+
state.format = .ollama
213+
case .claude:
214+
state.format = .claude
215+
case .openAICompatible:
216+
state.format = .openAICompatible
217+
case .deepSeekOpenAICompatible:
218+
state.format = .openAICompatible
219+
state.baseURLSelection.baseURL = "https://api.deepseek.com"
220+
state.baseURLSelection.isFullURL = false
221+
case .openRouterOpenAICompatible:
222+
state.format = .openAICompatible
223+
state.baseURLSelection.baseURL = "https://openrouter.ai"
224+
state.baseURLSelection.isFullURL = false
225+
case .grokOpenAICompatible:
226+
state.format = .openAICompatible
227+
state.baseURLSelection.baseURL = "https://api.x.ai"
228+
state.baseURLSelection.isFullURL = false
229+
case .mistralOpenAICompatible:
230+
state.format = .openAICompatible
231+
state.baseURLSelection.baseURL = "https://api.mistral.ai"
232+
state.baseURLSelection.isFullURL = false
233+
}
234+
return .none
235+
172236
case .apiKeySelection:
173237
return .none
174238

Core/Sources/HostApp/AccountSettings/ChatModelManagement/ChatModelEditView.swift

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,31 +86,42 @@ struct ChatModelEditView: View {
8686
var body: some View {
8787
WithPerceptionTracking {
8888
Picker(
89-
selection: $store.format,
89+
selection: Binding(
90+
get: { .init(store.format) },
91+
set: { store.send(.selectModelFormat($0)) }
92+
),
9093
content: {
9194
ForEach(
92-
ChatModel.Format.allCases,
93-
id: \.rawValue
95+
ChatModelEdit.ModelFormat.allCases,
96+
id: \.self
9497
) { format in
9598
switch format {
9699
case .openAI:
97-
Text("OpenAI").tag(format)
100+
Text("OpenAI")
98101
case .azureOpenAI:
99-
Text("Azure OpenAI").tag(format)
102+
Text("Azure OpenAI")
100103
case .openAICompatible:
101-
Text("OpenAI Compatible").tag(format)
104+
Text("OpenAI Compatible")
102105
case .googleAI:
103-
Text("Google Generative AI").tag(format)
106+
Text("Google AI")
104107
case .ollama:
105-
Text("Ollama").tag(format)
108+
Text("Ollama")
106109
case .claude:
107-
Text("Claude").tag(format)
110+
Text("Claude")
111+
case .deepSeekOpenAICompatible:
112+
Text("DeepSeek (OpenAI Compatible)")
113+
case .openRouterOpenAICompatible:
114+
Text("OpenRouter (OpenAI Compatible)")
115+
case .grokOpenAICompatible:
116+
Text("Grok (OpenAI Compatible)")
117+
case .mistralOpenAICompatible:
118+
Text("Mistral (OpenAI Compatible)")
108119
}
109120
}
110121
},
111122
label: { Text("Format") }
112123
)
113-
.pickerStyle(.segmented)
124+
.pickerStyle(.menu)
114125
}
115126
}
116127
}
@@ -393,16 +404,17 @@ struct ChatModelEditView: View {
393404
Text("Keep Alive")
394405
}
395406

407+
Button("Custom Headers") {
408+
isEditingCustomHeader.toggle()
409+
}
410+
396411
VStack(alignment: .leading, spacing: 8) {
397412
Text(Image(systemName: "exclamationmark.triangle.fill")) + Text(
398413
" For more details, please visit [https://ollama.com](https://ollama.com)."
399414
)
400415
}
401416
.padding(.vertical)
402417

403-
Button("Custom Headers") {
404-
isEditingCustomHeader.toggle()
405-
}
406418
}.sheet(isPresented: $isEditingCustomHeader) {
407419
CustomHeaderSettingsView(headers: $store.customHeaders)
408420
}

Core/Sources/HostApp/AccountSettings/EmbeddingModelManagement/EmbeddingModelEdit.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,32 @@ struct EmbeddingModelEdit {
4141
case testFailed(String)
4242
case fixDimensions(Int)
4343
case checkSuggestedMaxTokens
44+
case selectModelFormat(ModelFormat)
4445
case apiKeySelection(APIKeySelection.Action)
4546
case baseURLSelection(BaseURLSelection.Action)
4647
}
48+
49+
enum ModelFormat: CaseIterable {
50+
case openAI
51+
case azureOpenAI
52+
case ollama
53+
case openAICompatible
54+
case mistralOpenAICompatible
55+
case voyageAIOpenAICompatible
56+
57+
init(_ format: EmbeddingModel.Format) {
58+
switch format {
59+
case .openAI:
60+
self = .openAI
61+
case .azureOpenAI:
62+
self = .azureOpenAI
63+
case .ollama:
64+
self = .ollama
65+
case .openAICompatible:
66+
self = .openAICompatible
67+
}
68+
}
69+
}
4770

4871
var toast: (String, ToastType) -> Void {
4972
@Dependency(\.namespacedToast) var toast
@@ -155,6 +178,27 @@ struct EmbeddingModelEdit {
155178
case let .fixDimensions(value):
156179
state.dimensions = value
157180
return .none
181+
182+
case let .selectModelFormat(format):
183+
switch format {
184+
case .openAI:
185+
state.format = .openAI
186+
case .azureOpenAI:
187+
state.format = .azureOpenAI
188+
case .ollama:
189+
state.format = .ollama
190+
case .openAICompatible:
191+
state.format = .openAICompatible
192+
case .mistralOpenAICompatible:
193+
state.format = .openAICompatible
194+
state.baseURLSelection.baseURL = "https://api.mistral.ai"
195+
state.baseURLSelection.isFullURL = false
196+
case .voyageAIOpenAICompatible:
197+
state.format = .openAICompatible
198+
state.baseURLSelection.baseURL = "https://api.voyage.ai"
199+
state.baseURLSelection.isFullURL = false
200+
}
201+
return .none
158202

159203
case .apiKeySelection:
160204
return .none

Core/Sources/HostApp/AccountSettings/EmbeddingModelManagement/EmbeddingModelEditView.swift

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,34 @@ struct EmbeddingModelEditView: View {
8181
var body: some View {
8282
WithPerceptionTracking {
8383
Picker(
84-
selection: $store.format,
84+
selection: Binding(
85+
get: { .init(store.format) },
86+
set: { store.send(.selectModelFormat($0)) }
87+
),
8588
content: {
8689
ForEach(
87-
EmbeddingModel.Format.allCases,
88-
id: \.rawValue
90+
EmbeddingModelEdit.ModelFormat.allCases,
91+
id: \.self
8992
) { format in
9093
switch format {
9194
case .openAI:
92-
Text("OpenAI").tag(format)
95+
Text("OpenAI")
9396
case .azureOpenAI:
94-
Text("Azure OpenAI").tag(format)
95-
case .openAICompatible:
96-
Text("OpenAI Compatible").tag(format)
97+
Text("Azure OpenAI")
9798
case .ollama:
98-
Text("Ollama").tag(format)
99+
Text("Ollama")
100+
case .openAICompatible:
101+
Text("OpenAI Compatible")
102+
case .mistralOpenAICompatible:
103+
Text("Mistral (OpenAI Compatible)")
104+
case .voyageAIOpenAICompatible:
105+
Text("Voyage (OpenAI Compatible)")
99106
}
100107
}
101108
},
102109
label: { Text("Format") }
103110
)
104-
.pickerStyle(.segmented)
111+
.pickerStyle(.menu)
105112
}
106113
}
107114
}
@@ -174,7 +181,7 @@ struct EmbeddingModelEditView: View {
174181
}
175182
}
176183
}
177-
184+
178185
struct DimensionsTextField: View {
179186
@Perception.Bindable var store: StoreOf<EmbeddingModelEdit>
180187

@@ -212,7 +219,7 @@ struct EmbeddingModelEditView: View {
212219
return .primary
213220
}() as Color)
214221
}
215-
222+
216223
Text("If you are not sure, run test to get the correct value.")
217224
.font(.caption)
218225
.dynamicHeightTextInFormWorkaround()
@@ -327,7 +334,7 @@ struct EmbeddingModelEditView: View {
327334

328335
MaxTokensTextField(store: store)
329336
DimensionsTextField(store: store)
330-
337+
331338
Button("Custom Headers") {
332339
isEditingCustomHeader.toggle()
333340
}
@@ -340,15 +347,15 @@ struct EmbeddingModelEditView: View {
340347
struct OllamaForm: View {
341348
@Perception.Bindable var store: StoreOf<EmbeddingModelEdit>
342349
@State var isEditingCustomHeader = false
343-
350+
344351
var body: some View {
345352
WithPerceptionTracking {
346353
BaseURLTextField(store: store, prompt: Text("http://127.0.0.1:11434")) {
347354
Text("/api/embeddings")
348355
}
349-
356+
350357
ApiKeyNamePicker(store: store)
351-
358+
352359
TextField("Model Name", text: $store.modelName)
353360

354361
MaxTokensTextField(store: store)
@@ -360,16 +367,17 @@ struct EmbeddingModelEditView: View {
360367
}
361368
}
362369

370+
Button("Custom Headers") {
371+
isEditingCustomHeader.toggle()
372+
}
373+
363374
VStack(alignment: .leading, spacing: 8) {
364375
Text(Image(systemName: "exclamationmark.triangle.fill")) + Text(
365376
" For more details, please visit [https://ollama.com](https://ollama.com)."
366377
)
367378
}
368379
.padding(.vertical)
369-
370-
Button("Custom Headers") {
371-
isEditingCustomHeader.toggle()
372-
}
380+
373381
}.sheet(isPresented: $isEditingCustomHeader) {
374382
CustomHeaderSettingsView(headers: $store.customHeaders)
375383
}

0 commit comments

Comments
 (0)