Skip to content

Commit b654bed

Browse files
committed
Merge branch 'feature/improve-active-document-context-collector-function-calling' into develop
2 parents 7a9b65c + fbc2144 commit b654bed

6 files changed

Lines changed: 104 additions & 217 deletions

File tree

Tool/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/ActiveDocumentChatContextCollector.swift

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,7 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
4545
var functions = [any ChatGPTFunction]()
4646

4747
if !isSensitive {
48-
// When the bot is already focusing on a piece of code, it can expand the range.
49-
50-
if context.focusedContext != nil {
51-
functions.append(ExpandFocusRangeFunction(contextCollector: self))
52-
}
53-
54-
// When the bot is not focusing on any code, or the focusing area is not the user's
55-
// selection, it can move the focus back to the user's selection.
56-
57-
if context.focusedContext == nil ||
58-
!(context.focusedContext?.codeRange.contains(context.selectionRange) ?? false)
59-
{
60-
functions.append(MoveToFocusedCodeFunction(contextCollector: self))
61-
}
62-
63-
// When there is a line annotation not in the focused area, the bot can move the focus
64-
// area
65-
// to the code covering the line of the annotation.
66-
67-
if let focusedContext = context.focusedContext,
68-
!focusedContext.otherLineAnnotations.isEmpty
69-
{
70-
functions.append(MoveToCodeAroundLineFunction(contextCollector: self))
71-
}
72-
73-
if context.focusedContext == nil, !context.lineAnnotations.isEmpty {
74-
functions.append(MoveToCodeAroundLineFunction(contextCollector: self))
75-
}
48+
functions.append(GetCodeCodeAroundLineFunction(contextCollector: self))
7649
}
7750

7851
return .init(
@@ -104,7 +77,8 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
10477
let start = """
10578
## File and Code Scope
10679
107-
You can use the following context to answer my questions about the editing document or code. The context shows only a part of the code in the editing document, and will change during the conversation, so it may not match our conversation.
80+
You can use the following context to answer my questions about the editing document.\
81+
The context shows only a part of the code in the editing document.
10882
10983
\(
11084
context.focusedContext == nil
@@ -135,7 +109,9 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
135109
Ask the user to select the code in the editor to get help. Also tell them the file is in gitignore.
136110
"""
137111
: """
138-
Focused Code (start from line \(focusedContext.codeRange.start.line + 1)):
112+
Focused Code (from line \(
113+
focusedContext.codeRange.start.line + 1
114+
) to line \(focusedContext.codeRange.end.line + 1)):
139115
```\(context.language.rawValue)
140116
\(focusedContext.code)
141117
```
@@ -144,8 +120,8 @@ public final class ActiveDocumentChatContextCollector: ChatContextCollector {
144120
let fileAnnotations = focusedContext.otherLineAnnotations.isEmpty || isSensitive
145121
? ""
146122
: """
147-
Other Annotations:\"""
148-
(They are not inside the focused code. You don't known how to handle them until you get the code at the line)
123+
Out-of-scope Annotations:\"""
124+
(They are not inside the focused code. You can get the code at the line for details)
149125
\(
150126
focusedContext.otherLineAnnotations
151127
.map(convertAnnotationToText)

Tool/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/Functions/ExpandFocusRangeFunction.swift

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import ASTParser
2+
import Foundation
3+
import OpenAIService
4+
import SuggestionModel
5+
6+
struct GetCodeCodeAroundLineFunction: ChatGPTFunction {
7+
struct Arguments: Codable {
8+
var line: Int
9+
}
10+
11+
struct Result: ChatGPTFunctionResult {
12+
var range: CursorRange
13+
var content: String
14+
var language: CodeLanguage
15+
16+
var botReadableContent: String {
17+
"""
18+
Code in range \(range)
19+
```\(language.rawValue)
20+
\(content)
21+
```
22+
"""
23+
}
24+
}
25+
26+
struct E: Error, LocalizedError {
27+
var errorDescription: String?
28+
}
29+
30+
var name: String {
31+
"getCodeAtLine"
32+
}
33+
34+
var description: String {
35+
"Get the code at the given line. You must ONLY call it when the user give you a specific line or the user ask about an out of scope annotation."
36+
}
37+
38+
var argumentSchema: JSONSchemaValue { [
39+
.type: "object",
40+
.properties: [
41+
"line": [
42+
.type: "number",
43+
.description: "The line number in the file",
44+
],
45+
],
46+
.required: ["line"],
47+
] }
48+
49+
weak var contextCollector: ActiveDocumentChatContextCollector?
50+
51+
init(contextCollector: ActiveDocumentChatContextCollector) {
52+
self.contextCollector = contextCollector
53+
}
54+
55+
func prepare(reportProgress: @escaping (String) async -> Void) async {
56+
await reportProgress("Finding code around..")
57+
}
58+
59+
func call(
60+
arguments: Arguments,
61+
reportProgress: @escaping (String) async -> Void
62+
) async throws -> Result {
63+
guard var activeDocumentContext = contextCollector?.activeDocumentContext else {
64+
throw E(errorDescription: "No active document found.")
65+
}
66+
await reportProgress("Reading code around line \(arguments.line)..")
67+
activeDocumentContext.moveToCodeAroundLine(max(arguments.line - 1, 0))
68+
guard let newContext = activeDocumentContext.focusedContext else {
69+
let progress = "Failed to read code around line \(arguments.line)..)"
70+
await reportProgress(progress)
71+
throw E(errorDescription: progress)
72+
}
73+
let progress = "Finish reading code at \(newContext.codeRange)"
74+
await reportProgress(progress)
75+
return .init(
76+
range: newContext.codeRange,
77+
content: newContext.code
78+
.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)
79+
.enumerated()
80+
.map {
81+
let (index, content) = $0
82+
if index + newContext.codeRange.start.line == arguments.line - 1 {
83+
return content + " // <--- line \(arguments.line)"
84+
} else {
85+
return content
86+
}
87+
}
88+
.joined(separator: "\n"),
89+
language: activeDocumentContext.language
90+
)
91+
}
92+
}
93+

Tool/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/Functions/MoveToCodeAroundLineFunction.swift

Lines changed: 0 additions & 68 deletions
This file was deleted.

Tool/Sources/ChatContextCollectors/ActiveDocumentChatContextCollector/Functions/MoveToFocusedCodeFunction.swift

Lines changed: 0 additions & 55 deletions
This file was deleted.

Tool/Sources/XcodeInspector/SourceEditor.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,14 @@ public extension SourceEditor {
129129
}
130130

131131
static func breakLines(_ string: String) -> [String] {
132-
let lines = string.split(whereSeparator: \.isNewline, omittingEmptySubsequences: false)
132+
let lineEnding = string.first(where: \.isNewline) ?? "\n"
133+
let lines = string.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)
133134
var all = [String]()
134135
for (index, line) in lines.enumerated() {
135136
if index == lines.endIndex - 1 {
136137
all.append(String(line))
137138
} else {
138-
all.append(String(line) + "\n")
139+
all.append(String(line) + String(lineEnding))
139140
}
140141
}
141142
return all

0 commit comments

Comments
 (0)