Skip to content

Commit 3a5b599

Browse files
committed
Add custom header settings to OpenAI compatible
1 parent a547c49 commit 3a5b599

File tree

6 files changed

+115
-7
lines changed

6 files changed

+115
-7
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct ChatModelEdit {
3131
var enforceMessageOrder: Bool = false
3232
var openAIOrganizationID: String = ""
3333
var openAIProjectID: String = ""
34+
var customHeaders: [ChatModel.Info.CustomHeaderInfo.HeaderField] = []
3435
}
3536

3637
enum Action: Equatable, BindableAction {
@@ -205,7 +206,8 @@ extension ChatModel {
205206
),
206207
ollamaInfo: .init(keepAlive: state.ollamaKeepAlive),
207208
googleGenerativeAIInfo: .init(apiVersion: state.apiVersion),
208-
openAICompatibleInfo: .init(enforceMessageOrder: state.enforceMessageOrder)
209+
openAICompatibleInfo: .init(enforceMessageOrder: state.enforceMessageOrder),
210+
customHeaderInfo: .init(headers: state.customHeaders)
209211
)
210212
)
211213
}
@@ -227,7 +229,8 @@ extension ChatModel {
227229
baseURLSelection: .init(baseURL: info.baseURL, isFullURL: info.isFullURL),
228230
enforceMessageOrder: info.openAICompatibleInfo.enforceMessageOrder,
229231
openAIOrganizationID: info.openAIInfo.organizationID,
230-
openAIProjectID: info.openAIInfo.projectID
232+
openAIProjectID: info.openAIInfo.projectID,
233+
customHeaders: info.customHeaderInfo.headers
231234
)
232235
}
233236
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ struct ChatModelEditView: View {
285285

286286
struct OpenAICompatibleForm: View {
287287
@Perception.Bindable var store: StoreOf<ChatModelEdit>
288+
@State var isEditingCustomHeader = false
288289

289290
var body: some View {
290291
WithPerceptionTracking {
@@ -320,6 +321,12 @@ struct ChatModelEditView: View {
320321
Toggle(isOn: $store.enforceMessageOrder) {
321322
Text("Enforce message order to be user/assistant alternated")
322323
}
324+
325+
Button("Custom Headers") {
326+
isEditingCustomHeader.toggle()
327+
}
328+
}.sheet(isPresented: $isEditingCustomHeader) {
329+
CustomHeaderSettingsView(headers: $store.customHeaders)
323330
}
324331
}
325332
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import AIModel
2+
import Foundation
3+
import SwiftUI
4+
5+
struct CustomHeaderSettingsView: View {
6+
@Binding var headers: [ChatModel.Info.CustomHeaderInfo.HeaderField]
7+
@Environment(\.dismiss) var dismiss
8+
@State private var newKey = ""
9+
@State private var newValue = ""
10+
11+
var body: some View {
12+
VStack {
13+
List {
14+
ForEach(headers.indices, id: \.self) { index in
15+
HStack {
16+
TextField("Key", text: Binding(
17+
get: { headers[index].key },
18+
set: { newKey in
19+
headers[index].key = newKey
20+
}
21+
))
22+
TextField("Value", text: Binding(
23+
get: { headers[index].value },
24+
set: { headers[index].value = $0 }
25+
))
26+
Button(action: {
27+
headers.remove(at: index)
28+
}) {
29+
Image(systemName: "trash")
30+
.foregroundColor(.red)
31+
}
32+
}
33+
}
34+
35+
HStack {
36+
TextField("New Key", text: $newKey)
37+
TextField("New Value", text: $newValue)
38+
Button(action: {
39+
if !newKey.isEmpty {
40+
headers.append(ChatModel.Info.CustomHeaderInfo.HeaderField(
41+
key: newKey,
42+
value: newValue
43+
))
44+
newKey = ""
45+
newValue = ""
46+
}
47+
}) {
48+
Image(systemName: "plus.circle.fill")
49+
.foregroundColor(.green)
50+
}
51+
}
52+
}
53+
54+
HStack {
55+
Spacer()
56+
Button("Done") {
57+
dismiss()
58+
}
59+
}.padding()
60+
}
61+
.frame(height: 500)
62+
}
63+
}
64+
65+
#Preview {
66+
struct V: View {
67+
@State var headers: [ChatModel.Info.CustomHeaderInfo.HeaderField] = [
68+
.init(key: "key", value: "value"),
69+
.init(key: "key2", value: "value2"),
70+
]
71+
var body: some View {
72+
CustomHeaderSettingsView(headers: $headers)
73+
}
74+
}
75+
76+
return V()
77+
}
78+

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct EmbeddingModelEdit {
2626
var suggestedMaxTokens: Int?
2727
var apiKeySelection: APIKeySelection.State = .init()
2828
var baseURLSelection: BaseURLSelection.State = .init()
29+
var customHeaders: [ChatModel.Info.CustomHeaderInfo.HeaderField] = []
2930
}
3031

3132
enum Action: Equatable, BindableAction {
@@ -168,7 +169,8 @@ extension EmbeddingModel {
168169
isFullURL: state.isFullURL,
169170
maxTokens: state.maxTokens,
170171
modelName: state.modelName.trimmingCharacters(in: .whitespacesAndNewlines),
171-
ollamaInfo: .init(keepAlive: state.ollamaKeepAlive)
172+
ollamaInfo: .init(keepAlive: state.ollamaKeepAlive),
173+
customHeaderInfo: .init(headers: state.customHeaders)
172174
)
173175
)
174176
}
@@ -188,7 +190,8 @@ extension EmbeddingModel {
188190
baseURLSelection: .init(
189191
baseURL: info.baseURL,
190192
isFullURL: info.isFullURL
191-
)
193+
),
194+
customHeaders: info.customHeaderInfo.headers
192195
)
193196
}
194197
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ struct EmbeddingModelEditView: View {
248248

249249
struct OpenAICompatibleForm: View {
250250
@Perception.Bindable var store: StoreOf<EmbeddingModelEdit>
251+
@State var isEditingCustomHeader = false
251252

252253
var body: some View {
253254
WithPerceptionTracking {
@@ -278,6 +279,12 @@ struct EmbeddingModelEditView: View {
278279
TextField("Model Name", text: $store.modelName)
279280

280281
MaxTokensTextField(store: store)
282+
283+
Button("Custom Headers") {
284+
isEditingCustomHeader.toggle()
285+
}
286+
}.sheet(isPresented: $isEditingCustomHeader) {
287+
CustomHeaderSettingsView(headers: $store.customHeaders)
281288
}
282289
}
283290
}

Tool/Sources/AIModel/ChatModel.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,20 @@ public struct ChatModel: Codable, Equatable, Identifiable {
6666
}
6767

6868
public struct CustomHeaderInfo: Codable, Equatable {
69-
@FallbackDecoding<EmptyDictionary>
70-
public var headers: [String: String]
69+
public struct HeaderField: Codable, Equatable {
70+
public var key: String
71+
public var value: String
72+
73+
public init(key: String, value: String) {
74+
self.key = key
75+
self.value = value
76+
}
77+
}
78+
79+
@FallbackDecoding<EmptyArray>
80+
public var headers: [HeaderField]
7181

72-
public init(headers: [String : String] = [:]) {
82+
public init(headers: [HeaderField] = []) {
7383
self.headers = headers
7484
}
7585
}

0 commit comments

Comments
 (0)