rename TranscriptionAdapter to BatchAdapter, add StreamingAdapter interface

This commit is contained in:
leonardotrapani
2026-02-01 00:35:38 +01:00
parent c23ac60b8f
commit db7e3951a5
12 changed files with 57 additions and 22 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ func MockAudioFrame(data []byte) recording.AudioFrame {
} }
} }
// MockTranscriberAdapter implements transcriber.TranscriptionAdapter for testing // MockTranscriberAdapter implements transcriber.BatchAdapter for testing
type MockTranscriberAdapter struct { type MockTranscriberAdapter struct {
TranscribeFunc func(ctx context.Context, audioData []byte) (string, error) TranscribeFunc func(ctx context.Context, audioData []byte) (string, error)
} }
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"time" "time"
) )
// ElevenLabsAdapter implements TranscriptionAdapter for ElevenLabs Scribe API // ElevenLabsAdapter implements BatchAdapter for ElevenLabs Scribe API
type ElevenLabsAdapter struct { type ElevenLabsAdapter struct {
client *http.Client client *http.Client
config Config config Config
@@ -11,7 +11,7 @@ import (
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
) )
// GroqTranscriptionAdapter implements TranscriptionAdapter for Groq Whisper API // GroqTranscriptionAdapter implements BatchAdapter for Groq Whisper API
type GroqTranscriptionAdapter struct { type GroqTranscriptionAdapter struct {
client *openai.Client client *openai.Client
config Config config Config
@@ -11,7 +11,7 @@ import (
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
) )
// GroqTranslationAdapter implements TranscriptionAdapter for Groq Translation API // GroqTranslationAdapter implements BatchAdapter for Groq Translation API
// Translates audio to English text. The Language field in config hints at the source language. // Translates audio to English text. The Language field in config hints at the source language.
type GroqTranslationAdapter struct { type GroqTranslationAdapter struct {
client *openai.Client client *openai.Client
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
) )
// MistralAdapter implements TranscriptionAdapter for Mistral Voxtral API // MistralAdapter implements BatchAdapter for Mistral Voxtral API
type MistralAdapter struct { type MistralAdapter struct {
client *openai.Client client *openai.Client
config Config config Config
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
) )
// OpenAIAdapter implements TranscriptionAdapter for OpenAI Whisper API // OpenAIAdapter implements BatchAdapter for OpenAI Whisper API
type OpenAIAdapter struct { type OpenAIAdapter struct {
client *openai.Client client *openai.Client
config Config config Config
+2 -2
View File
@@ -11,7 +11,7 @@ import (
// SimpleTranscriber collects all audio and transcribes when stopped // SimpleTranscriber collects all audio and transcribes when stopped
type SimpleTranscriber struct { type SimpleTranscriber struct {
adapter TranscriptionAdapter adapter BatchAdapter
config Config config Config
// Audio collection // Audio collection
@@ -27,7 +27,7 @@ type SimpleTranscriber struct {
transcriptionText string transcriptionText string
} }
func NewSimpleTranscriber(config Config, adapter TranscriptionAdapter) *SimpleTranscriber { func NewSimpleTranscriber(config Config, adapter BatchAdapter) *SimpleTranscriber {
return &SimpleTranscriber{ return &SimpleTranscriber{
adapter: adapter, adapter: adapter,
config: config, config: config,
+25
View File
@@ -0,0 +1,25 @@
package transcriber
import "context"
// TranscriptionResult represents a single transcription result from a streaming adapter
type TranscriptionResult struct {
Text string // the transcription text (partial or final)
IsFinal bool // true if this is a final result, false for interim results
Error error // non-nil if an error occurred
}
// StreamingAdapter interface for streaming transcription backends (send audio in real-time)
type StreamingAdapter interface {
// Start initiates the streaming connection with the given language setting
Start(ctx context.Context, language string) error
// SendChunk sends a chunk of audio data to the transcription service
SendChunk(audio []byte) error
// Results returns a channel that receives transcription results (partial and final)
Results() <-chan TranscriptionResult
// Close gracefully closes the streaming connection
Close() error
}
+3 -3
View File
@@ -14,8 +14,8 @@ type Transcriber interface {
GetFinalTranscription() (string, error) GetFinalTranscription() (string, error)
} }
// Adapter interface for different transcription backends // BatchAdapter interface for batch transcription backends (collect all audio, transcribe at end)
type TranscriptionAdapter interface { type BatchAdapter interface {
Transcribe(ctx context.Context, audioData []byte) (string, error) Transcribe(ctx context.Context, audioData []byte) (string, error)
} }
@@ -31,7 +31,7 @@ type Config struct {
// NewTranscriber creates a new simple transcriber // NewTranscriber creates a new simple transcriber
func NewTranscriber(config Config) (Transcriber, error) { func NewTranscriber(config Config) (Transcriber, error) {
// Create the appropriate adapter // Create the appropriate adapter
var adapter TranscriptionAdapter var adapter BatchAdapter
switch config.Provider { switch config.Provider {
case "openai": case "openai":
+10 -10
View File
@@ -195,12 +195,12 @@ func TestConfig(t *testing.T) {
} }
} }
// MockTranscriptionAdapter implements TranscriptionAdapter for testing // MockBatchAdapter implements BatchAdapter for testing
type MockTranscriptionAdapter struct { type MockBatchAdapter struct {
TranscribeFunc func(ctx context.Context, audioData []byte) (string, error) TranscribeFunc func(ctx context.Context, audioData []byte) (string, error)
} }
func (m *MockTranscriptionAdapter) Transcribe(ctx context.Context, audioData []byte) (string, error) { func (m *MockBatchAdapter) Transcribe(ctx context.Context, audioData []byte) (string, error) {
if m.TranscribeFunc != nil { if m.TranscribeFunc != nil {
return m.TranscribeFunc(ctx, audioData) return m.TranscribeFunc(ctx, audioData)
} }
@@ -215,7 +215,7 @@ func TestSimpleTranscriber_Start(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{} adapter := &MockBatchAdapter{}
transcriber := NewSimpleTranscriber(config, adapter) transcriber := NewSimpleTranscriber(config, adapter)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
@@ -255,7 +255,7 @@ func TestSimpleTranscriber_Stop(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{} adapter := &MockBatchAdapter{}
transcriber := NewSimpleTranscriber(config, adapter) transcriber := NewSimpleTranscriber(config, adapter)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
@@ -299,7 +299,7 @@ func TestSimpleTranscriber_GetFinalTranscription(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{ adapter := &MockBatchAdapter{
TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) { TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) {
return "test transcription", nil return "test transcription", nil
}, },
@@ -327,7 +327,7 @@ func TestSimpleTranscriber_CollectAudio(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{} adapter := &MockBatchAdapter{}
transcriber := NewSimpleTranscriber(config, adapter) transcriber := NewSimpleTranscriber(config, adapter)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
@@ -411,7 +411,7 @@ func TestSimpleTranscriber_TranscribeAll(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{ adapter := &MockBatchAdapter{
TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) { TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) {
return tt.mockResult, tt.mockError return tt.mockResult, tt.mockError
}, },
@@ -452,7 +452,7 @@ func TestNewSimpleTranscriber(t *testing.T) {
Model: "whisper-1", Model: "whisper-1",
} }
adapter := &MockTranscriptionAdapter{} adapter := &MockBatchAdapter{}
transcriber := NewSimpleTranscriber(config, adapter) transcriber := NewSimpleTranscriber(config, adapter)
if transcriber == nil { if transcriber == nil {
@@ -478,7 +478,7 @@ func TestNewSimpleTranscriber(t *testing.T) {
} }
func TestTranscriptionAdapter(t *testing.T) { func TestTranscriptionAdapter(t *testing.T) {
adapter := &MockTranscriptionAdapter{ adapter := &MockBatchAdapter{
TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) { TranscribeFunc: func(ctx context.Context, audioData []byte) (string, error) {
return "test result", nil return "test result", nil
}, },
+10
View File
@@ -40,3 +40,13 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
- Updated TUI files to use ModelsOfType instead of old SupportsTranscription/SupportsLLM - Updated TUI files to use ModelsOfType instead of old SupportsTranscription/SupportsLLM
- Added comprehensive tests for all new helper functions - Added comprehensive tests for all new helper functions
- All tests passing, typecheck passes - All tests passing, typecheck passes
### Task 5: Define BatchAdapter and StreamingAdapter interfaces
- Renamed `TranscriptionAdapter` to `BatchAdapter` in transcriber.go
- Updated all adapters (openai, groq, mistral, elevenlabs) to reference BatchAdapter in comments
- Updated SimpleTranscriber to use BatchAdapter
- Updated test mocks (MockTranscriptionAdapter -> MockBatchAdapter)
- Created `internal/transcriber/streaming.go` with:
- `TranscriptionResult` struct: Text, IsFinal, Error fields
- `StreamingAdapter` interface: Start, SendChunk, Results, Close methods
- All tests passing, typecheck passes
+1 -1
View File
@@ -129,7 +129,7 @@
"TranscriptionResult has Text, IsFinal, Error fields", "TranscriptionResult has Text, IsFinal, Error fields",
"Typecheck passes" "Typecheck passes"
], ],
"passes": false "passes": true
}, },
{ {
"title": "Create StreamingTranscriber wrapper", "title": "Create StreamingTranscriber wrapper",