Bug Report
Severity: High (affects all orchestrator-mode tenants with custom AI prompts)
Component: publisher_v2/src/publisher_v2/services/ai.py
Discovered: 2025-12-30 during integration testing for lbd.shibari.photo
Problem
Custom AI prompts (system_prompt, role_prompt) sent by the orchestrator are ignored. The Publisher always uses the static YAML defaults instead of tenant-specific prompts.
Root Cause
In CaptionGeneratorOpenAI.__init__() (ai.py lines 209-231), the orchestrator prompts are loaded first, then overwritten by static config:
# Step 1: Load from orchestrator config ✅
self.system_prompt = config.system_prompt # Tenant's custom prompt
self.role_prompt = config.role_prompt
# Step 2: OVERWRITE with static YAML ❌ (wrong order!)
static_prompts = get_static_config().ai_prompts
if static_prompts.caption.system:
self.system_prompt = static_prompts.caption.system # ← Overwrites tenant prompt!
if static_prompts.caption.role:
self.role_prompt = static_prompts.caption.role # ← Overwrites tenant prompt!
Evidence
Orchestrator sends custom prompts for lbd.shibari.photo:
"ai": {
"system_prompt": "Using the image analysis, write a tiny caption between 100-150 characters. 1. Wrap the message in ✨ sparkles ✨. 2. Start with a theme: Memory Monday, Titty Tuesday...",
"role_prompt": "You are a classy, fun, and playful 30-year-old woman posting on FetLife. Your style is 'short and sweet'—sophisticated yet flirty..."
}
But Publisher uses static defaults from config/static/ai_prompts.yaml:
caption:
system: >
You are a senior social media copywriter. Write authentic, concise, platform-aware captions.
role: "Write a caption for:"
Expected Behavior
Orchestrator-provided prompts (tenant-specific) should take precedence over static YAML defaults. Static config should only be used as a fallback when the orchestrator doesn't provide prompts.
Proposed Fix
Change the conditional logic to use static config as fallback, not override:
# Load from orchestrator config first
self.system_prompt = config.system_prompt
self.role_prompt = config.role_prompt
# Only use static config as FALLBACK if orchestrator didn't provide prompts
static_prompts = get_static_config().ai_prompts
if not self.system_prompt and static_prompts.caption.system:
self.system_prompt = static_prompts.caption.system
if not self.role_prompt and static_prompts.caption.role:
self.role_prompt = static_prompts.caption.role
Same pattern needed for:
sd_caption_system_prompt (lines 228-229)
sd_caption_role_prompt (lines 230-231)
Affected Code Locations
| File |
Lines |
Issue |
publisher_v2/src/publisher_v2/services/ai.py |
224-227 |
Caption prompts overwritten |
publisher_v2/src/publisher_v2/services/ai.py |
228-231 |
SD caption prompts overwritten |
Acceptance Criteria
Testing Notes
To reproduce:
- Configure a tenant in orchestrator with custom
ai.system_prompt and ai.role_prompt
- Run Publisher in orchestrator mode
- Observe generated captions use generic "social media copywriter" style instead of custom prompts
Related: Feature 022 (Orchestrator Schema V2 Integration)
Bug Report
Severity: High (affects all orchestrator-mode tenants with custom AI prompts)
Component:
publisher_v2/src/publisher_v2/services/ai.pyDiscovered: 2025-12-30 during integration testing for
lbd.shibari.photoProblem
Custom AI prompts (
system_prompt,role_prompt) sent by the orchestrator are ignored. The Publisher always uses the static YAML defaults instead of tenant-specific prompts.Root Cause
In
CaptionGeneratorOpenAI.__init__()(ai.py lines 209-231), the orchestrator prompts are loaded first, then overwritten by static config:Evidence
Orchestrator sends custom prompts for
lbd.shibari.photo:But Publisher uses static defaults from
config/static/ai_prompts.yaml:Expected Behavior
Orchestrator-provided prompts (tenant-specific) should take precedence over static YAML defaults. Static config should only be used as a fallback when the orchestrator doesn't provide prompts.
Proposed Fix
Change the conditional logic to use static config as fallback, not override:
Same pattern needed for:
sd_caption_system_prompt(lines 228-229)sd_caption_role_prompt(lines 230-231)Affected Code Locations
publisher_v2/src/publisher_v2/services/ai.pypublisher_v2/src/publisher_v2/services/ai.pyAcceptance Criteria
system_prompttakes precedence over static YAMLrole_prompttakes precedence over static YAMLsd_caption_system_promptandsd_caption_role_promptnull/emptyTesting Notes
To reproduce:
ai.system_promptandai.role_promptRelated: Feature 022 (Orchestrator Schema V2 Integration)