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
This commit is contained in:
bobo.yang 2024-04-01 17:15:44 +08:00
parent 0a340a8409
commit 40d0fa502b
5 changed files with 54 additions and 37 deletions

View File

@ -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;

View File

@ -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", "");
}
}

View File

@ -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<void> {
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<void> {
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);

View File

@ -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 || {})) {

View File

@ -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) {