Skip to content

Commit 7485ff2

Browse files
committed
Merge tag '0.30.0' into develop
2 parents 1aa0803 + 381005f commit 7485ff2

7 files changed

Lines changed: 277 additions & 9 deletions

File tree

ExtensionService/AppDelegate+Menu.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,22 @@ extension AppDelegate: NSMenuDelegate {
126126
.append(.text("Active Workspace: \(inspector.activeWorkspaceURL?.path ?? "N/A")"))
127127
menu.items
128128
.append(.text("Active Document: \(inspector.activeDocumentURL?.path ?? "N/A")"))
129+
130+
if let focusedWindow = inspector.focusedWindow {
131+
menu.items.append(.text(
132+
"Active Window: \(focusedWindow.uiElement.identifier)"
133+
))
134+
} else {
135+
menu.items.append(.text("Active Window: N/A"))
136+
}
137+
138+
if let focusedElement = inspector.focusedElement {
139+
menu.items.append(.text(
140+
"Focused Element: \(focusedElement.description)"
141+
))
142+
} else {
143+
menu.items.append(.text("Focused Element: N/A"))
144+
}
129145

130146
if let sourceEditor = inspector.focusedEditor {
131147
menu.items.append(.text(

Tool/Sources/OpenAIService/Memory/AutoManagedChatGPTMemory.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,6 @@ extension AutoManagedChatGPTMemory {
286286
text += """
287287
Here are the information you know about the system and the project, \
288288
separated by \(separator)
289-
290-
291289
"""
292290
}
293291

@@ -302,7 +300,7 @@ extension AutoManagedChatGPTMemory {
302300
{
303301
var right = retrievedContent.count
304302
var left = 0
305-
var retrievedContent = retrievedContent
303+
var gappedRetrievedContent = retrievedContent
306304
var tokenCount: Int?
307305
var proposedMessage = buildMessage(retrievedContent: [])
308306

@@ -340,7 +338,7 @@ extension AutoManagedChatGPTMemory {
340338
let (isValid, _tokenCount) = await checkValid(proposedMessage: _proposedMessage)
341339
if isValid {
342340
proposedMessage = _proposedMessage
343-
retrievedContent = _retrievedContent
341+
gappedRetrievedContent = _retrievedContent
344342
tokenCount = _tokenCount
345343
left = count + 1
346344
} else {
@@ -355,7 +353,7 @@ extension AutoManagedChatGPTMemory {
355353
} else {
356354
await strategy.countToken(proposedMessage)
357355
}
358-
return (proposedMessage, retrievedContent, finalCount)
356+
return (proposedMessage, gappedRetrievedContent, finalCount)
359357
}
360358

361359
let (message, references, tokensCount) = await buildMessageThatFits()

Tool/Sources/XcodeInspector/XcodeWindowInspector.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Combine
55
import Foundation
66

77
public class XcodeWindowInspector: ObservableObject {
8-
let uiElement: AXUIElement
8+
public let uiElement: AXUIElement
99

1010
init(uiElement: AXUIElement) {
1111
self.uiElement = uiElement
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
import Foundation
2+
import XCTest
3+
4+
@testable import OpenAIService
5+
6+
class AutoManagedChatGPTMemoryRetrievedContentTests: XCTestCase {
7+
let separator = String(repeating: "=", count: 32)
8+
9+
func ref(_ text: String) -> ChatMessage.Reference {
10+
.init(
11+
title: "",
12+
subTitle: "",
13+
content: text,
14+
uri: "",
15+
startLine: nil,
16+
endLine: nil,
17+
kind: .text
18+
)
19+
}
20+
21+
func test_retrieved_content_when_the_context_window_is_large_enough() async {
22+
let strategy = Strategy()
23+
24+
let memory = AutoManagedChatGPTMemory(
25+
systemPrompt: "",
26+
configuration: UserPreferenceChatGPTConfiguration(),
27+
functionProvider: EmptyFunctionProvider()
28+
)
29+
30+
await memory.mutateRetrievedContent([
31+
ref("A"), ref("B"), ref("C"), ref("D"), ref("E"),
32+
])
33+
34+
let fullContent = """
35+
Here are the information you know about the system and the project, \
36+
separated by \(separator)
37+
38+
\(separator)[DOCUMENT 0]
39+
40+
A
41+
42+
\(separator)[DOCUMENT 1]
43+
44+
B
45+
46+
\(separator)[DOCUMENT 2]
47+
48+
C
49+
50+
\(separator)[DOCUMENT 3]
51+
52+
D
53+
54+
\(separator)[DOCUMENT 4]
55+
56+
E
57+
"""
58+
59+
let maxTokenCount = await strategy.countToken(.init(role: .user, content: fullContent))
60+
61+
let result = await memory.generateRetrievedContentMessage(
62+
maxTokenCount: maxTokenCount,
63+
strategy: strategy
64+
)
65+
66+
XCTAssertEqual(result.references.count, 5)
67+
XCTAssertEqual(result.retrievedContent.role, .user)
68+
XCTAssertEqual(result.retrievedContent.content, """
69+
Here are the information you know about the system and the project, \
70+
separated by \(separator)
71+
72+
\(separator)[DOCUMENT 0]
73+
74+
A
75+
76+
\(separator)[DOCUMENT 1]
77+
78+
B
79+
80+
\(separator)[DOCUMENT 2]
81+
82+
C
83+
84+
\(separator)[DOCUMENT 3]
85+
86+
D
87+
88+
\(separator)[DOCUMENT 4]
89+
90+
E
91+
""")
92+
}
93+
94+
func test_retrieved_content_when_the_context_window_is_just_not_large_enough() async {
95+
let strategy = Strategy()
96+
97+
let memory = AutoManagedChatGPTMemory(
98+
systemPrompt: "",
99+
configuration: UserPreferenceChatGPTConfiguration(),
100+
functionProvider: EmptyFunctionProvider()
101+
)
102+
103+
await memory.mutateRetrievedContent([
104+
ref("A"), ref("B"), ref("C"), ref("D"), ref("E"),
105+
])
106+
107+
let fullContent = """
108+
Here are the information you know about the system and the project, \
109+
separated by \(separator)
110+
111+
\(separator)[DOCUMENT 0]
112+
113+
A
114+
115+
\(separator)[DOCUMENT 1]
116+
117+
B
118+
119+
\(separator)[DOCUMENT 2]
120+
121+
C
122+
123+
\(separator)[DOCUMENT 3]
124+
125+
D
126+
127+
\(separator)[DOCUMENT 4]
128+
129+
E
130+
"""
131+
132+
let maxTokenCount = await strategy.countToken(.init(role: .user, content: fullContent))
133+
134+
let result = await memory.generateRetrievedContentMessage(
135+
maxTokenCount: maxTokenCount - 1,
136+
strategy: strategy
137+
)
138+
139+
XCTAssertEqual(result.references.count, 4)
140+
XCTAssertEqual(result.retrievedContent.role, .user)
141+
XCTAssertEqual(result.retrievedContent.content, """
142+
Here are the information you know about the system and the project, \
143+
separated by \(separator)
144+
145+
\(separator)[DOCUMENT 0]
146+
147+
A
148+
149+
\(separator)[DOCUMENT 1]
150+
151+
B
152+
153+
\(separator)[DOCUMENT 2]
154+
155+
C
156+
157+
\(separator)[DOCUMENT 3]
158+
159+
D
160+
""")
161+
}
162+
163+
func test_retrieved_content_when_the_context_window_can_take_only_one_document() async {
164+
let strategy = Strategy()
165+
166+
let memory = AutoManagedChatGPTMemory(
167+
systemPrompt: "",
168+
configuration: UserPreferenceChatGPTConfiguration(),
169+
functionProvider: EmptyFunctionProvider()
170+
)
171+
172+
await memory.mutateRetrievedContent([
173+
ref("A"), ref("B"), ref("C"), ref("D"), ref("E"),
174+
])
175+
176+
let fullContent = """
177+
Here are the information you know about the system and the project, \
178+
separated by \(separator)
179+
180+
\(separator)[DOCUMENT 0]
181+
182+
A
183+
"""
184+
185+
let maxTokenCount = await strategy.countToken(.init(role: .user, content: fullContent))
186+
187+
let result = await memory.generateRetrievedContentMessage(
188+
maxTokenCount: maxTokenCount + 1,
189+
strategy: strategy
190+
)
191+
192+
XCTAssertEqual(result.references.count, 1)
193+
XCTAssertEqual(result.retrievedContent.role, .user)
194+
XCTAssertEqual(result.retrievedContent.content, """
195+
Here are the information you know about the system and the project, \
196+
separated by \(separator)
197+
198+
\(separator)[DOCUMENT 0]
199+
200+
A
201+
""")
202+
}
203+
204+
func test_retrieved_content_when_the_context_window_empty() async {
205+
let strategy = Strategy()
206+
207+
let memory = AutoManagedChatGPTMemory(
208+
systemPrompt: "",
209+
configuration: UserPreferenceChatGPTConfiguration(),
210+
functionProvider: EmptyFunctionProvider()
211+
)
212+
213+
await memory.mutateRetrievedContent([
214+
ref("A"), ref("B"), ref("C"), ref("D"), ref("E"),
215+
])
216+
217+
let result = await memory.generateRetrievedContentMessage(
218+
maxTokenCount: 0,
219+
strategy: strategy
220+
)
221+
222+
XCTAssertEqual(result.references.count, 0)
223+
XCTAssertEqual(result.retrievedContent.role, .user)
224+
XCTAssertEqual(result.retrievedContent.content, "")
225+
}
226+
}
227+
228+
private struct EmptyFunctionProvider: ChatGPTFunctionProvider {
229+
var functions: [any ChatGPTFunction] { [] }
230+
var functionCallStrategy: FunctionCallStrategy? { nil }
231+
}
232+
233+
private struct Strategy: AutoManagedChatGPTMemoryStrategy {
234+
func countToken(_ message: OpenAIService.ChatMessage) async -> Int {
235+
message.content?.count ?? 0
236+
}
237+
238+
func countToken<F>(_: F) async -> Int where F: ChatGPTFunction {
239+
0
240+
}
241+
}
242+

Tool/Tests/OpenAIServiceTests/LimitMessagesTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import XCTest
44

55
@testable import OpenAIService
66

7-
final class AutoManagedChatGPTMemoryTests: XCTestCase {
7+
final class AutoManagedChatGPTMemoryLimitTests: XCTestCase {
88
func test_send_all_messages_if_not_reached_token_limit() async {
99
let (messages, memory) = await runService(
1010
systemPrompt: "system",

Version.xcconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
APP_VERSION = 0.29.1
2-
APP_BUILD = 301
1+
APP_VERSION = 0.30.0
2+
APP_BUILD = 311
33

appcast.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
<channel>
44
<title>Copilot for Xcode</title>
55

6+
<item>
7+
<title>0.30.0</title>
8+
<pubDate>Mon, 22 Jan 2024 16:01:13 +0800</pubDate>
9+
<sparkle:version>311</sparkle:version>
10+
<sparkle:shortVersionString>0.30.0</sparkle:shortVersionString>
11+
<sparkle:minimumSystemVersion>12.0</sparkle:minimumSystemVersion>
12+
<sparkle:releaseNotesLink>
13+
https://github.com/intitni/CopilotForXcode/releases/tag/0.30.0
14+
</sparkle:releaseNotesLink>
15+
<enclosure url="https://github.com/intitni/CopilotForXcode/releases/download/0.30.0/Copilot.for.Xcode.app.zip" length="37986282" type="application/octet-stream" sparkle:edSignature="m91DLVuZYl1x3HW3SJSexBAdXAn0XjcbDx6uyQwnmUN/NG0Z3GUoZ8UskcYC2jhRkj7/WfAcoQD4Wm8JUPIKCQ=="/>
16+
</item>
17+
618
<item>
719
<title>0.29.1</title>
820
<pubDate>Tue, 16 Jan 2024 01:12:50 +0800</pubDate>

0 commit comments

Comments
 (0)