add schemas and swap browser_use_runner in docker with browser and now agent use skill from the other container
This commit is contained in:
parent
480dfcd36e
commit
890d492de0
12 changed files with 173 additions and 6857 deletions
|
|
@ -4,6 +4,8 @@ ENV DEBIAN_FRONTEND=noninteractive
|
|||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
chromium \
|
||||
python3 \
|
||||
python3-pip \
|
||||
xvfb \
|
||||
fluxbox \
|
||||
x11vnc \
|
||||
|
|
@ -19,9 +21,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
WORKDIR /src
|
||||
RUN mkdir -p /src/browser_data
|
||||
|
||||
RUN python3 -m pip install --no-cache-dir --break-system-packages \
|
||||
"browser-use>=0.12.5" \
|
||||
"langchain-openai>=0.3.0"
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
COPY browser_use_runner.py /src/browser_use_runner.py
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 6080 9222
|
||||
EXPOSE 6080 9222 8787
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
102
browser_env/browser_use_runner.py
Normal file
102
browser_env/browser_use_runner.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
import asyncio
|
||||
import json
|
||||
import os
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from urllib import error, request
|
||||
|
||||
from browser_use import Agent, Browser, ChatOpenAI
|
||||
|
||||
|
||||
def _json_response(handler, status_code, payload):
|
||||
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
|
||||
handler.send_response(status_code)
|
||||
handler.send_header("Content-Type", "application/json; charset=utf-8")
|
||||
handler.send_header("Content-Length", str(len(data)))
|
||||
handler.end_headers()
|
||||
handler.wfile.write(data)
|
||||
|
||||
|
||||
async def run_browser_task(task):
|
||||
cdp_url = os.getenv("BROWSER_CDP_URL", "http://127.0.0.1:9222")
|
||||
browser_view_url = os.getenv("BROWSER_VIEW_URL", "")
|
||||
|
||||
browser = Browser(cdp_url=cdp_url)
|
||||
|
||||
llm = ChatOpenAI(
|
||||
model=os.getenv("MODEL_DEFAULT", "qwen3.5-122b"),
|
||||
api_key=os.getenv("OPENAI_API_KEY"),
|
||||
base_url=os.getenv("OPENAI_BASE_URL"),
|
||||
temperature=0.0,
|
||||
)
|
||||
|
||||
agent = Agent(task=task, llm=llm, browser=browser, use_vision=False)
|
||||
|
||||
try:
|
||||
history = await agent.run()
|
||||
return {
|
||||
"success": True,
|
||||
"result": history.final_result(),
|
||||
"browser_view": browser_view_url,
|
||||
}
|
||||
except Exception as err:
|
||||
return {"success": False, "error": f"Browser automation failed: {err}"}
|
||||
finally:
|
||||
try:
|
||||
await browser.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class BrowserUseRPCHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
if self.path != "/health":
|
||||
_json_response(self, 404, {"success": False, "error": "Not found"})
|
||||
return
|
||||
|
||||
try:
|
||||
debug_url = os.getenv("BROWSER_HEALTH_URL", "http://127.0.0.1:9222/json/version")
|
||||
with request.urlopen(debug_url, timeout=2):
|
||||
pass
|
||||
_json_response(self, 200, {"success": True})
|
||||
except Exception as err:
|
||||
_json_response(self, 503, {"success": False, "error": f"Browser is not ready: {err}"})
|
||||
|
||||
def do_POST(self):
|
||||
if self.path != "/run":
|
||||
_json_response(self, 404, {"success": False, "error": "Not found"})
|
||||
return
|
||||
|
||||
try:
|
||||
content_length = int(self.headers.get("Content-Length", "0"))
|
||||
raw = self.rfile.read(content_length)
|
||||
payload = json.loads(raw.decode("utf-8") if raw else "{}")
|
||||
task = payload.get("task", "")
|
||||
if not isinstance(task, str) or not task.strip():
|
||||
_json_response(self, 400, {"success": False, "error": "Field 'task' is required"})
|
||||
return
|
||||
|
||||
result = asyncio.run(run_browser_task(task.strip()))
|
||||
code = 200 if result.get("success") else 500
|
||||
_json_response(self, code, result)
|
||||
except json.JSONDecodeError:
|
||||
_json_response(self, 400, {"success": False, "error": "Invalid JSON payload"})
|
||||
except error.URLError as err:
|
||||
_json_response(self, 503, {"success": False, "error": f"Transport error: {err}"})
|
||||
except Exception as err:
|
||||
_json_response(self, 500, {"success": False, "error": f"Internal error: {err}"})
|
||||
|
||||
def log_message(self, format_str, *args):
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
host = os.getenv("BROWSER_USE_RPC_HOST", "0.0.0.0")
|
||||
port = int(os.getenv("BROWSER_USE_RPC_PORT", "8787"))
|
||||
server = ThreadingHTTPServer((host, port), BrowserUseRPCHandler)
|
||||
print(f"browser-use RPC listening on {host}:{port}")
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
|
@ -9,6 +9,7 @@ VNC_PORT="${VNC_PORT:-5900}"
|
|||
NOVNC_PORT="${NOVNC_PORT:-6080}"
|
||||
CHROME_LOCAL_DEBUG_PORT="${CHROME_LOCAL_DEBUG_PORT:-9223}"
|
||||
CHROME_PUBLIC_DEBUG_PORT="${CHROME_PUBLIC_DEBUG_PORT:-9222}"
|
||||
BROWSER_USE_RPC_PORT="${BROWSER_USE_RPC_PORT:-8787}"
|
||||
CHROME_PROFILE_DIR="${CHROME_PROFILE_DIR:-/src/browser_data}"
|
||||
|
||||
MAX_RESTARTS="${MAX_RESTARTS:-10}"
|
||||
|
|
@ -119,6 +120,7 @@ start_bg fluxbox
|
|||
start_bg x11vnc -display "$DISPLAY" -rfbport "$VNC_PORT" -nopw -listen 0.0.0.0 -xkb -forever -shared
|
||||
start_bg websockify --web=/usr/share/novnc/ "$NOVNC_PORT" "localhost:${VNC_PORT}"
|
||||
start_bg socat "TCP-LISTEN:${CHROME_PUBLIC_DEBUG_PORT},fork,reuseaddr" "TCP:127.0.0.1:${CHROME_LOCAL_DEBUG_PORT}"
|
||||
start_bg python3 -u /src/browser_use_runner.py
|
||||
|
||||
if ! wait_for_port 127.0.0.1 "$VNC_PORT" 20; then
|
||||
log "fatal: x11vnc did not open port ${VNC_PORT}"
|
||||
|
|
@ -128,8 +130,12 @@ if ! wait_for_port 127.0.0.1 "$NOVNC_PORT" 20; then
|
|||
log "fatal: websockify did not open port ${NOVNC_PORT}"
|
||||
exit 1
|
||||
fi
|
||||
if ! wait_for_port 127.0.0.1 "$BROWSER_USE_RPC_PORT" 20; then
|
||||
log "fatal: browser-use RPC did not open port ${BROWSER_USE_RPC_PORT}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "browser infrastructure is ready (noVNC:${NOVNC_PORT}, DevTools proxy:${CHROME_PUBLIC_DEBUG_PORT})"
|
||||
log "browser infrastructure is ready (noVNC:${NOVNC_PORT}, DevTools proxy:${CHROME_PUBLIC_DEBUG_PORT}, browser-use RPC:${BROWSER_USE_RPC_PORT})"
|
||||
|
||||
while true; do
|
||||
for pid in "${PIDS[@]}"; do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue