- Add AG Native DOM path: #conversation + .leading-relaxed.select-text - Keep Cascade path: [data-testid=conversation-view] + [data-step-index] - Register #632 in known-issues.md (SDK+DOM both blocked for AG Native) - Bump version 0.5.50 → 0.5.51 - Add DOM analysis helper scripts
110 lines
4.0 KiB
Python
110 lines
4.0 KiB
Python
"""Trace the DOM path from body to AI response container."""
|
|
import json, os
|
|
|
|
fpath = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity', 'bridge', 'dump_html_5.json')
|
|
with open(fpath, 'r', encoding='utf-8-sig') as f:
|
|
data = json.load(f)
|
|
|
|
body = data.get('body', data.get('bodyTree', {}))
|
|
|
|
def find_path_to_class(node, target_cls, path=None, depth=0):
|
|
"""Find the DOM path down to a node with a matching class."""
|
|
if path is None: path = []
|
|
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', {})
|
|
|
|
entry = {
|
|
'depth': depth,
|
|
'tag': tag,
|
|
'cls': cls[:120],
|
|
'children': len(children),
|
|
'text': text[:60] if text else '',
|
|
'attrs': {k:v[:40] for k,v in attrs.items() if k not in ('style',)}
|
|
}
|
|
|
|
if target_cls.lower() in cls.lower():
|
|
return path + [entry]
|
|
|
|
for i, child in enumerate(children):
|
|
result = find_path_to_class(child, target_cls, path + [entry], depth+1)
|
|
if result:
|
|
return result
|
|
|
|
return []
|
|
|
|
# Find path to the AI response container
|
|
print("=== PATH TO 'leading-relaxed select-text' ===")
|
|
path = find_path_to_class(body, 'leading-relaxed select-text')
|
|
for p in path:
|
|
indent = ' ' * p['depth']
|
|
print(f'{indent}[{p["tag"]}] cls="{p["cls"]}" children={p["children"]} {p["attrs"]}')
|
|
if p['text']:
|
|
print(f'{indent} text: "{p["text"]}"')
|
|
|
|
# Now get the full subtree of the AI response container
|
|
def get_subtree(node, target_cls, depth=0):
|
|
if not isinstance(node, dict): return None
|
|
cls = node.get('cls', '')
|
|
if target_cls.lower() in cls.lower():
|
|
return node
|
|
for child in node.get('children', []):
|
|
result = get_subtree(child, target_cls, depth+1)
|
|
if result:
|
|
return result
|
|
return None
|
|
|
|
print("\n=== AI RESPONSE CONTAINER SUBTREE ===")
|
|
container = get_subtree(body, 'leading-relaxed select-text')
|
|
if container:
|
|
def print_tree(node, depth=0, max_depth=4):
|
|
if not isinstance(node, dict) or depth > max_depth: return
|
|
tag = node.get('tag','')
|
|
cls = node.get('cls','')[:80]
|
|
text = node.get('text','')
|
|
children = node.get('children', [])
|
|
indent = ' ' * depth
|
|
line = f'{indent}[{tag}]'
|
|
if cls: line += f' cls="{cls}"'
|
|
line += f' children={len(children)}'
|
|
if text: line += f' text="{text[:60]}"'
|
|
print(line)
|
|
for c in children:
|
|
print_tree(c, depth+1, max_depth)
|
|
|
|
print_tree(container, 0, 3)
|
|
|
|
# Also search for the chat panel container - what wraps the entire conversation
|
|
print("\n=== SEARCH FOR CHAT PANEL WRAPPERS ===")
|
|
chat_patterns = ['chat', 'antigravity', 'gemini', 'panel', 'agentview', 'sidebar', 'conversation']
|
|
for pat in chat_patterns:
|
|
path = find_path_to_class(body, pat)
|
|
if path:
|
|
last = path[-1]
|
|
print(f' Pattern "{pat}" found at depth={last["depth"]} [{last["tag"]}] cls="{last["cls"]}" children={last["children"]}')
|
|
|
|
# Find the parent chain from body to the container - look by scanning ALL class names
|
|
print("\n=== ALL UNIQUE CLASS NAMES (depth <= 12) ===")
|
|
all_classes = set()
|
|
def collect_classes(node, depth=0, max_depth=12):
|
|
if not isinstance(node, dict) or depth > max_depth: return
|
|
cls = node.get('cls', '')
|
|
if cls:
|
|
for c in cls.split():
|
|
if len(c) > 3 and not c.startswith('{') and 'mtk' not in c:
|
|
all_classes.add(c)
|
|
for child in node.get('children', []):
|
|
collect_classes(child, depth+1, max_depth)
|
|
|
|
collect_classes(body)
|
|
# Print classes sorted, grouped by potential relevance
|
|
relevant = sorted([c for c in all_classes if any(k in c.lower() for k in
|
|
['chat', 'message', 'response', 'agent', 'gemini', 'turn', 'model', 'user', 'bot', 'conversation', 'markdown', 'prose', 'text-', 'content'])])
|
|
print("Relevant classes:")
|
|
for c in relevant:
|
|
print(f' {c}')
|