summaryrefslogtreecommitdiff
path: root/internal/processor
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-02 07:56:31 +0300
committerPaul Buetow <paul@buetow.org>2026-04-02 07:56:31 +0300
commitb7302580d840fc3d7e3d127df49d79ef12d79d9c (patch)
tree458132230aa1337be76701cb7af6f8c26b3e0d55 /internal/processor
parent0f2b16d1ccf461b706dd426727ed188c4ea3b60a (diff)
Align GUI and CLI provider wiring
Diffstat (limited to 'internal/processor')
-rw-r--r--internal/processor/processor.go42
-rw-r--r--internal/processor/processor_test.go42
2 files changed, 84 insertions, 0 deletions
diff --git a/internal/processor/processor.go b/internal/processor/processor.go
index 7d18aab..3ecbce8 100644
--- a/internal/processor/processor.go
+++ b/internal/processor/processor.go
@@ -634,6 +634,8 @@ func (p *Processor) guiConfigForRunMode() *gui.Config {
ImageProvider: imageProvider,
OpenAIKey: cli.GetOpenAIKey(),
GoogleAPIKey: cli.GetGoogleAPIKey(),
+ NanoBananaModel: p.nanoBananaModelForRunMode(),
+ NanoBananaTextModel: p.nanoBananaTextModelForRunMode(),
GeminiTTSModel: p.geminiTTSModel(),
GeminiVoice: p.geminiVoice(),
TranslationProvider: translation.Provider(viper.GetString("translation.provider")),
@@ -642,6 +644,46 @@ func (p *Processor) guiConfigForRunMode() *gui.Config {
}
}
+func (p *Processor) nanoBananaModelForRunMode() string {
+ if p != nil && p.flags != nil && p.flags.NanoBananaModelSpecified {
+ if model := strings.TrimSpace(p.flags.NanoBananaModel); model != "" {
+ return model
+ }
+ }
+
+ if model := strings.TrimSpace(viper.GetString("image.nanobanana_model")); model != "" {
+ return model
+ }
+
+ if p != nil && p.flags != nil {
+ if model := strings.TrimSpace(p.flags.NanoBananaModel); model != "" {
+ return model
+ }
+ }
+
+ return image.DefaultNanoBananaModel
+}
+
+func (p *Processor) nanoBananaTextModelForRunMode() string {
+ if p != nil && p.flags != nil && p.flags.NanoBananaTextModelSpecified {
+ if model := strings.TrimSpace(p.flags.NanoBananaTextModel); model != "" {
+ return model
+ }
+ }
+
+ if model := strings.TrimSpace(viper.GetString("image.nanobanana_text_model")); model != "" {
+ return model
+ }
+
+ if p != nil && p.flags != nil {
+ if model := strings.TrimSpace(p.flags.NanoBananaTextModel); model != "" {
+ return model
+ }
+ }
+
+ return image.DefaultNanoBananaTextModel
+}
+
func (p *Processor) newImageSearcher() (image.ImageSearcher, error) {
provider := p.imageProviderForRunMode()
diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go
index 2a4b331..8716e79 100644
--- a/internal/processor/processor_test.go
+++ b/internal/processor/processor_test.go
@@ -215,6 +215,8 @@ func TestGUIConfigForRunModeUsesNanoBananaDefaultWhenImageAPIIsNotSpecified(t *t
*viper.GetViper() = *originalConfig
}()
viper.Reset()
+ viper.Set("image.nanobanana_model", "config-image-model")
+ viper.Set("image.nanobanana_text_model", "config-text-model")
flags := cli.NewFlags()
flags.AudioFormat = "wav"
@@ -232,6 +234,12 @@ func TestGUIConfigForRunModeUsesNanoBananaDefaultWhenImageAPIIsNotSpecified(t *t
if guiConfig.AudioFormat != "wav" {
t.Fatalf("guiConfig.AudioFormat = %q, want %q", guiConfig.AudioFormat, "wav")
}
+ if guiConfig.NanoBananaModel != "config-image-model" {
+ t.Fatalf("guiConfig.NanoBananaModel = %q, want %q", guiConfig.NanoBananaModel, "config-image-model")
+ }
+ if guiConfig.NanoBananaTextModel != "config-text-model" {
+ t.Fatalf("guiConfig.NanoBananaTextModel = %q, want %q", guiConfig.NanoBananaTextModel, "config-text-model")
+ }
if guiConfig.GeminiTTSModel != "gemini-2.5-flash-preview-tts" {
t.Fatalf("guiConfig.GeminiTTSModel = %q, want %q", guiConfig.GeminiTTSModel, "gemini-2.5-flash-preview-tts")
}
@@ -268,6 +276,40 @@ func TestGUIConfigForRunModeHonorsExplicitImageAPI(t *testing.T) {
}
}
+func TestGUIConfigForRunModeHonorsExplicitNanoBananaModelFlags(t *testing.T) {
+ t.Setenv("OPENAI_API_KEY", "test-openai-key")
+ t.Setenv("GOOGLE_API_KEY", "test-google-key")
+
+ originalConfig := viper.New()
+ *originalConfig = *viper.GetViper()
+ defer func() {
+ *viper.GetViper() = *originalConfig
+ }()
+ viper.Reset()
+ viper.Set("image.nanobanana_model", "config-image-model")
+ viper.Set("image.nanobanana_text_model", "config-text-model")
+
+ flags := cli.NewFlags()
+ flags.ImageAPI = "openai"
+ flags.ImageAPISpecified = false
+ flags.NanoBananaModel = "flag-image-model"
+ flags.NanoBananaModelSpecified = true
+ flags.NanoBananaTextModel = "flag-text-model"
+ flags.NanoBananaTextModelSpecified = true
+ p := NewProcessor(flags)
+
+ guiConfig := p.guiConfigForRunMode()
+ if guiConfig.NanoBananaModel != "flag-image-model" {
+ t.Fatalf("guiConfig.NanoBananaModel = %q, want %q", guiConfig.NanoBananaModel, "flag-image-model")
+ }
+ if guiConfig.NanoBananaTextModel != "flag-text-model" {
+ t.Fatalf("guiConfig.NanoBananaTextModel = %q, want %q", guiConfig.NanoBananaTextModel, "flag-text-model")
+ }
+ if guiConfig.GoogleAPIKey != "test-google-key" {
+ t.Fatalf("guiConfig.GoogleAPIKey = %q, want %q", guiConfig.GoogleAPIKey, "test-google-key")
+ }
+}
+
func TestGenerateAudioUsesSharedOpenAIVoices(t *testing.T) {
originalFactory := newAudioProvider
t.Cleanup(func() {