Previously, proof metadata collected during upload was only used for database persistence. Now it flows through the entire analysis pipeline so agents can tailor their feedback to the specific channel and format being reviewed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
160 lines
6.3 KiB
Python
160 lines
6.3 KiB
Python
from typing import List, Optional, Tuple
|
|
|
|
from app.agents.base_agent import BaseAgent
|
|
from app.models.schemas import PreviousReviewContext, SubReview
|
|
from app.services.gemini_service import GeminiService
|
|
from app.services.reference_docs import ReferenceDocsService
|
|
|
|
|
|
class ChannelTechSpecsAgent(BaseAgent):
|
|
"""Channel Tech Specs Agent - analyzes proofs for technical specifications and format requirements using Gemini."""
|
|
|
|
name = "Channel Tech Specs Agent"
|
|
|
|
def __init__(self, gemini_service: GeminiService, reference_docs: ReferenceDocsService):
|
|
"""
|
|
Initialize the Channel Tech Specs 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 _build_revision_context(self, previous_review: PreviousReviewContext) -> str:
|
|
"""Build prompt section for revision-aware analysis."""
|
|
issues_list = "\n".join(f" - {issue}" for issue in previous_review.issues) if previous_review.issues else " (No issues)"
|
|
return f"""
|
|
---
|
|
|
|
**REVISION CONTEXT**
|
|
|
|
This is a revision of a previously reviewed proof. The previous version (Version {previous_review.version}) had the following channel tech specs review:
|
|
|
|
- RAG Status: {previous_review.ragStatus}
|
|
- Feedback: {previous_review.feedback}
|
|
- Issues identified:
|
|
{issues_list}
|
|
|
|
When analyzing this revision, you MUST:
|
|
1. Compare against the previous issues and determine which have been RESOLVED
|
|
2. Identify which previous issues are still OUTSTANDING (not fixed)
|
|
3. Identify any NEW issues introduced in this revision
|
|
|
|
Your response MUST include:
|
|
- resolvedIssues: Array of issues from the previous version that have been fixed
|
|
- outstandingIssues: Array of issues from the previous version that remain unfixed
|
|
- newIssues: Array of new issues not present in the previous version
|
|
|
|
---
|
|
"""
|
|
|
|
async def analyze(
|
|
self,
|
|
images: List[Tuple[bytes, str]],
|
|
previous_review: Optional[PreviousReviewContext] = None,
|
|
channel: Optional[str] = None,
|
|
sub_channel: Optional[str] = None,
|
|
proof_type: Optional[str] = None,
|
|
) -> SubReview:
|
|
"""
|
|
Analyze the proof for technical specifications compliance.
|
|
|
|
Args:
|
|
images: List of (file_data, mime_type) tuples representing the proof
|
|
previous_review: Optional context from previous version for revision-aware analysis
|
|
channel: Target channel (e.g. "Social", "Digital")
|
|
sub_channel: Target sub-channel (e.g. "Meta", "Google")
|
|
proof_type: Proof format type (e.g. "In-feed 1x1", "Banner")
|
|
|
|
Returns:
|
|
SubReview with technical specifications assessment
|
|
"""
|
|
# Get the channel tech specs specification
|
|
tech_specs_context = self.reference_docs.get_channel_tech_specs_spec()
|
|
|
|
# Build revision context if available
|
|
revision_context = ""
|
|
if previous_review:
|
|
revision_context = self._build_revision_context(previous_review)
|
|
|
|
prompt = f"""You are a digital channel technical specifications specialist for Barclays Bank. Your role is to analyze marketing proofs for technical compliance with platform specifications, dimensions, file formats, and character limits.
|
|
|
|
Here are the channel technical specifications to use for your analysis:
|
|
|
|
{tech_specs_context}
|
|
{revision_context}
|
|
---
|
|
|
|
**PROOF METADATA**
|
|
- Channel: {channel or "Not specified"}
|
|
- Sub-Channel: {sub_channel or "Not specified"}
|
|
- Proof Type: {proof_type or "Not specified"}
|
|
|
|
Use this metadata to focus your analysis on the specific technical specifications for this channel and format.
|
|
---
|
|
|
|
Analyze the uploaded proof for technical specification compliance, checking:
|
|
|
|
1. **Dimensions & Resolution**:
|
|
- Does the asset meet the required dimensions for the target platform?
|
|
- Is the resolution appropriate (DPI/PPI requirements)?
|
|
- Are aspect ratios correct for the intended placement?
|
|
|
|
2. **File Format Requirements**:
|
|
- Is the file format suitable for the platform?
|
|
- Are file size limits being respected?
|
|
- Is compression appropriate for quality vs. performance?
|
|
|
|
3. **Typography Specifications**:
|
|
- Are minimum font sizes met for the platform?
|
|
- Character counts within platform limits (headlines, body, etc.)?
|
|
- Is text readable at the intended display size?
|
|
|
|
4. **Digital Grid System**:
|
|
- Desktop: 12-column grid compliance
|
|
- Tablet: 12-column grid compliance
|
|
- Mobile: 6-column grid compliance
|
|
- 8px baseline grid adherence
|
|
|
|
5. **Accessibility Requirements**:
|
|
- Color contrast meets WCAG requirements?
|
|
- Only documented color pairings are used?
|
|
- Text is legible at intended display sizes?
|
|
|
|
6. **Platform-Specific Technical Requirements**:
|
|
- Safe zone compliance for interactive elements
|
|
- Video/animation format requirements (if applicable)
|
|
- Frame rate and duration limits (if applicable)
|
|
|
|
Provide your analysis as a JSON object. Be specific about any technical issues and reference the relevant specification.
|
|
|
|
RAG Status Guidelines:
|
|
- **Green**: Fully compliant with all technical specifications
|
|
- **Amber**: Minor technical adjustments needed but content is deployable
|
|
- **Red**: Significant technical issues that will prevent proper display or deployment
|
|
|
|
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 specification requirement
|
|
- Example: "Image resolution 72dpi - increase to minimum 150dpi for print quality"
|
|
"""
|
|
|
|
# Determine if revision fields should be included
|
|
include_revision_fields = previous_review is not None
|
|
|
|
# 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, include_revision_fields=include_revision_fields
|
|
)
|
|
else:
|
|
return await self.gemini.analyze_with_images(
|
|
prompt, images, include_revision_fields=include_revision_fields
|
|
)
|