Skip to content

Commit 0ff8826

Browse files
committed
Merge branch 'feature/rag-base-project-scope' into develop
2 parents eebff15 + d506429 commit 0ff8826

20 files changed

Lines changed: 230 additions & 116 deletions

File tree

Core/Package.swift

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ let package = Package(
210210

211211
// context collectors
212212
"WebChatContextCollector",
213-
"ActiveDocumentChatContextCollector",
214213
"SystemInfoChatContextCollector",
215214

216215
.product(name: "ChatContextCollector", package: "Tool"),
@@ -354,23 +353,6 @@ let package = Package(
354353
],
355354
path: "Sources/ChatContextCollectors/SystemInfoChatContextCollector"
356355
),
357-
358-
.target(
359-
name: "ActiveDocumentChatContextCollector",
360-
dependencies: [
361-
.product(name: "ChatContextCollector", package: "Tool"),
362-
.product(name: "OpenAIService", package: "Tool"),
363-
.product(name: "Preferences", package: "Tool"),
364-
.product(name: "FocusedCodeFinder", package: "Tool"),
365-
.product(name: "AppMonitoring", package: "Tool"),
366-
],
367-
path: "Sources/ChatContextCollectors/ActiveDocumentChatContextCollector"
368-
),
369-
370-
.testTarget(
371-
name: "ActiveDocumentChatContextCollectorTests",
372-
dependencies: ["ActiveDocumentChatContextCollector"]
373-
),
374356
]
375357
)
376358

