deploy Nous v21 update
This commit is contained in:
@@ -7,10 +7,11 @@ CAPTCHAs, rotate proxies, or continue after an access challenge.
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from typing import Any
|
||||
from typing import Any, Callable
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
@@ -96,6 +97,7 @@ def investigate_websites(
|
||||
api_key: str,
|
||||
model: str,
|
||||
user_agent: str,
|
||||
log_callback: Callable[[str, str, dict[str, Any]], Any] | None = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Run one bounded Browser Use investigation and return candidates."""
|
||||
if os.environ.get("BROWSER_USE_ENABLED", "1").strip().lower() in {"0", "false", "no", "off"}:
|
||||
@@ -132,6 +134,52 @@ Return ONLY JSON in this shape:
|
||||
Confidence must be an integer from 0 to 100. Include only plausible official website URLs and never invent a URL.
|
||||
""".strip()
|
||||
|
||||
async def emit(kind: str, event: str, details: dict[str, Any]) -> None:
|
||||
if not log_callback:
|
||||
return
|
||||
result = log_callback(kind, event, details)
|
||||
if inspect.isawaitable(result):
|
||||
await result
|
||||
|
||||
def output_actions(model_output: Any) -> list[Any]:
|
||||
try:
|
||||
actions = getattr(model_output, "action", []) or []
|
||||
values: list[Any] = []
|
||||
for action in list(actions)[:8]:
|
||||
if hasattr(action, "model_dump"):
|
||||
values.append(action.model_dump(mode="json"))
|
||||
else:
|
||||
values.append(str(action)[:2_000])
|
||||
return values
|
||||
except Exception:
|
||||
return [str(model_output)[:2_000]] if model_output is not None else []
|
||||
|
||||
async def on_step(browser_state: Any, model_output: Any, step_number: int) -> None:
|
||||
details = {
|
||||
"step": step_number,
|
||||
"url": str(getattr(browser_state, "url", "") or "")[:700],
|
||||
"title": str(getattr(browser_state, "title", "") or "")[:300],
|
||||
"actions": output_actions(model_output),
|
||||
"model": model,
|
||||
}
|
||||
await emit("browser", "browser_use_step", details)
|
||||
await emit("ai", "browser_use_model_step", {"step": step_number, "model": model, "actions": details["actions"]})
|
||||
|
||||
class LoggedChatOpenAI(ChatOpenAI):
|
||||
"""Capture Browser Use LLM turns without recording provider secrets."""
|
||||
|
||||
async def ainvoke(self, messages: list[Any], output_format: Any = None, **kwargs: Any) -> Any:
|
||||
started = asyncio.get_running_loop().time()
|
||||
serialised = [{"role": getattr(message, "type", "message"), "content": str(getattr(message, "content", ""))[:4_000]} for message in list(messages)[-20:]]
|
||||
await emit("ai", "browser_use_llm_request", {"model": self.model, "messages": serialised, "structured_output": bool(output_format)})
|
||||
try:
|
||||
result = await super().ainvoke(messages, output_format=output_format, **kwargs)
|
||||
await emit("ai", "browser_use_llm_response", {"model": self.model, "completion": str(getattr(result, "completion", result))[:4_000], "duration_ms": int((asyncio.get_running_loop().time() - started) * 1000)})
|
||||
return result
|
||||
except Exception as exc:
|
||||
await emit("ai", "browser_use_llm_error", {"model": self.model, "duration_ms": int((asyncio.get_running_loop().time() - started) * 1000)},)
|
||||
raise
|
||||
|
||||
async def run() -> Any:
|
||||
browser_profile = BrowserProfile(
|
||||
headless=True,
|
||||
@@ -141,7 +189,7 @@ Confidence must be an integer from 0 to 100. Include only plausible official web
|
||||
enable_default_extensions=False,
|
||||
captcha_solver=False,
|
||||
)
|
||||
llm = ChatOpenAI(
|
||||
llm = LoggedChatOpenAI(
|
||||
model=model,
|
||||
api_key=api_key,
|
||||
base_url=base_url,
|
||||
@@ -161,10 +209,19 @@ Confidence must be an integer from 0 to 100. Include only plausible official web
|
||||
use_judge=False,
|
||||
enable_planning=False,
|
||||
enable_signal_handler=False,
|
||||
register_new_step_callback=on_step,
|
||||
)
|
||||
return await agent.run(max_steps=max(3, min(15, int(os.environ.get("BROWSER_USE_MAX_STEPS", "10")))))
|
||||
try:
|
||||
max_steps = int(os.environ.get("BROWSER_USE_MAX_STEPS", "10"))
|
||||
except (TypeError, ValueError):
|
||||
max_steps = 10
|
||||
return await agent.run(max_steps=max(3, min(15, max_steps)))
|
||||
|
||||
timeout = max(30, min(300, int(os.environ.get("BROWSER_USE_TIMEOUT_SECONDS", "120"))))
|
||||
try:
|
||||
timeout = int(os.environ.get("BROWSER_USE_TIMEOUT_SECONDS", "120"))
|
||||
except (TypeError, ValueError):
|
||||
timeout = 120
|
||||
timeout = max(30, min(300, timeout))
|
||||
try:
|
||||
history = asyncio.run(asyncio.wait_for(run(), timeout=timeout))
|
||||
except asyncio.TimeoutError as exc:
|
||||
|
||||
Reference in New Issue
Block a user