11import { EmbeddingModelInfo } from "../config/schema.js" ;
22import { ProviderCredentials } from "./detector.js" ;
3- import { readFileSync , writeFileSync } from "fs" ;
4- import * as path from "path" ;
5- import * as os from "os" ;
63
74export interface EmbeddingResult {
85 embedding : number [ ] ;
@@ -38,69 +35,17 @@ export function createEmbeddingProvider(
3835 }
3936}
4037
41- const COPILOT_HEADERS = {
42- "User-Agent" : "GitHubCopilotChat/0.35.0" ,
43- "Editor-Version" : "vscode/1.107.0" ,
44- "Editor-Plugin-Version" : "copilot-chat/0.35.0" ,
45- "Copilot-Integration-Id" : "vscode-chat" ,
46- "Openai-Intent" : "conversation-edits" ,
47- } ;
48-
4938class GitHubCopilotEmbeddingProvider implements EmbeddingProviderInterface {
50- private accessToken : string ;
51- private tokenExpires : number ;
52-
5339 constructor (
5440 private credentials : ProviderCredentials ,
5541 private modelInfo : EmbeddingModelInfo
56- ) {
57- this . accessToken = credentials . accessToken || "" ;
58- this . tokenExpires = credentials . tokenExpires || 0 ;
59- }
60-
61- private async ensureValidToken ( ) : Promise < string > {
62- if ( this . accessToken && this . tokenExpires > Date . now ( ) ) {
63- return this . accessToken ;
64- }
42+ ) { }
6543
44+ private getToken ( ) : string {
6645 if ( ! this . credentials . refreshToken ) {
67- throw new Error ( "No refresh token available for GitHub Copilot" ) ;
68- }
69-
70- const response = await fetch ( "https://api.github.com/copilot_internal/v2/token" , {
71- headers : {
72- Accept : "application/json" ,
73- Authorization : `Bearer ${ this . credentials . refreshToken } ` ,
74- ...COPILOT_HEADERS ,
75- } ,
76- } ) ;
77-
78- if ( ! response . ok ) {
79- throw new Error ( `Token refresh failed: ${ response . status } ` ) ;
80- }
81-
82- const tokenData = await response . json ( ) as { token : string ; expires_at : number } ;
83- this . accessToken = tokenData . token ;
84- this . tokenExpires = tokenData . expires_at * 1000 - 5 * 60 * 1000 ;
85-
86- this . persistToken ( tokenData . token , this . tokenExpires ) ;
87-
88- return this . accessToken ;
89- }
90-
91- private persistToken ( token : string , expires : number ) : void {
92- try {
93- const authPath = path . join ( os . homedir ( ) , ".local" , "share" , "opencode" , "auth.json" ) ;
94- const authData = JSON . parse ( readFileSync ( authPath , "utf-8" ) ) ;
95-
96- if ( authData [ "github-copilot" ] ) {
97- authData [ "github-copilot" ] . access = token ;
98- authData [ "github-copilot" ] . expires = expires ;
99- writeFileSync ( authPath , JSON . stringify ( authData , null , 2 ) ) ;
100- }
101- } catch {
102- // Ignore token cache write errors
46+ throw new Error ( "No OAuth token available for GitHub" ) ;
10347 }
48+ return this . credentials . refreshToken ;
10449 }
10550
10651 async embed ( text : string ) : Promise < EmbeddingResult > {
@@ -112,17 +57,18 @@ class GitHubCopilotEmbeddingProvider implements EmbeddingProviderInterface {
11257 }
11358
11459 async embedBatch ( texts : string [ ] ) : Promise < EmbeddingBatchResult > {
115- const token = await this . ensureValidToken ( ) ;
60+ const token = this . getToken ( ) ;
11661
117- const response = await fetch ( `${ this . credentials . baseUrl } /embeddings` , {
62+ const response = await fetch ( `${ this . credentials . baseUrl } /inference/ embeddings` , {
11863 method : "POST" ,
11964 headers : {
12065 Authorization : `Bearer ${ token } ` ,
12166 "Content-Type" : "application/json" ,
122- ...COPILOT_HEADERS ,
67+ Accept : "application/vnd.github+json" ,
68+ "X-GitHub-Api-Version" : "2022-11-28" ,
12369 } ,
12470 body : JSON . stringify ( {
125- model : this . modelInfo . model ,
71+ model : `openai/ ${ this . modelInfo . model } ` ,
12672 input : texts ,
12773 } ) ,
12874 } ) ;
0 commit comments