summaryrefslogtreecommitdiff
path: root/internal/audio
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-08 10:14:40 +0300
committerPaul Buetow <paul@buetow.org>2026-04-08 10:14:40 +0300
commitf7deedf50f6fa00c7dfe989ed381989e202b3057 (patch)
tree72fe642a99101da79d2103af911c8dcf88b08484 /internal/audio
parent14995ca7a76e2a72a2169def7f55f3b9e2433ee2 (diff)
feat: add gobreaker circuit breakers for OpenAI and Gemini API calls
Introduce internal/apicircuit with sony/gobreaker: trip after five consecutive failures, 45s open state, 2m count reset, half-open trial cap. context.Canceled is not counted as a failure for breaker stats. Wrap OpenAI TTS, Gemini TTS, OpenAI DALL-E/chat (image path), and Nano Banana Gemini GenerateContent calls. HTTP timeouts remain unchanged in httpctx. Made-with: Cursor
Diffstat (limited to 'internal/audio')
-rw-r--r--internal/audio/gemini_provider.go9
-rw-r--r--internal/audio/openai_provider.go7
2 files changed, 11 insertions, 5 deletions
diff --git a/internal/audio/gemini_provider.go b/internal/audio/gemini_provider.go
index b573a02..74478bd 100644
--- a/internal/audio/gemini_provider.go
+++ b/internal/audio/gemini_provider.go
@@ -13,6 +13,7 @@ import (
"google.golang.org/genai"
+ "codeberg.org/snonux/totalrecall/internal/apicircuit"
"codeberg.org/snonux/totalrecall/internal/httpctx"
)
@@ -78,9 +79,11 @@ func (p *GeminiProvider) GenerateAudio(ctx context.Context, text string, outputF
SpeechConfig: p.speechConfig(),
}
- response, err := p.client.Models.GenerateContent(ctx, p.config.TTSModel, []*genai.Content{
- genai.NewContentFromText(prompt, genai.RoleUser),
- }, req)
+ response, err := apicircuit.GeminiTTS(func() (*genai.GenerateContentResponse, error) {
+ return p.client.Models.GenerateContent(ctx, p.config.TTSModel, []*genai.Content{
+ genai.NewContentFromText(prompt, genai.RoleUser),
+ }, req)
+ })
if err != nil {
return fmt.Errorf("gemini API error: %w", err)
}
diff --git a/internal/audio/openai_provider.go b/internal/audio/openai_provider.go
index 5b59a3e..58a9fb6 100644
--- a/internal/audio/openai_provider.go
+++ b/internal/audio/openai_provider.go
@@ -11,6 +11,7 @@ import (
"github.com/sashabaranov/go-openai"
+ "codeberg.org/snonux/totalrecall/internal/apicircuit"
"codeberg.org/snonux/totalrecall/internal/httpctx"
)
@@ -92,8 +93,10 @@ func (p *OpenAIProvider) GenerateAudio(ctx context.Context, text string, outputF
}
}
- // Make the API call
- response, err := p.client.CreateSpeech(ctx, req)
+ // Make the API call (circuit breaker limits load when OpenAI is unhealthy).
+ response, err := apicircuit.OpenAITTS(func() (openai.RawResponse, error) {
+ return p.client.CreateSpeech(ctx, req)
+ })
if err != nil {
// Check if it's a model access error
errStr := err.Error()