Files
AgentLab/backend/app/api/sandbox.py
T
ThearchyHelios 964eeaa829 AgentLab:可视化 Agent 编排实验台
在画布上拖拽编排 agent 工作流,并实时看着它执行。

后端 FastAPI + LangGraph:把画布 JSON 编译成 StateGraph,15 种节点
(模型/Agent/多Agent、工具/沙箱、分支/循环/子图、记忆/检索/整形、
人工介入/结构校验)。选 LangGraph 是因为可视化编排真正难的是暂停、
恢复和回放,而 checkpointer + interrupt() 正好把这几件事做在了底层。

前端 React + React Flow:节点元数据驱动属性面板与连接桩,运行时
节点高亮、边流动画、卡片内流式 token 全部由同一份事件流驱动。

关键实现:
- Agent 内工具审批用 @task 缓存模型调用,interrupt 重放时不重复计费
- 沙箱保持只读根文件系统,代码经 exec+base64 写入(put_archive 会被
  只读容器拒绝),断网、非 root、内存/CPU/超时限额
- 检索为向量与 BM25 混合,本地哈希 embedding 零配置可用
- 分支条件走 AST 白名单求值器;HTTP 工具逐 IP 拦截内网与元数据地址
- Mock provider 让无 API Key 也能跑通完整链路

7 个内置模板全部冒烟通过,含真实模型端到端验证。
2026-09-13 17:27:00 +08:00

50 lines
1.4 KiB
Python

from __future__ import annotations
from typing import Any
from fastapi import APIRouter
from pydantic import BaseModel, Field
from app.sandbox.base import SandboxLimits
from app.sandbox.manager import sandbox_manager
router = APIRouter(prefix="/api/sandbox", tags=["sandbox"])
@router.get("/health")
async def health() -> dict[str, Any]:
return await sandbox_manager.health()
class ExecIn(BaseModel):
code: str = Field(min_length=1)
language: str = "python"
timeout: int = Field(default=30, ge=1, le=300)
memory_mb: int = Field(default=512, ge=64, le=4096)
network: bool = False
session_id: str = "playground"
files: dict[str, str] = Field(default_factory=dict)
@router.post("/exec")
async def execute(payload: ExecIn) -> dict[str, Any]:
"""沙箱试验台。在画布外面直接跑一段代码,用来试限额、试依赖。"""
result = await sandbox_manager.run(
payload.code,
language=payload.language,
limits=SandboxLimits(
timeout=payload.timeout,
memory_mb=payload.memory_mb,
network=payload.network,
),
session_id=payload.session_id,
files=payload.files,
)
return result.model_dump()
@router.post("/cleanup/{session_id}")
async def cleanup(session_id: str) -> dict[str, bool]:
await sandbox_manager.cleanup(session_id)
return {"ok": True}