Skip to content

Commit 0eb29df

Browse files
committed
Initial Commit
1 parent fd98f4f commit 0eb29df

File tree

6 files changed

+68
-9
lines changed

6 files changed

+68
-9
lines changed

Localizable.xcstrings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,9 @@
11111111
},
11121112
"Reload model list" : {
11131113

1114+
},
1115+
"Resume this conversation" : {
1116+
11141117
},
11151118
"Scroll to Top" : {
11161119
"localizations" : {

macLlama/Views/ChatHistoryView/ChatHistoryView.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import SwiftData
1010

1111
struct ChatHistoryView: View {
1212
@Environment(\.modelContext) private var modelContext
13+
@Environment(\.openWindow) private var openWindow
1314
@Query(sort: \SwiftDataChatHistory.createdDate, order: .reverse) private var chatHistory: [SwiftDataChatHistory]
1415

1516
@State private var selectedId: String = ""
@@ -58,6 +59,15 @@ struct ChatHistoryView: View {
5859
.toolbar {
5960
ToolbarItemGroup {
6061
if !selectedId.isEmpty {
62+
//Continue from dedicated conversation button
63+
Button {
64+
openWindow(id: "newConversationWindow", value: selectedId)
65+
} label: {
66+
Label("Resume this conversation", systemImage: "chevron.forward.dotted.chevron.forward")
67+
.labelStyle(.titleAndIcon)
68+
.foregroundStyle(Color.green)
69+
}
70+
6171
Button {
6272
try? deleteChatHistory(conversationID: selectedId)
6373
} label: {

macLlama/Views/ConversationView/ChatBubbleView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ struct ChatBubbleView: View {
1212
@Environment(\.colorScheme) var colorScheme
1313
@AppStorage("chatFontSize") var chatFontSize: Int = AppSettings.chatFontSize
1414
@AppStorage("markdownTheme") var markdownTheme: String = AppSettings.markdownTheme
15+
1516
@Binding var isThinking: Bool
17+
18+
@State var chatMessage: String
1619
@State private var messageAnimationFactor: CGFloat = 0.0
1720
@State private var messageAnimated: Bool = false
1821
@State private var isMarkdownEnabled: Bool = false
19-
@State private var chatMessage: String = ""
2022
@State private var showAssistantThink: Bool = false
2123

2224
var assistantThinkContext: String? {

macLlama/Views/ConversationView/ChatInterfaceView/ChatInterfaceView.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ struct ChatInterfaceView: View {
3131
@State private var temperature: Double = 0.7
3232

3333
//Chat history state
34-
@State private var history: [LocalChatHistory] = []
34+
@State var history: [LocalChatHistory]
3535

3636
//Auto scrolling state
3737
@State private var isAutoScrolling: Bool = false
3838
@State private var autoScrollTask: Task<Void, Never>?
3939

4040
//Extra state
41-
@State private var conversationId: UUID = UUID()
41+
@State var conversationId: UUID
4242
@State private var hoveredTopButtonTag: Int? = nil
4343
@State private var showThink: Bool = false
4444
@State private var isSettingOn: Bool = false
@@ -102,8 +102,8 @@ struct ChatInterfaceView: View {
102102
ScrollView {
103103
ForEach(0..<self.history.count, id: \.self) { index in
104104
VStack {
105-
if history[index].message != "" {
106-
ChatBubbleView(isThinking: self.$isThinking, chatData: $history[index])
105+
if history[index].message.count > 0 {
106+
ChatBubbleView(isThinking: self.$isThinking, chatMessage: self.history[index].message ,chatData: $history[index])
107107
.padding(EdgeInsets(top: index == 0 ? Units.normalGap * 4 : Units.normalGap,
108108
leading: Units.normalGap,
109109
bottom: Units.normalGap, trailing: Units.normalGap))
@@ -261,13 +261,14 @@ extension ChatInterfaceView {
261261
self.isFetchingWebSearch = true
262262
if let summary = await self.viewModel.getWebResponse(from: prompt) {
263263
let searchedPrompt = """
264-
You are a helpful AI assistant dedicated to answering questions. Combine the information provided below with your existing knowledge to provide context and clarify details, but *all factual claims* must be directly supported by the provided text, meaning they must be either a direct quote or a paraphrase that accurately reflects the text’s meaning. Always cite the source (e.g., paragraph number, section title) whenever possible. If the provided text contains conflicting information, acknowledge the conflict and present both perspectives without taking a definitive stance. You will be asked factual and explanatory questions based on the provided text. Do *not* speculate, offer opinions, or generate information not found within the provided text.
264+
You are a helpful AI assistant dedicated to answering questions. Combine the information provided below with your existing knowledge to provide context and clarify details, but *all factual claims* must be directly supported by the provided text, meaning they must be either a direct quote or a paraphrase that accurately reflects the text’s meaning. Always cite the source (e.g., paragraph number, section title) whenever possible. If the provided text contains conflicting information, acknowledge the conflict and present both perspectives without taking a definitive stance. You will be asked factual and explanatory questions based on the provided text. Do *not* speculate, offer opinions, or generate information not found within the provided text.
265265
266266
If the question cannot be answered using the provided text, please respond with: "I'm sorry, the answer to this question isn't available in the provided information."
267267
268268
When answering, please cite the source and provide the URL for reference. Format your answers and citations like this:
269269
270270
Answer derived *directly* from the provided text
271+
Answer *must* answered in the language user questioned
271272
272273
Source: [A brief description of the provided text, e.g., "A summary from the World Wildlife Fund about polar bear populations."]
273274
Reference URL: \(summary.1) (This URL is for reference and does not need to be displayed in the answer.)

macLlama/Views/ConversationView/ConversationWindowView.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,57 @@ import SwiftData
1111
struct ConversationWindowView: View {
1212
@Environment(\.colorScheme) var colorScheme
1313
@EnvironmentObject var serverStatus: ServerStatus
14+
@Query(sort: \SwiftDataChatHistory.createdDate, order: .forward) private var chatHistory: [SwiftDataChatHistory]
15+
16+
var history: [LocalChatHistory] {
17+
fetchHistory()
18+
}
19+
20+
let conversationId: String?
21+
var conversationUUID: UUID {
22+
if let idString = conversationId {
23+
return UUID(uuidString: idString) ?? UUID()
24+
} else {
25+
return UUID()
26+
}
27+
}
1428

1529
var body: some View {
1630
if serverStatus.isOnline {
17-
ChatInterfaceView()
31+
ChatInterfaceView(history: history, conversationId: conversationUUID)
1832
.environmentObject(serverStatus)
1933
} else {
2034
StartServerView()
2135
.environmentObject(serverStatus)
2236
.padding(.top, Units.normalGap * -3)
2337
}
2438
}
39+
40+
///Get conversation from history
41+
private func fetchHistory() -> [LocalChatHistory] {
42+
var conversationHistory: [LocalChatHistory] = []
43+
guard let conversationId = self.conversationId else {
44+
return conversationHistory
45+
}
46+
let result = chatHistory.filter({$0.conversationId.uuidString == conversationId}).sorted(by: { $0.conversationDate < $1.conversationDate })
47+
48+
49+
if result.count == 0 {
50+
return conversationHistory
51+
}
52+
53+
result.forEach { history in
54+
let isUser = history.chatData.role == "user" ? true : false
55+
let message = history.chatData.content
56+
let history: LocalChatHistory = .init(isUser: isUser, modelName: "macLlama History", message: message)
57+
conversationHistory.append(history)
58+
}
59+
60+
return conversationHistory
61+
}
2562
}
2663

2764
#Preview {
28-
ConversationWindowView()
65+
ConversationWindowView(conversationId: nil)
2966
.modelContainer(for: Item.self, inMemory: true)
3067
}

macLlama/macLlamaApp.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct macLlamaApp: App {
4242

4343
var body: some Scene {
4444
WindowGroup {
45-
ConversationWindowView()
45+
ConversationWindowView(conversationId: nil)
4646
.environmentObject(serverStatus)
4747
.frame(minWidth: Units.appFrameMinWidth, minHeight: Units.appFrameMinHeight)
4848
.task {
@@ -171,5 +171,11 @@ struct macLlamaApp: App {
171171
.keyboardShortcut("h", modifiers: [.command, .shift], localization: .automatic)
172172
.modelContainer(for: SwiftDataChatHistory.self)
173173
.windowResizability(.contentSize)
174+
175+
WindowGroup(id: "newConversationWindow", for: String.self) { string in
176+
ConversationWindowView(conversationId: string.wrappedValue)
177+
.environmentObject(serverStatus)
178+
}
179+
.modelContainer(for: SwiftDataChatHistory.self)
174180
}
175181
}

0 commit comments

Comments
 (0)