summaryrefslogtreecommitdiff
path: root/internal/image/gemini_prompt.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/image/gemini_prompt.go')
-rw-r--r--internal/image/gemini_prompt.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/internal/image/gemini_prompt.go b/internal/image/gemini_prompt.go
new file mode 100644
index 0000000..09c54c7
--- /dev/null
+++ b/internal/image/gemini_prompt.go
@@ -0,0 +1,106 @@
+package image
+
+import (
+ "context"
+ "fmt"
+ "strings"
+)
+
+func normalizeCustomPrompt(prompt string) string {
+ prompt = strings.TrimSpace(prompt)
+ if len(prompt) > maxCustomPrompt {
+ prompt = prompt[:maxCustomPrompt-3] + "..."
+ }
+ return prompt
+}
+
+func (c *GeminiProvider) resolveTranslation(_ context.Context, opts *SearchOptions, translation string) (string, error) {
+ if translation != "" {
+ fmt.Printf("Using provided translation: %s -> %s\n", opts.Query, translation)
+ return translation, nil
+ }
+
+ return opts.Query, nil
+}
+
+func (c *GeminiProvider) resolvePrompt(ctx context.Context, opts *SearchOptions, translatedWord string) (string, error) {
+ if customPrompt := normalizeCustomPrompt(opts.CustomPrompt); customPrompt != "" {
+ fmt.Printf("Using custom prompt: %s\n", customPrompt)
+ return customPrompt, nil
+ }
+
+ return c.createEducationalPrompt(ctx, opts.Query, translatedWord), nil
+}
+
+func (c *GeminiProvider) buildPrompt(ctx context.Context, opts *SearchOptions) (string, string, error) {
+ if opts == nil {
+ return "", "", &SearchError{
+ Provider: geminiSource,
+ Code: "INVALID_OPTIONS",
+ Message: "search options are required",
+ }
+ }
+
+ translation := strings.TrimSpace(opts.Translation)
+ translatedWord, err := c.resolveTranslation(ctx, opts, translation)
+ if err != nil {
+ return "", "", err
+ }
+
+ prompt, err := c.resolvePrompt(ctx, opts, translatedWord)
+ if err != nil {
+ return "", "", err
+ }
+
+ return prompt, translatedWord, nil
+}
+
+// createEducationalPrompt generates a prompt optimized for image generation.
+func (c *GeminiProvider) createEducationalPrompt(ctx context.Context, query, translation string) string {
+ subject := promptSubject(translation, query)
+
+ scene, err := c.generateSceneDescription(ctx, query, translation)
+ if err != nil {
+ fmt.Printf(" Failed to generate scene: %v, using basic prompt\n", err)
+ scene = ""
+ }
+ if scene != "" {
+ scene = sanitizeSceneDescription(scene)
+ if !usableSceneDescription(scene) {
+ fmt.Printf(" Scene response was too short or generic, using basic prompt\n")
+ scene = ""
+ }
+ }
+
+ selectedStyle := chooseArtisticStyle()
+ if selectedStyle == defaultArtisticStyle {
+ fmt.Printf(" No artistic styles available, using generic prompt\n")
+ }
+ fmt.Printf(" Using image style: %s\n", selectedStyle)
+
+ return buildEducationalPrompt(selectedStyle, scene, subject)
+}
+
+func (c *GeminiProvider) generateSceneDescription(ctx context.Context, query, translation string) (string, error) {
+ fmt.Printf("Gemini Scene Generation: Creating scene for %q (%s)\n", query, translation)
+
+ scene, err := geminiGenerateText(
+ ctx,
+ c,
+ c.textModelName(),
+ "You are helping create educational flashcards for language learning. Generate a brief, vivid scene description that incorporates the given English word in a memorable, contextual way. The scene should be visually interesting and help with memory retention. Keep it to 1-2 sentences, focusing on visual elements that can be illustrated. The subject (the English word) should be the clear focal point of the image, prominent and centered.",
+ fmt.Sprintf("Create a scene description for the English word %q that would make a memorable flashcard image. Make sure %q is the main focus and most prominent element in the scene.", translation, translation),
+ 0.7,
+ 100,
+ )
+ if err != nil {
+ return "", fmt.Errorf("scene generation failed: %w", err)
+ }
+ scene = sanitizeSceneDescription(scene)
+ if !usableSceneDescription(scene) {
+ return "", fmt.Errorf("scene generation returned unusable content")
+ }
+
+ fmt.Printf("Generated scene: %s\n", scene)
+ return scene, nil
+}