diff --git a/internal/pipeline/pipeline.go b/internal/pipeline/pipeline.go index e71e3df..2a4cb9c 100644 --- a/internal/pipeline/pipeline.go +++ b/internal/pipeline/pipeline.go @@ -8,6 +8,7 @@ import ( "github.com/leonardotrapani/hyprvoice/internal/config" "github.com/leonardotrapani/hyprvoice/internal/injection" + "github.com/leonardotrapani/hyprvoice/internal/llm" "github.com/leonardotrapani/hyprvoice/internal/recording" "github.com/leonardotrapani/hyprvoice/internal/transcriber" ) @@ -25,6 +26,7 @@ const ( Idle Status = "idle" Recording Status = "recording" Transcribing Status = "transcribing" + Processing Status = "processing" // LLM post-processing Injecting Status = "injecting" ) @@ -226,9 +228,41 @@ func (p *pipeline) handleInjectAction(ctx context.Context, recorder *recording.R } log.Printf("Pipeline: Final transcription text: %s", transcriptionText) + // LLM post-processing phase + textToInject := transcriptionText + if p.config.IsLLMEnabled() { + p.setStatus(Processing) + log.Printf("Pipeline: LLM post-processing enabled, processing text") + + llmCfg := p.config.ToLLMConfig() + adapter, err := llm.NewAdapter(llm.Config{ + Provider: llmCfg.Provider, + APIKey: llmCfg.APIKey, + Model: llmCfg.Model, + RemoveStutters: llmCfg.RemoveStutters, + AddPunctuation: llmCfg.AddPunctuation, + FixGrammar: llmCfg.FixGrammar, + RemoveFillerWords: llmCfg.RemoveFillerWords, + CustomPrompt: llmCfg.CustomPrompt, + Keywords: llmCfg.Keywords, + }) + if err != nil { + log.Printf("Pipeline: Failed to create LLM adapter: %v, using raw transcription", err) + } else { + processed, err := adapter.Process(ctx, transcriptionText) + if err != nil { + log.Printf("Pipeline: LLM processing failed: %v, using raw transcription", err) + } else { + textToInject = processed + log.Printf("Pipeline: LLM processed text: %s", textToInject) + } + } + p.setStatus(Injecting) + } + injector := injection.NewInjector(p.config.ToInjectionConfig()) - if err := injector.Inject(ctx, transcriptionText); err != nil { + if err := injector.Inject(ctx, textToInject); err != nil { p.sendError("Injection Error", "Failed to inject text", err) } else { log.Printf("Pipeline: Text injection completed successfully") diff --git a/progress.txt b/progress.txt index d0fdc70..0d24c62 100644 --- a/progress.txt +++ b/progress.txt @@ -64,3 +64,17 @@ Key decisions: - System prompt builds dynamically based on enabled options - Keywords included in system prompt for correct spelling hints - Custom prompt prepended to user prompt if enabled + +## Task 4: Integrate LLM phase into pipeline - COMPLETE + +Updated internal/pipeline/pipeline.go: +- Added `Processing` status for LLM post-processing phase +- After transcription, checks `config.IsLLMEnabled()` before LLM processing +- Creates LLM adapter using config.ToLLMConfig() +- Processes text with adapter, uses result for injection +- Graceful fallback: logs warning and uses raw transcription text on any error + +Key decisions: +- LLM processing happens between transcription and injection +- Adapter creation and processing errors are logged but don't fail the pipeline +- Sets status to Processing during LLM phase, then back to Injecting diff --git a/tasks/prd.jsonc b/tasks/prd.jsonc index fe29398..276a8f4 100644 --- a/tasks/prd.jsonc +++ b/tasks/prd.jsonc @@ -84,7 +84,7 @@ "Graceful fallback on LLM error", "Typecheck passes" ], - "passes": false + "passes": true }, { "title": "Pass keywords to transcription adapters",