When a subsequent revision of a proof is uploaded, the analysis now takes place in context of the previous version's results. The system identifies: - Resolved issues: fixed in the new revision - Outstanding issues: still present from previous version - New issues: introduced in the new revision Key changes: - Add resolvedIssues, outstandingIssues, newIssues fields to SubReview - Add PreviousReviewContext model for passing previous review data - Update all specialist agents to accept previous_review context - Extend GeminiService with include_revision_fields parameter - Add get_latest_version_review() repository method - Update LeadAgent to synthesize cross-version context in summary - Fetch previous analysis in WebSocket handler for revisions First version analysis continues to work exactly as before with revision fields set to null. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
146 lines
5.7 KiB
Python
146 lines
5.7 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,
|
|
) -> 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
|
|
|
|
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}
|
|
---
|
|
|
|
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
|
|
)
|