Merge pull request #33 from covespace/add_message_hash
Refactor sendMessage and improve DevChat response handling
This commit is contained in:
commit
da9883f7f2
@ -2,7 +2,7 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import DevChat from '../toolwrapper/devchat';
|
import DevChat, { ChatResponse } from '../toolwrapper/devchat';
|
||||||
import CommandManager from '../command/commandManager';
|
import CommandManager from '../command/commandManager';
|
||||||
import { logger } from '../util/logger';
|
import { logger } from '../util/logger';
|
||||||
import { MessageHandler } from './messageHandler';
|
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> {
|
export async function sendMessage(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
const devChat = new DevChat();
|
const devChat = new DevChat();
|
||||||
|
|
||||||
const newText2 = await CommandManager.getInstance().processText(message.text);
|
const newText2 = await CommandManager.getInstance().processText(message.text);
|
||||||
const parsedMessage = parseMessage(newText2);
|
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) {
|
if (parsedMessage.context.length > 0) {
|
||||||
chatOptions.context = parsedMessage.context;
|
chatOptions.context = parsedMessage.context;
|
||||||
@ -92,25 +100,13 @@ export async function sendMessage(message: any, panel: vscode.WebviewPanel): Pro
|
|||||||
chatOptions.reference = parsedMessage.reference;
|
chatOptions.reference = parsedMessage.reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
let partialData = "";
|
const onData = (partialResponse: ChatResponse) => {
|
||||||
const onData = (partialResponse: string) => {
|
MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: partialResponse.response, user: partialResponse.user, date: partialResponse.date }, false);
|
||||||
partialData += partialResponse;
|
|
||||||
MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: partialData }, false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const chatResponse = await devChat.chat(parsedMessage.text, chatOptions, onData);
|
const chatResponse = await devChat.chat(parsedMessage.text, chatOptions, onData);
|
||||||
if (chatResponse && typeof chatResponse === 'object' && !Array.isArray(chatResponse) && !(chatResponse instanceof String)) {
|
|
||||||
// 检查 "prompt-hash" 是否在 chatResponse 中
|
MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: chatResponse.response, hash: chatResponse['prompt-hash'], user: chatResponse.user, date: chatResponse.date, isError: chatResponse.isError });
|
||||||
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 });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ export interface ChatResponse {
|
|||||||
|
|
||||||
|
|
||||||
class DevChat {
|
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"];
|
let args = ["prompt"];
|
||||||
|
|
||||||
if (options.reference) {
|
if (options.reference) {
|
||||||
@ -123,6 +123,64 @@ class DevChat {
|
|||||||
fs.writeFileSync(configPath, configJson);
|
fs.writeFileSync(configPath, configJson);
|
||||||
|
|
||||||
try {
|
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(" ")}`);
|
logger.channel()?.info(`Running devchat with args: ${args.join(" ")}`);
|
||||||
const { code, stdout, stderr } = await spawnAsync('devchat', args, {
|
const { code, stdout, stderr } = await spawnAsync('devchat', args, {
|
||||||
maxBuffer: 10 * 1024 * 1024, // Set maxBuffer to 10 MB
|
maxBuffer: 10 * 1024 * 1024, // Set maxBuffer to 10 MB
|
||||||
@ -131,7 +189,7 @@ class DevChat {
|
|||||||
...process.env,
|
...process.env,
|
||||||
OPENAI_API_KEY: openaiApiKey,
|
OPENAI_API_KEY: openaiApiKey,
|
||||||
},
|
},
|
||||||
}, onData);
|
}, onStdoutPartial);
|
||||||
|
|
||||||
if (stderr) {
|
if (stderr) {
|
||||||
const errorMessage = stderr.trim().match(/Error:(.+)/)?.[1];
|
const errorMessage = stderr.trim().match(/Error:(.+)/)?.[1];
|
||||||
@ -144,54 +202,8 @@ class DevChat {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseLines = stdout.trim().split("\n");
|
const response = parseOutData(stdout, false);
|
||||||
|
return response;
|
||||||
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,
|
|
||||||
};
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return {
|
return {
|
||||||
"prompt-hash": "",
|
"prompt-hash": "",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user