Checkpoint current interactive fiction state

This commit is contained in:
2026-05-14 21:17:43 +02:00
parent c745efd1d2
commit 873049f7e6
183 changed files with 13755 additions and 1459 deletions
+28 -14
View File
@@ -41,17 +41,25 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
// API key is already loaded in parent initialize() method
// Just check if it's available
if (!this.apiKey) {
console.error('ElevenLabs TTS: API key not configured');
return false;
console.info('ElevenLabs TTS: API key not configured; provider unavailable until configured');
this.isReady = false;
this.reportProgress(100, 'ElevenLabs TTS not configured');
return true;
}
// Load voices from ElevenLabs
try {
this.reportProgress(50, 'Loading ElevenLabs voices');
await this.loadVoices(this.apiKey);
const voicesLoaded = await this.loadVoices(this.apiKey);
if (!voicesLoaded) {
this.isReady = false;
this.reportProgress(100, 'ElevenLabs TTS not ready');
return true;
}
} catch (error) {
console.error('ElevenLabs TTS: Failed to load voices:', error);
return false;
this.isReady = false;
return true;
}
// Load preferences
@@ -65,9 +73,9 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
this.voiceOptions.model = preferredModel;
}
const preferredSpeed = persistenceManager.getPreference('tts', `${this.id}_speed`, this.voiceOptions.speed);
const preferredSpeed = persistenceManager.getPreference('tts', 'speed', this.voiceOptions.speed);
if (typeof preferredSpeed === 'number') {
this.voiceOptions.speed = preferredSpeed;
this.voiceOptions.speed = this.getApiSpeed(preferredSpeed);
}
this.isReady = true;
@@ -119,7 +127,7 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
if (!response.ok) {
console.error(`ElevenLabs TTS: API error ${response.status} ${response.statusText}`);
return true; // Continue with default voices
return false;
}
const data = await response.json();
@@ -136,10 +144,10 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
return true;
}
return true; // Continue with default voices
return this.voices.length > 0;
} catch (error) {
console.error('ElevenLabs TTS: Error loading voices:', error);
return true; // Continue with default voices
return false;
}
}
@@ -188,7 +196,7 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
similarity_boost: 0.75,
style: 0.0,
use_speaker_boost: true,
speed: this.voiceOptions.speed || 1.0
speed: this.getApiSpeed(this.voiceOptions.speed)
}
};
@@ -198,13 +206,15 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
headers: {
'Content-Type': 'application/json',
'xi-api-key': this.apiKey,
'Accept': 'audio/wav'
'Accept': 'audio/mpeg'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
const errorText = await response.text();
console.error(`ElevenLabs API error ${response.status}: ${errorText}`);
throw new Error(`API error: ${response.status} ${response.statusText} - ${errorText}`);
}
// Get audio blob from response
@@ -244,7 +254,7 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
}
if (typeof options.speed === 'number') {
this.voiceOptions.speed = Math.max(0.5, Math.min(2.0, options.speed));
this.voiceOptions.speed = this.getApiSpeed(options.speed);
}
// Handle ElevenLabs-specific options
@@ -258,6 +268,10 @@ export class ElevenLabsTTSModule extends ApiTTSModuleBase {
}
}
}
getApiSpeed(speed) {
return Math.max(0.7, Math.min(1.2, Number.isFinite(speed) ? speed : 1.0));
}
}
const elevenLabsTTSModule = new ElevenLabsTTSModule();