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.",
|
"description": "The max number of tokens of a prompt.",
|
||||||
"when": "DevChat.llmModel == 'OpenAI'"
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
},
|
},
|
||||||
"DevChat.API_KEY": {
|
"DevChat.Access_Key_DevChat": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"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'"
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
},
|
},
|
||||||
"DevChat.API_ENDPOINT": {
|
"DevChat.API_ENDPOINT": {
|
||||||
@ -205,8 +210,13 @@
|
|||||||
"title": "Create Entry"
|
"title": "Create Entry"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "DevChat.OPENAI_API_KEY",
|
"command": "DevChat.Api_Key_OpenAI",
|
||||||
"title": "Input Access Key",
|
"title": "Input OpenAI Api Key",
|
||||||
|
"category": "DevChat"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "DevChat.Access_Key_DevChat",
|
||||||
|
"title": "Input DevChat Access Key",
|
||||||
"category": "DevChat"
|
"category": "DevChat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -64,21 +64,40 @@ function registerAskForFileCommand(context: vscode.ExtensionContext) {
|
|||||||
context.subscriptions.push(vscode.commands.registerCommand('devchat.askForFile_chinese', callback));
|
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;
|
const secretStorage: vscode.SecretStorage = context.secrets;
|
||||||
context.subscriptions.push(
|
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({
|
const passwordInput: string = await vscode.window.showInputBox({
|
||||||
password: true,
|
password: true,
|
||||||
title: "Input Access Key",
|
title: "Input OpenAi Api Key",
|
||||||
placeHolder: "Set OPENAI_API_KEY (or DevChat Access 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)) {
|
if (passwordInput.trim() !== "" && !isValidApiKey(passwordInput)) {
|
||||||
UiUtilWrapper.showErrorMessage("Your access key is invalid!");
|
UiUtilWrapper.showErrorMessage("Your access key is invalid!");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
ApiKeyManager.writeApiKeySecret(passwordInput);
|
ApiKeyManager.writeApiKeySecret(passwordInput, "DevChat");
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ import {
|
|||||||
registerAddContextCommand,
|
registerAddContextCommand,
|
||||||
registerAskForCodeCommand,
|
registerAskForCodeCommand,
|
||||||
registerAskForFileCommand,
|
registerAskForFileCommand,
|
||||||
registerApiKeySettingCommand,
|
registerOpenAiApiKeySettingCommand,
|
||||||
|
registerDevChatApiKeySettingCommand,
|
||||||
regTopicDeleteCommand,
|
regTopicDeleteCommand,
|
||||||
regAddTopicCommand,
|
regAddTopicCommand,
|
||||||
regDeleteSelectTopicCommand,
|
regDeleteSelectTopicCommand,
|
||||||
@ -37,7 +38,8 @@ function activate(context: vscode.ExtensionContext) {
|
|||||||
regDevChatView(context);
|
regDevChatView(context);
|
||||||
regTopicView(context);
|
regTopicView(context);
|
||||||
|
|
||||||
registerApiKeySettingCommand(context);
|
registerOpenAiApiKeySettingCommand(context);
|
||||||
|
registerDevChatApiKeySettingCommand(context);
|
||||||
registerOpenChatPanelCommand(context);
|
registerOpenChatPanelCommand(context);
|
||||||
registerAddContextCommand(context);
|
registerAddContextCommand(context);
|
||||||
registerAskForCodeCommand(context);
|
registerAskForCodeCommand(context);
|
||||||
|
@ -45,9 +45,22 @@ OPENAI_API_KEY is missing from your environment or settings. Kindly input your O
|
|||||||
} as LogEntry;
|
} as LogEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidApiKey(apiKey: string) {
|
export function isValidApiKey(apiKey: string, llmType: string = "None") {
|
||||||
let apiKeyStrim = apiKey.trim();
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -45,7 +45,7 @@ export function createStatusBarItem(context: vscode.ExtensionContext): vscode.St
|
|||||||
if (apiKeyStatus !== 'ready') {
|
if (apiKeyStatus !== 'ready') {
|
||||||
statusBarItem.text = `$(warning)DevChat`;
|
statusBarItem.text = `$(warning)DevChat`;
|
||||||
statusBarItem.tooltip = `${apiKeyStatus}`;
|
statusBarItem.tooltip = `${apiKeyStatus}`;
|
||||||
statusBarItem.command = 'DevChat.OPENAI_API_KEY';
|
statusBarItem.command = 'DevChat.Access_Key_DevChat';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,28 @@
|
|||||||
import { UiUtilWrapper } from './uiUtil';
|
import { UiUtilWrapper } from './uiUtil';
|
||||||
|
|
||||||
export class ApiKeyManager {
|
export class ApiKeyManager {
|
||||||
static async getApiKey(): Promise<string | undefined> {
|
static async getApiKey(llmType: string = "OpenAI"): Promise<string | undefined> {
|
||||||
let apiKey = await UiUtilWrapper.secretStorageGet("devchat_OPENAI_API_KEY");
|
let apiKey: string|undefined = undefined;
|
||||||
|
|
||||||
|
if (llmType === "OpenAI") {
|
||||||
|
apiKey = await UiUtilWrapper.secretStorageGet("openai_OPENAI_API_KEY");
|
||||||
|
}
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
apiKey = UiUtilWrapper.getConfiguration('DevChat', 'API_KEY');
|
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 (!apiKey) {
|
||||||
apiKey = process.env.OPENAI_API_KEY;
|
if (llmType === "OpenAI") {
|
||||||
|
apiKey = process.env.OPENAI_API_KEY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return apiKey;
|
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> {
|
||||||
await UiUtilWrapper.storeSecret("devchat_OPENAI_API_KEY", apiKey);
|
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 {
|
static getEndPoint(apiKey: string | undefined): string | undefined {
|
||||||
|
@ -129,7 +129,7 @@ describe('sendMessageBase', () => {
|
|||||||
|
|
||||||
workspaceFoldersFirstPathStub.returns('./');
|
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.model').returns('gpt-4');
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||||
@ -156,7 +156,7 @@ describe('sendMessageBase', () => {
|
|||||||
|
|
||||||
workspaceFoldersFirstPathStub.returns('./');
|
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.model').returns('gpt-4');
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns('0');
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns('0');
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||||
@ -185,7 +185,7 @@ describe('sendMessageBase', () => {
|
|||||||
|
|
||||||
workspaceFoldersFirstPathStub.returns('./');
|
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.model').returns('gpt-4');
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.temperature').returns(0);
|
||||||
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
getConfigurationStub.withArgs('DevChat', 'OpenAI.stream').returns('true');
|
||||||
|
@ -85,7 +85,7 @@ describe('ApiKeyManager', () => {
|
|||||||
const storeSecretStub = sinon.stub(UiUtilWrapper, 'storeSecret').resolves();
|
const storeSecretStub = sinon.stub(UiUtilWrapper, 'storeSecret').resolves();
|
||||||
|
|
||||||
await ApiKeyManager.writeApiKeySecret('sk-secret');
|
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