From 40d0fa502bde388cd27c45ae61557886642d332e Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Mon, 1 Apr 2024 17:15:44 +0800 Subject: [PATCH] feat: Enhance config management in VSCode plugin - Refactor to use a single instance of DevChatConfig for efficiency - Update regInMessage and regOutMessage functions for better flexibility - Implement new getters and setters in DevChatConfig to handle complex keys --- src/contributes/commandsBase.ts | 5 ++-- src/extension.ts | 43 +++++++++++++++++---------------- src/handler/configHandler.ts | 10 ++++---- src/util/apiKey.ts | 11 +++++---- src/util/config.ts | 22 ++++++++++++++--- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/contributes/commandsBase.ts b/src/contributes/commandsBase.ts index dada88d..56f0af4 100644 --- a/src/contributes/commandsBase.ts +++ b/src/contributes/commandsBase.ts @@ -43,14 +43,15 @@ function getDefaultPythonCommand(): string | undefined { export function getValidPythonCommand(): string | undefined { try { - const pythonCommand = new DevChatConfig().get('python_for_chat'); + const devchatConfig = new DevChatConfig(); + const pythonCommand = devchatConfig.get('python_for_chat'); if (pythonCommand) { return pythonCommand; } const defaultPythonCommand = getDefaultPythonCommand(); if (defaultPythonCommand) { - new DevChatConfig().set('python_for_chat', defaultPythonCommand); + devchatConfig.set('python_for_chat', defaultPythonCommand); } return defaultPythonCommand; diff --git a/src/extension.ts b/src/extension.ts index 903532d..852e2be 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -35,8 +35,9 @@ import { DevChatConfig } from './util/config'; async function migrateConfig() { + const devchatConfig = new DevChatConfig(); const devchatProvider = "providers.devchat"; - const devchatProviderConfig: any = new DevChatConfig().get(devchatProvider); + const devchatProviderConfig: any = devchatConfig.get(devchatProvider); if (devchatProviderConfig) { return ; } @@ -44,19 +45,19 @@ async function migrateConfig() { const devchatVScodeProvider: any = vscode.workspace.getConfiguration("devchat").get("Provider.devchat"); if (devchatVScodeProvider && Object.keys(devchatVScodeProvider).length > 0) { if (devchatVScodeProvider["access_key"]) { - new DevChatConfig().set("providers.devchat.api_key", devchatVScodeProvider["access_key"]); + devchatConfig.set("providers.devchat.api_key", devchatVScodeProvider["access_key"]); } if (devchatVScodeProvider["api_base"]) { - new DevChatConfig().set("providers.devchat.api_base", devchatVScodeProvider["api_base"]); + devchatConfig.set("providers.devchat.api_base", devchatVScodeProvider["api_base"]); } } const openaiVScodeProvider: any = vscode.workspace.getConfiguration("devchat").get("Provider.openai"); if (openaiVScodeProvider && Object.keys(openaiVScodeProvider).length > 0) { if (openaiVScodeProvider["access_key"]) { - new DevChatConfig().set("providers.openai.api_key", openaiVScodeProvider["access_key"]); + devchatConfig.set("providers.openai.api_key", openaiVScodeProvider["access_key"]); } if (openaiVScodeProvider["api_base"]) { - new DevChatConfig().set("providers.openai.api_base", openaiVScodeProvider["api_base"]); + devchatConfig.set("providers.openai.api_base", openaiVScodeProvider["api_base"]); } } @@ -64,59 +65,59 @@ async function migrateConfig() { const openaiSecretKey = await UiUtilWrapper.secretStorageGet(`Access_KEY_OpenAI`); if (devchatSecretKey) { - new DevChatConfig().set("providers.devchat.api_key", devchatSecretKey); + devchatConfig.set("providers.devchat.api_key", devchatSecretKey); } if (openaiSecretKey) { - new DevChatConfig().set("providers.openai.api_key", openaiSecretKey); + devchatConfig.set("providers.openai.api_key", openaiSecretKey); } const enableFunctionCalling = vscode.workspace.getConfiguration("DevChat").get("EnableFunctionCalling"); if (enableFunctionCalling) { - new DevChatConfig().set("enable_function_calling", enableFunctionCalling); + devchatConfig.set("enable_function_calling", enableFunctionCalling); } else { - new DevChatConfig().set("enable_function_calling", false); + devchatConfig.set("enable_function_calling", false); } const betaInvitationCode = vscode.workspace.getConfiguration("DevChat").get("betaInvitationCode"); if (betaInvitationCode) { - new DevChatConfig().set("beta_invitation_code", betaInvitationCode); + devchatConfig.set("beta_invitation_code", betaInvitationCode); } else { - new DevChatConfig().set("beta_invitation_code", ""); + devchatConfig.set("beta_invitation_code", ""); } const maxLogCount = vscode.workspace.getConfiguration("DevChat").get("maxLogCount"); if (maxLogCount) { - new DevChatConfig().set("max_log_count", maxLogCount); + devchatConfig.set("max_log_count", maxLogCount); } else { - new DevChatConfig().set("max_log_count", 20); + devchatConfig.set("max_log_count", 20); } const pythonForChat = vscode.workspace.getConfiguration("DevChat").get("PythonForChat"); if (pythonForChat) { - new DevChatConfig().set("python_for_chat", pythonForChat); + devchatConfig.set("python_for_chat", pythonForChat); } else { - new DevChatConfig().set("python_for_chat", ""); + devchatConfig.set("python_for_chat", ""); } const pythonForCommands = vscode.workspace.getConfiguration("DevChat").get("PythonForCommands"); if (pythonForCommands) { - new DevChatConfig().set("python_for_commands", pythonForCommands); + devchatConfig.set("python_for_commands", pythonForCommands); } else { - new DevChatConfig().set("python_for_commands", ""); + devchatConfig.set("python_for_commands", ""); } const language = vscode.workspace.getConfiguration("DevChat").get("Language"); if (language) { - new DevChatConfig().set("language", language); + devchatConfig.set("language", language); } else { - new DevChatConfig().set("language", "en"); + devchatConfig.set("language", "en"); } const defaultModel = vscode.workspace.getConfiguration("devchat").get("defaultModel"); if (defaultModel) { - new DevChatConfig().set("default_model", defaultModel); + devchatConfig.set("default_model", defaultModel); } else { - new DevChatConfig().set("default_model", ""); + devchatConfig.set("default_model", ""); } } diff --git a/src/handler/configHandler.ts b/src/handler/configHandler.ts index de806ad..08dbf85 100644 --- a/src/handler/configHandler.ts +++ b/src/handler/configHandler.ts @@ -7,10 +7,10 @@ import { regInMessage, regOutMessage } from '../util/reg_messages'; import { MessageHandler } from './messageHandler'; import { DevChatConfig } from '../util/config'; -regInMessage({command: 'readConfig', key: ''}); // when key is "", it will get all config values -regOutMessage({command: 'readConfig', key: '', value: 'any'}); +regInMessage({command: 'readConfig', key: ['A','B']}); // when key is "", it will get all config values +regOutMessage({command: 'readConfig', key: ['A', 'B'], value: 'any'}); export async function readConfig(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise { - if (message.key === '*' || message.key === '') { + if (message.key.length === 0 || message.key[1] === '*') { const config = new DevChatConfig().getAll(); MessageHandler.sendMessage(panel, {command: 'readConfig', key: message.key, value: config}); } else { @@ -19,9 +19,9 @@ export async function readConfig(message: any, panel: vscode.WebviewPanel|vscode } } -regInMessage({command: 'writeConfig', key: '', value: 'any'}); // when key is "", it will rewrite all config values +regInMessage({command: 'writeConfig', key: ['A', 'B'], value: 'any'}); // when key is "", it will rewrite all config values export async function writeConfig(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise { - if (message.key === '*' || message.key === '') { + if (message.key.length === 0 || message.key[1] === '*') { new DevChatConfig().setAll(message.value); } else { new DevChatConfig().set(message.key, message.value); diff --git a/src/util/apiKey.ts b/src/util/apiKey.ts index 16fd819..6c6bcdd 100644 --- a/src/util/apiKey.ts +++ b/src/util/apiKey.ts @@ -7,22 +7,23 @@ import { logger } from './logger'; export class ApiKeyManager { static async llmModel() { - const defaultModel = new DevChatConfig().get('default_model'); + const devchatConfig = new DevChatConfig(); + const defaultModel = devchatConfig.get('default_model'); if (!defaultModel) { return undefined; } // get model provider - const defaultModelProvider = new DevChatConfig().get(`models.${defaultModel}.provider`); + const defaultModelProvider = devchatConfig.get(['models', defaultModel, 'provider']); if (!defaultModelProvider) { return undefined; } // get provider config - const defaultProvider = new DevChatConfig().get(`providers.${defaultModelProvider}`); - const devchatProvider = new DevChatConfig().get(`providers.devchat`); + const defaultProvider = devchatConfig.get(['providers', defaultModelProvider]); + const devchatProvider = devchatConfig.get(`providers.devchat`); - let defaultModelConfig = new DevChatConfig().get(`models.${defaultModel}`); + let defaultModelConfig = devchatConfig.get(['models', defaultModel]); defaultModelConfig["model"] = defaultModel; if (defaultProvider) { for (const key of Object.keys(defaultProvider || {})) { diff --git a/src/util/config.ts b/src/util/config.ts index 4389af0..a0fd88c 100644 --- a/src/util/config.ts +++ b/src/util/config.ts @@ -35,12 +35,26 @@ export class DevChatConfig { } } - public get(key: string): any { - return key.split('.').reduce((prev, curr) => prev ? prev[curr] : undefined, this.data); + public get(key: string | string[]): any { + let keys: string[] = []; + + if (typeof key === 'string') { + keys = key.split('.'); + } else { + keys = key; + } + return keys.reduce((prev, curr) => prev ? prev[curr] : undefined, this.data); } - public set(key: string, value: any): void { - let keys = key.split('.'); + public set(key: string | string[], value: any): void { + let keys: string[] = []; + + if (typeof key === 'string') { + keys = key.split('.'); + } else { + keys = key; + } + let lastKey = keys.pop(); let lastObj = keys.reduce((prev, k) => prev[k] = prev[k] || {}, this.data); // 这创建一个嵌套的对象结构,如果不存在的话 if (lastKey) {