项目初始化

This commit is contained in:
2026-07-02 11:31:16 +08:00
commit eef4c76e3f
64 changed files with 13369 additions and 0 deletions

87
bot/browser_service.py Normal file
View File

@@ -0,0 +1,87 @@
"""浏览器自动化服务:解析场景 + 启动 dev server + 执行步骤。"""
from __future__ import annotations
import asyncio
import logging
from urllib.parse import urlparse
from browser_executor import run_browser_scenario_sync
from browser_models import BrowserResult, BrowserScenario
from browser_parser import parse_browser_request
from preview_service import (
_package_dev_script,
_preview_port,
_project_cwd,
_startup_timeout,
_wait_for_port,
)
logger = logging.getLogger(__name__)
def _ensure_dev_server(base_url: str) -> bool:
parsed = urlparse(base_url)
host = parsed.hostname or "127.0.0.1"
port = parsed.port or (443 if parsed.scheme == "https" else 80)
if _wait_for_port(host, port, timeout=3):
return False
cwd = _project_cwd()
dev_command = _package_dev_script(cwd)
if not dev_command:
raise RuntimeError(
f"无法访问 {base_url},且未找到可启动的 dev 脚本。"
"请先手动启动前端,或设置 PREVIEW_URL。"
)
import subprocess
logger.info("启动 dev server: %s (cwd=%s)", dev_command, cwd)
proc = subprocess.Popen(
dev_command,
cwd=str(cwd),
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
if not _wait_for_port(host, port, timeout=_startup_timeout()):
err = ""
if proc.stderr:
err = proc.stderr.read().decode("utf-8", errors="replace")[-1000:]
proc.kill()
raise RuntimeError(
f"dev server 在 {_startup_timeout()}s 内未就绪 ({base_url})。"
f"{(' 日志: ' + err) if err else ''}"
)
return True
async def run_browser_automation(text: str) -> BrowserResult:
scenario = parse_browser_request(text)
if scenario is None:
raise RuntimeError("无法解析网页操作步骤")
started = await asyncio.to_thread(_ensure_dev_server, scenario.base_url)
result = await asyncio.to_thread(run_browser_scenario_sync, scenario)
result.started_dev_server = started
return result
def format_browser_caption(result: BrowserResult) -> str:
lines = [
"**网页操作完成**",
f"> 场景:`{result.scenario_name or '自定义'}`",
f"> 起始:`{result.base_url}`",
f"> 最终:`{result.final_url}`",
f"> 步骤数:{result.step_count}",
]
if result.started_dev_server:
lines.append("> dev server已自动启动")
if result.step_log:
lines.append("")
lines.append("执行记录:")
for item in result.step_log[-8:]:
lines.append(f"- {item}")
return "\n".join(lines)