in experiments/babel/speak.go [212:290]
func generateAudio(ctx context.Context, client *genai.Client, chosenVoice string, prompt string, prettyprint bool) (string, error) {
config := &genai.GenerateContentConfig{}
config.ResponseModalities = []string{"AUDIO"}
config.SpeechConfig = &genai.SpeechConfig{
VoiceConfig: &genai.VoiceConfig{
PrebuiltVoiceConfig: &genai.PrebuiltVoiceConfig{
VoiceName: chosenVoice,
},
},
}
/*
result, err := client.Models.GenerateContent(ctx, model, genai.Text(prompt), config)
if err != nil {
log.Fatal(err)
}
*/
var result *genai.GenerateContentResponse
var err error
maxRetries := 4
retryCount := 0
duration := 3 * time.Second // Initial backoff duration
maxDuration := 1 * time.Minute // Maximum backoff duration
for retryCount < maxRetries {
result, err = client.Models.GenerateContent(ctx, model, genai.Text(prompt), config)
if err == nil {
break // Success!
}
// TODO add break on 403, permission denied
log.Print(err.Error())
// retry logic
retryCount++
log.Printf("Error: %v, retrying in %v (attempt %d/%d)", err, duration, retryCount, maxRetries)
time.Sleep(duration) // Wait for the backoff duration
// Exponential backoff with jitter
duration *= 2
duration += time.Duration(rand.Int63n(int64(duration / 2))) // Add jitter
if duration > maxDuration {
duration = maxDuration
}
// TEMP try again with a random client
client = createGeminiClient(ctx, projectID)
}
if err != nil {
return "", fmt.Errorf("Failed after %d retries: %v", maxRetries, err)
}
if prettyprint {
prettyPrintJSON(result)
}
if result.Candidates[0].FinishReason == "STOP" {
timestamp := time.Now().Format(timeformat)
mimeType := result.Candidates[0].Content.Parts[0].InlineData.MIMEType
ext := getFileExtensionFromMimeType(mimeType)
var filename string
if outputfile == "" {
filename = fmt.Sprintf("%s-%s%s", timestamp, chosenVoice, ext)
} else {
filename = outputfile
}
audiobytes := result.Candidates[0].Content.Parts[0].InlineData.Data
err = os.WriteFile(filename, audiobytes, 0644)
if err != nil {
log.Println(err)
}
log.Printf("Written to %s", filename)
return filename, nil
} else {
log.Printf("Finish reason: %s", result.Candidates[0].FinishReason)
}
return "", fmt.Errorf("finish reason: %s", result.Candidates[0].FinishReason)
}