diff --git a/internal/provider/model.go b/internal/provider/model.go new file mode 100644 index 0000000..24bc24c --- /dev/null +++ b/internal/provider/model.go @@ -0,0 +1,68 @@ +package provider + +import "github.com/leonardotrapani/hyprvoice/internal/language" + +// ModelType represents the type of a model +type ModelType int + +const ( + Transcription ModelType = iota + LLM +) + +// Model represents a model with full metadata +type Model struct { + ID string // unique identifier (e.g., "whisper-1", "gpt-4o-mini") + Name string // display name (e.g., "Whisper 1", "GPT-4o Mini") + Description string // short description + Type ModelType // transcription or LLM + Streaming bool // supports streaming + Local bool // runs locally (no API call) + AdapterType string // which adapter to use (e.g., "openai", "elevenlabs", "whisper-cpp") + SupportedLanguages []string // explicit list of supported language codes + Endpoint *EndpointConfig // nil for local models + LocalInfo *LocalModelInfo // nil for cloud models +} + +// EndpointConfig holds HTTP/WebSocket endpoint configuration +type EndpointConfig struct { + BaseURL string // e.g., "https://api.openai.com" or "wss://api.deepgram.com" + Path string // e.g., "/v1/audio/transcriptions" +} + +// LocalModelInfo holds metadata for downloadable local models +type LocalModelInfo struct { + Filename string // e.g., "ggml-base.en.bin" + Size string // human readable size (e.g., "142MB") + DownloadURL string // full URL to download from +} + +// NeedsDownload returns true if this is a local model that requires downloading +func (m *Model) NeedsDownload() bool { + return m.LocalInfo != nil +} + +// IsStreaming returns true if this model supports streaming +func (m *Model) IsStreaming() bool { + return m.Streaming +} + +// SupportsLanguage returns true if the model supports the given language code. +// Auto-detect (empty string) is always supported. +func (m *Model) SupportsLanguage(code string) bool { + if code == "" { + return true // auto always supported + } + for _, supported := range m.SupportedLanguages { + if supported == code { + return true + } + } + return false +} + +// SupportsAllLanguages returns true if the model supports all 57 languages +func (m *Model) SupportsAllLanguages() bool { + allCodes := language.AllLanguageCodes() + return len(m.SupportedLanguages) == len(allCodes) +} diff --git a/progress.txt b/progress.txt index f54700e..f2a5b3d 100644 --- a/progress.txt +++ b/progress.txt @@ -16,3 +16,13 @@ Started: Sun Feb 1 12:22:47 AM CET 2026 - Deepgram locale mappings: en->en-US, pt->pt-BR, zh->zh-CN - Added comprehensive test coverage for all provider formats - 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 diff --git a/tasks/prd.jsonc b/tasks/prd.jsonc index 79a19f7..48b153d 100644 --- a/tasks/prd.jsonc +++ b/tasks/prd.jsonc @@ -80,7 +80,7 @@ "SupportsAllLanguages() returns false for English-only model", "Typecheck passes" ], - "passes": false + "passes": true }, { "title": "Refactor Provider interface to return Models",