Refactor DevChatConfig instantiation to use getInstance() method
This commit is contained in:
parent
da336b61ba
commit
2b505b5536
@ -12,7 +12,7 @@ import { createFileBlockInfo, createIdentifierSetByQuery } from './createIdentif
|
||||
|
||||
|
||||
let indexStore: IndexStore | undefined = undefined;
|
||||
const devchatConfig = new DevChatConfig();
|
||||
const devchatConfig = DevChatConfig.getInstance();
|
||||
|
||||
export const BLACK_LIST_DIRS = [
|
||||
"node_modules",
|
||||
|
@ -61,7 +61,7 @@ export class InlineCompletionProvider implements vscode.InlineCompletionItemProv
|
||||
// Read delay time from config
|
||||
this.debouncer = new Debouncer(500);
|
||||
this.cache = new MemoryCacheManager();
|
||||
this.devchatConfig = new DevChatConfig();
|
||||
this.devchatConfig = DevChatConfig.getInstance();
|
||||
this.lastComplete = "";
|
||||
this.recentEditors = new RecentEditsManager();
|
||||
}
|
||||
|
@ -16,15 +16,23 @@ export interface CodeCompletionChunk {
|
||||
}
|
||||
|
||||
export async function* streamComplete(prompt: string): AsyncGenerator<CodeCompletionChunk> {
|
||||
for await (const chunk of nvidiaStarcoderComplete(prompt)) {
|
||||
yield chunk;
|
||||
const nvidiaKey = DevChatConfig.getInstance().get("complete_key");
|
||||
const ollamaApiBase = DevChatConfig.getInstance().get("complete_ollama_api_base");
|
||||
if (ollamaApiBase) {
|
||||
for await (const chunk of ollamaDeepseekComplete(prompt)) {
|
||||
yield chunk;
|
||||
}
|
||||
} else if (nvidiaKey) {
|
||||
for await (const chunk of nvidiaStarcoderComplete(prompt)) {
|
||||
yield chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function * nvidiaStarcoderComplete(prompt: string) : AsyncGenerator<CodeCompletionChunk> {
|
||||
const invokeUrl = 'https://api.nvcf.nvidia.com/v2/nvcf/pexec/functions/6acada03-fe2f-4e4d-9e0a-e711b9fd1b59';
|
||||
|
||||
const nvidiaKey = new DevChatConfig().get("complete_key");
|
||||
const nvidiaKey = DevChatConfig.getInstance().get("complete_key");
|
||||
if (!nvidiaKey) {
|
||||
return;
|
||||
}
|
||||
@ -89,17 +97,24 @@ export async function * nvidiaStarcoderComplete(prompt: string) : AsyncGenerator
|
||||
}
|
||||
}
|
||||
|
||||
export async function * ollamaStarcoderComplete(prompt: string) : AsyncGenerator<CodeCompletionChunk> {
|
||||
const url = 'http://192.168.1.138:11434/api/generate';
|
||||
export async function * ollamaDeepseekComplete(prompt: string) : AsyncGenerator<CodeCompletionChunk> {
|
||||
const ollamaApiBase = DevChatConfig.getInstance().get("complete_ollama_api_base");
|
||||
if (!ollamaApiBase) {
|
||||
return;
|
||||
}
|
||||
|
||||
const urlBase = ollamaApiBase.trim().endsWith('/') ? ollamaApiBase : ollamaApiBase + '/';
|
||||
const url = urlBase + 'api/generate';
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const payload = {
|
||||
model: 'starcoder:7b',
|
||||
model: 'deepseek-coder:6.7b-base',
|
||||
prompt: prompt,
|
||||
stream: true,
|
||||
options: {
|
||||
stop: ["<|endoftext|>", "<file_sep>", "```", "\n\n"],
|
||||
stop: ["<|endoftext|>", "<|EOT|>", "<file_sep>", "```", "/", "\n\n"],
|
||||
temperature: 0.2
|
||||
}
|
||||
};
|
||||
@ -131,8 +146,8 @@ export async function * ollamaStarcoderComplete(prompt: string) : AsyncGenerator
|
||||
id: idResponse!
|
||||
};
|
||||
} catch (e: any) {
|
||||
logger.channel()?.info("receve:", chunkText);
|
||||
logger.channel()?.error("JSON Parsing Error:", e.message);
|
||||
// logger.channel()?.info("receive:", chunkText);
|
||||
logger.channel()?.warn("JSON Parsing fail:", e.message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -24,6 +24,7 @@ import MemoryCacheManager from "./cache";
|
||||
import { searchSimilarBlock } from "./astIndex";
|
||||
import { GitDiffWatcher } from "./gitDiffWatcher";
|
||||
import { findIdentifiersInAstNodeRange } from './ast/findIdentifiers';
|
||||
import { DevChatConfig } from '../../util/config';
|
||||
|
||||
|
||||
const CONTEXT_LIMITED_SIZE: number = 6000;
|
||||
@ -674,7 +675,14 @@ export async function createPrompt(filePath: string, fileContent: string, line:
|
||||
|
||||
logger.channel()?.info("Complete token:", tokenCount);
|
||||
|
||||
const prompt = "<fim_prefix>" + taskDescriptionContextWithCommentPrefix + neighborFileContext + recentEditContext + symbolContext + callDefContext + similarBlockContext + gitDiffContext + `${commentPrefix}<filename>${filePath}\n\n` + prefix + "<fim_suffix>" + suffix + "<fim_middle>";
|
||||
let prompt = "";
|
||||
const ollamaApiBase = DevChatConfig.getInstance().get("complete_ollama_api_base");
|
||||
if (ollamaApiBase) {
|
||||
prompt = "<|fim▁begin|>" + taskDescriptionContextWithCommentPrefix + neighborFileContext + recentEditContext + symbolContext + callDefContext + similarBlockContext + gitDiffContext + `${commentPrefix}<filename>${filePath}\n\n` + prefix + "<|fim▁hole|>" + suffix + "<|fim▁end|>";
|
||||
} else {
|
||||
prompt = "<fim_prefix>" + taskDescriptionContextWithCommentPrefix + neighborFileContext + recentEditContext + symbolContext + callDefContext + similarBlockContext + gitDiffContext + `${commentPrefix}<filename>${filePath}\n\n` + prefix + "<fim_suffix>" + suffix + "<fim_middle>";
|
||||
}
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import { DevChatConfig } from '../../../util/config';
|
||||
|
||||
// 记录文件的最后修改时间
|
||||
const lastModified = new Map<string, number>();
|
||||
const devchatConfig = new DevChatConfig();
|
||||
const devchatConfig = DevChatConfig.getInstance();
|
||||
|
||||
const BLACK_LIST_DIRS = [
|
||||
"node_modules",
|
||||
|
@ -145,7 +145,7 @@ export function regPythonPathCommand(context: vscode.ExtensionContext) {
|
||||
})) ?? "";
|
||||
|
||||
if (pythonPath) {
|
||||
new DevChatConfig().set("python_for_chat", pythonPath);
|
||||
DevChatConfig.getInstance().set("python_for_chat", pythonPath);
|
||||
}
|
||||
})
|
||||
);
|
||||
@ -290,7 +290,7 @@ export function registerInstallCommandsPython(context: vscode.ExtensionContext)
|
||||
return '';
|
||||
}
|
||||
|
||||
new DevChatConfig().set("python_for_commands", pythonCommand.trim());
|
||||
DevChatConfig.getInstance().set("python_for_commands", pythonCommand.trim());
|
||||
// vscode.window.showInformationMessage(`All slash Commands are ready to use! Please input / to try workflow commands!`);
|
||||
});
|
||||
|
||||
@ -352,7 +352,7 @@ export function registerHandleUri(context: vscode.ExtensionContext) {
|
||||
// 解析 URI 并执行相应的操作
|
||||
if (uri.path.includes("accesskey")) {
|
||||
const accessKey = uri.path.split("/")[2];
|
||||
new DevChatConfig().set("provides.devchat.api_key", accessKey);
|
||||
DevChatConfig.getInstance().set("provides.devchat.api_key", accessKey);
|
||||
ensureChatPanel(context);
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
|
@ -43,7 +43,7 @@ function getDefaultPythonCommand(): string | undefined {
|
||||
|
||||
export function getValidPythonCommand(): string | undefined {
|
||||
try {
|
||||
const devchatConfig = new DevChatConfig();
|
||||
const devchatConfig = DevChatConfig.getInstance();
|
||||
const pythonCommand = devchatConfig.get('python_for_chat');
|
||||
if (pythonCommand) {
|
||||
return pythonCommand;
|
||||
|
@ -36,7 +36,7 @@ import { indexDir } from "./contributes/codecomplete/astIndex";
|
||||
|
||||
|
||||
async function migrateConfig() {
|
||||
const devchatConfig = new DevChatConfig();
|
||||
const devchatConfig = DevChatConfig.getInstance();
|
||||
const devchatProvider = "providers.devchat";
|
||||
const devchatProviderConfig: any = devchatConfig.get(devchatProvider);
|
||||
if (devchatProviderConfig) {
|
||||
|
@ -11,10 +11,10 @@ regInMessage({command: 'readConfig', key: ['A','B']}); // when key is "", it wil
|
||||
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 === '*' || message.key.length === 0 || message.key[1] === '*') {
|
||||
const config = new DevChatConfig().getAll();
|
||||
const config = DevChatConfig.getInstance().getAll();
|
||||
MessageHandler.sendMessage(panel, {command: 'readConfig', key: message.key, value: config});
|
||||
} else {
|
||||
const config = new DevChatConfig().get(message.key);
|
||||
const config = DevChatConfig.getInstance().get(message.key);
|
||||
MessageHandler.sendMessage(panel, {command: 'readConfig', key: message.key, value: config});
|
||||
}
|
||||
}
|
||||
@ -22,8 +22,8 @@ export async function readConfig(message: any, panel: vscode.WebviewPanel|vscode
|
||||
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 === '*' || message.key.length === 0 || message.key[1] === '*') {
|
||||
new DevChatConfig().setAll(message.value);
|
||||
DevChatConfig.getInstance().setAll(message.value);
|
||||
} else {
|
||||
new DevChatConfig().set(message.key, message.value);
|
||||
DevChatConfig.getInstance().set(message.key, message.value);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ regInMessage({command: 'historyMessages', topicId: '', page: 0});
|
||||
regOutMessage({command: 'loadHistoryMessages', entries: [{hash: '',user: '',date: '',request: '',response: '',context: [{content: '',role: ''}]}]});
|
||||
export async function getHistoryMessages(message: {command: string, topicId: string, page: number}, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
|
||||
// if history message has load, send it to webview
|
||||
const maxCount = Number(new DevChatConfig().get('max_log_count'));
|
||||
const maxCount = Number(DevChatConfig.getInstance().get('max_log_count'));
|
||||
const skip = maxCount * (message.page ? message.page : 0);
|
||||
const topicId = message.topicId;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { DevChatConfig } from "../../util/config";
|
||||
|
||||
export async function ideLanguage() {
|
||||
const language = new DevChatConfig().get('language');
|
||||
const language = DevChatConfig.getInstance().get('language');
|
||||
// 'en' stands for English, 'zh' stands for Simplified Chinese
|
||||
return language;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export function createStatusBarItem(context: vscode.ExtensionContext): vscode.St
|
||||
function checkDevChatCommandsStatus() {
|
||||
const timerDevchatCommands = setInterval(async () => {
|
||||
try {
|
||||
const pythonCommand = new DevChatConfig().get('python_for_commands');
|
||||
const pythonCommand = DevChatConfig.getInstance().get('python_for_commands');
|
||||
if (!pythonCommand) {
|
||||
statusBarItem.text = `$(pass)DevChat$(warning)`;
|
||||
statusBarItem.tooltip = `ready to chat, command functionality limited`;
|
||||
|
@ -123,7 +123,7 @@ class DevChat {
|
||||
assertValue(!llmModelData || !llmModelData.model, 'You must select a LLM model to use for conversations');
|
||||
args.push("-m", llmModelData.model);
|
||||
|
||||
const functionCalling = new DevChatConfig().get('enable_function_calling');
|
||||
const functionCalling = DevChatConfig.getInstance().get('enable_function_calling');
|
||||
if (functionCalling) {
|
||||
args.push("-a");
|
||||
}
|
||||
@ -140,7 +140,7 @@ class DevChat {
|
||||
if (options.maxCount) {
|
||||
args.push('--max-count', `${options.maxCount}`);
|
||||
} else {
|
||||
const maxLogCount = new DevChatConfig().get('max_log_count');
|
||||
const maxLogCount = DevChatConfig.getInstance().get('max_log_count');
|
||||
args.push('--max-count', `${maxLogCount}`);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ class DevChat {
|
||||
"PYTHONPATH": UiUtilWrapper.extensionPath() + "/tools/site-packages"
|
||||
};
|
||||
|
||||
const pythonApp = new DevChatConfig().get('python_for_chat') || "python3";
|
||||
const pythonApp = DevChatConfig.getInstance().get('python_for_chat') || "python3";
|
||||
|
||||
// run command
|
||||
const { exitCode: code, stdout, stderr } = await this.commandRun.spawnAsync(
|
||||
@ -251,7 +251,7 @@ class DevChat {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
"PYTHONUTF8": 1,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
"command_python": new DevChatConfig().get('python_for_commands') || "",
|
||||
"command_python": DevChatConfig.getInstance().get('python_for_commands') || "",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
"PYTHONPATH": UiUtilWrapper.extensionPath() + "/tools/site-packages",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
@ -279,7 +279,7 @@ class DevChat {
|
||||
onData(data);
|
||||
};
|
||||
// run command
|
||||
const pythonApp = new DevChatConfig().get('python_for_chat') || "python3";
|
||||
const pythonApp = DevChatConfig.getInstance().get('python_for_chat') || "python3";
|
||||
logger.channel()?.info(`Running devchat:${pythonApp} ${args.join(" ")}`);
|
||||
const { exitCode: code, stdout, stderr } = await this.commandRun.spawnAsync(pythonApp, args, spawnAsyncOptions, onStdoutPartial, undefined, undefined, undefined);
|
||||
// handle result
|
||||
|
@ -7,7 +7,7 @@ import { logger } from './logger';
|
||||
|
||||
export class ApiKeyManager {
|
||||
static async llmModel() {
|
||||
const devchatConfig = new DevChatConfig();
|
||||
const devchatConfig = DevChatConfig.getInstance();
|
||||
const defaultModel = devchatConfig.get('default_model');
|
||||
if (!defaultModel) {
|
||||
return undefined;
|
||||
|
@ -5,18 +5,27 @@ import { logger } from './logger';
|
||||
|
||||
|
||||
export class DevChatConfig {
|
||||
private static instance: DevChatConfig;
|
||||
// 配置文件路径,根据操作系统的差异,可能需要调整
|
||||
private configFilePath: string;
|
||||
private data: any;
|
||||
// last modify timestamp of the config file
|
||||
private lastModifyTime: number;
|
||||
|
||||
constructor() {
|
||||
private constructor() {
|
||||
// 视操作系统的差异,可能需要调整路径 ~/.chat/config.yml
|
||||
this.configFilePath = path.join(process.env.HOME || process.env.USERPROFILE || '', '.chat', 'config.yml');
|
||||
this.lastModifyTime = 0;
|
||||
this.readConfigFile();
|
||||
}
|
||||
|
||||
public static getInstance(): DevChatConfig {
|
||||
if (!DevChatConfig.instance) {
|
||||
DevChatConfig.instance = new DevChatConfig();
|
||||
}
|
||||
return DevChatConfig.instance;
|
||||
}
|
||||
|
||||
private readConfigFile() {
|
||||
try {
|
||||
const fileContents = fs.readFileSync(this.configFilePath, 'utf8');
|
||||
|
@ -14,7 +14,7 @@ const featureToggles = JSON.parse(featureTogglesJson);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export function FT(feature: string): boolean {
|
||||
const betaInvitationCode = new DevChatConfig().get('beta_invitation_code');
|
||||
const betaInvitationCode = DevChatConfig.getInstance().get('beta_invitation_code');
|
||||
const expectedInvitationCode = 'WELCOMEADDTODEVCHAT';
|
||||
|
||||
return betaInvitationCode === expectedInvitationCode || featureToggles[feature] === true;
|
||||
|
@ -45,7 +45,7 @@ export async function installDevchat(): Promise<string> {
|
||||
fs.writeFileSync(pythonPathFile, content);
|
||||
|
||||
// update DevChat.PythonForChat configration
|
||||
await new DevChatConfig().set("python_for_chat", pythonApp);
|
||||
await DevChatConfig.getInstance().set("python_for_chat", pythonApp);
|
||||
return pythonApp;
|
||||
} else {
|
||||
// if current os is not windows, we need to get default python path
|
||||
@ -70,7 +70,7 @@ export async function installDevchat(): Promise<string> {
|
||||
}
|
||||
logger.channel()?.info(`Create env success: ${pythonCommand}`);
|
||||
|
||||
await new DevChatConfig().set("python_for_chat", pythonCommand);
|
||||
await DevChatConfig.getInstance().set("python_for_chat", pythonCommand);
|
||||
return pythonCommand;
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -41,12 +41,12 @@ describe('DevChatConfig', () => {
|
||||
});
|
||||
|
||||
it('should read config file and get the correct value for a given key', () => {
|
||||
const config = new DevChatConfig();
|
||||
const config = DevChatConfig.getInstance();
|
||||
expect(config.get('username')).to.equal('DevUser');
|
||||
});
|
||||
|
||||
it('should set a new key-value pair and write to the config file', () => {
|
||||
const config = new DevChatConfig();
|
||||
const config = DevChatConfig.getInstance();
|
||||
const newKey = 'notifications.enabled';
|
||||
const newValue = true;
|
||||
|
||||
@ -61,7 +61,7 @@ describe('DevChatConfig', () => {
|
||||
readFileStub.throws(new Error('Failed to read file'));
|
||||
|
||||
// Constructing the config will attempt to read the file and log an error
|
||||
const config = new DevChatConfig();
|
||||
const config = DevChatConfig.getInstance();
|
||||
|
||||
// Check if the error was logged
|
||||
sinon.assert.called(loggerStub);
|
||||
|
Loading…
x
Reference in New Issue
Block a user