UI: голосовой ввод/STT, TTS через OpenAI, настройки инструментов + учёт недопроверенных фич

This commit is contained in:
AidarKC
2026-05-13 02:01:51 +03:00
parent ddeaf82bfd
commit 8de4e95c6a
15 changed files with 716 additions and 5 deletions
+28
View File
@@ -81,6 +81,31 @@ const DEFAULT_SOLANA_SERVER = 'https://api.devnet.solana.com';
const DEFAULT_SHINE_SERVER = 'wss://shineup.me/ws';
const DEFAULT_ARWEAVE_SERVER = 'https://arweave.net';
const DEFAULT_CALL_PREFLIGHT_TIMEOUT_MS = 6000;
const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';
function normalizeToolsSettings(rawTools) {
const source = rawTools && typeof rawTools === 'object' ? rawTools : {};
const stt = source.speechToText && typeof source.speechToText === 'object' ? source.speechToText : {};
const tts = source.textToSpeech && typeof source.textToSpeech === 'object' ? source.textToSpeech : {};
return {
speechToText: {
provider: String(stt.provider || 'openai'),
baseUrl: String(stt.baseUrl || DEFAULT_OPENAI_BASE_URL),
apiKey: String(stt.apiKey || ''),
quality: String(stt.quality || 'medium'),
model: String(stt.model || ''),
},
textToSpeech: {
provider: String(tts.provider || 'openai'),
quality: String(tts.quality || 'medium'),
voice: String(tts.voice || ''),
piperBaseUrl: String(tts.piperBaseUrl || 'http://127.0.0.1:5000'),
externalBaseUrl: String(tts.externalBaseUrl || ''),
apiKey: String(tts.apiKey || ''),
model: String(tts.model || ''),
},
};
}
function loadStoredSession() {
try {
@@ -153,6 +178,7 @@ function persistEntrySettings(settings) {
shineServer: String(settings?.statuses?.shineServer || 'idle'),
arweaveServer: String(settings?.statuses?.arweaveServer || 'idle'),
},
tools: normalizeToolsSettings(settings?.tools),
};
localStorage.setItem(ENTRY_SETTINGS_STORAGE_KEY, JSON.stringify(payload));
} catch {
@@ -216,6 +242,7 @@ function createInitialState({ withStoredSession = true } = {}) {
shineServer: String(storedEntrySettings?.statuses?.shineServer || 'idle'),
arweaveServer: String(storedEntrySettings?.statuses?.arweaveServer || 'idle'),
},
tools: normalizeToolsSettings(storedEntrySettings?.tools),
},
registrationDraft: {
flowType: '',
@@ -630,6 +657,7 @@ export async function saveEntrySettings(nextSettings) {
...state.entrySettings.statuses,
...(nextSettings.statuses || {}),
},
tools: normalizeToolsSettings(nextSettings.tools || state.entrySettings.tools),
};
persistEntrySettings(state.entrySettings);
await authService.reconnect(state.entrySettings.shineServer);