Skip to content

Commit 60c553a

Browse files
authored
Merge pull request intitni#100 from SNQ-2001/feature/update-openai-settings
Allow ChatGPT Model and Reply in Language to be selected in Picker
2 parents 5551871 + 1fabffd commit 60c553a

4 files changed

Lines changed: 111 additions & 42 deletions

File tree

Copilot for Xcode/OpenAIView.swift

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,63 +30,76 @@ struct OpenAIView: View {
3030

3131
Form {
3232
HStack {
33-
Text("OpenAI API Key")
3433
TextField(text: $settings.openAIAPIKey, prompt: Text("sk-*")) {
35-
EmptyView()
36-
}.textFieldStyle(.copilot)
34+
Text("OpenAI API Key")
35+
}.textFieldStyle(.roundedBorder)
3736
Button(action: {
3837
openURL(apiKeyURL)
3938
}) {
4039
Image(systemName: "questionmark.circle.fill")
41-
}
42-
.buttonStyle(.plain)
40+
}.buttonStyle(.plain)
4341
}
4442

4543
HStack {
46-
Text("ChatGPT Model")
47-
TextField(text: $settings.chatGPTModel, prompt: Text("gpt-3.5-turbo")) {
48-
EmptyView()
49-
}.textFieldStyle(.copilot)
50-
44+
Picker(selection: $settings.chatGPTModel) {
45+
ForEach(ChatGPTModel.allCases, id: \.self) { model in
46+
Text(model.rawValue).tag(model.rawValue)
47+
}
48+
} label: {
49+
Text("ChatGPT Model")
50+
}.pickerStyle(.menu)
5151
Button(action: {
5252
openURL(modelURL)
5353
}) {
5454
Image(systemName: "questionmark.circle.fill")
55+
}.buttonStyle(.plain)
56+
}
57+
.onChange(of: settings.chatGPTModel) { newValue in
58+
if let model = ChatGPTModel(rawValue: newValue) {
59+
settings.chatGPTEndpoint = model.endpoint
5560
}
56-
.buttonStyle(.plain)
5761
}
5862

59-
HStack {
60-
Text("ChatGPT Endpoint")
61-
TextField(
62-
text: $settings.chatGPTEndpoint,
63-
prompt: Text("https://api.openai.com/v1/chat/completions")
64-
) {
65-
EmptyView()
66-
}.textFieldStyle(.copilot)
67-
}
68-
69-
HStack {
63+
TextField(
64+
text: $settings.chatGPTEndpoint,
65+
prompt: Text("https://api.openai.com/v1/chat/completions")
66+
) {
67+
Text("ChatGPT Server")
68+
}.textFieldStyle(.roundedBorder)
69+
70+
Picker(selection: $settings.chatGPTLanguage) {
71+
ForEach(Locale.availableLocalizedLocales, id: \.self) { localizedLocales in
72+
Text(localizedLocales).tag(localizedLocales)
73+
}
74+
} label: {
7075
Text("Reply in Language")
71-
TextField(
72-
text: $settings.chatGPTLanguage,
73-
prompt: Text("e.g. English. Leave it blank to let the bot decide.")
74-
) {
75-
EmptyView()
76-
}.textFieldStyle(.copilot)
77-
}
78-
79-
HStack {
80-
Text("Max Token")
81-
TextField(
82-
text: .init(get: {
83-
String(settings.chatGPTMaxToken)
84-
}, set: { newValue in
85-
settings.chatGPTMaxToken = Int(newValue) ?? 0
86-
})
87-
) {
88-
EmptyView()
89-
}.textFieldStyle(.copilot)
76+
}.pickerStyle(.menu)
77+
78+
if let model = ChatGPTModel(rawValue: settings.chatGPTModel) {
79+
let binding = Binding(
80+
get: { String(settings.chatGPTMaxToken) },
81+
set: {
82+
if let selectionMaxToken = Int($0) {
83+
settings.chatGPTMaxToken = model.maxToken < selectionMaxToken ? model.maxToken : selectionMaxToken
84+
} else {
85+
settings.chatGPTMaxToken = 0
86+
}
87+
}
88+
)
89+
HStack {
90+
Stepper(
91+
value: $settings.chatGPTMaxToken,
92+
in: 0...model.maxToken,
93+
step: 1
94+
) {
95+
Text("Max Token")
96+
}
97+
TextField(text: binding) {
98+
EmptyView()
99+
}
100+
.labelsHidden()
101+
.textFieldStyle(.roundedBorder)
102+
}
90103
}
91104
}
92105
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import Foundation
2+
3+
public enum ChatGPTModel: String {
4+
case gpt4 = "gpt-4"
5+
6+
case gpt40314 = "gpt-4-0314"
7+
8+
case gpt432k = "gpt-4-32k"
9+
10+
case gpt432k0314 = "gpt-4-32k-0314"
11+
12+
case gpt35Turbo = "gpt-3.5-turbo"
13+
14+
case gpt35Turbo0301 = "gpt-3.5-turbo-0301"
15+
}
16+
17+
public extension ChatGPTModel {
18+
var endpoint: String {
19+
"https://api.openai.com/v1/chat/completions"
20+
}
21+
22+
var maxToken: Int {
23+
switch self {
24+
case .gpt4:
25+
return 8192
26+
case .gpt40314:
27+
return 8192
28+
case .gpt432k:
29+
return 32768
30+
case .gpt432k0314:
31+
return 32768
32+
case .gpt35Turbo:
33+
return 4096
34+
case .gpt35Turbo0301:
35+
return 4096
36+
}
37+
}
38+
}
39+
40+
extension ChatGPTModel: CaseIterable {}

Core/Sources/Preferences/Keys.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public struct UserDefaultPreferenceKeys {
8080
public var chatGPTEndpoint: ChatGPTEndpoint { .init() }
8181

8282
public struct ChatGPTModel: UserDefaultPreferenceKey {
83-
public let defaultValue = ""
83+
public let defaultValue = Preferences.ChatGPTModel.gpt35Turbo.rawValue
8484
public let key = "ChatGPTModel"
8585
}
8686

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Foundation
2+
3+
public extension Locale {
4+
static var availableLocalizedLocales: [String] {
5+
var localizedLocales = Locale.availableIdentifiers.compactMap {
6+
Locale(identifier: $0).localizedString(forIdentifier: $0)
7+
}
8+
.sorted()
9+
localizedLocales.insert("Auto-detected by ChatGPT", at: 0)
10+
return localizedLocales
11+
}
12+
13+
var languageName: String {
14+
localizedString(forLanguageCode: languageCode ?? "") ?? ""
15+
}
16+
}

0 commit comments

Comments
 (0)