import { event_types, eventSource, getRequestHeaders } from '../../../script.js'; import { SECRET_KEYS, secret_state } from '../../secrets.js'; import { getPreviewString, saveTtsProviderSettings } from './index.js'; export { ChutesTtsProvider }; class ChutesTtsProvider { settings; voices = []; models = []; separator = ' . '; defaultSettings = { voiceMap: {}, model: 'kokoro', speed: 1, }; get settingsHtml() { let html = `
Chutes TTS API
`; return html; } constructor() { this.handler = async function (/** @type {string} */ key) { if (key !== SECRET_KEYS.CHUTES) return; $('#chutes_tts_key').toggleClass('success', !!secret_state[SECRET_KEYS.CHUTES]); await this.onRefreshClick(); }.bind(this); } dispose() { [event_types.SECRET_WRITTEN, event_types.SECRET_DELETED, event_types.SECRET_ROTATED].forEach(event => { eventSource.removeListener(event, this.handler); }); } onSettingsChange() { this.settings.model = $('#chutes_tts_model').val(); this.settings.speed = Number($('#chutes_tts_speed').val()); saveTtsProviderSettings(); } async loadSettings(settings) { if (Object.keys(settings).length === 0) { Object.assign(settings, this.defaultSettings); } this.settings = settings; if (!this.settings.voiceMap) { this.settings.voiceMap = {}; } // Update UI $('#chutes_tts_model').val(this.settings.model); $('#chutes_tts_speed').val(this.settings.speed); $('#chutes_tts_speed_output').text(this.settings.speed); $('#chutes_tts_key').toggleClass('success', !!secret_state[SECRET_KEYS.CHUTES]); [event_types.SECRET_WRITTEN, event_types.SECRET_DELETED, event_types.SECRET_ROTATED].forEach(event => { eventSource.on(event, this.handler); }); await this.checkReady(); $('#chutes_tts_model').on('change', () => this.onSettingsChange()); $('#chutes_tts_speed').on('input', () => { const value = $('#chutes_tts_speed').val(); $('#chutes_tts_speed_output').text(String(value)); this.onSettingsChange(); }); } async checkReady() { await this.updateModels(); if (this.models.length === 0) { // No models available } await this.updateVoices(); } async onRefreshClick() { return await this.checkReady(); } async updateModels() { // For Chutes TTS, we always use the Kokoro model currently. this.models = ['kokoro']; $('#chutes_tts_model').empty(); $('#chutes_tts_model').append($('