feat: load conversation

This commit is contained in:
josc146 2024-02-04 22:03:59 +08:00
parent 4added7390
commit 1c025c3d29
5 changed files with 107 additions and 39 deletions

View File

@ -337,5 +337,6 @@
"Penalty Decay": "ペナルティ減衰", "Penalty Decay": "ペナルティ減衰",
"If you don't know what it is, keep it default.": "何であるかわからない場合はデフォルトのままにしてください。", "If you don't know what it is, keep it default.": "何であるかわからない場合はデフォルトのままにしてください。",
"Failed to find the base model, please try to change your base model.": "ベースモデルが見つかりませんでした、ベースモデルを変更してみてください。", "Failed to find the base model, please try to change your base model.": "ベースモデルが見つかりませんでした、ベースモデルを変更してみてください。",
"Markdown Renderer": "Markdownレンダリング" "Markdown Renderer": "Markdownレンダリング",
"Load Conversation": "会話を読み込む"
} }

View File

@ -337,5 +337,6 @@
"Penalty Decay": "惩罚衰减", "Penalty Decay": "惩罚衰减",
"If you don't know what it is, keep it default.": "如果你不知道这是什么,保持默认", "If you don't know what it is, keep it default.": "如果你不知道这是什么,保持默认",
"Failed to find the base model, please try to change your base model.": "未找到基底模型,请尝试更换基底模型", "Failed to find the base model, please try to change your base model.": "未找到基底模型,请尝试更换基底模型",
"Markdown Renderer": "Markdown渲染" "Markdown Renderer": "Markdown渲染",
"Load Conversation": "读取对话"
} }

View File

@ -29,14 +29,14 @@ import {
} from '../../types/composition'; } from '../../types/composition';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { import {
absPathAsset,
flushMidiRecordingContent, flushMidiRecordingContent,
getMidiRawContentMainInstrument, getMidiRawContentMainInstrument,
getMidiRawContentTime, getMidiRawContentTime,
getServerRoot, getServerRoot,
OpenFileDialog,
refreshTracksTotalTime refreshTracksTotalTime
} from '../../utils'; } from '../../utils';
import { OpenOpenFileDialog, PlayNote } from '../../../wailsjs/go/backend_golang/App'; import { PlayNote } from '../../../wailsjs/go/backend_golang/App';
const snapValue = 25; const snapValue = 25;
const minimalMoveTime = 8; // 1000/125=8ms wait_events=125 const minimalMoveTime = 8; // 1000/125=8ms wait_events=125
@ -471,15 +471,7 @@ const AudiotrackEditor: FC<{ setPrompt: (prompt: string) => void }> = observer((
return; return;
} }
OpenOpenFileDialog('*.mid').then(async filePath => { OpenFileDialog('*.mid').then(async blob => {
if (!filePath)
return;
let blob: Blob;
if (commonStore.platform === 'web')
blob = (filePath as unknown as { blob: Blob }).blob;
else
blob = await fetch(absPathAsset(filePath)).then(r => r.blob());
const bodyForm = new FormData(); const bodyForm = new FormData();
bodyForm.append('file_data', blob); bodyForm.append('file_data', blob);
fetch(getServerRoot(commonStore.getCurrentModelConfig().apiParameters.apiPort) + '/midi-to-text', { fetch(getServerRoot(commonStore.getCurrentModelConfig().apiParameters.apiPort) + '/midi-to-text', {
@ -510,8 +502,6 @@ const AudiotrackEditor: FC<{ setPrompt: (prompt: string) => void }> = observer((
).catch(e => { ).catch(e => {
toast(t('Error') + ' - ' + (e.message || e), { type: 'error', autoClose: 2500 }); toast(t('Error') + ' - ' + (e.message || e), { type: 'error', autoClose: 2500 });
}); });
}).catch(e => {
toast(t('Error') + ' - ' + (e.message || e), { type: 'error', autoClose: 2500 });
}); });
}}> }}>
{t('Import MIDI')} {t('Import MIDI')}

View File

