{ "project": "hyprvoice LLM Post-Processing", "description": "Add LLM post-processing phase with unified provider system, TUI configure command, and configurable cleanup options", "issue": "https://github.com/LeonardoTrapani/hyprvoice/issues/4", "tasks": [ { "title": "Create Provider interface and registry", "steps": [ "Create new package internal/provider", "Define Provider interface: Name(), RequiresAPIKey(), ValidateAPIKey(key), SupportsTranscription(), SupportsLLM(), DefaultTranscriptionModel(), DefaultLLMModel(), TranscriptionModels(), LLMModels()", "Create ProviderConfig struct with APIKey field", "Implement OpenAIProvider: transcription (whisper-1) + LLM (gpt-4o-mini)", "Implement GroqProvider: transcription (whisper-large-v3, turbo) + LLM (llama-3.3-70b-versatile)", "Implement MistralProvider: transcription only (voxtral-mini-latest)", "Implement ElevenLabsProvider: transcription only (scribe_v1, scribe_v2)", "Create GetProvider(name) and ListProviders() functions", "Create ListProvidersWithLLM() and ListProvidersWithTranscription() helpers" ], "verify": [ "All providers implement the interface", "GetProvider returns correct provider for each name", "Capability methods return correct values", "Typecheck passes" ], "passes": true }, { "title": "Refactor config to unified provider structure", "steps": [ "Add Providers map[string]ProviderConfig to Config struct", "Add global Keywords []string field to Config", "Remove api_key from TranscriptionConfig, keep provider/model/language", "Add LLMConfig with Enabled (default true), Provider, Model", "Add LLMPostProcessingConfig: RemoveStutters, AddPunctuation, FixGrammar, RemoveFillerWords (all default true)", "Add LLMCustomPromptConfig: Enabled, Prompt", "Add migration in Load() to detect old format (transcription.api_key) and convert to providers map", "Migration logs: 'Config migrated. Run hyprvoice configure to update format.'", "Update ToTranscriberConfig() to resolve API key from Providers", "Add ToLLMConfig() method", "Environment variables still work as fallback" ], "verify": [ "Old config with transcription.api_key still loads (backward compatible)", "New config with [providers.openai] works", "Environment variable fallback works", "Migration logs warning", "Typecheck passes", "go test ./internal/config/... passes" ], "passes": true }, { "title": "Create LLM adapter interface and implementations", "steps": [ "Create internal/llm package", "Define LLMAdapter interface: Process(ctx, text) (string, error)", "Define Config struct with all options", "Create prompt.go with BuildSystemPrompt(opts, keywords) and BuildUserPrompt(text, customPrompt)", "Implement OpenAIAdapter using chat completions API", "Implement GroqAdapter using Groq API (OpenAI-compatible)", "Create NewAdapter(config) factory function" ], "verify": [ "Both adapters implement interface", "Prompt builder generates correct prompts", "Factory returns correct adapter", "Typecheck passes" ], "passes": true }, { "title": "Integrate LLM phase into pipeline", "steps": [ "Update internal/pipeline/pipeline.go", "After transcription, check if LLM enabled", "If enabled, create adapter and process text", "Use processed text for injection", "On failure, fall back to raw text with warning", "Add LLM processing notification" ], "verify": [ "Pipeline unchanged when LLM disabled", "LLM processes text when enabled", "Graceful fallback on LLM error", "Typecheck passes" ], "passes": true }, { "title": "Pass keywords to transcription adapters", "steps": [ "Add Keywords []string to transcriber.Config", "Update ToTranscriberConfig() to pass keywords", "OpenAI transcriber uses keywords in initial_prompt", "Groq transcriber uses keywords in prompt parameter", "Other transcribers ignore if unsupported" ], "verify": [ "Keywords passed to transcription", "OpenAI includes in request", "Non-supporting transcribers still work", "Typecheck passes" ], "passes": true }, { "title": "Add TUI dependencies and base components", "steps": [ "Run: go get github.com/charmbracelet/bubbletea github.com/charmbracelet/lipgloss github.com/charmbracelet/huh", "Create internal/tui package", "Create styles.go with lipgloss styles: header, label, success, error, muted, highlight, selected", "Create theme.go with color scheme matching hyprvoice branding" ], "verify": [ "Dependencies in go.mod", "Styles render in terminal", "Typecheck passes" ], "passes": true }, { "title": "Create TUI configure - fresh install flow", "steps": [ "Create internal/tui/configure.go with Run() function", "Welcome screen with hyprvoice ASCII/branding", "Provider selection: multi-select which to configure (OpenAI, Groq, Mistral, ElevenLabs)", "For each selected: API key input with password mask", "Transcription: provider dropdown (only configured + supports transcription), model dropdown", "LLM: 'Enable post-processing? (Recommended)' - defaults YES", "If LLM yes: provider (only configured + supports LLM), model, post-processing toggles (all default true), custom prompt", "Keywords: comma-separated input", "Injection: backend multi-select with descriptions", "Notifications: enable toggle", "Summary screen with confirm" ], "verify": [ "Fresh install walks through all steps", "Only shows providers user selected for API keys", "Transcription only shows configured + capable providers", "LLM defaults to enabled, Yes is recommended", "Typecheck passes" ], "passes": true }, { "title": "Create TUI configure - edit existing flow", "steps": [ "Detect if config exists and has user changes", "Show section picker: 'What to configure?' multi-select", "Sections: Providers, Transcription, LLM, Keywords, Injection, Notifications, Full Setup", "For each section, show only that form", "Smart provider detection: if user picks unconfigured provider, prompt for API key", "If provider already configured, show 'Using existing key' (no re-prompt unless in Providers section)", "Merge with existing config, preserve unedited sections" ], "verify": [ "Existing config shows section picker", "Single section only edits that section", "Unconfigured provider triggers key prompt", "Configured providers don't re-prompt", "Unedited sections preserved", "Typecheck passes" ], "passes": true }, { "title": "Replace old configure with TUI", "steps": [ "Update cmd/hyprvoice/main.go configureCmd to call tui.Run()", "Remove runInteractiveConfig and related helpers (maskAPIKey, formatBackends, etc.)", "Update saveConfig to write new TOML structure with [providers.X]", "Ensure validation before save", "Show next steps after successful save" ], "verify": [ "hyprvoice configure launches TUI", "Old code removed", "Saved config valid TOML with new structure", "Typecheck passes" ], "passes": true }, { "title": "Update default config template", "steps": [ "Update SaveDefaultConfig() in config.go", "Add [providers.openai] and [providers.groq] sections", "Add keywords = [] global", "Add [llm] with enabled = true, provider, model", "Add [llm.post_processing] all true", "Add [llm.custom_prompt] enabled = false", "Clear comments explaining structure", "Add migration note about old format" ], "verify": [ "Default config valid TOML", "LLM enabled by default", "Post-processing all true by default", "Comments clear", "Typecheck passes" ], "passes": true }, { "title": "Add LLM processing notification", "steps": [ "Add MsgLLMProcessing to notify types", "Default: title='Hyprvoice', body='Processing...'", "Add to MessagesConfig", "Trigger when LLM starts", "Make configurable" ], "verify": [ "Type defined", "Notification appears", "Configurable in config", "Typecheck passes" ], "passes": true }, { "title": "Update README documentation", "steps": [ "Add '## LLM Post-Processing' section", "Document unified provider structure with examples", "Document post-processing options", "Document custom prompt with use cases", "Document keywords (helps transcription + LLM)", "Example configs for common setups", "Document migration from old format", "Note LLM enabled by default" ], "verify": [ "README clear", "Examples valid TOML", "Migration documented", "Keywords explained" ], "passes": false }, { "title": "End-to-end testing", "steps": [ "Test old config loads (backward compatible)", "Test new config works", "Test LLM enabled by default improves output", "Test LLM can be disabled", "Test each post-processing option", "Test custom prompt", "Test keywords in transcription", "Test TUI fresh install flow", "Test TUI edit existing flow", "Test smart provider detection", "Test config hot-reload" ], "verify": [ "Old configs work unchanged", "New configs work", "LLM improves text quality", "TUI flows intuitive and state-aware", "No regressions" ], "passes": false } ] }