Skip to content

Commit 08306e4

Browse files
committed
Add default system prompt settings
1 parent 02ba264 commit 08306e4

File tree

5 files changed

+96
-80
lines changed

5 files changed

+96
-80
lines changed

Core/Sources/ChatService/ChatService.swift

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,13 @@ import Combine
44
import Foundation
55
import OpenAIService
66

7-
let defaultSystemPrompt = """
8-
You are an AI programming assistant.
9-
Your reply should be concise, clear, informative and logical.
10-
You MUST reply in the format of markdown.
11-
You MUST embed every code you provide in a markdown code block.
12-
You MUST add the programming language name at the start of the markdown code block.
13-
If you are asked to help perform a task, you MUST think step-by-step, then describe each step concisely.
14-
If you are asked to explain code, you MUST explain it step-by-step in a ordered list.
15-
Make your answer short and structured.
16-
"""
17-
187
public final class ChatService: ObservableObject {
198
public let chatGPTService: any ChatGPTServiceType
209
let pluginController: ChatPluginController
2110
let contextController: DynamicContextController
2211
var cancellable = Set<AnyCancellable>()
23-
@Published public internal(set) var systemPrompt = defaultSystemPrompt
12+
@Published public internal(set) var systemPrompt = UserDefaults.shared
13+
.value(for: \.defaultChatSystemPrompt)
2414
@Published public internal(set) var extraSystemPrompt = ""
2515

2616
public init<T: ChatGPTServiceType>(chatGPTService: T) {
@@ -58,7 +48,7 @@ public final class ChatService: ObservableObject {
5848
}
5949

6050
public func resetPrompt() async {
61-
systemPrompt = defaultSystemPrompt
51+
systemPrompt = UserDefaults.shared.value(for: \.defaultChatSystemPrompt)
6252
extraSystemPrompt = ""
6353
}
6454

@@ -89,7 +79,7 @@ public final class ChatService: ObservableObject {
8979

9080
/// Setting it to `nil` to reset the system prompt
9181
public func mutateSystemPrompt(_ newPrompt: String?) {
92-
systemPrompt = newPrompt ?? defaultSystemPrompt
82+
systemPrompt = newPrompt ?? UserDefaults.shared.value(for: \.defaultChatSystemPrompt)
9383
}
9484

9585
public func mutateExtraSystemPrompt(_ newPrompt: String) {

Core/Sources/HostApp/CustomCommandView.swift

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -330,42 +330,14 @@ struct EditCustomCommandView: View {
330330
}
331331
.padding(.bottom)
332332
.background(.regularMaterial)
333-
.sheet(isPresented: .init(get: { editingContentInFullScreen != nil }, set: {
334-
if $0 == false {
335-
editingContentInFullScreen = nil
336-
}
337-
}), content: {
338-
VStack {
339-
if let editingContentInFullScreen {
340-
TextEditor(text: editingContentInFullScreen)
341-
.font(Font.system(.body, design: .monospaced))
342-
.padding(4)
343-
.frame(minHeight: 120)
344-
.multilineTextAlignment(.leading)
345-
.overlay(
346-
RoundedRectangle(cornerRadius: 4)
347-
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
348-
)
349-
}
350-
351-
Button(action: {
352-
editingContentInFullScreen = nil
353-
}) {
354-
Text("Done")
355-
}
356-
}
357-
.padding()
358-
.frame(width: 600, height: 500)
359-
.background(Color(nsColor: .windowBackgroundColor))
360-
})
361333
}
362334
}
363335

364336
@ViewBuilder
365337
var promptTextField: some View {
366338
VStack(alignment: .leading, spacing: 4) {
367339
Text("Prompt")
368-
editableText($prompt)
340+
EditableText(text: $prompt)
369341
}
370342
.padding(.vertical, 4)
371343
}
@@ -378,7 +350,7 @@ struct EditCustomCommandView: View {
378350
} else {
379351
Text(title ?? "System Prompt")
380352
}
381-
editableText($systemPrompt)
353+
EditableText(text: $systemPrompt)
382354
}
383355
.padding(.vertical, 4)
384356
}
@@ -390,38 +362,6 @@ struct EditCustomCommandView: View {
390362
var generateDescriptionToggle: some View {
391363
Toggle("Generate Description", isOn: $generatingPromptToCodeDescription)
392364
}
393-
394-
func editableText(_ binding: Binding<String>) -> some View {
395-
Button(action: {
396-
editingContentInFullScreen = binding
397-
}) {
398-
HStack(alignment: .top) {
399-
Text(binding.wrappedValue)
400-
.font(Font.system(.body, design: .monospaced))
401-
.padding(4)
402-
.multilineTextAlignment(.leading)
403-
.frame(maxWidth: .infinity, alignment: .leading)
404-
.background {
405-
RoundedRectangle(cornerRadius: 4)
406-
.fill(Color(nsColor: .textBackgroundColor))
407-
}
408-
.overlay {
409-
RoundedRectangle(cornerRadius: 4)
410-
.stroke(Color(nsColor: .separatorColor), style: .init(lineWidth: 1))
411-
}
412-
Image(systemName: "square.and.pencil")
413-
.resizable()
414-
.scaledToFit()
415-
.frame(width: 14)
416-
.padding(4)
417-
.background(
418-
Color.primary.opacity(0.1),
419-
in: RoundedRectangle(cornerRadius: 4)
420-
)
421-
}
422-
}
423-
.buttonStyle(.plain)
424-
}
425365
}
426366

