Refactor sendMessage and improve DevChat response handling
- Import ChatResponse from DevChat in sendMessage.ts - Update sendMessage function to handle parent_hash and partial responses - Refactor DevChat.chat to parse response data and handle partial stdout - Remove unused lastPromptHash variable
This commit is contained in:
parent
d7622abe28
commit
13c4453651
@ -2,7 +2,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import DevChat from '../toolwrapper/devchat';
|
||||
import DevChat, { ChatResponse } from '../toolwrapper/devchat';
|
||||
import CommandManager from '../command/commandManager';
|
||||
import { logger } from '../util/logger';
|
||||
import { MessageHandler } from './messageHandler';
|
||||
@ -70,14 +70,22 @@ function getInstructionFiles(): string[] {
|
||||
}
|
||||
|
||||
|
||||
let lastPromptHash: string | undefined;
|
||||
|
||||
// message: { command: 'sendMessage', text: 'xxx', parent_hash: 'xxx'}
|
||||
// return message:
|
||||
// { command: 'receiveMessage', text: 'xxxx', hash: 'xxx', user: 'xxx', date: 'xxx'}
|
||||
// { command: 'receiveMessagePartial', text: 'xxxx', user: 'xxx', date: 'xxx'}
|
||||
export async function sendMessage(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||
const devChat = new DevChat();
|
||||
|
||||
const newText2 = await CommandManager.getInstance().processText(message.text);
|
||||
const parsedMessage = parseMessage(newText2);
|
||||
const chatOptions: any = lastPromptHash ? { parent: lastPromptHash } : {};
|
||||
const chatOptions: any = {};
|
||||
|
||||
logger.channel()?.info(`parent_hash: ${message.parent_hash}`)
|
||||
if (message.parent_hash) {
|
||||
chatOptions.parent = message.parent_hash;
|
||||
}
|
||||
|
||||
if (parsedMessage.context.length > 0) {
|
||||
chatOptions.context = parsedMessage.context;
|
||||
@ -92,25 +100,13 @@ export async function sendMessage(message: any, panel: vscode.WebviewPanel): Pro
|
||||
chatOptions.reference = parsedMessage.reference;
|
||||
}
|
||||
|
||||
let partialData = "";
|
||||
const onData = (partialResponse: string) => {
|
||||
partialData += partialResponse;
|
||||
MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: partialData }, false);
|
||||
const onData = (partialResponse: ChatResponse) => {
|
||||
MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: partialResponse.response, user: partialResponse.user, date: partialResponse.date }, false);
|
||||
};
|
||||
|
||||
const chatResponse = await devChat.chat(parsedMessage.text, chatOptions, onData);
|
||||
if (chatResponse && typeof chatResponse === 'object' && !Array.isArray(chatResponse) && !(chatResponse instanceof String)) {
|
||||
// 检查 "prompt-hash" 是否在 chatResponse 中
|
||||
if ('prompt-hash' in chatResponse) {
|
||||
// 检查 chatResponse['prompt-hash'] 是否不为空
|
||||
if (chatResponse['prompt-hash']) {
|
||||
// 如果 "prompt-hash" 在 chatResponse 中且不为空,则更新 lastPromptHash 的值
|
||||
lastPromptHash = chatResponse['prompt-hash'];
|
||||
}
|
||||
}
|
||||
}
|
||||
const response = chatResponse.response;
|
||||
MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: response });
|
||||
|
||||
MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: chatResponse.response, hash: chatResponse['prompt-hash'], user: chatResponse.user, date: chatResponse.date, isError: chatResponse.isError });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ export interface ChatResponse {
|
||||
|
||||
|
||||
class DevChat {
|
||||
async chat(content: string, options: ChatOptions = {}, onData: (data: string) => void): Promise<ChatResponse> {
|
||||
async chat(content: string, options: ChatOptions = {}, onData: (data: ChatResponse) => void): Promise<ChatResponse> {
|
||||
let args = ["prompt"];
|
||||
|
||||
if (options.reference) {
|
||||
@ -123,6 +123,64 @@ class DevChat {
|
||||
fs.writeFileSync(configPath, configJson);
|
||||
|
||||
try {
|
||||
const parseOutData = (stdout: string, isPartial: boolean) => {
|
||||
const responseLines = stdout.trim().split("\n");
|
||||
|
||||
if (responseLines.length < 2) {
|
||||
return {
|
||||
"prompt-hash": "",
|
||||
user: "",
|
||||
date: "",
|
||||
response: "",
|
||||
isError: isPartial ? false : true,
|
||||
};
|
||||
}
|
||||
|
||||
const userLine = responseLines.shift()!;
|
||||
const user = (userLine.match(/User: (.+)/)?.[1]) ?? "";
|
||||
|
||||
const dateLine = responseLines.shift()!;
|
||||
const date = (dateLine.match(/Date: (.+)/)?.[1]) ?? "";
|
||||
|
||||
|
||||
let promptHashLine = "";
|
||||
for (let i = responseLines.length - 1; i >= 0; i--) {
|
||||
if (responseLines[i].startsWith("prompt")) {
|
||||
promptHashLine = responseLines[i];
|
||||
responseLines.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!promptHashLine) {
|
||||
return {
|
||||
"prompt-hash": "",
|
||||
user: user,
|
||||
date: date,
|
||||
response: responseLines.join("\n"),
|
||||
isError: isPartial ? false : true,
|
||||
};
|
||||
}
|
||||
|
||||
const promptHash = promptHashLine.split(" ")[1];
|
||||
const response = responseLines.join("\n");
|
||||
|
||||
return {
|
||||
"prompt-hash": promptHash,
|
||||
user,
|
||||
date,
|
||||
response,
|
||||
isError: false,
|
||||
};
|
||||
};
|
||||
|
||||
let receviedStdout = "";
|
||||
const onStdoutPartial = (stdout: string) => {
|
||||
receviedStdout += stdout;
|
||||
const data = parseOutData(receviedStdout, true);
|
||||
onData(data);
|
||||
};
|
||||
|
||||
logger.channel()?.info(`Running devchat with args: ${args.join(" ")}`);
|
||||
const { code, stdout, stderr } = await spawnAsync('devchat', args, {
|
||||
maxBuffer: 10 * 1024 * 1024, // Set maxBuffer to 10 MB
|
||||
@ -131,7 +189,7 @@ class DevChat {
|
||||
...process.env,
|
||||
OPENAI_API_KEY: openaiApiKey,
|
||||
},
|
||||
}, onData);
|
||||
}, onStdoutPartial);
|
||||
|
||||
if (stderr) {
|
||||
const errorMessage = stderr.trim().match(/Error:(.+)/)?.[1];
|
||||
@ -144,54 +202,8 @@ class DevChat {
|
||||
};
|
||||
}
|
||||
|
||||
const responseLines = stdout.trim().split("\n");
|
||||
|
||||
if (responseLines.length === 0) {
|
||||
return {
|
||||
"prompt-hash": "",
|
||||
user: "",
|
||||
date: "",
|
||||
response: "",
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
let promptHashLine = "";
|
||||
for (let i = responseLines.length - 1; i >= 0; i--) {
|
||||
if (responseLines[i].startsWith("prompt")) {
|
||||
promptHashLine = responseLines[i];
|
||||
responseLines.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!promptHashLine) {
|
||||
return {
|
||||
"prompt-hash": "",
|
||||
user: "",
|
||||
date: "",
|
||||
response: responseLines.join("\n"),
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
const promptHash = promptHashLine.split(" ")[1];
|
||||
|
||||
const userLine = responseLines.shift()!;
|
||||
const user = (userLine.match(/User: (.+)/)?.[1]) ?? "";
|
||||
|
||||
const dateLine = responseLines.shift()!;
|
||||
const date = (dateLine.match(/Date: (.+)/)?.[1]) ?? "";
|
||||
|
||||
const response = responseLines.join("\n");
|
||||
|
||||
return {
|
||||
"prompt-hash": promptHash,
|
||||
user,
|
||||
date,
|
||||
response,
|
||||
isError: false,
|
||||
};
|
||||
const response = parseOutData(stdout, false);
|
||||
return response;
|
||||
} catch (error: any) {
|
||||
return {
|
||||
"prompt-hash": "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user