@@ -5,79 +5,29 @@ import OpenAIService
55
66public final class ChatService : ObservableObject {
77 public let chatGPTService : any ChatGPTServiceType
8- let plugins = registerPlugins (
9- TerminalChatPlugin . self,
10- AITerminalChatPlugin . self
11- )
8+ let pluginController : ChatPluginController
129 var runningPlugin : ChatPlugin ?
1310 var cancellable = Set < AnyCancellable > ( )
1411
1512 public init < T: ChatGPTServiceType > ( chatGPTService: T ) {
1613 self . chatGPTService = chatGPTService
14+ pluginController = ChatPluginController (
15+ chatGPTService: chatGPTService,
16+ plugins:
17+ TerminalChatPlugin . self,
18+ AITerminalChatPlugin . self
19+ )
1720
1821 chatGPTService. objectWillChange. sink { [ weak self] _ in
1922 self ? . objectWillChange. send ( )
2023 } . store ( in: & cancellable)
2124 }
2225
2326 public func send( content: String ) async throws {
24- // look for the prefix of content, see if there is something like /command.
25- // If there is, then we need to find the plugin that can handle this command.
26- // If there is no such plugin, then we just send the message to the GPT service.
27- let regex = try NSRegularExpression ( pattern: #"^\/([a-zA-Z0-9]+)"# )
28- let matches = regex. matches ( in: content, range: NSRange ( content. startIndex... , in: content) )
29- if let match = matches. first {
30- let command = String ( content [ Range ( match. range ( at: 1 ) , in: content) !] )
31- if command == " exit " {
32- if let plugin = runningPlugin {
33- runningPlugin = nil
34- _ = await chatGPTService. mutateHistory { history in
35- history. append ( . init(
36- role: . user,
37- content: " " ,
38- summary: " Exit plugin \( plugin. name) . "
39- ) )
40- history. append ( . init(
41- role: . system,
42- content: " " ,
43- summary: " Exited plugin \( plugin. name) . "
44- ) )
45- }
46- } else {
47- _ = await chatGPTService. mutateHistory { history in
48- history. append ( . init(
49- role: . system,
50- content: " " ,
51- summary: " No plugin running. "
52- ) )
53- }
54- }
55- } else if let runningPlugin {
56- await runningPlugin. send ( content: content, originalMessage: content)
57- } else if let pluginType = plugins [ command] {
58- let plugin = pluginType. init ( inside: chatGPTService, delegate: self )
59- if #available( macOS 13 . 0 , * ) {
60- await plugin. send (
61- content: String (
62- content. dropFirst ( command. count + 1 )
63- . trimmingPrefix ( while: { $0 == " " } )
64- ) ,
65- originalMessage: content
66- )
67- } else {
68- await plugin. send (
69- content: String ( content. dropFirst ( command. count + 1 ) ) ,
70- originalMessage: content
71- )
72- }
73- } else {
74- _ = try await chatGPTService. send ( content: content, summary: nil )
75- }
76- } else if let runningPlugin {
77- await runningPlugin. send ( content: content, originalMessage: content)
78- } else {
79- _ = try await chatGPTService. send ( content: content, summary: nil )
80- }
27+ let handledInPlugin = try await pluginController. handleContent ( content)
28+ if handledInPlugin { return }
29+
30+ _ = try await chatGPTService. send ( content: content, summary: nil )
8131 }
8232
8333 public func stopReceivingMessage( ) async {
@@ -110,42 +60,3 @@ public final class ChatService: ObservableObject {
11060 await chatGPTService. mutateSystemPrompt ( newPrompt)
11161 }
11262}
113-
114- extension ChatService : ChatPluginDelegate {
115- public func pluginDidStartResponding( _: ChatPlugins . ChatPlugin ) {
116- Task {
117- await chatGPTService. markReceivingMessage ( true )
118- }
119- }
120-
121- public func pluginDidEndResponding( _: ChatPlugins . ChatPlugin ) {
122- Task {
123- await chatGPTService. markReceivingMessage ( false )
124- }
125- }
126-
127- public func pluginDidStart( _ plugin: ChatPlugin ) {
128- runningPlugin = plugin
129- }
130-
131- public func pluginDidEnd( _ plugin: ChatPlugin ) {
132- if runningPlugin === plugin {
133- runningPlugin = nil
134- }
135- }
136-
137- public func shouldStartAnotherPlugin( _ type: ChatPlugin . Type , withContent content: String ) {
138- let plugin = type. init ( inside: chatGPTService, delegate: self )
139- Task {
140- await plugin. send ( content: content, originalMessage: content)
141- }
142- }
143- }
144-
145- func registerPlugins( _ plugins: ChatPlugin . Type ... ) -> [ String : ChatPlugin . Type ] {
146- var all = [ String: ChatPlugin . Type] ( )
147- for plugin in plugins {
148- all [ plugin. command] = plugin
149- }
150- return all
151- }
0 commit comments