427367
// MARK: - Previews

Core/Sources/HostApp/FeatureSettings/ChatSettingsView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct ChatSettingsView: View {
1919

2020
@AppStorage(\.chatFeatureProvider) var chatFeatureProvider
2121
@AppStorage(\.chatGPTModel) var chatGPTModel
22+
@AppStorage(\.defaultChatSystemPrompt) var defaultChatSystemPrompt
2223

2324
init() {}
2425
}
@@ -122,6 +123,13 @@ struct ChatSettingsView: View {
122123
Text("9 Messages").tag(9)
123124
Text("11 Messages").tag(11)
124125
}
126+
127+
VStack(alignment: .leading, spacing: 4) {
128+
Text("Default System Prompt")
129+
EditableText(text: $settings.defaultChatSystemPrompt)
130+
.lineLimit(6)
131+
}
132+
.padding(.vertical, 4)
125133
}.onAppear {
126134
checkMaxToken()
127135
}.onChange(of: settings.chatFeatureProvider) { _ in
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import Foundation
2+
import SwiftUI
3+
4+
struct EditableText: View {
5+
var text: Binding<String>
6+
@State var isEditing: Bool = false
7+
8+
var body: some View {
9+
Button(action: {
10+
isEditing = true
11+
}) {
12+
HStack(alignment: .top) {
13+
Text(text.wrappedValue)
14+
.font(Font.system(.body, design: .monospaced))
15+
.padding(4)
16+
.multilineTextAlignment(.leading)
17+
.frame(maxWidth: .infinity, alignment: .leading)
18+
.background {
19+
RoundedRectangle(cornerRadius: 4)
20+
.fill(Color(nsColor: .textBackgroundColor))
21+
}
22+
.overlay {
23+
RoundedRectangle(cornerRadius: 4)
24+
.stroke(Color(nsColor: .separatorColor), style: .init(lineWidth: 1))
25+
}
26+
Image(systemName: "square.and.pencil")
27+
.resizable()
28+
.scaledToFit()
29+
.frame(width: 14)
30+
.padding(4)
31+
.background(
32+
Color.primary.opacity(0.1),
33+
in: RoundedRectangle(cornerRadius: 4)
34+
)
35+
}
36+
}
37+
.buttonStyle(.plain)
38+
.sheet(isPresented: $isEditing) {
39+
VStack {
40+
TextEditor(text: text)
41+
.font(Font.system(.body, design: .monospaced))
42+
.padding(4)
43+
.frame(minHeight: 120)
44+
.multilineTextAlignment(.leading)
45+
.overlay(
46+
RoundedRectangle(cornerRadius: 4)
47+
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
48+
)
49+
50+
Button(action: {
51+
isEditing = false
52+
}) {
53+
Text("Done")
54+
}
55+
}
56+
.padding()
57+
.frame(width: 600, height: 500)
58+
.background(Color(nsColor: .windowBackgroundColor))
59+
}
60+
}
61+
}
62+

Tool/Sources/Preferences/Keys.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ public extension UserDefaultPreferenceKeys {
105105
var azureOpenAIAPIKey: PreferenceKey<String> {
106106
.init(defaultValue: "", key: "AzureOpenAIAPIKey")
107107
}
108-
108+
109109
var azureOpenAIBaseURL: PreferenceKey<String> {
110110
.init(defaultValue: "", key: "AzureOpenAIBaseURL")
111111
}
112-
112+
113113
var azureChatGPTDeployment: PreferenceKey<String> {
114114
.init(defaultValue: "", key: "AzureChatGPTDeployment")
115115
}
@@ -205,7 +205,7 @@ public extension UserDefaultPreferenceKeys {
205205
var chatFeatureProvider: PreferenceKey<ChatFeatureProvider> {
206206
.init(defaultValue: .openAI, key: "ChatFeatureProvider")
207207
}
208-
208+
209209
var chatFontSize: PreferenceKey<Double> {
210210
.init(defaultValue: 12, key: "ChatFontSize")
211211
}
@@ -225,10 +225,26 @@ public extension UserDefaultPreferenceKeys {
225225
var maxEmbeddableFileInChatContextLineCount: PreferenceKey<Int> {
226226
.init(defaultValue: 100, key: "MaxEmbeddableFileInChatContextLineCount")
227227
}
228-
228+
229229
var useSelectionScopeByDefaultInChatContext: PreferenceKey<Bool> {
230230
.init(defaultValue: true, key: "UseSelectionScopeByDefaultInChatContext")
231231
}
232+
233+
var defaultChatSystemPrompt: PreferenceKey<String> {
234+
.init(
235+
defaultValue: """
236+
You are an AI programming assistant.
237+
Your reply should be concise, clear, informative and logical.
238+
You MUST reply in the format of markdown.
239+
You MUST embed every code you provide in a markdown code block.
240+
You MUST add the programming language name at the start of the markdown code block.
241+
If you are asked to help perform a task, you MUST think step-by-step, then describe each step concisely.
242+
If you are asked to explain code, you MUST explain it step-by-step in a ordered list.
243+
Make your answer short and structured.
244+
""",
245+
key: "DefaultChatSystemPrompt"
246+
)
247+
}
232248
}
233249

234250
// MARK: - Custom Commands

0 commit comments

Comments
 (0)