"""Analyze AG Native DOM structure to find AI response containers.""" import json, os, sys def load_dump(): bridge = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity', 'bridge') # Try deep-inspect result first, then dump_html for fname in ['deep-inspect-result.json', 'dump_html.json']: fpath = os.path.join(bridge, fname) if os.path.exists(fpath): print(f"Loading: {fname} ({os.path.getsize(fpath)} bytes)") with open(fpath, 'r', encoding='utf-8-sig') as f: return json.load(f), fname return None, None def find_text_containers(node, path="", depth=0, results=None): """Recursively find nodes with substantial text content (potential AI response containers).""" if results is None: results = [] if not isinstance(node, dict): return results tag = node.get('tag', '') cls = node.get('cls', '') text = node.get('text', '') attrs = node.get('attrs', {}) children = node.get('children', []) cur_path = f"{path}/{tag}" if cls: short_cls = cls[:60] cur_path += f".{short_cls}" # Look for nodes with long text (potential AI responses) if text and len(text) > 50: results.append({ 'path': cur_path, 'depth': depth, 'tag': tag, 'cls': cls[:100], 'text_len': len(text), 'text_preview': text[:120], 'attrs': {k:v for k,v in attrs.items() if k not in ('style',)} }) for child in children: find_text_containers(child, cur_path, depth+1, results) return results def find_by_class_pattern(node, patterns, path="", depth=0, results=None): """Find nodes matching class patterns.""" if results is None: results = [] if not isinstance(node, dict): return results tag = node.get('tag', '') cls = node.get('cls', '') attrs = node.get('attrs', {}) children = node.get('children', []) text = node.get('text', '') cur_path = f"{path}/{tag}" for pattern in patterns: if pattern.lower() in cls.lower() or pattern.lower() in str(attrs).lower(): child_count = len(children) results.append({ 'path': cur_path, 'depth': depth, 'tag': tag, 'cls': cls[:150], 'pattern': pattern, 'text_preview': text[:80] if text else '', 'child_count': child_count, 'attrs': {k:v[:50] for k,v in attrs.items() if k != 'style'} }) for child in children: find_by_class_pattern(child, patterns, cur_path, depth+1, results) return results def analyze_chat_structure(node, path="", depth=0): """Find the chat/conversation area by looking at the main layout.""" if not isinstance(node, dict): return tag = node.get('tag', '') cls = node.get('cls', '') children = node.get('children', []) text = node.get('text', '') attrs = node.get('attrs', {}) # Print interesting structural nodes at shallow depths if depth <= 6: child_count = len(children) has_text = bool(text and len(text) > 10) info = f"{' '*depth}{tag}" if cls: info += f" .{cls[:80]}" if attrs: attr_str = ' '.join(f'{k}={v[:30]}' for k,v in attrs.items() if k not in ('style','class')) if attr_str: info += f" [{attr_str}]" info += f" children={child_count}" if has_text: info += f" text=\"{text[:50]}...\"" print(info) for child in children: analyze_chat_structure(child, f"{path}/{tag}", depth+1) data, fname = load_dump() if not data: print("No dump file found!") sys.exit(1) # Handle both dump formats body = data.get('body', data) qi = data.get('quickInfo', {}) print("=" * 60) print("QUICK INFO") print("=" * 60) if qi: for k, v in qi.items(): if k == 'buttons': print(f"buttons ({len(v)}):") for b in v[:15]: print(f" [{b.get('tag')}] \"{b.get('text','')[:50]}\" visible={b.get('visible')} cls={b.get('cls','')[:60]}") elif k == 'dataAttrs': print(f"dataAttrs: {v[:30]}") else: print(f"{k}: {v}") print("\n" + "=" * 60) print("CHAT-RELATED CLASS PATTERNS") print("=" * 60) patterns = ['chat', 'message', 'conversation', 'response', 'answer', 'reply', 'markdown', 'prose', 'content', 'panel', 'agent', 'assistant', 'planner', 'step', 'trajectory', 'bot', 'ai-', 'turn'] matches = find_by_class_pattern(body, patterns) for m in matches: print(f" [{m['tag']}] cls=\"{m['cls']}\" pattern={m['pattern']} children={m['child_count']} {m.get('attrs',{})}") print("\n" + "=" * 60) print("LONG TEXT NODES (potential AI responses)") print("=" * 60) texts = find_text_containers(body) texts.sort(key=lambda x: x['text_len'], reverse=True) for t in texts[:20]: print(f" [{t['tag']}] depth={t['depth']} len={t['text_len']} cls=\"{t['cls'][:60]}\"") print(f" text: \"{t['text_preview']}\"") if t['attrs']: print(f" attrs: {t['attrs']}") print("\n" + "=" * 60) print("DOM TREE (depth<=6)") print("=" * 60) analyze_chat_structure(body)