- Add brand field to AnalyzeProofOptions interface and WebSocket message - Pass campaign's brandGuidelines to analyzeProof in App.tsx (upload & retry) - Extract brand from WebSocket message in handlers.py and pass to analysis - Update AnalysisService.analyze_proof to accept brand parameter - Refactor BrandAgent to dynamically select brand spec based on brand param - Add get_barclays_brand_spec() method to ReferenceDocsService (placeholder) The brand agent now uses the appropriate specification (Barclaycard spec or Barclays spec when available) based on the campaign's brandGuidelines setting. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
101 lines
4.3 KiB
Python
Executable file
101 lines
4.3 KiB
Python
Executable file
from typing import List, Tuple
|
|
|
|
from app.agents.base_agent import BaseAgent
|
|
from app.models.schemas import SubReview
|
|
from app.services.gemini_service import GeminiService
|
|
from app.services.reference_docs import ReferenceDocsService
|
|
|
|
|
|
class BrandAgent(BaseAgent):
|
|
"""Brand Agent - analyzes proofs against Barclays brand guidelines using Gemini."""
|
|
|
|
name = "Brand Agent"
|
|
|
|
def __init__(self, gemini_service: GeminiService, reference_docs: ReferenceDocsService):
|
|
"""
|
|
Initialize the Brand Agent.
|
|
|
|
Args:
|
|
gemini_service: Service for making Gemini API calls
|
|
reference_docs: Service for loading reference documents
|
|
"""
|
|
self.gemini = gemini_service
|
|
self.reference_docs = reference_docs
|
|
|
|
def _get_brand_context(self, brand: str) -> str:
|
|
"""
|
|
Get the appropriate brand specification based on the brand selection.
|
|
|
|
Args:
|
|
brand: Brand name ('Barclays' or 'Barclaycard')
|
|
|
|
Returns:
|
|
Brand specification content
|
|
"""
|
|
if brand == "Barclays":
|
|
return self.reference_docs.get_barclays_brand_spec()
|
|
else:
|
|
# Default to Barclaycard
|
|
return self.reference_docs.get_barclaycard_brand_spec()
|
|
|
|
async def analyze(self, images: List[Tuple[bytes, str]], brand: str = "Barclaycard") -> SubReview:
|
|
"""
|
|
Analyze the proof for brand guideline adherence.
|
|
|
|
Args:
|
|
images: List of (file_data, mime_type) tuples representing the proof
|
|
brand: Brand to analyze against ('Barclays' or 'Barclaycard')
|
|
|
|
Returns:
|
|
SubReview with brand compliance assessment
|
|
"""
|
|
# Get the appropriate brand specification
|
|
brand_context = self._get_brand_context(brand)
|
|
|
|
prompt = f"""You are a brand expert for {brand}. Your role is to analyze marketing proofs for adherence to {brand} brand guidelines.
|
|
|
|
Here is the {brand} brand specification to use for your analysis:
|
|
|
|
{brand_context}
|
|
|
|
---
|
|
|
|
Analyze the uploaded proof against the {brand} brand specification above, checking for:
|
|
|
|
1. **Logo Usage**: Is the {brand} logo used correctly? Check minimum size, clear space, placement, and that it hasn't been altered. Verify correct logo colors per guidelines.
|
|
|
|
2. **Card Portal** (if applicable for {brand}): If the Card Portal asset is present, verify it follows sizing rules (stroke weight and corner radius based on shortest side), proper border color, rotation limits, and that the logo is not placed outside it.
|
|
|
|
3. **Color Palette**: Are only approved {brand} masterbrand colors used? Check for proper WCAG-compliant color pairings and that sacred/primary colors are used appropriately.
|
|
|
|
4. **Typography**: Is Barclays Effra (or Arial fallback) used correctly? Check font weights (Medium/Bold for headings, Regular/Medium for body), sizes per type scale, and line spacing.
|
|
|
|
5. **Design Principles**: Does the overall design reflect the brand principles defined in the specification?
|
|
|
|
6. **Sacred Assets**: Verify that sacred/primary brand assets are present and not altered or misused.
|
|
|
|
7. **Accessibility**: Check for legible font sizes, proper contrast, and appropriate use of special typography elements per guidelines.
|
|
|
|
Provide your analysis as a JSON object. Be specific about any issues found and reference the relevant guideline sections.
|
|
|
|
RAG Status Guidelines:
|
|
- **Green**: Fully compliant with brand guidelines, no issues
|
|
- **Amber**: Minor deviations that should be addressed but don't severely impact brand integrity
|
|
- **Red**: Significant brand guideline violations that must be fixed before use
|
|
|
|
If the proof is nonsensical, not a marketing material, or cannot be analyzed, set analysisStatus to 'low_confidence'.
|
|
|
|
**Response Format:**
|
|
- Keep feedback brief and scannable
|
|
- Use bullet points for each finding
|
|
- Each bullet should be one actionable sentence
|
|
- Start with the issue, then the recommendation
|
|
- Example: "Logo placement incorrect (bottom-left) - move to top-right corner per guidelines"
|
|
"""
|
|
|
|
# Use single-image or multi-image analysis depending on input
|
|
if len(images) == 1:
|
|
file_data, file_type = images[0]
|
|
return await self.gemini.analyze_with_image(prompt, file_data, file_type)
|
|
else:
|
|
return await self.gemini.analyze_with_images(prompt, images)
|