mirror of
https://github.com/OpenBMB/ChatDev.git
synced 2026-08-01 19:06:06 +00:00
fix frontend error
This commit is contained in:
parent
cf8d7f0f05
commit
54ad9a57ee
@ -197,7 +197,7 @@ export async function fetchWorkflowsWithDesc() {
|
|||||||
const filesWithDesc = await Promise.all(
|
const filesWithDesc = await Promise.all(
|
||||||
data.workflows.map(async (filename) => {
|
data.workflows.map(async (filename) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(apiUrl(`/api/workflows/${encodeURIComponent(filename)}/get`))
|
const response = await fetch(apiUrl(`/api/workflows/${encodeURIComponent(filename)}/desc`))
|
||||||
const fileData = await response.json()
|
const fileData = await response.json()
|
||||||
return {
|
return {
|
||||||
name: filename,
|
name: filename,
|
||||||
|
|||||||
@ -1,8 +1,15 @@
|
|||||||
|
"""Application bootstrap helpers for the FastAPI server."""
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from server import state
|
from server import state
|
||||||
from server.config_schema_router import router as config_schema_router
|
from server.config_schema_router import router as config_schema_router
|
||||||
|
from server.routes import ALL_ROUTERS
|
||||||
|
from utils.error_handler import add_exception_handlers
|
||||||
|
from utils.middleware import add_middleware
|
||||||
|
|
||||||
|
|
||||||
def init_app(app: FastAPI) -> None:
|
def init_app(app: FastAPI) -> None:
|
||||||
"""Apply shared middleware, routers, and global state to ``app``."""
|
"""Apply shared middleware, routers, and global state to ``app``."""
|
||||||
|
|
||||||
@ -15,4 +22,11 @@ def init_app(app: FastAPI) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_exception_handlers(app)
|
add_exception_handlers(app)
|
||||||
add_middleware(app)
|
add_middleware(app)
|
||||||
|
|
||||||
|
state.init_state()
|
||||||
|
|
||||||
|
for router in ALL_ROUTERS:
|
||||||
|
app.include_router(router)
|
||||||
|
|
||||||
|
app.include_router(config_schema_router)
|
||||||
|
|||||||
@ -153,6 +153,69 @@ async def get_workflow_args(filename: str):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/workflows/{filename}/desc")
|
||||||
|
async def get_workflow_desc(filename: str):
|
||||||
|
try:
|
||||||
|
safe_filename = validate_workflow_filename(filename, require_yaml_extension=True)
|
||||||
|
file_path = YAML_DIR / safe_filename
|
||||||
|
|
||||||
|
if not file_path.exists() or not file_path.is_file():
|
||||||
|
raise ResourceNotFoundError(
|
||||||
|
"Workflow file not found",
|
||||||
|
resource_type="workflow",
|
||||||
|
resource_id=safe_filename,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Load and validate YAML content
|
||||||
|
raw_content = file_path.read_text(encoding="utf-8")
|
||||||
|
_, yaml_content = validate_workflow_content(safe_filename, raw_content)
|
||||||
|
|
||||||
|
desc = ""
|
||||||
|
if isinstance(yaml_content, dict):
|
||||||
|
graph = yaml_content.get("graph") or {}
|
||||||
|
if isinstance(graph, dict):
|
||||||
|
desc = graph.get("description") or ""
|
||||||
|
if len(desc) == 0:
|
||||||
|
raise ResourceNotFoundError(
|
||||||
|
"Workflow file does not have args",
|
||||||
|
resource_type="workflow",
|
||||||
|
resource_id=safe_filename,
|
||||||
|
)
|
||||||
|
logger = get_server_logger()
|
||||||
|
logger.info(
|
||||||
|
"Workflow description retrieved",
|
||||||
|
log_type=LogType.WORKFLOW,
|
||||||
|
filename=safe_filename,
|
||||||
|
)
|
||||||
|
return {"description": desc}
|
||||||
|
except ValidationError as exc:
|
||||||
|
# 参数或文件名等校验错误
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail={"message": str(exc)},
|
||||||
|
)
|
||||||
|
except SecurityError as exc:
|
||||||
|
# 安全相关错误(例如路径遍历)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail={"message": str(exc)},
|
||||||
|
)
|
||||||
|
except ResourceNotFoundError as exc:
|
||||||
|
# 文件不存在
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail={"message": str(exc)},
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger = get_server_logger()
|
||||||
|
logger.log_exception(exc, f"Unexpected error retrieving workflow args: {filename}")
|
||||||
|
# 兜底错误
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail={"message": f"Failed to retrieve workflow args: {exc}"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/workflows/upload/content")
|
@router.post("/api/workflows/upload/content")
|
||||||
async def upload_workflow_content(request: WorkflowUploadContentRequest):
|
async def upload_workflow_content(request: WorkflowUploadContentRequest):
|
||||||
return _persist_workflow_from_content(
|
return _persist_workflow_from_content(
|
||||||
@ -294,4 +357,5 @@ async def get_workflow_raw_content(filename: str):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger = get_server_logger()
|
logger = get_server_logger()
|
||||||
logger.log_exception(exc, f"Unexpected error retrieving workflow: {filename}")
|
logger.log_exception(exc, f"Unexpected error retrieving workflow: {filename}")
|
||||||
raise WorkflowExecutionError(f"Failed to retrieve workflow: {exc}")
|
raise WorkflowExecutionError(f"Failed to retrieve workflow: {exc}")
|
||||||
|
|
||||||
|
|||||||
@ -18,31 +18,16 @@ from utils.structured_logger import get_server_logger, LogType
|
|||||||
|
|
||||||
|
|
||||||
def _update_workflow_id(content: str, workflow_id: str) -> str:
|
def _update_workflow_id(content: str, workflow_id: str) -> str:
|
||||||
# Pattern to match graph:\n id: <value>
|
pattern = re.compile(r"^(id:\\s*).*$", re.MULTILINE)
|
||||||
pattern = re.compile(r"(graph:\s*\n\s*id:\s*).*$", re.MULTILINE)
|
|
||||||
match = pattern.search(content)
|
match = pattern.search(content)
|
||||||
if match:
|
if match:
|
||||||
# Replace the value after "graph:\n id: "
|
return pattern.sub(rf"\\1{workflow_id}", content, count=1)
|
||||||
return pattern.sub(rf"\1{workflow_id}", content, count=1)
|
|
||||||
|
|
||||||
# If no graph.id found, look for standalone id: at root level (legacy support)
|
|
||||||
root_id_pattern = re.compile(r"^(id:\s*).*$", re.MULTILINE)
|
|
||||||
root_match = root_id_pattern.search(content)
|
|
||||||
if root_match:
|
|
||||||
return root_id_pattern.sub(rf"\1{workflow_id}", content, count=1)
|
|
||||||
|
|
||||||
# If neither found, add graph.id after graph: section if it exists
|
|
||||||
graph_pattern = re.compile(r"(graph:\s*\n)")
|
|
||||||
graph_match = graph_pattern.search(content)
|
|
||||||
if graph_match:
|
|
||||||
return graph_pattern.sub(rf"\1 id: {workflow_id}\n", content, count=1)
|
|
||||||
|
|
||||||
# Fallback (is invalid)
|
|
||||||
lines = content.splitlines()
|
lines = content.splitlines()
|
||||||
insert_index = 0
|
insert_index = 0
|
||||||
if lines and lines[0].strip() == "---":
|
if lines and lines[0].strip() == "---":
|
||||||
insert_index = 1
|
insert_index = 1
|
||||||
lines.insert(insert_index, f"graph:\n id: {workflow_id}")
|
lines.insert(insert_index, f"id: {workflow_id}")
|
||||||
updated = "\n".join(lines)
|
updated = "\n".join(lines)
|
||||||
if content.endswith("\n"):
|
if content.endswith("\n"):
|
||||||
updated += "\n"
|
updated += "\n"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user