summaryrefslogtreecommitdiff
path: root/internal/audio/provider.go
AgeCommit message (Collapse)Author
2026-04-08config: centralize NanoBanana and audio defaults in defaults.goPaul Buetow
Add internal/config/defaults.go with shared model IDs, output format, OpenAI/Gemini audio literals, and speed defaults. Wire audio.DefaultProviderConfig, CLI flags, GUI defaulting paths, and image package re-exports to these constants. Update command_test to use the public config identifiers. Made-with: Cursor
2026-04-08refactor: registry pattern for audio and image provider factoriesPaul Buetow
Add internal/registry generic Registry[K,T] for keyed factory registration. Wire audio.NewProvider via registered per-provider constructors; GUI and processor newImageSearcher use registries of *Orchestrator/*Processor methods. Export image.ImageProviderOpenAI and ImageProviderNanoBanana from search.go and use them across gui to avoid duplicate string constants. Made-with: Cursor
2026-04-06refactor: consolidate provider factory test seams into shared named typesPaul Buetow
Define audio.ProviderFactory, image.PromptAwareClient, image.OpenAIClientFactory, image.NanoBananaClientFactory, and image.ClientFactories as the single source of truth for the three injectable factory signatures that were previously duplicated across processor.Processor, gui.Application, and gui.GenerationOrchestrator. Replace all three separate function-type fields with imageFactories image.ClientFactories + newAudioProvider audio.ProviderFactory, eliminating the parallel field declarations and the local promptAwareImageClient interface in gui/generator.go. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06refactor: decompose Processor god object into focused files (SRP)Paul Buetow
Extract audio coordination (voice selection, config assembly, attribution writing) into audio_coordinator.go, card directory management into card_store.go, and image downloading/searcher construction into image_downloader.go. processor.go shrinks from ~1119 to ~575 lines, each file now has a single clear responsibility. Also apply go fmt to all touched files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02task zz: add Voices()/BuildAttribution() to Provider interface [OCP]Paul Buetow
Extend audio.Provider with Voices() []string and BuildAttribution() string so all provider-specific behaviour is encapsulated in the implementation rather than scattered as switch-cases across callers. Add package-level VoicesFor(name) and BuildAttributionFor(name, params) for callers (processor, GUI) that need these before constructing a Provider instance. Add AttributionParamsFrom(config, word, ...) so callers can build AttributionParams from the flat Config without a manual provider switch. Implement both new interface methods in OpenAIProvider and GeminiProvider. Update all Provider mock/fake types in tests. Migrate audioVoicesForProvider() and saveAudioAttribution() in both processor.go and gui/generator.go to use the new package-level helpers, replacing the 10+ duplicated switch blocks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02task 00j: separate OpenAI vs Gemini provider-specific config fields [ISP]Paul Buetow
Introduce OpenAIAudioConfig and GeminiAudioConfig sub-structs so each provider implementation only receives the fields it needs. NewOpenAIProvider and NewGeminiProvider now accept their respective sub-configs; NewProvider extracts the appropriate sub-config from the flat Config via two helper functions. The flat Config struct is preserved unchanged for all external callers (gui, processor, tests) so no consumer needs to be updated. InstructionForProvider in sidecar.go uses the helpers to extract sub-configs before calling provider-specific helpers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02task 00g/00k/00h/008: gofmt, remove ProviderWithFallback, stdlib helpers, ↵Paul Buetow
shared prompt - task 00g: fix gofmt violations (trailing whitespace, missing newlines, indentation) in 8 files; all pass gofmt -l now - task 00k: remove unused ProviderWithFallback and its tests (YAGNI — no production caller existed; voice-level fallback via RunWithVoiceFallbacks already covers the real use case) - task 00h: replace private splitLines/trimSpace/isSpace helpers in internal/batch/processor.go with strings.Split+ReplaceAll and strings.TrimSpace from the stdlib; remove the now-redundant tests - task 008: extract buildEducationalPrompt into internal/image/prompt.go so the prompt-assembly policy (scene truncation cascade, char limit) lives in one place; both OpenAIClient and NanoBananaClient delegate to it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02task 00m/00n/00b: remove dead stub, add interface assertions, fix HTTP timeoutPaul Buetow
- Remove dead DownloadImage stub from image/search.go (always returned nil, real implementation lives in Downloader.DownloadImage in download.go) - Add compile-time interface assertions for OpenAIProvider, ProviderWithFallback, and OpenAIClient to catch interface drift at compile time - Replace http.DefaultClient (no timeout) with a shared imageHTTPClient (60s timeout) in both OpenAIClient and NanoBananaClient Download methods; prevents goroutine hangs on slow/unresponsive image servers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02Release v0.9.0v0.9.0Paul Buetow
2026-04-02Fix verification gate lint and test issuesPaul Buetow
2026-04-01Align Gemini audio defaults with TTS APIPaul Buetow
2026-04-01Fix Gemini audio provider defaultsPaul Buetow
2026-04-01zg: extract shared audio voice listsPaul Buetow
2026-04-01zf: align Gemini TTS default modelPaul Buetow
2026-04-01zf: fix Gemini provider routing and output validationPaul Buetow
2026-04-01zf: add Gemini TTS providerPaul Buetow
2025-07-22Remove audio cache feature to simplify codebase and avoid cache-related issuesPaul Buetow
🤖 Generated with [opencode](https://opencode.ai) Co-Authored-By: opencode <noreply@opencode.ai>
2025-07-19feat: improve flashcard storage and audio regenerationv0.6.0Paul Buetow
- Change default card storage from ~/Downloads to ~/.local/state/totalrecall/cards/ - Keep .apkg exports in ~/Downloads for user convenience - Fix audio regeneration to use random voice and speed (0.9-1.0) - Fix GNOME dock icon by updating StartupWMClass to "Totalrecall" - Fix navigation to properly find cards in new XDG state directory - Ensure config defaults are properly filled when using GUI mode - Bump version to 0.6.0 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19feat: update default voice to alloy with speed 0.98Paul Buetow
- Changed default voice from 'nova' to 'alloy' - Changed default speed from 0.9 to 0.98 for better clarity - GUI now uses default voice/speed for first generation - Regeneration still uses random voice/speed for variety 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-16feat: add Fyne GUI mode with interactive flashcard managementPaul Buetow
- Add --gui flag to launch interactive GUI mode - Implement word navigation with prev/next buttons through existing cards - Add delete functionality to remove unwanted flashcards - Add fine-grained regeneration (image-only, audio-only, or both) - Implement audio playback using mpg123 on Linux - Auto-load first word on startup if cards exist - Save translation files for navigation persistence - Use DALL-E 2 with 512x512 images (half size) - Update audio speed to 0.9 (from 0.8) - Add comprehensive GUI documentation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15feat: remove espeak, add random voice/style selection, fix punctuation in TTSPaul Buetow
- Removed espeak audio provider completely, now only uses OpenAI TTS - Audio now uses random voice selection by default (can override with --openai-voice) - Added --all-voices flag to generate audio in all 11 OpenAI voices - Images now use random art styles (13 different styles including superhero, yoga, cat-themed) - Fixed TTS to remove punctuation marks before speaking - Updated Bulgarian pronunciation instructions to explicitly avoid Russian accent 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15feat: add OpenAI gpt-4o-mini-tts support with voice instructionsPaul Buetow
- Add support for OpenAI's new gpt-4o-mini-tts model with customizable voice instructions - Add OpenAIInstruction field to audio configuration for natural language voice control - Update CLI with --openai-instruction flag for runtime voice customization - Enhanced cache key generation to include voice instructions - Update default model to gpt-4o-mini-tts with Bulgarian-optimized instructions - Add support for new voices: ash, ballad, coral, sage, verse - Improve error handling for models requiring special API access - Update documentation with examples and model information - Create .totalrecall.yaml.example with comprehensive configuration options Note: The gpt-4o-mini-tts model requires special API access and may not be available to all accounts yet. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15feat: add OpenAI DALL-E image generation and make OpenAI defaultv0.1.0Paul Buetow
- Implement OpenAI DALL-E provider for generating educational flashcard images - Add support for DALL-E 2 and DALL-E 3 with configurable size, quality, and style - Implement intelligent caching to minimize API costs - Make OpenAI the default provider for both audio (TTS) and images (DALL-E) - Add automatic fallback to free alternatives (espeak/pixabay) when OpenAI unavailable - Fix bug where cached images couldn't be copied to output directory - Update documentation with OpenAI setup instructions and examples - Add comprehensive unit tests for OpenAI image provider - Bump version to 0.1.0 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14initial commitPaul Buetow