From cd4265b8f87811db758c89bab5e62daa6c39337a Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 8 Apr 2026 09:53:17 +0300 Subject: feat(httpctx): add timeouts for OpenAI, Gemini, and HTTP downloads Introduce internal/httpctx with non-zero http.Client timeouts for go-openai and google.golang.org/genai, shared image download client, and WithTimeoutUnlessSet for operation-level deadlines when callers use Background. Wire NewOpenAIClient/NewGenAIClient everywhere clients are constructed. Apply Search timeouts for DALL-E and Nano Banana, provider audio timeouts, model-list timeouts, Veo operation timeouts, story page download context, and single-word CLI processing cap. Made-with: Cursor --- internal/audio/gemini_provider.go | 7 ++++++- internal/audio/openai_provider.go | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'internal/audio') diff --git a/internal/audio/gemini_provider.go b/internal/audio/gemini_provider.go index 5100c5e..b573a02 100644 --- a/internal/audio/gemini_provider.go +++ b/internal/audio/gemini_provider.go @@ -12,6 +12,8 @@ import ( "strings" "google.golang.org/genai" + + "codeberg.org/snonux/totalrecall/internal/httpctx" ) const ( @@ -44,7 +46,7 @@ func NewGeminiProvider(config GeminiAudioConfig, outputFormat string) (Provider, return nil, errors.New("google API key is required") } - client, err := genai.NewClient(context.Background(), &genai.ClientConfig{ + client, err := httpctx.NewGenAIClient(context.Background(), &genai.ClientConfig{ APIKey: normalized.APIKey, Backend: genai.BackendGeminiAPI, }) @@ -60,6 +62,9 @@ func NewGeminiProvider(config GeminiAudioConfig, outputFormat string) (Provider, // GenerateAudio generates audio using Gemini TTS and writes it to the output file. func (p *GeminiProvider) GenerateAudio(ctx context.Context, text string, outputFile string) error { + ctx, cancel := httpctx.WithTimeoutUnlessSet(ctx, httpctx.GenAIHTTPTimeout) + defer cancel() + if err := ValidateBulgarianText(text); err != nil { return err } diff --git a/internal/audio/openai_provider.go b/internal/audio/openai_provider.go index e6212f8..5b59a3e 100644 --- a/internal/audio/openai_provider.go +++ b/internal/audio/openai_provider.go @@ -10,6 +10,8 @@ import ( "strings" "github.com/sashabaranov/go-openai" + + "codeberg.org/snonux/totalrecall/internal/httpctx" ) // Compile-time check that OpenAIProvider implements the Provider interface. @@ -31,7 +33,7 @@ func NewOpenAIProvider(config OpenAIAudioConfig, outputFormat string) (Provider, } return &OpenAIProvider{ - client: openai.NewClient(config.Key), + client: httpctx.NewOpenAIClient(config.Key), config: config, outputFormat: outputFormat, }, nil @@ -39,6 +41,9 @@ func NewOpenAIProvider(config OpenAIAudioConfig, outputFormat string) (Provider, // GenerateAudio generates audio using OpenAI TTS func (p *OpenAIProvider) GenerateAudio(ctx context.Context, text string, outputFile string) error { + ctx, cancel := httpctx.WithTimeoutUnlessSet(ctx, httpctx.OpenAIHTTPTimeout) + defer cancel() + // Validate Bulgarian text if err := ValidateBulgarianText(text); err != nil { return err -- cgit v1.2.3