stiff
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
44f56e0554
commit
30ce68a949
3 changed files with 33 additions and 14 deletions
|
|
@ -13,13 +13,15 @@ export const voiceServiceApi = {
|
|||
* @param voice Voice identifier (optional, defaults to 'alloy')
|
||||
* @param language Language code (optional)
|
||||
* @param instructions Instructions for speech generation (optional)
|
||||
* @param model Model identifier (optional)
|
||||
* @returns Object ID and presigned URL
|
||||
*/
|
||||
async generateTTS(
|
||||
text: string,
|
||||
voice?: string,
|
||||
language?: string,
|
||||
instructions?: string
|
||||
instructions?: string,
|
||||
model?: string
|
||||
): Promise<GenerateTTSResponse> {
|
||||
const response = await adminApiClient.post<GenerateTTSResponse>(
|
||||
'/api/v2/media/generate-tts',
|
||||
|
|
@ -28,6 +30,7 @@ export const voiceServiceApi = {
|
|||
voice: voice || 'alloy',
|
||||
...(language && { language }),
|
||||
...(instructions && { instructions }),
|
||||
...(model && { model }),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export function CardVoicesManager({
|
|||
const [dialogVoice, setDialogVoice] = useState('alloy')
|
||||
const [dialogLanguage, setDialogLanguage] = useState('es')
|
||||
const [dialogInstructions, setDialogInstructions] = useState('pronunciar la frase claramente')
|
||||
const [dialogModel, setDialogModel] = useState('gpt-4o-mini-tts')
|
||||
|
||||
// Load voices for the card
|
||||
const { data: voicesData, isLoading, refetch } = useQuery({
|
||||
|
|
@ -124,6 +125,7 @@ export function CardVoicesManager({
|
|||
setDialogVoice('alloy')
|
||||
setDialogLanguage('es')
|
||||
setDialogInstructions('pronunciar la frase claramente')
|
||||
setDialogModel('gpt-4o-mini-tts')
|
||||
setShowTTSDialog(true)
|
||||
}
|
||||
|
||||
|
|
@ -146,12 +148,13 @@ export function CardVoicesManager({
|
|||
const voice = dialogVoice || 'alloy'
|
||||
const language = dialogLanguage || 'es'
|
||||
const instructions = dialogInstructions || undefined
|
||||
const model = dialogModel || undefined
|
||||
|
||||
console.log('🔄 CardVoicesManager: Requesting TTS generation', { text, voice, language, instructions })
|
||||
console.log('🔄 CardVoicesManager: Requesting TTS generation', { text, voice, language, instructions, model })
|
||||
|
||||
// Generate TTS via backend API
|
||||
// Backend calls voice-service (which handles caching) and saves to MinIO
|
||||
const ttsResponse = await voiceServiceApi.generateTTS(text, voice, language, instructions)
|
||||
const ttsResponse = await voiceServiceApi.generateTTS(text, voice, language, instructions, model)
|
||||
console.log('✅ CardVoicesManager: TTS generated and saved to MinIO', {
|
||||
objectId: ttsResponse.objectId
|
||||
})
|
||||
|
|
@ -311,16 +314,27 @@ export function CardVoicesManager({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="dialog-instructions">Instructions</Label>
|
||||
<Textarea
|
||||
id="dialog-instructions"
|
||||
value={dialogInstructions}
|
||||
onChange={(e) => setDialogInstructions(e.target.value)}
|
||||
placeholder="pronunciar la frase claramente"
|
||||
className="min-h-[80px]"
|
||||
disabled={isGeneratingTTS}
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="dialog-model">Model</Label>
|
||||
<Input
|
||||
id="dialog-model"
|
||||
value={dialogModel}
|
||||
onChange={(e) => setDialogModel(e.target.value)}
|
||||
placeholder="gpt-4o-mini-tts"
|
||||
disabled={isGeneratingTTS}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="dialog-instructions">Instructions</Label>
|
||||
<Input
|
||||
id="dialog-instructions"
|
||||
value={dialogInstructions}
|
||||
onChange={(e) => setDialogInstructions(e.target.value)}
|
||||
placeholder="pronunciar la frase claramente"
|
||||
disabled={isGeneratingTTS}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
|
|
|||
|
|
@ -511,13 +511,14 @@ class MediaApiV2 {
|
|||
final voice = json['voice'] as String?;
|
||||
final language = json['language'] as String?;
|
||||
final instructions = json['instructions'] as String?;
|
||||
final model = json['model'] as String?;
|
||||
|
||||
if (text == null || text.trim().isEmpty) {
|
||||
return _badRequest('Text is required');
|
||||
}
|
||||
|
||||
print(
|
||||
'🔄 MediaApiV2: Requesting TTS from voice-service: text="${text.substring(0, text.length > 50 ? 50 : text.length)}", voice="${voice ?? 'default'}", language="${language ?? 'not provided'}", instructions="${instructions != null ? instructions.substring(0, instructions.length > 50 ? 50 : instructions.length) : 'not provided'}"',
|
||||
'🔄 MediaApiV2: Requesting TTS from voice-service: text="${text.substring(0, text.length > 50 ? 50 : text.length)}", voice="${voice ?? 'default'}", language="${language ?? 'not provided'}", instructions="${instructions != null ? instructions.substring(0, instructions.length > 50 ? 50 : instructions.length) : 'not provided'}", model="${model ?? 'not provided'}"',
|
||||
);
|
||||
|
||||
// Call voice-service
|
||||
|
|
@ -529,6 +530,7 @@ class MediaApiV2 {
|
|||
'format': 'mp3',
|
||||
if (language != null) 'language': language,
|
||||
if (instructions != null) 'instructions': instructions,
|
||||
if (model != null) 'model': model,
|
||||
},
|
||||
options: dio.Options(
|
||||
responseType: dio.ResponseType.bytes,
|
||||
|
|
|
|||
Loading…
Reference in a new issue