mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
Supports calling LLM in a way compatible with OpenAI's API, and adds explicit configuration items for users。
This commit is contained in:
parent
8dde88222c
commit
2e5be73f0c
5 changed files with 78 additions and 5 deletions
8
extensions/void/package-lock.json
generated
8
extensions/void/package-lock.json
generated
|
|
@ -20,7 +20,7 @@
|
|||
"@types/node": "^22.5.1",
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/vscode": "1.92.0",
|
||||
"@types/vscode": "^1.92.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.3.0",
|
||||
"@typescript-eslint/parser": "^8.3.0",
|
||||
"@vscode/test-cli": "^0.0.10",
|
||||
|
|
@ -761,9 +761,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
"version": "1.92.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.92.0.tgz",
|
||||
"integrity": "sha512-DcZoCj17RXlzB4XJ7IfKdPTcTGDLYvTOcTNkvtjXWF+K2TlKzHHkBEXNWQRpBIXixNEUgx39cQeTFunY0E2msw==",
|
||||
"version": "1.94.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.94.0.tgz",
|
||||
"integrity": "sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
"anthropic",
|
||||
"azure",
|
||||
"greptile",
|
||||
"ollama"
|
||||
"ollama",
|
||||
"openaicompatible"
|
||||
]
|
||||
},
|
||||
"void.anthropic.apiKey": {
|
||||
|
|
@ -191,6 +192,21 @@
|
|||
"smollm:360m",
|
||||
"smollm:1.7b"
|
||||
]
|
||||
},
|
||||
"void.openaiCompatible.endpoint": {
|
||||
"type": "string",
|
||||
"default": "http://127.0.0.1:11434/v1",
|
||||
"description": "The openai compatible api provider's endpoint. default value is a example of the ollama openai-mode uri"
|
||||
},
|
||||
"void.openaiCompatible.model": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "Your provider's model name to use."
|
||||
},
|
||||
"void.openaiCompatible.apiKey": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "Your provider's API Key."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -272,6 +288,7 @@
|
|||
"@types/node": "^22.5.1",
|
||||
"@types/react": "^18.3.4",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/vscode": "^1.92.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.3.0",
|
||||
"@typescript-eslint/parser": "^8.3.0",
|
||||
"@vscode/test-cli": "^0.0.10",
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
|
|||
const ollamaEndpoint: string | undefined = vscode.workspace.getConfiguration('void').get('ollama.endpoint');
|
||||
if (ollamaEndpoint)
|
||||
allowed_urls.push(ollamaEndpoint);
|
||||
const openaiCompatibleEndpoint: string | undefined = vscode.workspace.getConfiguration('void').get('openaiCompatible.endpoint');
|
||||
if (openaiCompatibleEndpoint)
|
||||
allowed_urls.push(openaiCompatibleEndpoint);
|
||||
|
||||
const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'dist/sidebar/index.js'));
|
||||
const stylesUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'dist/sidebar/styles.css'));
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ export type ApiConfig = {
|
|||
endpoint: string,
|
||||
model: string
|
||||
},
|
||||
openaicompatible: {
|
||||
endpoint: string,
|
||||
model: string,
|
||||
apikey: string
|
||||
}
|
||||
whichApi: string
|
||||
}
|
||||
|
||||
|
|
@ -146,6 +151,47 @@ const sendOpenAIMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinal
|
|||
return { abort };
|
||||
};
|
||||
|
||||
// OpenAI Compatible
|
||||
const sendOpenAICompatibleMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
|
||||
|
||||
let didAbort = false
|
||||
let fullText = ''
|
||||
|
||||
// if abort is called, onFinalMessage is NOT called, and no later onTexts are called either
|
||||
let abort: () => void = () => {
|
||||
didAbort = true;
|
||||
};
|
||||
|
||||
const openai = new OpenAI({ apiKey: apiConfig.openaicompatible.apikey, baseURL: apiConfig.openaicompatible.endpoint, dangerouslyAllowBrowser: true });
|
||||
|
||||
openai.chat.completions.create({
|
||||
model: apiConfig.openaicompatible.model,
|
||||
messages: messages,
|
||||
stream: true,
|
||||
})
|
||||
.then(async response => {
|
||||
abort = () => {
|
||||
// response.controller.abort()
|
||||
didAbort = true;
|
||||
}
|
||||
// when receive text
|
||||
try {
|
||||
for await (const chunk of response) {
|
||||
if (didAbort) return;
|
||||
const newText = chunk.choices[0]?.delta?.content || '';
|
||||
fullText += newText;
|
||||
onText(newText, fullText);
|
||||
}
|
||||
onFinalMessage(fullText);
|
||||
}
|
||||
// when error/fail
|
||||
catch (error) {
|
||||
console.error('Error in OpenAI stream:', error);
|
||||
onFinalMessage(fullText);
|
||||
}
|
||||
})
|
||||
return { abort };
|
||||
};
|
||||
|
||||
|
||||
// Ollama
|
||||
|
|
@ -277,6 +323,8 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText,
|
|||
return sendGreptileMsg({ messages, onText, onFinalMessage, apiConfig });
|
||||
case 'ollama':
|
||||
return sendOllamaMsg({ messages, onText, onFinalMessage, apiConfig });
|
||||
case 'openaicompatible':
|
||||
return sendOpenAICompatibleMsg({ messages, onText, onFinalMessage, apiConfig });
|
||||
default:
|
||||
console.error(`Error: whichApi was ${apiConfig.whichApi}, which is not recognized!`);
|
||||
return { abort: () => { } }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ const getApiConfig = () => {
|
|||
endpoint: vscode.workspace.getConfiguration('void.ollama').get('endpoint') ?? '',
|
||||
model: vscode.workspace.getConfiguration('void.ollama').get('model') ?? '',
|
||||
},
|
||||
openaicompatible: {
|
||||
endpoint: vscode.workspace.getConfiguration('void.openaiCompatible').get('endpoint') ?? '',
|
||||
apikey: vscode.workspace.getConfiguration('void.openaiCompatible').get('apiKey') ?? '',
|
||||
model: vscode.workspace.getConfiguration('void.openaiCompatible').get('model') ?? '',
|
||||
},
|
||||
whichApi: vscode.workspace.getConfiguration('void').get('whichApi') ?? ''
|
||||
}
|
||||
return apiConfig
|
||||
|
|
|
|||
Loading…
Reference in a new issue