181 lines
6.0 KiB
TypeScript
Raw Normal View History

2023-05-05 21:27:40 +08:00
import * as vscode from 'vscode';
2023-05-09 10:34:33 +08:00
import { MessageHandler } from './messageHandler';
2023-05-10 17:56:56 +08:00
import { regInMessage, regOutMessage } from '../util/reg_messages';
2023-10-11 23:51:58 +08:00
import { stopDevChatBase, sendMessageBase, deleteChatMessageBase, insertDevChatLog, handleTopic } from './sendMessageBase';
import { UiUtilWrapper } from '../util/uiUtil';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { ApiKeyManager } from '../util/apiKey';
import { logger } from '../util/logger';
import { exec as execCb } from 'child_process';
import { promisify } from 'util';
2023-11-22 17:45:38 +08:00
import { CommandResult, CommandRun, createTempSubdirectory } from '../util/commonUtil';
import { WorkflowRunner } from './workflowExecutor';
import DevChat from '../toolwrapper/devchat';
2023-05-10 17:56:56 +08:00
const exec = promisify(execCb);
2023-05-05 21:27:40 +08:00
2023-11-22 17:45:38 +08:00
let commandRunner : WorkflowRunner | null = null;
2023-10-11 23:51:57 +08:00
let _lastMessage: any = undefined;
2023-11-22 17:45:38 +08:00
export function createTempFile(content: string): string {
// Generate a unique file name
const fileName = path.join(os.tmpdir(), `temp_${Date.now()}.txt`);
// Write the content to the file
fs.writeFileSync(fileName, content);
return fileName;
}
export function deleteTempFiles(fileName: string): void {
// Delete the file
fs.unlinkSync(fileName);
}
2023-11-22 17:45:38 +08:00
regInMessage({command: 'userInput', text: '{"field": "value", "field2": "value2"}'});;
export async function userInput(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
commandRunner?.input(message.text);
}
2023-11-22 17:45:38 +08:00
// eslint-disable-next-line @typescript-eslint/naming-convention
regInMessage({command: 'sendMessage', text: '', parent_hash: undefined});
2023-05-10 17:56:56 +08:00
regOutMessage({ command: 'receiveMessage', text: 'xxxx', hash: 'xxx', user: 'xxx', date: 'xxx'});
regOutMessage({ command: 'receiveMessagePartial', text: 'xxxx', user: 'xxx', date: 'xxx'});
2023-11-22 17:45:38 +08:00
export async function sendMessage(message: any, panel: vscode.WebviewPanel|vscode.WebviewView, functionName: string|undefined = undefined): Promise<void> {
// check whether the message is a command
if (functionName !== undefined && functionName !== "") {
const messageText = _lastMessage[0].text.trim();
if (messageText[0] === '/' && message.text[0] !== '/') {
const indexS = messageText.indexOf(' ');
let preCommand = messageText;
if (indexS !== -1) {
preCommand = messageText.substring(0, indexS);
}
message.text = preCommand + ' ' + message.text;
}
}
2023-11-22 17:45:38 +08:00
_lastMessage = [message, functionName];
const messageText = message.text.trim();
if (messageText[0] === '/') {
// split messageText by ' ' or '\n' or '\t'
const messageTextArr = messageText.split(/ |\n|\t/);
// get command name from messageTextArr
const commandName = messageTextArr[0].substring(1);
// test whether the command is a execute command
const devChat = new DevChat();
const stdout = await devChat.commandPrompt(commandName);
// try parse stdout by json
let stdoutJson: any = null;
try {
stdoutJson = JSON.parse(stdout);
} catch (error) {
// do nothing
}
if (stdoutJson) {
// run command
try {
commandRunner = null;
commandRunner = new WorkflowRunner();
await commandRunner.run(commandName, stdoutJson, message, panel);
} finally {
commandRunner = null;
}
return ;
}
}
// Add a new field to store the names of temporary files
let tempFiles: string[] = [];
// Handle the contextInfo field in the message
if (Array.isArray(message.contextInfo)) {
for (let context of message.contextInfo) {
if (typeof context === 'object' && context !== null && 'context' in context) {
// If the file name is not present, create a temporary file
if (!context.file) {
try {
const contextStr = JSON.stringify(context.context);
context.file = createTempFile(contextStr);
// Add the file name to the tempFiles array
tempFiles.push(context.file);
} catch (err) {
console.error('Failed to create temporary file:', err);
throw err;
}
}
// Insert the file name into the text field
message.text += ` [context|${context.file}]`;
}
}
}
// clear message.contextInfo
message.contextInfo = undefined;
const responseMessage = await sendMessageBase(message, (data: { command: string, text: string, user: string, date: string}) => {
MessageHandler.sendMessage(panel, data, false);
2023-11-22 17:45:38 +08:00
}, functionName);
if (responseMessage) {
MessageHandler.sendMessage(panel, responseMessage);
}
// Delete all temporary files created
for (let file of tempFiles) {
deleteTempFiles(file);
}
2023-05-05 21:27:40 +08:00
}
2023-05-23 11:16:48 +08:00
// regeneration last message again
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) {
2023-11-22 17:45:38 +08:00
await sendMessage(_lastMessage[0], panel, _lastMessage[1]);
2023-05-23 11:16:48 +08:00
}
}
2023-05-10 17:56:56 +08:00
regInMessage({command: 'stopDevChat'});
2023-05-16 14:35:01 +08:00
export async function stopDevChat(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
stopDevChatBase(message);
2023-10-11 23:51:57 +08:00
2023-11-22 17:45:38 +08:00
if (commandRunner) {
commandRunner.stop();
commandRunner = null;
2023-10-11 23:51:57 +08:00
}
}
regInMessage({command: 'deleteChatMessage', hash: 'xxx'});
regOutMessage({ command: 'deletedChatMessage', hash: 'xxxx'});
export async function deleteChatMessage(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
// prompt user to confirm
const confirm = await vscode.window.showWarningMessage(
`Are you sure to delete this message?`,
{ modal: true },
'Delete'
);
if (confirm !== 'Delete') {
return;
}
const deleted = await deleteChatMessageBase(message);
if (deleted) {
MessageHandler.sendMessage(panel, { command: 'deletedChatMessage', hash: message.hash });
} else {
UiUtilWrapper.showErrorMessage('Delete message failed!');
}
}
2023-05-08 12:09:52 +08:00
2023-05-05 21:27:40 +08:00