This commit is contained in:
a2a-platform
2026-06-27 17:04:31 +00:00
parent 116dc861bd
commit 94e5b42223
3 changed files with 61 additions and 9 deletions

View File

@@ -129,7 +129,7 @@ class BrowserToApiAgent(A2AAgent[BrowserToApiConfig, NoAuth]):
"SeleniumBase-style browser agent that turns observed website traffic "
"into OpenAPI specs, coverage reports, samples, and a replay client."
)
version = "0.2.7"
version = "0.2.8"
config_model = BrowserToApiConfig
auth_model = NoAuth
@@ -383,6 +383,11 @@ def capture_browser_traffic(
page.wait_for_timeout(wait_seconds * 1000)
if ai_explore and ai_steps > 0 and llm_config:
log.append(
"ai: using ctx.llm "
f"model={llm_config.get('model', 'unknown')} "
f"source={llm_config.get('source', 'unknown')}"
)
_ai_explore_page(
page,
llm_config=llm_config,
@@ -414,7 +419,13 @@ def _llm_config_from_ctx(ctx: RunContext[NoAuth]) -> dict[str, Any] | None:
model = str(getattr(creds, "model", "") or "")
if not (api_key and base_url and model):
return None
return {"api_key": api_key, "base_url": base_url, "model": model}
return {
"api_key": api_key,
"base_url": base_url,
"model": model,
"source": str(getattr(creds, "source", "") or ""),
"extra_body": dict(getattr(creds, "extra_body", None) or {}),
}
def _default_ai_goal(url: str) -> str:
@@ -558,15 +569,48 @@ def _llm_choose_action(
def _chat_completion_json(llm_config: dict[str, Any], *, system: str, user: str) -> str:
url = f"{llm_config['base_url'].rstrip('/')}/chat/completions"
payload = {
base_payload = {
"model": llm_config["model"],
"messages": [
{"role": "system", "content": system},
{"role": "user", "content": user},
],
"max_tokens": 320,
"response_format": {"type": "json_object"},
}
extra_body = dict(llm_config.get("extra_body") or {})
attempts = [
{
**base_payload,
"max_completion_tokens": 1200,
"reasoning_effort": "minimal",
**extra_body,
},
{
**base_payload,
"max_tokens": 800,
**extra_body,
},
{
**base_payload,
"max_completion_tokens": 1200,
"response_format": {"type": "json_object"},
**extra_body,
},
]
last_error: Exception | None = None
for payload in attempts:
try:
content = _post_chat_completion(url, llm_config["api_key"], payload)
except Exception as exc: # noqa: BLE001
last_error = exc
continue
if content.strip():
return content
if last_error is not None:
raise last_error
return ""
def _post_chat_completion(url: str, api_key: str, payload: dict[str, Any]) -> str:
req = urllib.request.Request(
url,
data=json.dumps(payload).encode("utf-8"),
@@ -586,7 +630,15 @@ def _chat_completion_json(llm_config: dict[str, Any], *, system: str, user: str)
if not choices:
return ""
message = choices[0].get("message") if isinstance(choices[0], dict) else {}
return str(message.get("content") or "")
content = message.get("content")
if isinstance(content, list):
parts = [
str(item.get("text") or item.get("content") or "")
for item in content
if isinstance(item, dict)
]
return "\n".join(part for part in parts if part)
return str(content or "")
def _apply_ai_action(