Files
gravity_control/scratch_dom_probe.py

91 lines
4.0 KiB
Python

"""
Inject a DOM probe into AG Native to capture the actual conversation DOM structure.
Posts the DOM structure to the HTTP bridge's /dump-html endpoint.
"""
import requests, json
BASE = "http://127.0.0.1:34332"
# We already have observer script running in workbench-jetski-agent.html
# But the issue is: the script is in the OUTER workbench, while the
# conversation UI might be in a webview/iframe.
# Let's first check what the observer CAN see by triggering a dump
# We'll post a custom HTML dump request
# Actually, let's analyze from a different angle:
# The observer's scanChatBodies() uses these selectors:
# '.text-ide-message-block-bot-color', '[data-testid*="bot"]', etc.
# If none match, it returns nothing. But we ARE getting DOM content
# (the garbage text), so SOMETHING is matching.
# The garbage text ("Running command", "content_copy", "Always run", etc.)
# This is the tool execution UI, not the AI response.
# Let's check what the current status says about sessionStalled
print("=== Bridge Status ===")
status = requests.get(f"{BASE}/status").json()
print(json.dumps(status, indent=2))
# Check if we can identify the DOM structure by examining what
# the observer script actually matched.
# The fact that it sends "Running command\n...\n content_copy\n Always run"
# means it's grabbing a tool execution panel, not the AI text response.
# Key insight: In AG Native UI (Tailwind/React), the conversation is in
# the SAME document as the workbench (not in a separate webview/iframe).
# The observer IS running in the right context, BUT the CSS selectors
# (.text-ide-message-block-bot-color) don't match AG Native's actual classes.
# What's happening: scanChatBodies() falls through to the broader selectors
# like [class*="agent-convo"] or [class*="bot-message"], which might be
# accidentally matching the tool panel UI.
# SOLUTION: We need to know the actual CSS class names for:
# 1. AI response text containers (the markdown output)
# 2. Tool call approval containers (Run/Allow/Cancel buttons)
print("\n=== DOM Probe via dump-html (injecting probe) ===")
# The observer's deep-inspect didn't work, but maybe we can
# create a targeted probe via a modified observer script
# Let's check what HTML files are currently being served
print("\nChecking if we can reach the webview...")
try:
# The observer script's scan() function runs every 3s.
# Let's see what it's finding by checking recent chat snapshots on disk
import os
bridge_path = os.path.expanduser("~/.gemini/antigravity/bridge")
pending_dir = os.path.join(bridge_path, "pending")
if os.path.exists(pending_dir):
files = sorted(os.listdir(pending_dir), key=lambda f: os.path.getmtime(os.path.join(pending_dir, f)), reverse=True)
print(f"\nRecent pending files: {len(files)}")
for f in files[:5]:
fpath = os.path.join(pending_dir, f)
try:
data = json.loads(open(fpath, encoding='utf-8').read())
print(f" {f}: cmd=\"{data.get('command','?')[:50]}\" src={data.get('source','?')} type={data.get('step_type','?')}")
except Exception as e:
print(f" {f}: error: {e}")
# Check brain directory for session artifacts
brain_dir = os.path.expanduser("~/.gemini/antigravity/brain/bdfc07d3-d87e-453a-b785-e38c2e9254e3")
if os.path.exists(brain_dir):
print(f"\nBrain dir exists: {brain_dir}")
entries = os.listdir(brain_dir)
print(f" Contents: {entries[:20]}")
# Check for conversation log
log_dir = os.path.join(brain_dir, ".system_generated", "logs")
if os.path.exists(log_dir):
print(f" Log dir: {os.listdir(log_dir)}")
else:
print(f"\nBrain dir NOT found: {brain_dir}")
# List available brain dirs
parent = os.path.expanduser("~/.gemini/antigravity/brain")
if os.path.exists(parent):
dirs = sorted(os.listdir(parent), key=lambda d: os.path.getmtime(os.path.join(parent, d)), reverse=True)
print(f" Available: {dirs[:5]}")
except Exception as e:
print(f"Error: {e}")