forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChatTabFactory.swift
More file actions
110 lines (103 loc) · 3.86 KB
/
ChatTabFactory.swift
File metadata and controls
110 lines (103 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import BuiltinExtension
import ChatGPTChatTab
import ChatService
import ChatTab
import Foundation
import PromptToCodeService
import SuggestionBasic
import SuggestionWidget
import XcodeInspector
#if canImport(ProChatTabs)
import ProChatTabs
#endif
enum ChatTabFactory {
static func chatTabBuilderCollection() -> [ChatTabBuilderCollection] {
#if canImport(ProChatTabs)
_ = lazyLoadDependency
let collection = [
folderIfNeeded(ChatGPTChatTab.chatBuilders(), title: ChatGPTChatTab.name),
folderIfNeeded(BrowserChatTab.chatBuilders(), title: BrowserChatTab.name),
folderIfNeeded(TerminalChatTab.chatBuilders(), title: TerminalChatTab.name),
]
#else
let collection = [
folderIfNeeded(ChatGPTChatTab.chatBuilders(), title: ChatGPTChatTab.name),
]
#endif
return collection.compactMap { $0 } + chatTabsFromExtensions()
}
private static func folderIfNeeded(
_ builders: [any ChatTabBuilder],
title: String
) -> ChatTabBuilderCollection? {
if builders.count > 1 {
return .folder(title: title, kinds: builders.map(ChatTabKind.init))
}
if let first = builders.first { return .kind(ChatTabKind(first)) }
return nil
}
static func chatTabsFromExtensions() -> [ChatTabBuilderCollection] {
let extensions = BuiltinExtensionManager.shared.extensions
let chatTabTypes = extensions.flatMap(\.chatTabTypes)
return chatTabTypes.compactMap { folderIfNeeded($0.chatBuilders(), title: $0.name) }
}
}
#if canImport(ProChatTabs)
let lazyLoadDependency: () = {
BrowserChatTab.externalDependency = .init(
handleCustomCommand: { command, prompt in
switch command.feature {
case let .chatWithSelection(extraSystemPrompt, _, useExtraSystemPrompt):
let service = ChatService()
return try await service.processMessage(
systemPrompt: nil,
extraSystemPrompt: (useExtraSystemPrompt ?? false) ? extraSystemPrompt :
nil,
prompt: prompt
)
case let .customChat(systemPrompt, _):
let service = ChatService()
return try await service.processMessage(
systemPrompt: systemPrompt,
extraSystemPrompt: nil,
prompt: prompt
)
case let .singleRoundDialog(
systemPrompt,
overwriteSystemPrompt,
_,
_
):
let service = ChatService()
return try await service.handleSingleRoundDialogCommand(
systemPrompt: systemPrompt,
overwriteSystemPrompt: overwriteSystemPrompt ?? false,
prompt: prompt
)
case let .promptToCode(extraSystemPrompt, instruction, _, _):
let service = OpenAIPromptToCodeService()
let result = try await service.modifyCode(
code: prompt,
requirement: instruction ?? "Modify content.",
source: .init(
language: .plaintext,
documentURL: .init(fileURLWithPath: "/"),
projectRootURL: .init(fileURLWithPath: "/"),
content: prompt,
lines: prompt.breakLines(),
range: .outOfScope
),
isDetached: true,
extraSystemPrompt: extraSystemPrompt,
generateDescriptionRequirement: false
)
var code = ""
for try await (newCode, _) in result {
code = newCode
}
return code
}
}
)
}()
#endif