zcbot/tools/publish_web_preview.py

90 lines
3.0 KiB
Python

"""Publish a built static web project as a live multi-file preview."""
from __future__ import annotations
import json
from pathlib import Path
from typing import ClassVar
from uuid import UUID
from core.web_previews import WebPreviewError, create_web_preview
from .base import Tool
class PublishWebPreviewTool(Tool):
name = "publish_web_preview"
description = (
"Publish an existing static multi-file web build from the current task as an interactive "
"preview. Use it after creating and testing a project and producing its final static output "
"directory (for example dist or build). The directory must contain the HTML entry and all "
"local CSS/JS/assets. This tool does not run a development server or backend. Re-publishing "
"the same directory refreshes the existing preview."
)
parameters: ClassVar[dict] = {
"type": "object",
"properties": {
"directory": {
"type": "string",
"minLength": 1,
"maxLength": 1000,
"description": "Static output directory relative to the current task working directory.",
},
"entry": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"default": "index.html",
"description": "HTML entry path relative to directory.",
},
"name": {
"type": "string",
"maxLength": 120,
"default": "网页项目预览",
"description": "Short user-facing preview name.",
},
"spa_fallback": {
"type": "boolean",
"default": True,
"description": "Serve the HTML entry for extensionless missing routes used by client-side routers.",
},
},
"required": ["directory"],
"additionalProperties": False,
}
def __init__(
self,
user_id: UUID,
task_id: UUID,
*,
working_dir: Path,
**kwargs,
) -> None:
super().__init__(**kwargs)
self.user_id = user_id
self.task_id = task_id
self.working_dir = Path(working_dir)
def execute(
self,
directory: str,
entry: str = "index.html",
name: str = "网页项目预览",
spa_fallback: bool = True,
) -> str:
if self.user_root is None:
return "[Error] web preview publishing requires a user workspace"
try:
preview = create_web_preview(
user_id=self.user_id,
task_id=self.task_id,
working_dir=self.working_dir,
directory=directory,
entry=entry,
name=name,
spa_fallback=spa_fallback,
)
except WebPreviewError as exc:
return f"[Error] cannot publish web preview: {exc}"
return "[WebPreview] " + json.dumps(preview, ensure_ascii=False, separators=(",", ":"))