deploy Nous v21 update

This commit is contained in:
Marco0300
2026-09-05 22:25:52 +02:00
parent c2f14edd29
commit aacb71221b
9 changed files with 320 additions and 16 deletions
+61 -4
View File
@@ -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: