Files
daily-robots/bot/router.py
2026-07-02 11:31:16 +08:00

110 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""消息路由skills 快查 / 网页操作 / 截图预览 / Cursor 通用任务。"""
from __future__ import annotations
import re
import env_config
from browser_parser import is_browser_intent, parse_browser_request
from browser_service import format_browser_caption, run_browser_automation
from cursor_runner import run_cursor_task, strip_mention
from image_extract import find_image_paths, strip_fake_image_markdown
from preview_service import capture_preview, is_preview_intent, resolve_preview_request
from skills_service import handle_command, parse_command
from bot_types import RouteResult
def routing_mode() -> str:
return (env_config.env("ROUTING_MODE", "hybrid") or "hybrid").lower()
def _normalize(text: str) -> str:
return re.sub(r"@\S+\s*", "", text).strip().lower()
def is_skills_fast_command(text: str) -> bool:
raw = _normalize(text)
if not raw:
return True
if raw in {"help", "帮助", "?", "h"}:
return True
cmd = parse_command(text)
if cmd.kind in {"help", "list", "detail"}:
return True
if cmd.kind == "search" and re.match(r"^(search|搜索|find|查)\s+", raw):
return True
return False
async def _run_browser(text: str, on_progress=None) -> RouteResult:
if parse_browser_request(text) is None:
raise RuntimeError("无法解析网页操作步骤")
if on_progress:
await on_progress("正在按步骤执行网页操作…")
result = await run_browser_automation(text)
return RouteResult(
source="browser",
text=format_browser_caption(result),
image_path=str(result.screenshot_path),
)
async def _run_preview(text: str, on_progress=None) -> RouteResult:
preview_req = resolve_preview_request(text)
if preview_req is None:
raise RuntimeError("无法解析截图请求")
if on_progress:
await on_progress(f"正在访问并截图:{preview_req.url or '默认地址'}")
result = await capture_preview(preview_req.url, preview_req.port)
caption = (
f"**页面预览**\n"
f"> URL`{result.final_url or result.url}`\n"
f"> 项目:`{env_config.env('CURSOR_CWD', '')}`\n"
f"> dev server{'已自动启动' if result.started_dev_server else '使用已有服务'}"
)
return RouteResult(
source="preview",
text=caption,
image_path=str(result.screenshot_path),
)
async def route_message(text: str, on_progress=None) -> RouteResult:
task = strip_mention(text)
if not task:
return RouteResult("skills", handle_command("help"))
if is_browser_intent(text):
return await _run_browser(text, on_progress=on_progress)
if resolve_preview_request(text) is not None:
return await _run_preview(text, on_progress=on_progress)
mode = routing_mode()
if mode == "skills":
return RouteResult("skills", handle_command(text))
if mode == "cursor" or not is_skills_fast_command(text):
reply = await run_cursor_task(task, on_progress=on_progress)
reply = strip_fake_image_markdown(reply)
image_path: str | None = None
paths = find_image_paths(reply)
if paths:
image_path = str(paths[0])
elif is_preview_intent(text) or is_browser_intent(text):
if on_progress:
await on_progress("未找到截图文件,改用 Playwright 自动执行…")
if is_browser_intent(text):
return await _run_browser(text, on_progress=on_progress)
return await _run_preview(text, on_progress=on_progress)
return RouteResult("cursor", reply, image_path=image_path)
return RouteResult("skills", handle_command(text))