diff --git a/internal/transcriber/adapter_groq_transcription.go b/internal/transcriber/adapter_groq_transcription.go deleted file mode 100644 index 54d0fe0..0000000 --- a/internal/transcriber/adapter_groq_transcription.go +++ /dev/null @@ -1,66 +0,0 @@ -package transcriber - -import ( - "bytes" - "context" - "fmt" - "log" - "strings" - "time" - - "github.com/sashabaranov/go-openai" -) - -// GroqTranscriptionAdapter implements BatchAdapter for Groq Whisper API -type GroqTranscriptionAdapter struct { - client *openai.Client - config Config -} - -func NewGroqTranscriptionAdapter(config Config) *GroqTranscriptionAdapter { - clientConfig := openai.DefaultConfig(config.APIKey) - clientConfig.BaseURL = "https://api.groq.com/openai/v1" - client := openai.NewClientWithConfig(clientConfig) - - return &GroqTranscriptionAdapter{ - client: client, - config: config, - } -} - -func (a *GroqTranscriptionAdapter) Transcribe(ctx context.Context, audioData []byte) (string, error) { - if len(audioData) == 0 { - return "", nil - } - - // Convert raw PCM to WAV format - wavData, err := convertToWAV(audioData) - if err != nil { - return "", fmt.Errorf("convert to WAV: %w", err) - } - - // Create transcription request - req := openai.AudioRequest{ - Model: a.config.Model, - Reader: bytes.NewReader(wavData), - FilePath: "audio.wav", - Language: a.config.Language, - } - - // Add keywords as prompt to help with spelling hints - if len(a.config.Keywords) > 0 { - req.Prompt = strings.Join(a.config.Keywords, ", ") - } - - start := time.Now() - resp, err := a.client.CreateTranscription(ctx, req) - duration := time.Since(start) - - if err != nil { - log.Printf("groq-transcription-adapter: API call failed after %v: %v", duration, err) - return "", fmt.Errorf("groq transcription: %w", err) - } - - log.Printf("groq-transcription-adapter: transcribed %d bytes in %v: %q", len(audioData), duration, resp.Text) - return resp.Text, nil -} diff --git a/internal/transcriber/adapter_mistral.go b/internal/transcriber/adapter_mistral.go deleted file mode 100644 index 4d8d0a9..0000000 --- a/internal/transcriber/adapter_mistral.go +++ /dev/null @@ -1,60 +0,0 @@ -package transcriber - -import ( - "bytes" - "context" - "fmt" - "log" - "time" - - "github.com/sashabaranov/go-openai" -) - -// MistralAdapter implements BatchAdapter for Mistral Voxtral API -type MistralAdapter struct { - client *openai.Client - config Config -} - -func NewMistralAdapter(config Config) *MistralAdapter { - clientConfig := openai.DefaultConfig(config.APIKey) - clientConfig.BaseURL = "https://api.mistral.ai/v1" - client := openai.NewClientWithConfig(clientConfig) - - return &MistralAdapter{ - client: client, - config: config, - } -} - -func (a *MistralAdapter) Transcribe(ctx context.Context, audioData []byte) (string, error) { - if len(audioData) == 0 { - return "", nil - } - - // Convert raw PCM to WAV format - wavData, err := convertToWAV(audioData) - if err != nil { - return "", fmt.Errorf("convert to WAV: %w", err) - } - - // Create transcription request - req := openai.AudioRequest{ - Model: a.config.Model, - Reader: bytes.NewReader(wavData), - FilePath: "audio.wav", - Language: a.config.Language, - } - - start := time.Now() - resp, err := a.client.CreateTranscription(ctx, req) - duration := time.Since(start) - - if err != nil { - log.Printf("mistral-adapter: API call failed after %v: %v", duration, err) - return "", fmt.Errorf("mistral transcription: %w", err) - } - - log.Printf("mistral-adapter: transcribed %d bytes in %v: %q", len(audioData), duration, resp.Text) - return resp.Text, nil -} diff --git a/internal/transcriber/transcriber.go b/internal/transcriber/transcriber.go index f5bfb04..51c204e 100644 --- a/internal/transcriber/transcriber.go +++ b/internal/transcriber/transcriber.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/leonardotrapani/hyprvoice/internal/provider" "github.com/leonardotrapani/hyprvoice/internal/recording" ) @@ -44,7 +45,9 @@ func NewTranscriber(config Config) (Transcriber, error) { if config.APIKey == "" { return nil, fmt.Errorf("Groq API key required") } - adapter = NewGroqTranscriptionAdapter(config) + // use consolidated OpenAI adapter with Groq endpoint + endpoint := &provider.EndpointConfig{BaseURL: "https://api.groq.com/openai"} + adapter = NewOpenAIAdapter(endpoint, config.APIKey, config.Model, config.Language, config.Keywords, "groq") case "groq-translation": if config.APIKey == "" { @@ -56,7 +59,9 @@ func NewTranscriber(config Config) (Transcriber, error) { if config.APIKey == "" { return nil, fmt.Errorf("Mistral API key required") } - adapter = NewMistralAdapter(config) + // use consolidated OpenAI adapter with Mistral endpoint + endpoint := &provider.EndpointConfig{BaseURL: "https://api.mistral.ai"} + adapter = NewOpenAIAdapter(endpoint, config.APIKey, config.Model, config.Language, config.Keywords, "mistral") case "elevenlabs": if config.APIKey == "" { diff --git a/progress.txt b/progress.txt index bb17e8a..2d326d3 100644 --- a/progress.txt +++ b/progress.txt @@ -115,3 +115,11 @@ Started: Sun Feb 1 12:22:47 AM CET 2026 - Added tests: `TestOpenAIAdapter_Creation`, `TestOpenAIAdapterFromConfig` - Updated factory to use `NewOpenAIAdapterFromConfig` for now (will be updated in Task 15) - All tests passing, typecheck passes + +### Task 13: Remove redundant Groq and Mistral transcription adapters +- Deleted `internal/transcriber/adapter_groq_transcription.go` +- Deleted `internal/transcriber/adapter_mistral.go` +- KEPT `adapter_groq_translation.go` (uses CreateTranslation, different from CreateTranscription) +- Updated `transcriber.go` factory to use consolidated OpenAI adapter for groq-transcription and mistral-transcription +- Both now use `NewOpenAIAdapter` with their respective endpoints +- All tests passing, typecheck passes diff --git a/tasks/prd.jsonc b/tasks/prd.jsonc index 8df67a9..21fe956 100644 --- a/tasks/prd.jsonc +++ b/tasks/prd.jsonc @@ -330,7 +330,7 @@ "No broken imports", "Typecheck passes" ], - "passes": false + "passes": true }, { "title": "Update ElevenLabs BatchAdapter to use EndpointConfig",