Add PythonVirtualEnv configuration and improve error handling

- Added PythonVirtualEnv configuration to customAction.ts.
- Improved error handling in doCommand.ts by using logger instead of console.error.
- Updated sendMessage.ts to handle askCode command and improved error handling.
- Added environment variables for OPENAI_API_KEY and OPENAI_API_BASE in commonUtil.ts.
- Created new action 'query_data' in _setting_.json and its handler in handler.py.
This commit is contained in:
bobo.yang 2023-08-21 11:52:00 +08:00
parent df679ea613
commit b837365427
6 changed files with 146 additions and 11 deletions

View File

@ -83,6 +83,12 @@ export class CustomActions {
const tempDir = await createTempSubdirectory('devchat/action');
const tempFile = path.join(tempDir, 'apply.json');
if (UiUtilWrapper.getConfiguration('DevChat', 'PythonVirtualEnv')) {
args['PythonVirtualEnv'] = UiUtilWrapper.getConfiguration('DevChat', 'PythonVirtualEnv')!;
} else {
args['PythonVirtualEnv'] = 'python';
}
const contextMap = {
'codeBlock': args,
'workspaceDir': UiUtilWrapper.workspaceFoldersFirstPath(),

View File

@ -3,9 +3,8 @@ execute vscode command
*/
import * as vscode from 'vscode';
import DtmWrapper from '../toolwrapper/dtm';
import { regInMessage, regOutMessage } from '../util/reg_messages';
import { runCommandAndWriteOutput } from '../util/commonUtil';
import { logger } from '../util/logger';
regInMessage({command: 'doCommand', content: ['command', 'arg1', 'arg2']});
export async function doCommand(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
@ -15,7 +14,8 @@ export async function doCommand(message: any, panel: vscode.WebviewPanel|vscode.
try {
await vscode.commands.executeCommand(message.content[0], ...message.content.slice(1));
} catch (error) {
console.error(`Failed to execute command ${message.content[0]}: ${error}`);
}
logger.channel()?.error(`Failed to execute command ${message.content[0]}: ${error}`);
logger.channel()?.show();
}
return;
}

View File

@ -35,12 +35,24 @@ export function deleteTempFiles(fileName: string): void {
regInMessage({command: 'askCode', text: '', parent_hash: undefined});
regOutMessage({ command: 'receiveMessage', text: 'xxxx', hash: 'xxx', user: 'xxx', date: 'xxx'});
export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
_lastMessage = message;
_lastMessage = [message];
_lastMessage[0]['askCode'] = true;
const pythonVirtualEnv: string|undefined = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv');
let pythonVirtualEnv: string|undefined = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv');
if (!pythonVirtualEnv) {
MessageHandler.sendMessage(panel, { "command": "systemMessage", "text": "请先设置DevChat.PythonVirtualEnv" });
return ;
try {
await vscode.commands.executeCommand('DevChat.AskCodeIndexStart');
} catch (error) {
logger.channel()?.error(`Failed to execute command ${message.content[0]}: ${error}`);
logger.channel()?.show();
return;
}
pythonVirtualEnv = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv');
if (!pythonVirtualEnv) {
MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Index code fail.", hash: "", user: "", date: 0, isError: true });
return ;
}
}
let envs = {};
@ -157,7 +169,11 @@ regInMessage({command: 'regeneration'});
export async function regeneration(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
// call sendMessage to send last message again
if (_lastMessage) {
sendMessage(_lastMessage[0], panel, _lastMessage[1]);
if (_lastMessage[0]['askCode']) {
await askCode(_lastMessage[0], panel);
} else {
await sendMessage(_lastMessage[0], panel, _lastMessage[1]);
}
}
}

View File

@ -8,6 +8,7 @@ import { parseArgsStringToArgv } from 'string-argv';
import { logger } from './logger';
import { spawn, exec } from 'child_process';
import { UiUtilWrapper } from './uiUtil';
import { ApiKeyManager } from './apiKey';
export function createTempSubdirectory(subdir: string): string {
// 获取系统临时目录
@ -113,9 +114,21 @@ export async function runCommandAndWriteOutput(
args: string[],
outputFile: string | undefined
): Promise<CommandResult> {
let envs = {}
let openaiApiKey = await ApiKeyManager.getApiKey();
if (openaiApiKey) {
envs['OPENAI_API_KEY'] = openaiApiKey;
}
const openAiApiBase = ApiKeyManager.getEndPoint(openaiApiKey);
if (openAiApiBase) {
envs['OPENAI_API_BASE'] = openAiApiBase;
}
const run = new CommandRun();
const options = {
cwd: UiUtilWrapper.workspaceFoldersFirstPath() || '.',
env: envs
};
return run.spawnAsync(command, args, options, undefined, undefined, undefined, outputFile);
@ -125,9 +138,21 @@ export async function runCommandStringAndWriteOutput(
commandString: string,
outputFile: string | undefined
): Promise<CommandResult> {
let envs = {}
let openaiApiKey = await ApiKeyManager.getApiKey();
if (openaiApiKey) {
envs['OPENAI_API_KEY'] = openaiApiKey;
}
const openAiApiBase = ApiKeyManager.getEndPoint(openaiApiKey);
if (openAiApiBase) {
envs['OPENAI_API_BASE'] = openAiApiBase;
}
const run = new CommandRun();
const options = {
cwd: UiUtilWrapper.workspaceFoldersFirstPath() || '.'
cwd: UiUtilWrapper.workspaceFoldersFirstPath() || '.',
env: envs
};
// Split the commandString into command and args array using string-argv
@ -150,9 +175,21 @@ export async function runCommandStringArrayAndWriteOutput(
commandStringList: string[],
outputFile: string
): Promise<CommandResult> {
let envs = {};
let openaiApiKey = await ApiKeyManager.getApiKey();
if (openaiApiKey) {
envs['OPENAI_API_KEY'] = openaiApiKey;
}
const openAiApiBase = ApiKeyManager.getEndPoint(openaiApiKey);
if (openAiApiBase) {
envs['OPENAI_API_BASE'] = openAiApiBase;
}
const run = new CommandRun();
const options = {
cwd: UiUtilWrapper.workspaceFoldersFirstPath() || '.'
cwd: UiUtilWrapper.workspaceFoldersFirstPath() || '.',
env: envs
};
const commandString = commandStringList[0];

View File

@ -0,0 +1,13 @@
{
"name": "query_data",
"description": "Search for content information related to the problem from the vector database",
"type": ["question"],
"args": [{
"name": "question",
"description": "selected question",
"type": "string",
"from": "content.content.question"
}],
"action": "query_data",
"handler": ["${PythonVirtualEnv}", "${CurDir}/handler.py", "${question}"]
}

View File

@ -0,0 +1,63 @@
import os
import re
import sys
import json
import tempfile
import uuid
from chat.ask_codebase.store.qdrant import QdrantWrapper as Q, get_client
from chat.ask_codebase.indexing.embedding import EmbeddingWrapper as E
from langchain.embeddings import HuggingFaceEmbeddings
from chat.ask_codebase.indexing.loader.file import (
FileLoader,
FileSource,
gen_local_reference_maker,
)
from chat.util.misc import is_source_code
from chat.ask_codebase.chains.simple_qa import SimpleQA
from chat.ask_codebase.chains.stuff_dc_qa import StuffDocumentCodeQa
STORAGE_FILE = os.path.join(tempfile.gettempdir(), "qdrant_storage2")
SOURCE_NAME = ""
def query(question: str):
try:
client = get_client(mode=STORAGE_FILE)
q = Q.reuse(
source_name=SOURCE_NAME,
embedding_cls=HuggingFaceEmbeddings,
client=client,
)
chain = StuffDocumentCodeQa(q)
_, docs = chain.run(question)
for d in docs:
print(d.metadata.get('filepath'))
print(d.page_content)
sys.exit(0)
except Exception as e:
print(e)
sys.exit(1)
if __name__ == "__main__":
try:
if os.path.exists(".chat/askcode.json"):
with open(".chat/askcode.json", "r") as f:
askcode_data = json.load(f)
SOURCE_NAME = askcode_data.get("SOURCE_NAME", str(uuid.uuid4()))
else:
SOURCE_NAME = str(uuid.uuid4())
with open(".chat/askcode.json", "w+") as f:
json.dump({"SOURCE_NAME": SOURCE_NAME}, f)
query(sys.argv[1])
sys.exit(0)
except Exception as e:
print(e)
sys.exit(1)