"""Pipeline: obtiene el AX tree de un tab Chrome y lo convierte en outline legible.""" import argparse import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from pipelines.cdp_get_ax_tree import cdp_get_ax_tree from core.trim_ax_tree import trim_ax_tree from core.render_ax_outline import render_ax_outline def cdp_perceive_outline( debug_port: int, tab_id: str, max_chars: int = 20000, ) -> str: """Obtiene el AX tree de un tab Chrome y devuelve un outline indentado legible. Compone tres pasos: 1. cdp_get_ax_tree — obtiene nodos crudos via CDP WebSocket. 2. trim_ax_tree — poda nodos irrelevantes (ignored, generic sin hijos, etc.). 3. render_ax_outline — convierte en outline indentado con #ref para accionables. Args: debug_port: Puerto de debug remoto de Chrome (ej. 9333). Chrome debe estar corriendo con --remote-debugging-port=PORT. tab_id: ID del tab CDP. Obtenerlo via GET http://127.0.0.1:{port}/json/list o con cdp_list_tabs_go_browser. max_chars: Límite de caracteres del outline resultante. 0 = sin límite. Default 20000 (~5k tokens), apropiado para context window de Claude. Returns: String con el outline indentado. Cada nodo accionable tiene #ref=nodeId para que el LLM pueda referenciarlo en acciones posteriores. Raises: RuntimeError: Si Chrome no responde, el tab no existe, o falla la conexión WS. TimeoutError: Si Accessibility.getFullAXTree no responde en 15s. """ nodes = cdp_get_ax_tree(debug_port=debug_port, tab_id=tab_id) trimmed = trim_ax_tree(nodes) return render_ax_outline(trimmed, max_chars=max_chars) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Obtiene el outline del AX tree de un tab Chrome via CDP." ) parser.add_argument( "--debug-port", type=int, default=9222, help="Puerto de debug remoto de Chrome (default: 9222).", ) parser.add_argument( "--tab-id", required=True, help="ID del tab CDP (campo 'id' de GET /json/list).", ) parser.add_argument( "--max-chars", type=int, default=20000, help="Límite de caracteres del outline. 0 = sin límite (default: 20000).", ) args = parser.parse_args() try: outline = cdp_perceive_outline( debug_port=args.debug_port, tab_id=args.tab_id, max_chars=args.max_chars, ) print(outline) except (RuntimeError, TimeoutError) as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1)