Skip to content

[BUG] SD caption prompts overwritten by static YAML when tenant provides custom prompts #50

@dhirmadi

Description

@dhirmadi

Bug Report

Severity: High (affects all orchestrator-mode tenants with sd_caption_enabled=true)
Component: publisher_v2/src/publisher_v2/services/ai.py
Related to: Issue #48 (fix was incomplete)
Discovered: 2026-01-03 during production testing for lbd.shibari.photo


Problem

When sd_caption_enabled=true, captions are generated using generate_with_sd() which uses SD-specific prompts (sd_caption_system_prompt, sd_caption_role_prompt). These are still being overwritten by static YAML even when the tenant provides custom system_prompt/role_prompt.

Issue #48 fixed the regular prompt precedence but missed the SD caption prompt case.

Root Cause

In CaptionGeneratorOpenAI.__init__() (ai.py lines 237-252):

# SD caption prompts: if tenant explicitly provided sd prompts, keep them
if cfg_sd_system:                                    # False (orchestrator didn't provide explicit SD prompts)
    self.sd_caption_system_prompt = cfg_sd_system
elif static_prompts.sd_caption.system:               # True (YAML has a value)
    self.sd_caption_system_prompt = static_prompts.sd_caption.system  # ❌ OVERWRITES!

The problem: when orchestrator provides custom system_prompt but NOT explicit sd_caption_system_prompt, the code falls back to static YAML instead of inheriting from the custom system_prompt.

Evidence

Orchestrator config for lbd.shibari.photo:

{
  "system_prompt": "Using the image analysis, write a tiny caption between 100-150 characters. 1. Wrap the message in ✨ sparkles ✨...",
  "role_prompt": "You are a classy, fun, and playful 30-year-old woman posting on FetLife...",
  "sd_caption_system_prompt": null,
  "sd_caption_role_prompt": null,
  "sd_caption_enabled": true,
  "sd_caption_single_call_enabled": true
}

What gets used (from static YAML):

sd_caption:
  system: >
    You are a fine-art prompt engineer. Produce Stable-Diffusion-ready prompts...
  role: >
    Write two outputs for the provided analysis and platform spec...

Result

Email subject: "What emotions do you feel when viewing intimate art like this? Share your thoughts!"

Missing: ✨ sparkles ✨, themed headers, no hashtags rule, "| Selfshot unless tagged" suffix

Expected Behavior

When tenant provides custom system_prompt/role_prompt but NOT explicit SD prompts:

  1. SD prompts should inherit from the custom tenant prompts
  2. Static YAML should only be used when tenant uses schema defaults

Proposed Fix

Change the SD prompt fallback logic to check if tenant has custom prompts:

default_cfg = OpenAIConfig()

# SD caption prompts: inherit from tenant prompts if they're custom
if cfg_sd_system:
    self.sd_caption_system_prompt = cfg_sd_system
elif self.system_prompt != default_cfg.system_prompt:
    # Tenant has custom prompts - inherit them for SD too
    self.sd_caption_system_prompt = self.system_prompt
elif static_prompts.sd_caption.system:
    self.sd_caption_system_prompt = static_prompts.sd_caption.system

if cfg_sd_role:
    self.sd_caption_role_prompt = cfg_sd_role
elif self.role_prompt != default_cfg.role_prompt:
    # Tenant has custom prompts - inherit them for SD too  
    self.sd_caption_role_prompt = self.role_prompt
elif static_prompts.sd_caption.role:
    self.sd_caption_role_prompt = static_prompts.sd_caption.role

Affected Code Locations

File Lines Issue
publisher_v2/src/publisher_v2/services/ai.py 237-252 SD prompts don't inherit from custom tenant prompts

Acceptance Criteria

  • When tenant provides custom system_prompt, SD prompts inherit from it if no explicit SD prompts provided
  • When tenant provides custom role_prompt, SD prompts inherit from it if no explicit SD prompts provided
  • When tenant provides explicit sd_caption_system_prompt, use that (existing behavior)
  • When tenant uses default prompts, static YAML is used as fallback (existing behavior)
  • Add unit test to verify SD prompt inheritance

Testing Notes

To reproduce:

  1. Configure tenant with custom system_prompt and role_prompt but NO sd_caption_* prompts
  2. Ensure sd_caption_enabled=true
  3. Generate caption → observe it doesn't follow custom prompts

Blocking: Production FetLife prompts not working

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmust-fix

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions