Separate handling for OpenAI and DevChat API keys
- Renamed and split the API key settings in package.json into DevChat and OpenAI specific keys. - Updated the commands for setting API keys to handle OpenAI and DevChat keys separately. - Modified the ApiKeyManager to handle and validate OpenAI and DevChat keys separately. - Updated the status bar view to use the DevChat access key command. - Adjusted the tests to reflect the new handling of API keys.
This commit is contained in:
parent
c665bc881f
commit
e2e761fd16
18
package.json
18
package.json
@ -107,10 +107,15 @@
|
||||
"description": "The max number of tokens of a prompt.",
|
||||
"when": "DevChat.llmModel == 'OpenAI'"
|
||||
},
|
||||
"DevChat.API_KEY": {
|
||||
"DevChat.Access_Key_DevChat": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "API key for accessing the LLM model",
|
||||
"description": "DevChat's secret key for accessing multiple LLM models"
|
||||
},
|
||||
"DevChat.Api_Key_OpenAI": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "OpenAI's secret key for accessing LLM models. (Leave blank if using DevChat's key.)",
|
||||
"when": "DevChat.llmModel == 'OpenAI'"
|
||||
},
|
||||
"DevChat.API_ENDPOINT": {
|
||||
@ -205,8 +210,13 @@
|
||||
"title": "Create Entry"
|
||||
},
|
||||
{
|
||||
"command": "DevChat.OPENAI_API_KEY",
|
||||
"title": "Input Access Key",
|
||||
"command": "DevChat.Api_Key_OpenAI",
|
||||
"title": "Input OpenAI Api Key",
|
||||
"category": "DevChat"
|
||||
},
|
||||
{
|
||||
"command": "DevChat.Access_Key_DevChat",
|
||||
"title": "Input DevChat Access Key",
|
||||
"category": "DevChat"
|
||||
},
|
||||
{
|
||||
|
@ -64,21 +64,40 @@ function registerAskForFileCommand(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.commands.registerCommand('devchat.askForFile_chinese', callback));
|
||||
}
|
||||
|
||||
export function registerApiKeySettingCommand(context: vscode.ExtensionContext) {
|
||||
export function registerOpenAiApiKeySettingCommand(context: vscode.ExtensionContext) {
|
||||
const secretStorage: vscode.SecretStorage = context.secrets;
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('DevChat.OPENAI_API_KEY', async () => {
|
||||
vscode.commands.registerCommand('DevChat.Api_Key_OpenAI', async () => {
|
||||
const passwordInput: string = await vscode.window.showInputBox({
|
||||
password: true,
|
||||
title: "Input Access Key",
|
||||
placeHolder: "Set OPENAI_API_KEY (or DevChat Access Key)"
|
||||
title: "Input OpenAi Api Key",
|
||||
placeHolder: "Set OpenAI Api Key.(Leave blank if clearing stored key.)"
|
||||
}) ?? '';
|
||||
|
||||
if (passwordInput.trim() !== "" && !isValidApiKey(passwordInput)) {
|
||||
UiUtilWrapper.showErrorMessage("Your api key is invalid!");
|
||||
return ;
|
||||
}
|
||||
ApiKeyManager.writeApiKeySecret(passwordInput, "OpenAI");
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function registerDevChatApiKeySettingCommand(context: vscode.ExtensionContext) {
|
||||
const secretStorage: vscode.SecretStorage = context.secrets;
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('DevChat.Access_Key_DevChat', async () => {
|
||||
const passwordInput: string = await vscode.window.showInputBox({
|
||||
password: true,
|
||||
title: "Input DevChat Access Key",
|
||||
placeHolder: "Set DevChat Access Key.(Leave blank if clearing stored key.)"
|
||||
}) ?? '';
|
||||
|
||||
if (passwordInput.trim() !== "" && !isValidApiKey(passwordInput)) {
|
||||
UiUtilWrapper.showErrorMessage("Your access key is invalid!");
|
||||
return ;
|
||||
}
|
||||
ApiKeyManager.writeApiKeySecret(passwordInput);
|
||||
ApiKeyManager.writeApiKeySecret(passwordInput, "DevChat");
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ import {
|
||||
registerAddContextCommand,
|
||||
registerAskForCodeCommand,
|
||||
registerAskForFileCommand,
|
||||
registerApiKeySettingCommand,
|
||||
registerOpenAiApiKeySettingCommand,
|
||||
registerDevChatApiKeySettingCommand,
|
||||
regTopicDeleteCommand,
|
||||
regAddTopicCommand,
|
||||
regDeleteSelectTopicCommand,
|
||||
@ -37,7 +38,8 @@ function activate(context: vscode.ExtensionContext) {
|
||||
regDevChatView(context);
|
||||
regTopicView(context);
|
||||
|
||||
registerApiKeySettingCommand(context);
|
||||
registerOpenAiApiKeySettingCommand(context);
|
||||
registerDevChatApiKeySettingCommand(context);
|
||||
registerOpenChatPanelCommand(context);
|
||||
registerAddContextCommand(context);
|
||||
registerAskForCodeCommand(context);
|
||||
|
@ -45,9 +45,22 @@ OPENAI_API_KEY is missing from your environment or settings. Kindly input your O
|
||||
} as LogEntry;
|
||||
}
|
||||
|
||||
export function isValidApiKey(apiKey: string) {
|
||||
export function isValidApiKey(apiKey: string, llmType: string = "None") {
|
||||
let apiKeyStrim = apiKey.trim();
|
||||
if (ApiKeyManager.getKeyType(apiKeyStrim) === undefined) {
|
||||
const apiKeyType = ApiKeyManager.getKeyType(apiKeyStrim);
|
||||
if (apiKeyType === undefined) {
|
||||
return false;
|
||||
}
|
||||
if (llmType === "OpenAI") {
|
||||
if (apiKeyType === "sk") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (llmType === "DevChat") {
|
||||
if (apiKeyType === "DC") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -45,7 +45,7 @@ export function createStatusBarItem(context: vscode.ExtensionContext): vscode.St
|
||||
if (apiKeyStatus !== 'ready') {
|
||||
statusBarItem.text = `$(warning)DevChat`;
|
||||
statusBarItem.tooltip = `${apiKeyStatus}`;
|
||||
statusBarItem.command = 'DevChat.OPENAI_API_KEY';
|
||||
statusBarItem.command = 'DevChat.Access_Key_DevChat';
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,29 @@
|
||||
import { UiUtilWrapper } from './uiUtil';
|
||||
|
||||
export class ApiKeyManager {
|
||||
static async getApiKey(): Promise<string | undefined> {
|
||||
let apiKey = await UiUtilWrapper.secretStorageGet("devchat_OPENAI_API_KEY");
|
||||
if (!apiKey) {
|
||||
apiKey = UiUtilWrapper.getConfiguration('DevChat', 'API_KEY');
|
||||
static async getApiKey(llmType: string = "OpenAI"): Promise<string | undefined> {
|
||||
let apiKey: string|undefined = undefined;
|
||||
|
||||
if (llmType === "OpenAI") {
|
||||
apiKey = await UiUtilWrapper.secretStorageGet("openai_OPENAI_API_KEY");
|
||||
}
|
||||
if (!apiKey) {
|
||||
apiKey = await UiUtilWrapper.secretStorageGet("devchat_OPENAI_API_KEY");
|
||||
}
|
||||
|
||||
if (!apiKey) {
|
||||
if (llmType === "OpenAI") {
|
||||
apiKey = UiUtilWrapper.getConfiguration('DevChat', 'Api_Key_OpenAI');
|
||||
}
|
||||
if (!apiKey) {
|
||||
apiKey = UiUtilWrapper.getConfiguration('DevChat', 'Access_Key_DevChat');
|
||||
}
|
||||
}
|
||||
if (!apiKey) {
|
||||
if (llmType === "OpenAI") {
|
||||
apiKey = process.env.OPENAI_API_KEY;
|
||||
}
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@ -24,8 +39,18 @@ export class ApiKeyManager {
|
||||
}
|
||||
}
|
||||
|
||||
static async writeApiKeySecret(apiKey: string): Promise<void> {
|
||||
static async writeApiKeySecret(apiKey: string, llmType: string = "Unknow"): Promise<void> {
|
||||
if (apiKey.startsWith("sk-")) {
|
||||
await UiUtilWrapper.storeSecret("openai_OPENAI_API_KEY", apiKey);
|
||||
} else if (apiKey.startsWith("DC.")) {
|
||||
await UiUtilWrapper.storeSecret("devchat_OPENAI_API_KEY", apiKey);
|
||||
} else {
|
||||
if (llmType === "OpenAI") {
|
||||
await UiUtilWrapper.storeSecret("openai_OPENAI_API_KEY", apiKey);
|
||||
} else if (llmType === "DevChat") {
|
||||
await UiUtilWrapper.storeSecret("devchat_OPENAI_API_KEY", apiKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getEndPoint(apiKey: string | undefined): string | undefined {
|
||||
|
@ -129,7 +129,7 @@ describe('sendMessageBase', () => {
|
||||
|
||||
workspaceFoldersFirstPathStub.returns('./');
|
||||
|
||||
getConfigurationStub.withArgs('DevChat', 'API_KEY').returns(process.env.TEST_DEVCHAT_KEY);
|
||||
getConfigurationStub.withArgs('DevChat', 'Access_Key_DevChat').returns(process.env.TEST_DEVCHAT_KEY);
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.model').returns('gpt-4');
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||
@ -156,7 +156,7 @@ describe('sendMessageBase', () => {
|
||||
|
||||
workspaceFoldersFirstPathStub.returns('./');
|
||||
|
||||
getConfigurationStub.withArgs('DevChat', 'API_KEY').returns('sk-KvH7ZCtHmFDCBTqH0jUv');
|
||||
getConfigurationStub.withArgs('DevChat', 'Access_Key_DevChat').returns('sk-KvH7ZCtHmFDCBTqH0jUv');
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.model').returns('gpt-4');
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns('0');
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||
@ -185,7 +185,7 @@ describe('sendMessageBase', () => {
|
||||
|
||||
workspaceFoldersFirstPathStub.returns('./');
|
||||
|
||||
getConfigurationStub.withArgs('DevChat', 'API_KEY').returns(process.env.TEST_DEVCHAT_KEY);
|
||||
getConfigurationStub.withArgs('DevChat', 'Access_Key_DevChat').returns(process.env.TEST_DEVCHAT_KEY);
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.model').returns('gpt-4');
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||
|
@ -85,7 +85,7 @@ describe('ApiKeyManager', () => {
|
||||
const storeSecretStub = sinon.stub(UiUtilWrapper, 'storeSecret').resolves();
|
||||
|
||||
await ApiKeyManager.writeApiKeySecret('sk-secret');
|
||||
expect(storeSecretStub.calledWith('devchat_OPENAI_API_KEY', 'sk-secret')).to.be.true;
|
||||
expect(storeSecretStub.calledWith('openai_OPENAI_API_KEY', 'sk-secret')).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user