Files
hyprvoice/progress.txt
T
leonardotrapani 3563def987 refactor transcriber factory to use model metadata
- factory now looks up Model via provider.GetModel()
- switches on model.AdapterType instead of provider name
- uses model.Endpoint for adapter configuration
- streaming models return clear error (not yet implemented)
- empty model falls back to provider default
- added tests for streaming and unknown model errors
2026-02-01 01:00:21 +01:00

149 lines
8.8 KiB
Plaintext

# Ralph Progress Log
Started: Sun Feb 1 12:22:47 AM CET 2026
---
## Completed
### Task 1: Create language package with core types and helpers
- Created `internal/language/language.go` with Language struct, Auto constant
- Implemented FromCode, List, Codes, AllLanguageCodes, IsValidCode
- Full 57 language list from OpenAI Whisper
- All tests passing, typecheck passes
### Task 8: Migrate OpenAI provider to new Model structure
- Added gpt-4o-transcribe and gpt-4o-mini-transcribe transcription models
- Removed gpt-4-turbo and gpt-3.5-turbo LLM models (not in PRD)
- OpenAI now has 5 models: 3 transcription (whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe) + 2 LLM (gpt-4o-mini, gpt-4o)
- All models have AdapterType='openai', Endpoint with BaseURL='https://api.openai.com'
- All models use language.AllLanguageCodes() for SupportedLanguages (57 languages)
- Updated provider_test.go to expect 3 transcription and 2 LLM models
- All tests passing, typecheck passes
### Task 3: Create Model type with full metadata
- Created `internal/provider/model.go`
- ModelType enum: Transcription, LLM
- Model struct: ID, Name, Description, Type, Streaming, Local, AdapterType, SupportedLanguages, Endpoint, LocalInfo
- EndpointConfig: BaseURL, Path
- LocalModelInfo: Filename, Size, DownloadURL
- Helper methods: NeedsDownload(), IsStreaming(), SupportsLanguage(code), SupportsAllLanguages()
- SupportsLanguage("") always returns true (auto always allowed)
- All tests passing, typecheck passes
### Task 4: Refactor Provider interface to return Models
- Updated `internal/provider/provider.go` Provider interface
- Replaced old methods with: Models() []Model, DefaultModel(t ModelType) string, IsLocal() bool
- Added package-level helpers:
- GetModel(providerName, modelID string) (*Model, error)
- ModelsOfType(p Provider, t ModelType) []Model
- FindModelByID(modelID string) (*Model, Provider, error)
- ModelsForLanguage(p Provider, t ModelType, langCode string) []Model
- ValidateModelLanguage(providerName, modelID, langCode string) error
- Updated all providers (openai, groq, mistral, elevenlabs) with full Model metadata
- Updated TUI files to use ModelsOfType instead of old SupportsTranscription/SupportsLLM
- Added comprehensive tests for all new helper functions
- 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
### Task 6: Create StreamingTranscriber wrapper
- Created `internal/transcriber/streaming_transcriber.go`
- StreamingTranscriber struct with: adapter, language, finalText builder, mutex, ctx/cancel, WaitGroup
- Start() creates cancelable context, starts adapter, spawns 2 goroutines
- Goroutine 1: reads frames from channel, calls adapter.SendChunk()
- Goroutine 2: reads from adapter.Results(), accumulates final results with space separator
- Stop() cancels context, waits for goroutines, closes adapter
- GetFinalTranscription() returns accumulated text with mutex protection
- Added MockStreamingAdapter and comprehensive tests
- Tests verify: start/stop, result accumulation, partial result filtering, error handling, concurrent access
- All tests passing with -race flag, typecheck passes
### Task 7: Write tests for Model, Provider, and interfaces
- Created `internal/provider/model_test.go`
- TestModel_NeedsDownload: local with LocalInfo = true, cloud = false, nil = false
- TestModel_IsStreaming: returns Streaming field value
- TestModel_SupportsLanguage: multilingual supports all, english-only supports en, auto always true
- TestModel_SupportsAllLanguages: true when 57 languages, false otherwise
- TestModelType_Constants: Transcription=0, LLM=1
- TestEndpointConfig_Fields, TestLocalModelInfo_Fields: struct fields accessible
- TestModel_AllFields: comprehensive struct field test
- provider_test.go already had GetModel, ModelsOfType, FindModelByID, ModelsForLanguage, ValidateModelLanguage tests
- All tests passing, typecheck passes
### Task 9: Migrate Groq provider to new Model structure
- Implementation was already complete from previous work
- Verified 6 models: 3 transcription (whisper-large-v3, whisper-large-v3-turbo, distil-whisper-large-v3-en) + 3 LLM
- All models use AdapterType='openai' (Groq is OpenAI-compatible)
- Endpoint.BaseURL='https://api.groq.com/openai' for all
- distil-whisper-large-v3-en correctly has SupportedLanguages=['en'] (English only)
- Multilingual models have all 57 language codes
- All verification items confirmed working
### Task 10: Migrate Mistral provider to new Model structure
- Implementation was already complete from previous work
- Verified 2 models: voxtral-mini-latest, voxtral-mini-2507
- All models use AdapterType='openai' (Mistral transcription is OpenAI-compatible)
- Endpoint.BaseURL='https://api.mistral.ai' with Path='/v1/audio/transcriptions'
- SupportedLanguages set to all 57 language codes (multilingual per Mistral docs)
- Researched Mistral API docs - language parameter is optional, no specific list of restrictions
- All tests passing, typecheck passes
### Task 11: Migrate ElevenLabs provider to new Model structure
- Added 4 models: 2 batch (scribe_v1, scribe_v2) + 2 streaming (scribe_v1-streaming, scribe_v2-streaming)
- Batch models: AdapterType='elevenlabs', Streaming=false, Endpoint.BaseURL='https://api.elevenlabs.io'
- Streaming models: AdapterType='elevenlabs-streaming', Streaming=true, Endpoint.BaseURL='wss://api.elevenlabs.io'
- Researched ElevenLabs docs: Scribe supports 90+ languages, including all 57 from our master list
- SupportedLanguages set to all 57 language codes
- Added TestElevenLabsProvider test verifying all requirements
- All tests passing, typecheck passes
### Task 12: Create consolidated OpenAI-compatible BatchAdapter
- Refactored `internal/transcriber/adapter_openai.go` to be configurable
- New constructor: `NewOpenAIAdapter(endpoint *EndpointConfig, apiKey, model, lang string, keywords []string, providerName string)`
- Removed hardcoded base URL, now uses `endpoint.BaseURL + "/v1"` when endpoint provided
- Added `NewOpenAIAdapterFromConfig(config Config)` for backward compatibility during migration
- Language code converted to provider format via `language.ToProviderFormat(lang, providerName)`
- Log messages now include provider name for better debugging
- 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
### Task 14: Update ElevenLabs BatchAdapter to use EndpointConfig
- Refactored `internal/transcriber/adapter_elevenlabs.go` to use EndpointConfig
- New constructor: `NewElevenLabsAdapter(endpoint *EndpointConfig, apiKey, model, lang string)`
- Uses `endpoint.BaseURL + endpoint.Path` for URL (no hardcoded URL)
- Language converted via `language.ToProviderFormat(a.language, "elevenlabs")`
- Kept `xi-api-key` header for ElevenLabs-specific auth
- Added `NewElevenLabsAdapterFromConfig` for backward compatibility
- Updated factory to use `NewElevenLabsAdapterFromConfig`
- Updated tests for new constructor signature
- All tests passing, typecheck passes
### Task 15: Update transcriber factory to use Model metadata
- Refactored `NewTranscriber()` to look up Model via `provider.GetModel()`
- Added `mapConfigProviderToRegistryName()` to map config provider names (e.g., "groq-transcription") to registry names (e.g., "groq")
- Factory now switches on `model.AdapterType` instead of provider name
- Special case: "groq-translation" still uses dedicated `GroqTranslationAdapter` (uses CreateTranslation API)
- For "openai" adapter type: creates `OpenAIAdapter` with model's endpoint config
- For "elevenlabs" adapter type: creates `ElevenLabsAdapter` with model's endpoint config
- Streaming models return clear error: "streaming model %s not supported yet (coming soon)"
- Empty model now uses provider's default transcription model
- Added tests for streaming model rejection and unknown model error
- All tests passing, typecheck passes