Core/Sources/ChatContextCollectors/SystemInfoChatContextCollector/SystemInfoChatContextCollector.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ public final class SystemInfoChatContextCollector: ChatContextCollector {
1616
scopes: Set<String>,
1717
content: String,
1818
configuration: ChatGPTConfiguration
19-
) -> ChatContext? {
19+
) -> ChatContext {
2020
return .init(
2121
systemPrompt: """
22-
Current Time: \(Self.dateFormatter.string(from: Date())) (You can use it to calculate time in another time zone)
23-
""",
22+
Current Time: \(
23+
Self.dateFormatter.string(from: Date())
24+
) (You can use it to calculate time in another time zone)
25+
""",
26+
retrievedContent: [],
2427
functions: []
2528
)
2629
}

Core/Sources/ChatContextCollectors/WebChatContextCollector/WebChatContextCollector.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public final class WebChatContextCollector: ChatContextCollector {
1212
scopes: Set<String>,
1313
content: String,
1414
configuration: ChatGPTConfiguration
15-
) -> ChatContext? {
16-
guard scopes.contains("web") || scopes.contains("w") else { return nil }
15+
) -> ChatContext {
16+
guard scopes.contains("web") || scopes.contains("w") else { return .empty }
1717
let links = Self.detectLinks(from: history) + Self.detectLinks(from: content)
1818
let functions: [(any ChatGPTFunction)?] = [
1919
SearchFunction(maxTokens: configuration.maxTokens),
@@ -22,6 +22,7 @@ public final class WebChatContextCollector: ChatContextCollector {
2222
]
2323
return .init(
2424
systemPrompt: "You prefer to answer questions with latest content on the internet.",
25+
retrievedContent: [],
2526
functions: functions.compactMap { $0 }
2627
)
2728
}

Core/Sources/ChatGPTChatTab/ChatPanel.swift

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct ChatPanelMessages: View {
5858

5959
ChatHistory(chat: chat)
6060
.listItemTint(.clear)
61-
61+
6262
WithViewStore(chat, observe: \.isReceivingMessage) { viewStore in
6363
if viewStore.state {
6464
Spacer(minLength: 12)
@@ -231,35 +231,35 @@ private struct Instruction: View {
231231
Group {
232232
Markdown(
233233
"""
234-
You can use scopes to give the bot extra abilities.
234+
You can use plugins to perform various tasks.
235235
236-
| Scope Name | Abilities |
236+
| Plugin Name | Description |
237237
| --- | --- |
238-
| `@file` | Read the metadata of the editing file |
239-
| `@code` | Read the code and metadata in the editing file |
240-
| `@web` (beta) | Search on Bing or query from a web page |
241-
| `@project` | Experimental. Access content of the project |
242-
243-
To use scopes, you can prefix a message with `@code`.
238+
| `/run` | Runs a command under the project root |
239+
| `/math` | Solves a math problem in natural language |
240+
| `/search` | Searches on Bing and summarizes the results |
241+
| `/shortcut(name)` | Runs a shortcut from the Shortcuts.app, with the previous message as input |
242+
| `/shortcutInput(name)` | Runs a shortcut and uses its result as a new message |
244243
245-
You can use shorthand to represent a scope, such as `@c`, and enable multiple scopes with `@c+web`.
244+
To use plugins, you can prefix a message with `/pluginName`.
246245
"""
247246
)
248247
.modifier(InstructionModifier())
249248

250249
Markdown(
251250
"""
252-
You can use plugins to perform various tasks.
251+
You can use scopes to give the bot extra abilities.
253252
254-
| Plugin Name | Description |
253+
| Scope Name | Abilities |
255254
| --- | --- |
256-
| `/run` | Runs a command under the project root |
257-
| `/math` | Solves a math problem in natural language |
258-
| `/search` | Searches on Bing and summarizes the results |
259-
| `/shortcut(name)` | Runs a shortcut from the Shortcuts.app, with the previous message as input |
260-
| `/shortcutInput(name)` | Runs a shortcut and uses its result as a new message |
255+
| `@file` | Read the metadata of the editing file |
256+
| `@code` | Read the code and metadata in the editing file |
257+
| `@web` (beta) | Search on Bing or query from a web page |
258+
| `@project` | Experimental. Access content of the project |
261259
262-
To use plugins, you can prefix a message with `/pluginName`.
260+
To use scopes, you can prefix a message with `@code`.
261+
262+
You can use shorthand to represent a scope, such as `@c`, and enable multiple scopes with `@c+web`.
263263
"""
264264
)
265265
.modifier(InstructionModifier())
@@ -537,7 +537,7 @@ struct ChatPanelInputArea: View {
537537
let availableFeatures = plugins + [
538538
"/exit",
539539
"@code",
540-
"@file",
540+
"@project",
541541
"@web",
542542
]
543543

Core/Sources/ChatService/AllContextCollector.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import WebChatContextCollector
66
import ProChatContextCollectors
77
let allContextCollectors: [any ChatContextCollector] = [
88
SystemInfoChatContextCollector(),
9-
ActiveDocumentChatContextCollector(),
109
WebChatContextCollector(),
1110
ProChatContextCollectors(),
1211
]

Core/Sources/ChatService/DynamicContextController.swift

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,42 @@ final class DynamicContextController {
4646
functionProvider.removeAll()
4747
let language = UserDefaults.shared.value(for: \.chatGPTLanguage)
4848
let oldMessages = await memory.history
49-
let contexts = contextCollectors.compactMap {
50-
$0.generateContext(
51-
history: oldMessages,
52-
scopes: scopes,
53-
content: content,
54-
configuration: configuration
55-
)
49+
let contexts = await withTaskGroup(
50+
of: ChatContext.self
51+
) { [scopes, content, configuration] group in
52+
for collector in contextCollectors {
53+
group.addTask {
54+
await collector.generateContext(
55+
history: oldMessages,
56+
scopes: scopes,
57+
content: content,
58+
configuration: configuration
59+
)
60+
}
61+
}
62+
var contexts = [ChatContext]()
63+
for await context in group {
64+
contexts.append(context)
65+
}
66+
return contexts
5667
}
68+
69+
let extraSystemPrompt = contexts
70+
.map(\.systemPrompt)
71+
.filter { !$0.isEmpty }
72+
.joined(separator: "\n")
73+
74+
let contextPrompts = contexts
75+
.flatMap(\.retrievedContent)
76+
.filter { !$0.content.isEmpty }
77+
.sorted { $0.priority > $1.priority }
78+
5779
let contextualSystemPrompt = """
5880
\(language.isEmpty ? "" : "You must always reply in \(language)")
59-
\(systemPrompt)
60-
61-
\(contexts.map(\.systemPrompt).filter { !$0.isEmpty }.joined(separator: "\n\n"))
81+
\(systemPrompt)\(extraSystemPrompt.isEmpty ? "" : "\n\(extraSystemPrompt)")
6282
"""
6383
await memory.mutateSystemPrompt(contextualSystemPrompt)
84+
await memory.mutateRetrievedContent(contextPrompts.map(\.content))
6485
functionProvider.append(functions: contexts.flatMap(\.functions))
6586
}
6687
}

Pro

Submodule Pro updated from a8895f1 to 9e61bb2

Tool/Package.swift

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ let package = Package(
1515
.library(name: "Logger", targets: ["Logger"]),
1616
.library(name: "OpenAIService", targets: ["OpenAIService"]),
1717
.library(name: "ChatTab", targets: ["ChatTab"]),
18-
.library(name: "ChatContextCollector", targets: ["ChatContextCollector"]),
18+
.library(
19+
name: "ChatContextCollector",
20+
targets: ["ChatContextCollector", "ActiveDocumentChatContextCollector"]
21+
),
1922
.library(name: "Environment", targets: ["Environment"]),
2023
.library(name: "SuggestionModel", targets: ["SuggestionModel"]),
2124
.library(name: "ASTParser", targets: ["ASTParser"]),
@@ -70,7 +73,7 @@ let package = Package(
7073
// MARK: - Helpers
7174

7275
.target(name: "XPCShared", dependencies: ["SuggestionModel"]),
73-
76+
7477
.target(name: "Configs"),
7578

7679
.target(name: "Preferences", dependencies: ["Configs", "AIModel"]),
@@ -234,14 +237,6 @@ let package = Package(
234237
]
235238
),
236239

237-
.target(
238-
name: "ChatContextCollector",
239-
dependencies: [
240-
"SuggestionModel",
241-
"OpenAIService",
242-
]
243-
),
244-
245240
.target(name: "BingSearchService"),
246241

247242
.target(name: "SuggestionService", dependencies: [
@@ -310,6 +305,33 @@ let package = Package(
310305
)]
311306
),
312307

308+
// MARK: - Chat Context Collector
309+
310+
.target(
311+
name: "ChatContextCollector",
312+
dependencies: [
313+
"SuggestionModel",
314+
"OpenAIService",
315+
]
316+
),
317+
318+
.target(
319+
name: "ActiveDocumentChatContextCollector",
320+
dependencies: [
321+
"ChatContextCollector",
322+
"OpenAIService",
323+
"Preferences",
324+
"FocusedCodeFinder",
325+
"XcodeInspector",
326+
],
327+
path: "Sources/ChatContextCollectors/ActiveDocumentChatContextCollector"
328+
),
329+
330+
.testTarget(
331+
name: "ActiveDocumentChatContextCollectorTests",
332+
dependencies: ["ActiveDocumentChatContextCollector"]
333+
),
334+
313335
// MARK: - Tests
314336

315337
.testTarget(

Tool/Sources/ChatContextCollector/ChatContextCollector.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,32 @@ import Foundation
22
import OpenAIService
33

44
public struct ChatContext {
5+
public struct RetrievedContent {
6+
public var content: String
7+
public var priority: Int
8+
9+
public init(content: String, priority: Int) {
10+
self.content = content
11+
self.priority = priority
12+
}
13+
}
14+
515
public var systemPrompt: String
16+
public var retrievedContent: [RetrievedContent]
617
public var functions: [any ChatGPTFunction]
7-
public init(systemPrompt: String, functions: [any ChatGPTFunction]) {
18+
public init(
19+
systemPrompt: String,
20+
retrievedContent: [RetrievedContent],
21+
functions: [any ChatGPTFunction]
22+
) {
823
self.systemPrompt = systemPrompt
24+
self.retrievedContent = retrievedContent
925
self.functions = functions
1026
}
27+
28+
public static var empty: Self {
29+
.init(systemPrompt: "", retrievedContent: [], functions: [])
30+
}
1131
}
1232

1333
public protocol ChatContextCollector {
@@ -16,6 +36,6 @@ public protocol ChatContextCollector {
1636
scopes: Set<String>,
1737
content: String,
1838
configuration: ChatGPTConfiguration
19-
) -> ChatContext?
39+
) async -> ChatContext
2040
}
2141

Core/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/ActiveDocumentChatContextCollector.swift renamed to Tool/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/ActiveDocumentChatContextCollector.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import XcodeInspector
1010
public final class ActiveDocumentChatContextCollector: ChatContextCollector {
1111
public init() {}
1212

13-
var activeDocumentContext: ActiveDocumentContext?
13+
public var activeDocumentContext: ActiveDocumentContext?
1414

1515
public func generateContext(
1616
history: [ChatMessage],
1717
scopes: Set<String>,
1818
content: String,
1919
configuration: ChatGPTConfiguration
20-
) -> ChatContext? {
21-
guard let info = getEditorInformation() else { return nil }
20+
) -> ChatContext {
21+
guard let info = getEditorInformation() else { return .empty }
2222
let context = getActiveDocumentContext(info)
2323
activeDocumentContext = context
2424

@@ -28,10 +28,11 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
2828
removedCode.focusedContext = nil
2929
return .init(
3030
systemPrompt: extractSystemPrompt(removedCode),
31+
retrievedContent: [],
3132
functions: []
3233
)
3334
}
34-
return nil
35+
return .empty
3536
}
3637

3738
var functions = [any ChatGPTFunction]()
@@ -66,6 +67,7 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
6667

6768
return .init(
6869
systemPrompt: extractSystemPrompt(context),
70+
retrievedContent: [],
6971
functions: functions
7072
)
7173
}

0 commit comments

Comments
 (0)