import CopilotForXcodeKit import Foundation import SuggestionBasic import Workspace import SuggestionProvider public final class GitHubCopilotSuggestionService: SuggestionServiceType, NESSuggestionServiceType { public var configuration: SuggestionServiceConfiguration { .init( acceptsRelevantCodeSnippets: true, mixRelevantCodeSnippetsInSource: true, acceptsRelevantSnippetsFromOpenedFiles: false ) } let serviceLocator: ServiceLocatorType init(serviceLocator: ServiceLocatorType) { self.serviceLocator = serviceLocator } public func getSuggestions( _ request: CopilotForXcodeKit.SuggestionRequest, workspace: WorkspaceInfo ) async throws -> [CopilotForXcodeKit.CodeSuggestion] { guard let service = await serviceLocator.getService(from: workspace) else { return [] } return try await service.getCompletions( fileURL: request.fileURL, content: request.content, originalContent: request.originalContent, cursorPosition: .init( line: request.cursorPosition.line, character: request.cursorPosition.character ), tabSize: request.tabSize, indentSize: request.indentSize, usesTabsForIndentation: request.usesTabsForIndentation ).map(Self.convert) } public func getNESSuggestions( _ request: CopilotForXcodeKit.SuggestionRequest, workspace: WorkspaceInfo ) async throws -> [CopilotForXcodeKit.CodeSuggestion] { guard let service = await serviceLocator.getService(from: workspace) else { return [] } return try await service .getCopilotInlineEdit( fileURL: request.fileURL, content: request.content, cursorPosition: .init(line: request.cursorPosition.line, character: request.cursorPosition.character) ) .map(Self.convert) } public func notifyAccepted( _ suggestion: CopilotForXcodeKit.CodeSuggestion, workspace: WorkspaceInfo ) async { guard let service = await serviceLocator.getService(from: workspace) else { return } await service.notifyAccepted(Self.convert(suggestion)) } public func notifyRejected( _ suggestions: [CopilotForXcodeKit.CodeSuggestion], workspace: WorkspaceInfo ) async { guard let service = await serviceLocator.getService(from: workspace) else { return } await service.notifyRejected(suggestions.map(Self.convert)) } public func cancelRequest(workspace: WorkspaceInfo) async { guard let service = await serviceLocator.getService(from: workspace) else { return } await service.cancelRequest() } static func convert( _ suggestion: SuggestionBasic.CodeSuggestion ) -> CopilotForXcodeKit.CodeSuggestion { .init( id: suggestion.id, text: suggestion.text, position: .init( line: suggestion.position.line, character: suggestion.position.character ), range: .init( start: .init( line: suggestion.range.start.line, character: suggestion.range.start.character ), end: .init( line: suggestion.range.end.line, character: suggestion.range.end.character ) ) ) } static func convert( _ suggestion: CopilotForXcodeKit.CodeSuggestion ) -> SuggestionBasic.CodeSuggestion { .init( id: suggestion.id, text: suggestion.text, position: .init( line: suggestion.position.line, character: suggestion.position.character ), range: .init( start: .init( line: suggestion.range.start.line, character: suggestion.range.start.character ), end: .init( line: suggestion.range.end.line, character: suggestion.range.end.character ) ) ) } }