diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-08 09:53:17 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-08 09:53:17 +0300 |
| commit | cd4265b8f87811db758c89bab5e62daa6c39337a (patch) | |
| tree | 94c0a129b4b6ee9132baaa81eb3fbc96b083cbd4 /internal/video | |
| parent | 7e7d34bfc0aec2aa8dff4cefa720e4a9b42d95d8 (diff) | |
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
Diffstat (limited to 'internal/video')
| -rw-r--r-- | internal/video/veo.go | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/internal/video/veo.go b/internal/video/veo.go index 018c06a..05fd0f3 100644 --- a/internal/video/veo.go +++ b/internal/video/veo.go @@ -13,6 +13,8 @@ import ( "time" "google.golang.org/genai" + + "codeberg.org/snonux/totalrecall/internal/httpctx" ) const ( @@ -48,7 +50,7 @@ type VeoGenerator struct { // newGenaiClient is the constructor used in production and can be replaced in // unit tests to inject a mock transport. -var newGenaiClient = genai.NewClient +var newGenaiClient = httpctx.NewGenAIClient // NewVeoGenerator creates a new VeoGenerator backed by the Gemini API. // It returns an error if the API key is empty or the SDK client cannot be @@ -82,6 +84,9 @@ func NewVeoGenerator(apiKey string) (*VeoGenerator, error) { // outputDir is where the output MP4 will be written. // pageNum selects which gallery page to animate (1-based). func (g *VeoGenerator) GenerateVideoFromGallery(ctx context.Context, galleryPath string, outputDir string, pageNum int) (string, error) { + ctx, cancel := httpctx.WithTimeoutUnlessSet(ctx, httpctx.VeoCLIPerVideoTimeout) + defer cancel() + imgPath, imgBytes, err := loadGalleryImage(galleryPath, pageNum) if err != nil { return "", err @@ -109,6 +114,9 @@ func (g *VeoGenerator) GenerateVideoFromGallery(ctx context.Context, galleryPath // because it avoids a second glob search and always writes the video next to // its source image. func (g *VeoGenerator) GenerateVideoFromPath(ctx context.Context, imgPath string) (string, error) { + ctx, cancel := httpctx.WithTimeoutUnlessSet(ctx, httpctx.VeoCLIPerVideoTimeout) + defer cancel() + imgBytes, err := os.ReadFile(imgPath) if err != nil { return "", fmt.Errorf("veo: reading gallery image %s: %w", imgPath, err) |
