Spaces:
Sleeping
Sleeping
| """Web search tools for MapMorph agents.""" | |
| import re | |
| from typing import Dict, Any, List | |
| from agents import function_tool | |
| # Curated database of popular brand colors | |
| # Format: brand_name: [primary_color, secondary_color, ...] | |
| BRAND_COLOR_DATABASE = { | |
| # Tech companies | |
| "google": ["#4285F4", "#34A853", "#FBBC05", "#EA4335"], | |
| "facebook": ["#1877F2", "#F0F2F5"], | |
| "meta": ["#0668E1", "#F0F2F5"], | |
| "twitter": ["#1DA1F2", "#14171A", "#657786"], | |
| "x": ["#000000", "#FFFFFF"], | |
| "instagram": ["#E4405F", "#FCAF45", "#833AB4"], | |
| "linkedin": ["#0A66C2", "#313335"], | |
| "youtube": ["#FF0000", "#282828", "#FFFFFF"], | |
| "spotify": ["#1DB954", "#191414"], | |
| "apple": ["#000000", "#A6A6A6", "#F5F5F7"], | |
| "microsoft": ["#00A4EF", "#F25022", "#7FBA00", "#FFB900"], | |
| "amazon": ["#FF9900", "#146EB4"], | |
| "netflix": ["#E50914", "#000000"], | |
| "slack": ["#4A154B", "#36C5F0", "#2EB67D", "#ECB22E"], | |
| "zoom": ["#2D8CFF", "#FFFFFF"], | |
| "dropbox": ["#0061FF", "#1E1919"], | |
| "github": ["#24292E", "#FFFFFF"], | |
| "gitlab": ["#FC6D26", "#554488"], | |
| # Brands | |
| "nike": ["#000000", "#FFFFFF"], | |
| "adidas": ["#000000", "#FFFFFF"], | |
| "coca-cola": ["#F40009", "#FFFFFF"], | |
| "pepsi": ["#004B93", "#E32934", "#FFFFFF"], | |
| "starbucks": ["#00704A", "#FFFFFF"], | |
| "mcdonald's": ["#FFC72C", "#DA291C"], | |
| "mcdonals": ["#FFC72C", "#DA291C"], # Common misspelling | |
| "subway": ["#00923F", "#FBAF3F"], | |
| "kfc": ["#E4002B", "#FFFFFF"], | |
| "ikea": ["#0051BA", "#FFCC00"], | |
| "walmart": ["#0071CE", "#FFC220"], | |
| "target": ["#CC0000", "#FFFFFF"], | |
| "lego": ["#F6EC35", "#D11013", "#000000"], | |
| # Automotive | |
| "ferrari": ["#DC0000", "#000000"], | |
| "lamborghini": ["#FFB81C", "#000000"], | |
| "bmw": ["#1C69D4", "#FFFFFF"], | |
| "audi": ["#BB0A30", "#000000"], | |
| "toyota": ["#EB0A1E", "#FFFFFF"], | |
| "tesla": ["#E82127", "#000000"], | |
| # Fashion & Luxury | |
| "gucci": ["#00693E", "#CE1126"], | |
| "louis vuitton": ["#5B401F", "#FFFFFF"], | |
| "chanel": ["#000000", "#FFFFFF"], | |
| "hermes": ["#FF7A00", "#000000"], | |
| "prada": ["#000000", "#FFFFFF"], | |
| # Airlines | |
| "delta": ["#003A70", "#C8102E"], | |
| "united": ["#0066CC", "#FFFFFF"], | |
| "american airlines": ["#0078D2", "#C8102E"], | |
| "southwest": ["#304CB2", "#FFBF27"], | |
| } | |
| def search_brand_colors(brand_name: str) -> Dict[str, Any]: | |
| """Search for a brand's official color palette. | |
| This tool searches a curated database of popular brand colors and returns | |
| hex color codes. Use this when users mention brand names and want to apply | |
| brand colors to the map. | |
| Examples of when to use this: | |
| - "Use Nike's brand colors" | |
| - "Apply Coca-Cola colors to the map" | |
| - "Make it look like the Spotify brand" | |
| - "Use Apple's colors for the water" | |
| Args: | |
| brand_name: Name of the brand to search for (e.g., "Nike", "Coca-Cola", "Spotify") | |
| Returns: | |
| Dictionary containing: | |
| - brand: Brand name | |
| - colors: List of hex color codes found | |
| - primary_color: Main brand color (if identifiable) | |
| - found: Whether the brand was found in the database | |
| - source: Information about where colors were found | |
| """ | |
| # Normalize brand name for search | |
| normalized_name = brand_name.lower().strip() | |
| # Search in database | |
| if normalized_name in BRAND_COLOR_DATABASE: | |
| colors = BRAND_COLOR_DATABASE[normalized_name] | |
| return { | |
| "brand": brand_name, | |
| "colors": colors, | |
| "primary_color": colors[0] if colors else None, | |
| "found": True, | |
| "source": "Curated brand color database", | |
| "color_count": len(colors) | |
| } | |
| # Check for partial matches | |
| for db_brand, colors in BRAND_COLOR_DATABASE.items(): | |
| if normalized_name in db_brand or db_brand in normalized_name: | |
| return { | |
| "brand": brand_name, | |
| "colors": colors, | |
| "primary_color": colors[0] if colors else None, | |
| "found": True, | |
| "source": f"Curated database (matched '{db_brand}')", | |
| "color_count": len(colors) | |
| } | |
| # Brand not found | |
| return { | |
| "brand": brand_name, | |
| "colors": [], | |
| "primary_color": None, | |
| "found": False, | |
| "source": "Not found in database", | |
| "suggestion": f"Brand '{brand_name}' not found. Try a different brand or specify colors directly." | |
| } | |
| def extract_colors_from_text(text: str) -> List[str]: | |
| """Extract hex color codes from text. | |
| Use this helper tool to parse hex color codes from web search results, | |
| documentation, or user input. | |
| Args: | |
| text: Text containing hex color codes (e.g., "#FF5733, #C70039, #900C3F") | |
| Returns: | |
| List of valid hex color codes found in the text | |
| """ | |
| # Regex pattern for hex colors: # followed by 3 or 6 hex digits | |
| hex_pattern = r'#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\b' | |
| matches = re.findall(hex_pattern, text) | |
| # Normalize 3-digit hex to 6-digit | |
| normalized = [] | |
| for match in matches: | |
| if len(match) == 3: | |
| # Expand #RGB to #RRGGBB | |
| normalized.append(f"#{match[0]}{match[0]}{match[1]}{match[1]}{match[2]}{match[2]}") | |
| else: | |
| normalized.append(f"#{match}") | |
| # Remove duplicates while preserving order | |
| seen = set() | |
| unique_colors = [] | |
| for color in normalized: | |
| color_upper = color.upper() | |
| if color_upper not in seen: | |
| seen.add(color_upper) | |
| unique_colors.append(color_upper) | |
| return unique_colors | |
| def suggest_layer_mapping_for_brand( | |
| brand_colors: List[str], | |
| brand_name: str = "" | |
| ) -> Dict[str, str]: | |
| """Suggest which brand colors should be applied to which map layers. | |
| Use this tool after finding a brand's colors to intelligently map them | |
| to appropriate map layers based on color psychology and aesthetics. | |
| Args: | |
| brand_colors: List of hex color codes from the brand palette | |
| brand_name: Optional brand name for context | |
| Returns: | |
| Dictionary mapping layer IDs to suggested colors: | |
| { | |
| "water": "#HEXCODE", | |
| "earth": "#HEXCODE", | |
| "buildings": "#HEXCODE", | |
| ... | |
| } | |
| """ | |
| if not brand_colors: | |
| return {"error": "No brand colors provided"} | |
| suggestions = {} | |
| # Analyze colors by their properties | |
| def color_brightness(hex_color: str) -> float: | |
| """Calculate perceived brightness (0-1) of a hex color.""" | |
| hex_color = hex_color.lstrip('#') | |
| r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16) | |
| # Perceived brightness formula | |
| return (0.299 * r + 0.587 * g + 0.114 * b) / 255 | |
| def is_blue_ish(hex_color: str) -> bool: | |
| """Check if color is blue-ish.""" | |
| hex_color = hex_color.lstrip('#') | |
| r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16) | |
| return b > r and b > g | |
| def is_green_ish(hex_color: str) -> bool: | |
| """Check if color is green-ish.""" | |
| hex_color = hex_color.lstrip('#') | |
| r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16) | |
| return g > r and g > b | |
| # Sort colors by brightness | |
| sorted_colors = sorted(brand_colors, key=color_brightness) | |
| darkest = sorted_colors[0] | |
| lightest = sorted_colors[-1] | |
| # Find blue-ish colors for water | |
| blue_colors = [c for c in brand_colors if is_blue_ish(c)] | |
| if blue_colors: | |
| suggestions["water"] = blue_colors[0] | |
| elif len(brand_colors) >= 2: | |
| # Use second color if no blue found | |
| suggestions["water"] = brand_colors[1] if len(brand_colors) > 1 else brand_colors[0] | |
| # Find green-ish colors for parks/nature | |
| green_colors = [c for c in brand_colors if is_green_ish(c)] | |
| if green_colors: | |
| suggestions["landuse"] = green_colors[0] | |
| # Use lightest color for earth/background | |
| suggestions["earth"] = lightest | |
| # Use darkest or primary color for buildings | |
| suggestions["buildings"] = darkest if len(brand_colors) > 2 else brand_colors[0] | |
| # Use light color for roads | |
| if color_brightness(lightest) > 0.7: | |
| suggestions["roads"] = lightest | |
| else: | |
| suggestions["roads"] = "#FFFFFF" # Default to white if no light color | |
| return suggestions | |