better compatibility for custom api (ollama etc.)

This commit is contained in:
josc146 2024-03-26 21:33:30 +08:00
parent 253568ef29
commit a15c4bdf63
7 changed files with 42 additions and 20 deletions

View File

@ -353,5 +353,6 @@
"The name used internally by the model when processing AI message, changing this value helps improve the role-playing effect.": "AIメッセージを処理する際にモデルが内部で使用する名前、この値を変更することで、役割演技の効果を向上させることができます。", "The name used internally by the model when processing AI message, changing this value helps improve the role-playing effect.": "AIメッセージを処理する際にモデルが内部で使用する名前、この値を変更することで、役割演技の効果を向上させることができます。",
"Inside the model, there is a default prompt to improve the model's handling of common issues, but it may degrade the role-playing effect. You can disable this option to achieve a better role-playing effect.": "モデル内部には、一般的な問題の処理を改善するためのデフォルトのプロンプトがありますが、役割演技の効果を低下させる可能性があります。このオプションを無効にすることで、より良い役割演技効果を得ることができます。", "Inside the model, there is a default prompt to improve the model's handling of common issues, but it may degrade the role-playing effect. You can disable this option to achieve a better role-playing effect.": "モデル内部には、一般的な問題の処理を改善するためのデフォルトのプロンプトがありますが、役割演技の効果を低下させる可能性があります。このオプションを無効にすることで、より良い役割演技効果を得ることができます。",
"Exit without saving": "保存せずに終了", "Exit without saving": "保存せずに終了",
"Content has been changed, are you sure you want to exit without saving?": "コンテンツが変更されています、保存せずに終了してもよろしいですか?" "Content has been changed, are you sure you want to exit without saving?": "コンテンツが変更されています、保存せずに終了してもよろしいですか?",
"Don't forget to correctly fill in your Ollama API Chat Model Name.": "Ollama APIチャットモデル名を正しく記入するのを忘れないでください。"
} }

View File

@ -353,5 +353,6 @@
"The name used internally by the model when processing AI message, changing this value helps improve the role-playing effect.": "模型内部处理AI发言时使用的名称, 更改此值有助于改善角色扮演效果", "The name used internally by the model when processing AI message, changing this value helps improve the role-playing effect.": "模型内部处理AI发言时使用的名称, 更改此值有助于改善角色扮演效果",
"Inside the model, there is a default prompt to improve the model's handling of common issues, but it may degrade the role-playing effect. You can disable this option to achieve a better role-playing effect.": "模型内部有一个默认提示来改善模型处理常规问题的效果, 但它可能会让角色扮演的效果变差, 你可以关闭此选项来获得更好的角色扮演效果", "Inside the model, there is a default prompt to improve the model's handling of common issues, but it may degrade the role-playing effect. You can disable this option to achieve a better role-playing effect.": "模型内部有一个默认提示来改善模型处理常规问题的效果, 但它可能会让角色扮演的效果变差, 你可以关闭此选项来获得更好的角色扮演效果",
"Exit without saving": "退出而不保存", "Exit without saving": "退出而不保存",
"Content has been changed, are you sure you want to exit without saving?": "内容已经被修改, 你确定要退出而不保存吗?" "Content has been changed, are you sure you want to exit without saving?": "内容已经被修改, 你确定要退出而不保存吗?",
"Don't forget to correctly fill in your Ollama API Chat Model Name.": "不要忘记正确填写你的Ollama API 聊天模型名"
} }

View File