@ -26,6 +26,7 @@ import {
Delete28Regular, Delete28Regular,
Dismiss16Regular, Dismiss16Regular,
Dismiss24Regular, Dismiss24Regular,
FolderOpenVerticalRegular,
RecordStop28Regular, RecordStop28Regular,
SaveRegular, SaveRegular,
TextAlignJustify24Regular, TextAlignJustify24Regular,
@ -37,9 +38,17 @@ import { toast } from 'react-toastify';
import { WorkHeader } from '../components/WorkHeader'; import { WorkHeader } from '../components/WorkHeader';
import { DialogButton } from '../components/DialogButton'; import { DialogButton } from '../components/DialogButton';
import { OpenFileFolder, OpenOpenFileDialog, OpenSaveFileDialog } from '../../wailsjs/go/backend_golang/App'; import { OpenFileFolder, OpenOpenFileDialog, OpenSaveFileDialog } from '../../wailsjs/go/backend_golang/App';
import { absPathAsset, bytesToReadable, getServerRoot, setActivePreset, toastWithButton } from '../utils'; import {
absPathAsset,
bytesToReadable,
getServerRoot,
newChatConversation,
OpenFileDialog,
setActivePreset,
toastWithButton
} from '../utils';
import { useMediaQuery } from 'usehooks-ts'; import { useMediaQuery } from 'usehooks-ts';
import { botName, ConversationMessage, MessageType, userName, welcomeUuid } from '../types/chat'; import { botName, ConversationMessage, MessageType, Role, userName, welcomeUuid } from '../types/chat';
import { Labeled } from '../components/Labeled'; import { Labeled } from '../components/Labeled';
import { ValuedSlider } from '../components/ValuedSlider'; import { ValuedSlider } from '../components/ValuedSlider';
import { PresetsButton } from './PresetsManager/PresetsButton'; import { PresetsButton } from './PresetsManager/PresetsButton';
@ -302,12 +311,45 @@ const SidePanel: FC = observer(() => {
}); });
}} /> }} />
} /> } />
{/*<Button*/} <Button
{/* icon={<FolderOpenVerticalRegular />}*/} icon={<FolderOpenVerticalRegular />}
{/* onClick={() => {*/} onClick={() => {
{/* }}>*/} OpenFileDialog('*.txt;*.md').then(async blob => {
{/* {t('Load Conversation')}*/} const userNames = ['User:', 'Question:', 'Q:', 'Human:', 'Bob:'];
{/*</Button>*/} const assistantNames = ['Assistant:', 'Answer:', 'A:', 'Bot:', 'Alice:'];
const names = userNames.concat(assistantNames);
const content = await blob.text();
const lines = content.split('\n');
const { pushMessage, saveConversation } = newChatConversation();
let messageRole: Role = 'user';
let messageContent = '';
for (const [i, line] of lines.entries()) {
let lineName = '';
if (names.some(name => {
lineName = name;
return line.startsWith(name);
})) {
if (messageContent.trim())
pushMessage(messageRole, messageContent.trim());
if (userNames.includes(lineName))
messageRole = 'user';
else
messageRole = 'assistant';
messageContent = line.replace(lineName, '');
} else {
messageContent += '\n' + line;
}
if (i === lines.length - 1)
pushMessage(messageRole, messageContent.trim());
}
saveConversation();
});
}}>
{t('Load Conversation')}
</Button>
<Button <Button
icon={<SaveRegular />} icon={<SaveRegular />}
onClick={() => { onClick={() => {

View File

@ -4,6 +4,7 @@ import {
DepCheck, DepCheck,
InstallPyDep, InstallPyDep,
ListDirFiles, ListDirFiles,
OpenOpenFileDialog,
ReadFileInfo, ReadFileInfo,
ReadJson, ReadJson,
SaveJson, SaveJson,
@ -25,7 +26,7 @@ import { DataProcessParameters, LoraFinetuneParameters } from '../types/train';
import { InstrumentTypeNameMap, MidiMessage, tracksMinimalTotalTime } from '../types/composition'; import { InstrumentTypeNameMap, MidiMessage, tracksMinimalTotalTime } from '../types/composition';
import logo from '../assets/images/logo.png'; import logo from '../assets/images/logo.png';
import { Preset } from '../types/presets'; import { Preset } from '../types/presets';
import { botName, Conversation, MessageType, userName } from '../types/chat'; import { botName, Conversation, MessageType, Role, userName } from '../types/chat';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { findLastIndex } from 'lodash-es'; import { findLastIndex } from 'lodash-es';
@ -579,24 +580,12 @@ export async function getSoundFont() {
export const setActivePreset = (preset: Preset | null) => { export const setActivePreset = (preset: Preset | null) => {
commonStore.setActivePreset(preset); commonStore.setActivePreset(preset);
//TODO if (preset.displayPresetMessages) { //TODO if (preset.displayPresetMessages) {
const conversation: Conversation = {}; const { pushMessage, saveConversation } = newChatConversation();
const conversationOrder: string[] = [];
if (preset) if (preset)
for (const message of preset.messages) { for (const message of preset.messages) {
const newUuid = uuid(); pushMessage(message.role, message.content);
conversationOrder.push(newUuid);
conversation[newUuid] = {
sender: message.role === 'user' ? userName : botName,
type: MessageType.Normal,
color: message.role === 'user' ? 'brand' : 'colorful',
time: new Date().toISOString(),
content: message.content,
side: message.role === 'user' ? 'right' : 'left',
done: true
};
} }
commonStore.setConversation(conversation); saveConversation();
commonStore.setConversationOrder(conversationOrder);
//} //}
}; };
@ -613,3 +602,48 @@ export function getSupportedCustomCudaFile(isBeta: boolean) {
else else
return ''; return '';
} }
// a wrapper for webOpenOpenFileDialog and OpenOpenFileDialog
export function OpenFileDialog(filterPattern: string): Promise<Blob> {
return new Promise((resolve) => {
OpenOpenFileDialog(filterPattern).then(async filePath => {
if (!filePath)
return;
let blob: Blob;
if (commonStore.platform === 'web')
blob = (filePath as unknown as { blob: Blob }).blob;
else
blob = await fetch(absPathAsset(filePath)).then(r => r.blob());
resolve(blob);
}).catch(e => {
toast(t('Error') + ' - ' + (e.message || e), { type: 'error', autoClose: 2500 });
});
}
);
}
export function newChatConversation() {
const conversation: Conversation = {};
const conversationOrder: string[] = [];
const pushMessage = (role: Role, content: string) => {
const newUuid = uuid();
conversationOrder.push(newUuid);
conversation[newUuid] = {
sender: role === 'user' ? userName : botName,
type: MessageType.Normal,
color: role === 'user' ? 'brand' : 'colorful',
avatarImg: role === 'user' ? undefined : logo,
time: new Date().toISOString(),
content: content,
side: role === 'user' ? 'right' : 'left',
done: true
};
};
const saveConversation = () => {
commonStore.setConversation(conversation);
commonStore.setConversationOrder(conversationOrder);
};
return { pushMessage, saveConversation };
}