├── visual-tree-search-backend ├── app │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ ├── lwats │ │ │ ├── __init__.py │ │ │ ├── core_async │ │ │ │ ├── __init__.py │ │ │ │ ├── config.py │ │ │ │ └── agent_factory.py │ │ │ ├── agents_async │ │ │ │ ├── __init__.py │ │ │ │ └── SearchAgents │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── tree_vis.py │ │ │ │ │ ├── lats_agent.py │ │ │ │ │ ├── trajectory_score.py │ │ │ │ │ └── lats_node.py │ │ │ ├── webagent_utils_async │ │ │ │ ├── __init__.py │ │ │ │ ├── action │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── action_parser.py │ │ │ │ │ ├── parsers.py │ │ │ │ │ └── base.py │ │ │ │ ├── tools │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── upload_file.py │ │ │ │ │ ├── select_option.py │ │ │ │ │ ├── navigation.py │ │ │ │ │ ├── registry.py │ │ │ │ │ ├── shared_utils.py │ │ │ │ │ └── webscraping.py │ │ │ │ ├── utils │ │ │ │ │ └── __init__.py │ │ │ │ ├── browser_env │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── constants.py │ │ │ │ │ └── javascript │ │ │ │ │ │ └── frame_unmark_elements.js │ │ │ │ └── evaluation │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── evaluators.py │ │ │ │ │ └── feedback.py │ │ │ └── evaluation_async │ │ │ │ └── evaluators.py │ │ ├── services │ │ │ └── hello_service.py │ │ ├── controllers │ │ │ └── hello_controller.py │ │ ├── routes │ │ │ ├── hello.py │ │ │ ├── terminate_session.py │ │ │ ├── sse.py │ │ │ ├── websocket.py │ │ │ ├── tree_traversal.py │ │ │ └── tree_websocket.py │ │ └── run_demo_treesearch_async.py │ ├── lib │ │ └── supabase.py │ └── main.py ├── test │ ├── __init__.py │ ├── test-ws.py │ ├── test-tree-ws.py │ ├── test_tree_search_depth.py │ ├── websocket-client.html │ ├── test-tree-search-ws-simple.py │ └── test-tree-search-ws-lats.py ├── .env.example ├── Dockerfile ├── requirements.txt └── README.md ├── visual-tree-search-browser-service ├── README.md ├── app │ └── __init__.py ├── requirements.txt └── Dockerfile ├── visual-tree-search-state-reset ├── app │ ├── __init__.py │ ├── api │ │ ├── services │ │ │ └── hello_service.py │ │ ├── controllers │ │ │ └── hello_controller.py │ │ └── routes │ │ │ ├── hello.py │ │ │ ├── test_sql.py │ │ │ ├── test_container.py │ │ │ └── test_db.py │ └── main.py ├── .gitignore ├── requirements.txt ├── README.md └── Server_Setup.md ├── visual-tree-search-app ├── .env.example ├── postcss.config.mjs ├── public │ ├── favicon.ico │ ├── vercel.svg │ ├── window.svg │ ├── file.svg │ ├── globe.svg │ └── next.svg ├── lib │ └── utils.ts ├── next.config.ts ├── pages │ ├── _document.tsx │ ├── api │ │ └── hello.ts │ └── _app.tsx ├── eslint.config.mjs ├── components.json ├── components │ ├── Footer.tsx │ ├── ui │ │ ├── label.tsx │ │ ├── input.tsx │ │ ├── checkbox.tsx │ │ ├── scroll-area.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ └── dialog.tsx │ ├── Layout.tsx │ ├── LiveBrowserView.tsx │ ├── Header.tsx │ └── Sidebar.tsx ├── tsconfig.json ├── .gitignore ├── package.json ├── README.md └── styles │ └── globals.css ├── .env.example ├── .gitignore ├── .github └── workflows │ ├── backend-ecs.yml │ └── browser-service-ecs.yml ├── LICENSE └── README.md /visual-tree-search-backend/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-browser-service/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-state-reset/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-browser-service/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-app/.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_BACKEND_URL="" -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/core_async/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/agents_async/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/agents_async/SearchAgents/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/action/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/browser_env/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/evaluation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-backend/test/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test package for Visual Tree Search 3 | """ -------------------------------------------------------------------------------- /visual-tree-search-state-reset/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .DS_Store 3 | venv 4 | .env 5 | 6 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | BROWSERBASE_PROJECT_ID= 3 | BROWSERBASE_API_KEY= 4 | ACCOUNT_RESET_URL= -------------------------------------------------------------------------------- /visual-tree-search-backend/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY="" 2 | BROWSERBASE_PROJECT_ID="" 3 | BROWSERBASE_API_KEY="" 4 | ACCOUNT_RESET_URL="" -------------------------------------------------------------------------------- /visual-tree-search-app/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /visual-tree-search-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PathOnAIOrg/VisualTreeSearch-Demo/HEAD/visual-tree-search-app/public/favicon.ico -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/services/hello_service.py: -------------------------------------------------------------------------------- 1 | class HelloService: 2 | def get_hello_data(self): 3 | return {"name": "John Doe"} -------------------------------------------------------------------------------- /visual-tree-search-state-reset/app/api/services/hello_service.py: -------------------------------------------------------------------------------- 1 | class HelloService: 2 | def get_hello_data(self): 3 | return {"name": "John Doe"} -------------------------------------------------------------------------------- /visual-tree-search-app/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-browser-service/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi==0.109.2 2 | uvicorn==0.27.1 3 | python-multipart==0.0.9 4 | pydantic==2.6.1 5 | playwright==1.41.2 6 | python-dotenv==1.0.1 7 | boto3==1.34.34 -------------------------------------------------------------------------------- /visual-tree-search-state-reset/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi>=0.103.1 2 | uvicorn>=0.23.2 3 | websockets>=11.0.3 4 | python-dotenv>=1.0.0 5 | supabase>=1.0.3 6 | httpx>=0.24.1 7 | sqlalchemy>=2.0.27 8 | pymysql>=1.1.0 9 | docker -------------------------------------------------------------------------------- /visual-tree-search-app/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /visual-tree-search-app/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | reactStrictMode: true, 6 | }; 7 | 8 | export default nextConfig; 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | visual-tree-search-backend/app/api/test_logs/* 2 | visual-tree-search-backend/log/* 3 | log/* 4 | shopping.json 5 | Log.md 6 | visual-tree-search-backend/log/ 7 | visual-tree-search-backend/app/api/log/ 8 | __pycache__/ 9 | .DS_Store 10 | venv 11 | .env 12 | 13 | -------------------------------------------------------------------------------- /visual-tree-search-app/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/browser_env/constants.py: -------------------------------------------------------------------------------- 1 | TEXT_MAX_LENGTH = 2**32 - 1 2 | 3 | BROWSERGYM_ID_ATTRIBUTE = "data-unique-test-id" # Playwright's default is "data-testid" 4 | BROWSERGYM_VISIBILITY_ATTRIBUTE = "browsergym_visibility_ratio" 5 | BROWSERGYM_SETOFMARKS_ATTRIBUTE = "browsergym_set_of_marks" 6 | 7 | EXTRACT_OBS_MAX_TRIES = 5 8 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/controllers/hello_controller.py: -------------------------------------------------------------------------------- 1 | from fastapi import Response 2 | from app.api.services.hello_service import HelloService 3 | 4 | class HelloController: 5 | def __init__(self): 6 | self.hello_service = HelloService() 7 | 8 | def get_hello(self): 9 | data = self.hello_service.get_hello_data() 10 | return data -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/routes/hello.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | from app.api.controllers.hello_controller import HelloController 3 | 4 | router = APIRouter( 5 | prefix="", 6 | tags=["hello"] 7 | ) 8 | hello_controller = HelloController() 9 | 10 | @router.get("", include_in_schema=True) 11 | async def get_hello(): 12 | return hello_controller.get_hello() -------------------------------------------------------------------------------- /visual-tree-search-state-reset/app/api/controllers/hello_controller.py: -------------------------------------------------------------------------------- 1 | from fastapi import Response 2 | from app.api.services.hello_service import HelloService 3 | 4 | class HelloController: 5 | def __init__(self): 6 | self.hello_service = HelloService() 7 | 8 | def get_hello(self): 9 | data = self.hello_service.get_hello_data() 10 | return data -------------------------------------------------------------------------------- /visual-tree-search-state-reset/app/api/routes/hello.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | from app.api.controllers.hello_controller import HelloController 3 | 4 | router = APIRouter( 5 | prefix="", 6 | tags=["hello"] 7 | ) 8 | hello_controller = HelloController() 9 | 10 | @router.get("", include_in_schema=True) 11 | async def get_hello(): 12 | return hello_controller.get_hello() -------------------------------------------------------------------------------- /visual-tree-search-app/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | type Data = { 5 | name: string; 6 | }; 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse, 11 | ) { 12 | res.status(200).json({ name: "John Doe" }); 13 | } 14 | -------------------------------------------------------------------------------- /visual-tree-search-app/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-app/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-app/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "../styles/globals.css"; 2 | import type { AppProps } from "next/app"; 3 | import Layout from "../components/Layout"; 4 | import { ThemeProvider } from "next-themes"; 5 | 6 | 7 | export default function App({ Component, pageProps }: AppProps) { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /visual-tree-search-app/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /visual-tree-search-app/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "styles/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /visual-tree-search-app/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | const Footer = () => { 2 | return ( 3 |
4 |
5 |
6 | © 2025 VisualTreeSearch 7 | 8 | All rights reserved 9 |
10 |
11 |
12 | ); 13 | }; 14 | 15 | export default Footer; 16 | 17 | -------------------------------------------------------------------------------- /visual-tree-search-backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim 2 | 3 | WORKDIR /app 4 | 5 | # Set environment variables 6 | ENV PYTHONDONTWRITEBYTECODE=1 7 | ENV PYTHONUNBUFFERED=1 8 | 9 | # Install dependencies 10 | COPY requirements.txt . 11 | RUN pip install --no-cache-dir -r requirements.txt 12 | 13 | # Copy all files 14 | COPY . . 15 | 16 | # Expose the port your app runs on 17 | EXPOSE 3000 18 | 19 | # Set production environment 20 | ENV APP_ENV=production 21 | 22 | # Start the application 23 | CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "3000"] -------------------------------------------------------------------------------- /visual-tree-search-backend/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi>=0.103.1 2 | uvicorn>=0.23.2 3 | websockets>=11.0.3 4 | python-dotenv>=1.0.0 5 | supabase>=1.0.3 6 | httpx>=0.24.1 7 | openai==1.42.0 8 | playwright==1.39.0 9 | watchdog==4.0.2 10 | pyparsing==3.1.2 11 | litellm==1.42.1 12 | Pillow>=10.1 13 | beautifulsoup4>=4.12 14 | elevenlabs==1.6.1 15 | numpy>= 1.14 16 | lxml>= 4.9 17 | httpx==0.27.2 18 | evaluate==0.4.0 19 | beartype==0.12.0 20 | scikit-image==0.22.0 21 | numpy==1.25.2 22 | aiolimiter==1.1.0 23 | transformers==4.34.0 24 | nltk==3.8.1 25 | browserbase 26 | aiohttp 27 | boto3==1.34.34 -------------------------------------------------------------------------------- /visual-tree-search-browser-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/playwright/python:v1.41.2-jammy 2 | 3 | WORKDIR /app 4 | 5 | # Copy requirements first to leverage Docker cache 6 | COPY requirements.txt . 7 | RUN pip install --no-cache-dir -r requirements.txt 8 | 9 | # Copy all files 10 | COPY . . 11 | 12 | # Expose the port your app runs on 13 | EXPOSE 3000 14 | 15 | # Set production environment 16 | ENV APP_ENV=production 17 | 18 | # Start the application 19 | # Start the application 20 | CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "3000"] -------------------------------------------------------------------------------- /visual-tree-search-backend/app/lib/supabase.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | from supabase import create_client, Client 4 | 5 | # Load environment variables 6 | load_dotenv() 7 | 8 | # Get Supabase configuration 9 | SUPABASE_URL = os.getenv("SUPABASE_URL") 10 | SUPABASE_KEY = os.getenv("SUPABASE_KEY") 11 | 12 | if not SUPABASE_URL: 13 | raise ValueError("Missing SUPABASE_URL environment variable") 14 | 15 | if not SUPABASE_KEY: 16 | raise ValueError("Missing SUPABASE_KEY environment variable") 17 | 18 | # Create Supabase client 19 | supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY) -------------------------------------------------------------------------------- /visual-tree-search-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "paths": { 17 | "@/*": ["./*"] 18 | } 19 | }, 20 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 21 | "exclude": ["node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /visual-tree-search-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /visual-tree-search-app/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | function Label({ 7 | className, 8 | ...props 9 | }: React.ComponentProps) { 10 | return ( 11 | 19 | ) 20 | } 21 | 22 | export { Label } 23 | -------------------------------------------------------------------------------- /visual-tree-search-state-reset/README.md: -------------------------------------------------------------------------------- 1 | # VisualTreeSearch Website State Reset 2 | 3 | This repo contains the FastAPI server for state reset on the backend database of WebArena shopping website. 4 | 5 | ## usage 6 | 7 | 8 | ### Setup 9 | 10 | 11 | [Setup WebArena shopping website on AWS](./Server_Setup.md) 12 | 13 | 14 | 15 | ### start FastAPI server 16 | 17 | uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload 18 | 19 | ### send http requests 20 | 21 | - Test 22 | 23 | `curl -N http://localhost:8000/api/hello` 24 | 25 | - Test DB status 26 | 27 | `curl -N http://localhost:8000/api/db/status` 28 | 29 | - Reset account information with DB SQL operations 30 | 31 | `curl -N http://localhost:8000/api/sql/restore ` 32 | 33 | - Reset the whole container 34 | 35 | `curl -N http://localhost:8000/api/container/reset/****PUBLICIP****` 36 | 37 | 38 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/tools/upload_file.py: -------------------------------------------------------------------------------- 1 | from .shared_utils import take_action 2 | from .registry import ToolRegistry, Tool 3 | 4 | def upload_file(task_description, features=None, branching_factor=None, playwright_manager=None, log_folder='log', elements_filter=None): 5 | response = take_action(task_description, ["file"], features, branching_factor, playwright_manager, log_folder, elements_filter) 6 | return response 7 | 8 | 9 | def register_upload_file_tool(): 10 | ToolRegistry.register(Tool( 11 | name="upload_file", 12 | func=upload_file, 13 | description="Upload a file.", 14 | parameters={ 15 | "task_description": { 16 | "type": "string", 17 | "description": "The description of the file upload task" 18 | } 19 | } 20 | )) 21 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/tools/select_option.py: -------------------------------------------------------------------------------- 1 | from .shared_utils import take_action 2 | from .registry import ToolRegistry, Tool 3 | 4 | 5 | def select_option(task_description, features=None, branching_factor=None, playwright_manager=None, log_folder='log', elements_filter=None): 6 | response = take_action(task_description, ["select_option"], features, branching_factor, playwright_manager, 7 | log_folder, elements_filter) 8 | return response 9 | 10 | 11 | def register_select_option_tool(): 12 | ToolRegistry.register(Tool( 13 | name="select_option", 14 | func=select_option, 15 | description="Select an option from a dropdown or list.", 16 | parameters={ 17 | "task_description": { 18 | "type": "string", 19 | "description": "The description of the option selection task" 20 | } 21 | } 22 | )) 23 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/lwats/webagent_utils_async/tools/navigation.py: -------------------------------------------------------------------------------- 1 | from .shared_utils import take_action 2 | from .registry import ToolRegistry, Tool 3 | 4 | 5 | def navigation(task_description, features=None, branching_factor=None, playwright_manager=None, log_folder='log', elements_filter=None): 6 | response = take_action(task_description, ["bid", "nav"], features, branching_factor, playwright_manager, log_folder, elements_filter) 7 | return response 8 | 9 | 10 | def register_navigation_tool(): 11 | ToolRegistry.register(Tool( 12 | name="navigation", 13 | func=navigation, 14 | description="Perform a web navigation task, including fill text, click, search, go to new page", 15 | parameters={ 16 | "task_description": { 17 | "type": "string", 18 | "description": "The description of the web navigation task, including fill text, click, search, go to new page" 19 | } 20 | } 21 | )) -------------------------------------------------------------------------------- /visual-tree-search-app/public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-app/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | function Input({ className, type, ...props }: React.ComponentProps<"input">) { 6 | return ( 7 | 18 | ) 19 | } 20 | 21 | export { Input } 22 | -------------------------------------------------------------------------------- /visual-tree-search-backend/app/api/routes/terminate_session.py: -------------------------------------------------------------------------------- 1 | # terminate browser session session 2 | from fastapi import APIRouter, HTTPException 3 | from dotenv import load_dotenv 4 | from browserbase import Browserbase 5 | from playwright.async_api import async_playwright 6 | import os 7 | 8 | # Load environment variables from .env file 9 | load_dotenv() 10 | 11 | API_KEY = os.environ["BROWSERBASE_API_KEY"] 12 | PROJECT_ID = os.environ["BROWSERBASE_PROJECT_ID"] 13 | 14 | router = APIRouter() 15 | 16 | @router.post("/{session_id}") 17 | async def terminate_session(session_id: str): 18 | try: 19 | # Initialize the Browserbase client 20 | bb = Browserbase(api_key=API_KEY) 21 | 22 | # Update the session's status to request release 23 | bb.sessions.update( 24 | session_id, 25 | project_id=PROJECT_ID, 26 | status="REQUEST_RELEASE" 27 | ) 28 | 29 | return {"status": "success", "message": f"Session {session_id} termination requested"} 30 | except Exception as e: 31 | raise HTTPException(status_code=500, detail=str(e)) -------------------------------------------------------------------------------- /visual-tree-search-app/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import Header from "./Header"; 2 | import Sidebar from "./Sidebar"; 3 | import Head from "next/head"; 4 | 5 | interface LayoutProps { 6 | children: React.ReactNode; 7 | } 8 | 9 | const Layout: React.FC = ({ children }) => { 10 | return ( 11 | <> 12 | 13 | Visual Tree Search 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 | {children} 25 |
26 |
27 |
28 |
29 | 30 | ); 31 | }; 32 | 33 | export default Layout; -------------------------------------------------------------------------------- /visual-tree-search-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "visual-tree-search-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-checkbox": "^1.1.4", 13 | "@radix-ui/react-dialog": "^1.1.6", 14 | "@radix-ui/react-label": "^2.1.2", 15 | "@radix-ui/react-scroll-area": "^1.2.3", 16 | "@radix-ui/react-slot": "^1.1.2", 17 | "@types/d3": "^7.4.3", 18 | "class-variance-authority": "^0.7.1", 19 | "clsx": "^2.1.1", 20 | "d3": "^7.9.0", 21 | "framer-motion": "^12.9.2", 22 | "lucide-react": "^0.479.0", 23 | "next": "15.2.2", 24 | "next-themes": "^0.4.6", 25 | "react": "^19.0.0", 26 | "react-dom": "^19.0.0", 27 | "react-icons": "^5.5.0", 28 | "tailwind-merge": "^3.0.2", 29 | "tailwindcss-animate": "^1.0.7" 30 | }, 31 | "devDependencies": { 32 | "@eslint/eslintrc": "^3", 33 | "@tailwindcss/postcss": "^4", 34 | "@types/node": "^20", 35 | "@types/react": "^19", 36 | "@types/react-dom": "^19", 37 | "eslint": "^9", 38 | "eslint-config-next": "15.2.2", 39 | "tailwindcss": "^4", 40 | "typescript": "^5" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /visual-tree-search-app/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 3 | import { CheckIcon } from "lucide-react" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | function Checkbox({ 8 | className, 9 | ...props 10 | }: React.ComponentProps) { 11 | return ( 12 | 20 | 24 | 25 | 26 | 27 | ) 28 | } 29 | 30 | export { Checkbox } 31 | -------------------------------------------------------------------------------- /visual-tree-search-app/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual-tree-search-state-reset/app/api/routes/test_sql.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | from ...sql.ops import delete_data, restore_data, fetch_data 5 | from ...sql.verify import verifyAccountStatus 6 | 7 | 8 | import logging 9 | from fastapi import APIRouter, HTTPException 10 | 11 | # Configure basic logging 12 | logging.basicConfig( 13 | level=logging.INFO, 14 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' 15 | ) 16 | 17 | router = APIRouter() 18 | 19 | 20 | def runcmd(cmd): 21 | print('------------------------------------------------------------') 22 | print(cmd) 23 | res=os.popen(cmd).read() 24 | print(res) 25 | print('------------------------------------------------------------') 26 | return(res) 27 | 28 | 29 | 30 | # curl -N http://localhost:8000/api/sql/restore 31 | @router.get("/restore") 32 | async def sql_restore(): 33 | delres=delete_data() 34 | resres=restore_data() 35 | return { 36 | "delres":delres, 37 | "resres":resres 38 | } 39 | 40 | 41 | # curl -N http://localhost:8000/api/sql/extract 42 | @router.get("/extract") 43 | async def sql_extract(): 44 | res=fetch_data() 45 | return { 46 | "status":res 47 | } 48 | 49 | 50 | 51 | 52 | # curl -N http://localhost:8000/api/sql/verify 53 | @router.get("/verify") 54 | async def sql_verify(): 55 | res=verifyAccountStatus() 56 | return { 57 | "status":res 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /visual-tree-search-app/components/LiveBrowserView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Globe } from 'lucide-react'; 3 | 4 | interface LiveBrowserViewProps { 5 | liveBrowserUrl: string | null; 6 | width: string; 7 | } 8 | 9 | const LiveBrowserView: React.FC = ({ liveBrowserUrl, width }) => { 10 | return ( 11 |
15 |
16 |

17 | 18 | Live Browser View 19 |

20 |
21 |
22 | {liveBrowserUrl ? ( 23 |