@ -32,7 +32,7 @@ import {
flushMidiRecordingContent, flushMidiRecordingContent,
getMidiRawContentMainInstrument, getMidiRawContentMainInstrument,
getMidiRawContentTime, getMidiRawContentTime,
getServerRoot, getReqUrl,
OpenFileDialog, OpenFileDialog,
refreshTracksTotalTime refreshTracksTotalTime
} from '../../utils'; } from '../../utils';
@ -474,8 +474,13 @@ const AudiotrackEditor: FC<{ setPrompt: (prompt: string) => void }> = observer((
OpenFileDialog('*.mid').then(async blob => { OpenFileDialog('*.mid').then(async 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', { const {
url,
headers
} = await getReqUrl(commonStore.getCurrentModelConfig().apiParameters.apiPort, '/midi-to-text');
fetch(url, {
method: 'POST', method: 'POST',
headers,
body: bodyForm body: bodyForm
}).then(async r => { }).then(async r => {
if (r.status === 200) { if (r.status === 200) {

View File

@ -41,7 +41,7 @@ import { OpenFileFolder, OpenOpenFileDialog, OpenSaveFileDialog } from '../../wa
import { import {
absPathAsset, absPathAsset,
bytesToReadable, bytesToReadable,
getServerRoot, getReqUrl,
newChatConversation, newChatConversation,
OpenFileDialog, OpenFileDialog,
setActivePreset, setActivePreset,
@ -475,7 +475,7 @@ const ChatPanel: FC = observer(() => {
// if answerId is not null, override the answer with new response; // if answerId is not null, override the answer with new response;
// if startUuid is null, start generating api body messages from first message; // if startUuid is null, start generating api body messages from first message;
// if endUuid is null, generate api body messages until last message; // if endUuid is null, generate api body messages until last message;
const onSubmit = useCallback((message: string | null = null, answerId: string | null = null, const onSubmit = useCallback(async (message: string | null = null, answerId: string | null = null,
startUuid: string | null = null, endUuid: string | null = null, includeEndUuid: boolean = false) => { startUuid: string | null = null, endUuid: string | null = null, includeEndUuid: boolean = false) => {
if (message) { if (message) {
const newId = uuid(); const newId = uuid();
@ -557,13 +557,15 @@ const ChatPanel: FC = observer(() => {
}; };
const chatSseController = new AbortController(); const chatSseController = new AbortController();
chatSseControllers[answerId] = chatSseController; chatSseControllers[answerId] = chatSseController;
const { url, headers } = await getReqUrl(port, '/v1/chat/completions', true);
fetchEventSource( // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/v1/chat/completions fetchEventSource( // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/v1/chat/completions
getServerRoot(port, true) + '/v1/chat/completions', url,
{ {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${commonStore.settings.apiKey}` Authorization: `Bearer ${commonStore.settings.apiKey}`,
...headers
}, },
body: JSON.stringify({ body: JSON.stringify({
messages: messages.slice(-commonStore.chatParams.historyN), messages: messages.slice(-commonStore.chatParams.historyN),
@ -727,8 +729,10 @@ const ChatPanel: FC = observer(() => {
const urlPath = `/file-to-text?file_name=${attachmentName}`; const urlPath = `/file-to-text?file_name=${attachmentName}`;
const bodyForm = new FormData(); const bodyForm = new FormData();
bodyForm.append('file_data', blob, attachmentName); bodyForm.append('file_data', blob, attachmentName);
fetch(getServerRoot(port) + urlPath, { const { url, headers } = await getReqUrl(port, urlPath);
fetch(url, {
method: 'POST', method: 'POST',
headers,
body: bodyForm body: bodyForm
}).then(async r => { }).then(async r => {
if (r.status === 200) { if (r.status === 200) {

View File

@ -14,7 +14,7 @@ import { ToolTipButton } from '../components/ToolTipButton';
import { ArrowSync20Regular } from '@fluentui/react-icons'; import { ArrowSync20Regular } from '@fluentui/react-icons';
import { defaultPresets } from './defaultConfigs'; import { defaultPresets } from './defaultConfigs';
import { CompletionParams, CompletionPreset } from '../types/completion'; import { CompletionParams, CompletionPreset } from '../types/completion';
import { getServerRoot } from '../utils'; import { getReqUrl } from '../utils';
let completionSseController: AbortController | null = null; let completionSseController: AbortController | null = null;
@ -68,7 +68,7 @@ const CompletionPanel: FC = observer(() => {
}); });
}; };
const onSubmit = (prompt: string) => { const onSubmit = async (prompt: string) => {
commonStore.setCompletionSubmittedPrompt(prompt); commonStore.setCompletionSubmittedPrompt(prompt);
if (commonStore.status.status === ModelStatus.Offline && !commonStore.settings.apiUrl && commonStore.platform !== 'web') { if (commonStore.status.status === ModelStatus.Offline && !commonStore.settings.apiUrl && commonStore.platform !== 'web') {
@ -86,13 +86,15 @@ const CompletionPanel: FC = observer(() => {
commonStore.setCompletionGenerating(false); commonStore.setCompletionGenerating(false);
}; };
completionSseController = new AbortController(); completionSseController = new AbortController();
const { url, headers } = await getReqUrl(port, '/v1/completions', true);
fetchEventSource( // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/v1/completions fetchEventSource( // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/v1/completions
getServerRoot(port, true) + '/v1/completions', url,
{ {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${commonStore.settings.apiKey}` Authorization: `Bearer ${commonStore.settings.apiKey}`,
...headers
}, },
body: JSON.stringify({ body: JSON.stringify({
prompt, prompt,

View File

@ -26,7 +26,7 @@ import {
SaveFile, SaveFile,
StartFile StartFile
} from '../../wailsjs/go/backend_golang/App'; } from '../../wailsjs/go/backend_golang/App';
import { getServerRoot, getSoundFont, toastWithButton } from '../utils'; import { getReqUrl, getSoundFont, toastWithButton } from '../utils';
import { CompositionParams } from '../types/composition'; import { CompositionParams } from '../types/composition';
import { useMediaQuery } from 'usehooks-ts'; import { useMediaQuery } from 'usehooks-ts';
import { AudiotrackButton } from './AudiotrackManager/AudiotrackButton'; import { AudiotrackButton } from './AudiotrackManager/AudiotrackButton';
@ -135,7 +135,7 @@ const CompositionPanel: FC = observer(() => {
} }
}, [commonStore.midiPorts]); }, [commonStore.midiPorts]);
const generateNs = (autoPlay: boolean) => { const generateNs = async (autoPlay: boolean) => {
if (commonStore.getCurrentModelConfig().modelParameters.modelName.toLowerCase().includes('abc')) { if (commonStore.getCurrentModelConfig().modelParameters.modelName.toLowerCase().includes('abc')) {
import('abcjs').then(ABCJS => { import('abcjs').then(ABCJS => {
ABCJS.renderAbc('abc-paper', commonStore.compositionParams.prompt, { responsive: 'resize' }); ABCJS.renderAbc('abc-paper', commonStore.compositionParams.prompt, { responsive: 'resize' });
@ -143,10 +143,12 @@ const CompositionPanel: FC = observer(() => {
return; return;
} }
fetch(getServerRoot(port) + '/text-to-midi', { const { url, headers } = await getReqUrl(port, '/text-to-midi');
fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json',
...headers
}, },
body: JSON.stringify({ body: JSON.stringify({
'text': commonStore.compositionParams.prompt.replaceAll(/<pad>|<start>|<end>/g, '').replaceAll(' ', ' ').trim() 'text': commonStore.compositionParams.prompt.replaceAll(/<pad>|<start>|<end>/g, '').replaceAll(' ', ' ').trim()
@ -175,7 +177,7 @@ const CompositionPanel: FC = observer(() => {
}); });
}; };
const onSubmit = (prompt: string) => { const onSubmit = async (prompt: string) => {
commonStore.setCompositionSubmittedPrompt(prompt); commonStore.setCompositionSubmittedPrompt(prompt);
if (commonStore.status.status === ModelStatus.Offline && !commonStore.settings.apiUrl && commonStore.platform !== 'web') { if (commonStore.status.status === ModelStatus.Offline && !commonStore.settings.apiUrl && commonStore.platform !== 'web') {
@ -192,13 +194,15 @@ const CompositionPanel: FC = observer(() => {
generateNs(commonStore.compositionParams.autoPlay); generateNs(commonStore.compositionParams.autoPlay);
}; };
compositionSseController = new AbortController(); compositionSseController = new AbortController();
const { url, headers } = await getReqUrl(port, '/v1/completions', true);
fetchEventSource( // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/v1/completions fetchEventSource( // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/v1/completions
getServerRoot(port, true) + '/v1/completions', url,
{ {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${commonStore.settings.apiKey}` Authorization: `Bearer ${commonStore.settings.apiKey}`,
...headers
}, },
body: JSON.stringify({ body: JSON.stringify({
prompt, prompt,

View File

@ -17,6 +17,7 @@ import { useTranslation } from 'react-i18next';
import { checkUpdate, toastWithButton } from '../utils'; import { checkUpdate, toastWithButton } from '../utils';
import { RestartApp } from '../../wailsjs/go/backend_golang/App'; import { RestartApp } from '../../wailsjs/go/backend_golang/App';
import { Language, Languages } from '../types/settings'; import { Language, Languages } from '../types/settings';
import { toast } from 'react-toastify';
export const GeneralSettings: FC = observer(() => { export const GeneralSettings: FC = observer(() => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -113,11 +114,15 @@ export const AdvancedGeneralSettings: FC = observer(() => {
commonStore.setSettings({ commonStore.setSettings({
apiCompletionModelName: 'rwkv' apiCompletionModelName: 'rwkv'
}); });
} else if (data.optionText === 'Ollama') {
toast(t('Don\'t forget to correctly fill in your Ollama API Chat Model Name.'),
{ type: 'info' });
} }
}}> }}>
<Option value="">{t('Localhost')!}</Option> <Option value="">{t('Localhost')!}</Option>
<Option value="https://rwkv.ai-creator.net/chntuned">RWKV</Option> <Option value="https://rwkv.ai-creator.net/chntuned">RWKV</Option>
<Option value="https://api.openai.com">OpenAI</Option> <Option value="https://api.openai.com">OpenAI</Option>
<Option value="http://localhost:11434">Ollama</Option>
</Dropdown> </Dropdown>
</div> </div>
} /> } />