"""CYPHER V12 M39 — Multimodal Chain-of-Thought. Extension of M10 multimodal_stub. For prompts containing images: 1. Describe image via M10 (external API) 2. Extract structured features (text/UI/diagram/screenshot) 3. Build CoT prompt combining text + image features 4. Generate response grounded in BOTH Cross-modal reasoning: e.g. "Analyze this network diagram + this PCAP" → diagram describes infrastructure, PCAP describes traffic, response correlates. """ from __future__ import annotations import logging import re from typing import Callable, Any logger = logging.getLogger(__name__) # Image type detection (from description text) _IMAGE_TYPE_PATTERNS = { "screenshot": ("screenshot", "screen", "window", "dialog", "menu"), "diagram": ("diagram", "architecture", "topology", "flowchart", "schema"), "code": ("code", "snippet", "function", "class", "syntax highlight"), "log": ("log", "console", "terminal", "output", "stack trace"), "chart": ("chart", "graph", "axis", "plot", "candle", "ohlcv"), "ui_form": ("form", "input field", "button", "login", "credential"), "phishing": ("urgent", "verify", "suspended", "click here"), } def classify_image_type(description: str) -> list[str]: """Detect image type from M10 description text.""" d_lower = description.lower() types: list[str] = [] for itype, kws in _IMAGE_TYPE_PATTERNS.items(): if any(kw in d_lower for kw in kws): types.append(itype) return types def extract_image_facts(description: str) -> dict: """Extract structured facts from image description.""" facts: dict = {} # URLs / IPs / domains ips = re.findall(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", description) urls = re.findall(r"https?://\S+", description) domains = re.findall(r"\b[a-z0-9-]+\.(?:com|net|org|io|xyz|ru|cn)\b", description.lower()) if ips: facts["ips"] = ips[:5] if urls: facts["urls"] = urls[:5] if domains: facts["domains"] = domains[:5] # CVEs cves = re.findall(r"CVE-\d{4}-\d+", description, re.IGNORECASE) if cves: facts["cves"] = list(set(c.upper() for c in cves))[:3] # Numbers (timestamps, counts) numbers = re.findall(r"\b\d{3,}\b", description) if numbers: facts["large_numbers"] = numbers[:5] # Possible credentials (just signal, not extraction) if "password" in description.lower() or "credentials" in description.lower(): facts["credentials_signal"] = True return facts class MultimodalCoT: """Cross-modal CoT: image + text → integrated reasoning.""" def __init__( self, multimodal_stub=None, # M10 MultimodalStub instance generate_fn: Callable[[str, int, float], str] | None = None, ): self.mm = multimodal_stub self.generate_fn = generate_fn def analyze( self, prompt: str, image_src: str | bytes | None = None, text_context: str = "", ) -> dict: result: dict = {"prompt": prompt, "has_image": image_src is not None} # Step 1: image description image_description = "" image_types: list[str] = [] image_facts: dict = {} if image_src is not None and self.mm: try: image_description = self.mm.describe_image( image_src, prompt="Describe this image for cybersecurity analysis. List visible text, UI elements, URLs, IPs, code, processes, or suspicious indicators." ) image_types = classify_image_type(image_description) image_facts = extract_image_facts(image_description) except Exception as e: logger.warning(f"Image describe fail: {e}") image_description = f"[Image description unavailable: {type(e).__name__}]" result["image_description"] = image_description result["image_types"] = image_types result["image_facts"] = image_facts # Step 2: build cross-modal CoT prompt cot_parts: list[str] = [] if image_description: cot_parts.append(f"[IMAGE_DESCRIPTION: {image_description[:400]}]") if image_types: cot_parts.append(f"[IMAGE_TYPE: {','.join(image_types)}]") if image_facts: cot_parts.append(f"[IMAGE_FACTS: {image_facts}]") if text_context: cot_parts.append(f"[TEXT_CONTEXT: {text_context[:400]}]") cot_parts.append(f"\nQuestion: {prompt}") cot_parts.append("Analyze step by step (image observation → text correlation → conclusion):") cot_prompt = "\n".join(cot_parts) result["cot_prompt"] = cot_prompt # Step 3: generate cross-modal reasoning if self.generate_fn: try: response = self.generate_fn(cot_prompt, 300, 0.35) result["response"] = response except Exception as e: result["response"] = f"[Generation error: {e}]" else: result["response"] = "[no generate_fn provided]" return result __all__ = ["MultimodalCoT", "classify_image_type", "extract_image_facts"] if __name__ == "__main__": logging.basicConfig(level=logging.INFO) print("=== M39 cypher_multimodal_cot SMOKE ===") # Mock multimodal stub class MockMM: def describe_image(self, src, prompt=""): return ("Screenshot of a Windows login form. URL https://micros0ft-security.com/login " "shows fake Microsoft branding. User must enter password and verify. " "Suspicious IP 185.220.101.5 in URL bar. Text says 'Your account is suspended, " "click here urgent action required'.") def mock_gen(prompt, mt, t): return ("Step 1: Image shows phishing screenshot. " "Step 2: Domain micros0ft-security.com is typosquat. " "Step 3: IP 185.220.101.5 is Tor exit node. " "Conclusion: Confirmed phishing site, do not enter credentials.") mc = MultimodalCoT(multimodal_stub=MockMM(), generate_fn=mock_gen) result = mc.analyze( "Is this login page legitimate?", image_src="/tmp/fake.png", text_context="User clicked email link about account suspension.", ) print(f"\nImage types: {result['image_types']}") print(f"Image facts: {result['image_facts']}") print(f"CoT prompt (preview): {result['cot_prompt'][:300]}") print(f"\nResponse: {result['response'][:300]}") # Classification tests print(f"\nclassify 'screenshot of dialog' → {classify_image_type('screenshot of a dialog box')}") print(f"classify 'network diagram' → {classify_image_type('network architecture diagram')}") print("=== SMOKE PASS ===")