diff --git a/src/extension/byok/vscode-node/byokContribution.ts b/src/extension/byok/vscode-node/byokContribution.ts index b9358c42b..a8a12fc10 100644 --- a/src/extension/byok/vscode-node/byokContribution.ts +++ b/src/extension/byok/vscode-node/byokContribution.ts @@ -17,6 +17,7 @@ import { AnthropicLMProvider } from './anthropicProvider'; import { AzureBYOKModelProvider } from './azureProvider'; import { BYOKStorageService, IBYOKStorageService } from './byokStorageService'; import { GeminiBYOKLMProvider } from './geminiProvider'; +import { GitHubProvider } from './githubProvider'; import { GroqBYOKLMProvider } from './groqProvider'; import { OllamaLMProvider } from './ollamaProvider'; import { OAIBYOKLMProvider } from './openAIProvider'; @@ -64,6 +65,7 @@ export class BYOKContrib extends Disposable implements IExtensionContribution { this._providers.set(OAIBYOKLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OAIBYOKLMProvider, knownModels[OAIBYOKLMProvider.providerName], this._byokStorageService)); this._providers.set(OpenRouterLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OpenRouterLMProvider, this._byokStorageService)); this._providers.set(AzureBYOKModelProvider.providerName.toLowerCase(), instantiationService.createInstance(AzureBYOKModelProvider, this._byokStorageService)); + this._providers.set(GitHubProvider.providerName.toLowerCase(), instantiationService.createInstance(GitHubProvider, this._byokStorageService)); for (const [providerName, provider] of this._providers) { this._store.add(lm.registerChatModelProvider(providerName, provider)); diff --git a/src/extension/byok/vscode-node/githubProvider.ts b/src/extension/byok/vscode-node/githubProvider.ts new file mode 100644 index 000000000..21c047b70 --- /dev/null +++ b/src/extension/byok/vscode-node/githubProvider.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { authentication } from 'vscode'; +import { ILogService } from '../../../platform/log/common/logService'; +import { IFetcherService } from '../../../platform/networking/common/fetcherService'; +import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation'; +import { BYOKAuthType, BYOKKnownModels } from '../common/byokProvider'; +import { BaseOpenAICompatibleLMProvider } from './baseOpenAICompatibleProvider'; +import { IBYOKStorageService } from './byokStorageService'; + +export class GitHubProvider extends BaseOpenAICompatibleLMProvider { + public static readonly providerName = 'GitHub'; + constructor( + byokStorageService: IBYOKStorageService, + @IFetcherService _fetcherService: IFetcherService, + @ILogService _logService: ILogService, + @IInstantiationService _instantiationService: IInstantiationService, + ) { + super( + BYOKAuthType.None, + GitHubProvider.providerName, + 'https://models.github.ai/inference', + undefined, + byokStorageService, + _fetcherService, + _logService, + _instantiationService + ); + } + + protected override async getAllModels(): Promise { + try { + const response = await this._fetcherService.fetch('https://models.github.ai/catalog/models', { method: 'GET' }); + const models: any = await response.json(); + const knownModels: BYOKKnownModels = {}; + for (const model of models) { + knownModels[model.id] = { + name: model.name, + toolCalling: model.capabilities?.includes('tool-calling') ?? false, + vision: model.supported_input_modalities?.includes('image') ?? false, + maxInputTokens: model.limits?.max_input_tokens ?? 4096, + maxOutputTokens: model.limits?.max_output_tokens ?? 4096 + }; + } + this._knownModels = knownModels; + return knownModels; + } catch (error) { + this._logService.error('Error fetching available GitHub models:', error); + throw error; + } + } + /** + * Gets the GitHub access token using VS Code's authentication API + * @returns Promise GitHub access token if available + */ + async getGitHubToken(): Promise { + const session = await authentication.getSession( + 'github', + ['repo', 'user:email'], + { createIfNone: true } + ); + return session?.accessToken; + } +} \ No newline at end of file