Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ server that `veadk frontend` launches — no separate backend.
existing Sessions or rebuild their snapshots. BytePlus has automated coverage,
but its image update has not been verified against a live account.

- **Code projects**: open 工作区 → 代码项目 or 从工作区新建 to name,
create and reopen projects. Each user has one persistent cloud Sandbox;
projects are directories under `/home/gem/Projects`. Creating another project
reuses the same Session and opening a project changes VS Code's `folder` path.
The image initializes Git, `AGENTS.md` and a Python environment per project.
The dedicated Private Tool must enable snapshots. Studio reuses the user's
stable cloud session identity and automatically restores its latest ready
snapshot after hibernation, rather than creating an empty replacement.
Project lists are read from the Sandbox filesystem and survive Studio restarts.
The editor opens directly at `/code-server/`; signed routing parameters remain
private/no-store. Returning to management keeps the editor mounted, while
switching directories opens the selected project directly. Volcengine
defaults to Chinese and BytePlus to English.

- **Streaming chat** over the ADK `/run_sse` event stream. While an Agent is
generating, the composer exposes a stop control that cancels only the active
response, preserves content already received, and immediately enables the
Expand Down Expand Up @@ -495,6 +509,11 @@ cd frontend && npm run dev # http://localhost:5173
The Vite development server proxies the ADK API routes, including the
`/dev/apps/.../debug/trace` session-trace endpoint, to the backend on port 8000.

For code projects, configure `STUDIO_WORKSPACE_TOOL_ID` with a dedicated
snapshot-enabled Tool in the selected provider and region. The former
single-project `/web/workspace-preview/session` preview is replaced by the
personal-workspace project APIs.

## Branding

Set a custom title (up to six characters) and a local or remote image logo when
Expand Down Expand Up @@ -968,3 +987,42 @@ to `DeleteSessionSnapshot`; it deletes the selected saved record only. If that
logical agent has older records, the next latest record can appear on refresh.
Failed records remain visible for deletion but cannot be opened. The UI uses
agent terminology rather than exposing these control-plane resource types.

### Studio Sandbox 工作区

`veadk studio deploy` 默认创建或复用启用持久化快照的 Studio Sandbox Tool,
新建规格为 8 核 CPU、16 GB 内存,更新时自动补建也使用相同规格,
按云环境和地域选择 `studio-sandbox-1.0.1` 镜像:

| 云环境 | 地域 | 镜像 |
| --- | --- | --- |
| 火山引擎 | cn-beijing | `enterprise-public-cn-beijing.cr.volces.com/vefaas-public/agentkit-sandbox:studio-sandbox-1.0.1` |
| 火山引擎 | cn-shanghai | `enterprise-cn-shanghai-cn-shanghai.cr.volces.com/vefaas-public/agentkit-sandbox:studio-sandbox-1.0.1` |
| BytePlus | ap-southeast-1 | `enterprise-public-ap-southeast-1.cr.volces.com/vefaas-public/agentkit-sandbox:studio-sandbox-1.0.1` |

可通过 `STUDIO_WORKSPACE_IMAGE` 指定区域可访问的其他镜像。启动命令使用镜像内的
`/opt/gem/run.sh`,不再注入编辑器补丁。火山引擎默认中文,BytePlus 默认英文,
模型配置沿用相应云环境的 Studio 配置。

部署通过 `STUDIO_WORKSPACE_TOOL_ID` 绑定工作区,系统信息显示对应 Tool ID。
`veadk studio update` 和前端更新都会自动补齐缺失的持久化工作区 Tool,并保存绑定。
已有 Tool ID 时保留绑定,避免切换个人项目存储;创建失败时更新报错,不忽略失败。
从尚不支持补建的旧版本更新时,新版本首次启动会在后台补建并保存函数环境中的 Tool ID。
补建期间代码项目暂不可用,失败会记录日志,可检查权限后重试更新。
每位用户的项目共用自己的持久化 Session,打开项目时剩余不足一小时会通过
`SetSessionTtl` 续期为八小时。标题栏显示倒计时,项目管理右侧支持全屏展开;
内嵌浏览器使用当前页面的可用空间。

### 工作区项目模板

默认模板位于 `frontend/server/templates/python-agent/`,由 Studio 在创建项目时传入
Sandbox。修改这些模板只需要更新 Studio,不需要重建镜像,也不会覆盖已有项目。
`${project_name}` 和 `${agent_name}` 在创建时替换为项目名和合法 Python Agent 名。

新镜像的 `studio-project-create NAME --json --template-stdin` 从标准输入接收
`{"version":1,"files":{"main.py":"...","README.md":"..."}}` 格式的 UTF-8 文件项目,
支持子目录。最多 256 个文件、1 MiB,不接受绝对路径、父目录跳转或 `.git`、`.venv`
文件。工具仅将模板写入新项目,保留离线 Python 环境初始化和 `git init`。
模板中的新依赖不会自动安装,运行环境依赖仍由镜像管理。

其他地域需要显式设置 `STUDIO_WORKSPACE_IMAGE`,避免错误使用跨地域镜像。
27 changes: 27 additions & 0 deletions frontend/sandbox-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ARG BASE_IMAGE
FROM ${BASE_IMAGE}

ARG APT_MIRROR_URL=https://mirrors.aliyun.com/ubuntu
ARG PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
ARG NPM_REGISTRY_URL=https://registry.npmmirror.com

# Keep the base runtime's root entrypoint; it starts the editor and terminals as gem
USER root
ENV WORKSPACE=/home/gem/Projects \
DISABLE_CODE_SERVER=false \
DISABLE_JUPYTER=false \
PIP_INDEX_URL=${PIP_INDEX_URL} \
UV_INDEX_URL=${PIP_INDEX_URL} \
UV_HTTP_TIMEOUT=60 \
UV_HTTP_RETRIES=3 \
npm_config_registry=${NPM_REGISTRY_URL}

COPY runtime/ /opt/studio-sandbox/runtime/
COPY assets/ /opt/studio-sandbox/assets/
COPY assets.lock.json settings.json requirements.lock /opt/studio-sandbox/

# All browser extensions and fonts are local assets; Python uses an overridable domestic index
RUN /opt/agentkit-code-env/venv/bin/python /opt/studio-sandbox/runtime/configure-apt.py "${APT_MIRROR_URL}" \
&& /opt/agentkit-code-env/venv/bin/python /opt/studio-sandbox/runtime/install-image.py

# Preserve the base image ENTRYPOINT and CMD
7 changes: 7 additions & 0 deletions frontend/sandbox-image/Dockerfile.update
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# BASE_IMAGE must be a previously built Studio image, pinned by digest for release builds
ARG BASE_IMAGE
FROM ${BASE_IMAGE}
USER root
COPY runtime/ /opt/studio-sandbox/runtime/
COPY settings.json /opt/studio-sandbox/settings.json
RUN /opt/agentkit-code-env/venv/bin/python /opt/studio-sandbox/runtime/refresh-editor.py
167 changes: 167 additions & 0 deletions frontend/sandbox-image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Studio Sandbox 镜像

在现有 AgentKit Code Sandbox 基础上预装开发环境,不更改 AIO 服务入口

## 镜像内容

- `/home/gem/Projects` 作为默认工作目录
- 独立 VeADK 环境 `/opt/studio-sandbox/venv`,包含 `veadk-python 1.1.9` 和官方 `agentkit-sdk-python 0.8.6` 提供的 `agentkit` 命令
- 固定版本 Python 依赖及 uv 离线缓存,新项目无需再次联网下载
- 默认 Dark Modern,代码和终端使用 Maple Mono v7.9,其他界面字体不变
- Python 语法高亮、BasedPyright 补全、Ruff 格式化和 `.venv` 解释器自动选择
- code-server 与 Jupyter 开启,原 sandbox 启动入口和鉴权方式保持不变

| 插件 | 固定版本 |
| --- | --- |
| Git History | 0.6.20 |
| gitignore | 0.10.0 |
| MDX | 1.8.18 |
| Modern MDX Preview | 1.7.0 |
| Python | 2026.4.0 |
| BasedPyright | 1.40.0 |
| Python Debugger | 2026.6.0,Linux x64 |
| Ruff | 2026.78.0,Linux x64 |
| Even Better TOML | 0.21.2 |

MDX Preview 采用 Open VSX 上的 `ggfincke.vsc-mdx-preview`,固定在兼容基础镜像 Node 22.18 / Code 1.104 的版本,不依赖微软 Marketplace 或 Pylance

构建先校验原始 VSIX,再从本地安装副本中移除可选 `extensionPack` 捆绑列表,避免 Python 插件自动下载 Pylance 或额外插件;插件代码、许可证和必要依赖保持不变

Maple Mono 通过同源 WOFF2 文件和 `@font-face` 提供给浏览器,不要求用户电脑安装字体,字体许可证随文件保留

## 准备构建上下文

在可访问 Open VSX 和 GitHub 的准备环境执行,不能在云流水线内临时下载这些资产

```sh
python3 prepare-context.py \
--cache /tmp/studio-sandbox-assets \
--output /tmp/studio-sandbox-context.tar.gz \
--base-image '<当前区域可访问的 Code Sandbox 镜像引用>'
```

脚本按 `assets.lock.json` 校验 SHA256,仅将 Dockerfile、固定依赖、运行脚本和必要插件/字体打包,排除整个仓库、`.env`、Git 信息和本机虚拟环境

压缩包内 Dockerfile 位于根目录,适用于 CodePipeline 从私有 TOS 下载解压后直接构建

Dockerfile 通过构建参数适配火山引擎和 BytePlus,不写入账号、区域或凭据

- `BASE_IMAGE`:对应区域的基础镜像,准备上下文时注入默认值
- `APT_MIRROR_URL`:默认 `https://mirrors.aliyun.com/ubuntu`
- `PIP_INDEX_URL`:默认 `https://mirrors.aliyun.com/pypi/simple/`
- `NPM_REGISTRY_URL`:默认 `https://registry.npmmirror.com`

BytePlus 可换成部署区域内可访问的官方源或企业镜像源,镜像内不包含 AK/SK、Git 授权或模型密钥

## 新建项目

```sh
studio-project-create my-agent --json
```

生成 `Projects/my-agent/main.py`、独立 `.venv`、`.gitignore`、`README.md` 和 `AGENTS.md`,并执行 `git init --initial-branch=main`,不自动提交或设置远程仓库,依赖从镜像缓存离线安装,不复制其他路径的虚拟环境,不覆盖重名目录

项目名以英文字母开头,允许字母、数字、短横线、下划线,最多 64 个字符;Agent 的 Python 名称会把短横线转换为下划线

初始化失败保留目录供检查,避免误删任何工作内容

## 手动升级编辑器

```sh
studio-vscode-upgrade --check
studio-vscode-upgrade --version 4.136.2
```

检查默认使用 code-server 官方 Release API,有连接超时,不在 Session 启动时执行;可通过 `STUDIO_CODE_SERVER_RELEASE_API` 切换为兼容官方响应格式的企业镜像接口

国内环境建议先把官方安装包校验后放入账号对象存储,再指定下载地址和 SHA256

```sh
studio-vscode-upgrade --version '<版本号>' \
--archive-url '<国内 HTTPS 下载地址>' \
--sha256 '<官方 SHA256>'
```

命令要求先保存文件,只准备下一次启动使用的 code-server 版本,重新应用 Maple Mono 字体,不自动重启正在使用的编辑器,不修改项目、插件和用户设置

可用 `--rollback` 选择上一个版本,升级仅影响当前 Sandbox 文件系统,新 Session 的默认版本仍需更新镜像;不要为应用升级销毁正在使用的 Session

基础镜像每次启动覆盖用户设置的行为已改为仅首次初始化,后续重启保留用户设置

## 轻量检查

```sh
python3 -m unittest discover -s tests -v
```

镜像构建还会验证 Python/AgentKit 导入和离线项目创建,检查成功后移除仅供构建验证的临时项目

## 编辑器和终端默认行为

`VSCODE_LANG` 未设置或为 `zh-CN` 时使用简体中文,为 `en` 时使用英文,编辑器和欢迎页保持一致
火山引擎默认中文,BytePlus 启动时设置 `VSCODE_LANG=en`
中文界面使用官方 `MS-CEINTL.vscode-language-pack-zh-hans` 1.104.0

首次进入只显示 VS Code,欢迎页包含文档链接、VeADK 介绍和 AgentKit 介绍
每个工作区默认创建 Bash 和 Codex 两个集成终端,工作目录均为当前项目
刷新时复用已恢复的同名终端,Codex 使用 `--cd` 显式指定项目目录
配置 `MODEL_AGENT_API_KEY`、`MODEL_AGENT_NAME` 和 `MODEL_AGENT_BASE_URL` 后,基础镜像生成 Codex 模型配置,无需交互登录;凭据只在启动时传入,不写入镜像

Bash 使用上游 ble.sh v0.4.0-devel3 提供输入高亮,采用固定 SHA256 的官方发布包,不切换 Shell

本地 Apple Silicon 在 QEMU 中运行 x64 Codex 0.139.0 时,可能因不支持 TCGETS2 终端接口报 `os error 38`
本地预览容器可通过基础镜像已有的 `CODEX_REAL_BIN` 覆盖为相同版本 Linux ARM64 musl 程序
此替换仅用于本地兼容,不改变云端 x64 镜像的默认程序,也不放宽权限或沙箱限制

## Apple Silicon 本地预览

云端继续使用基础镜像的 `/opt/gem/run.sh` 和原始 x64 Codex
本地 ARM 预览显式选择 `/opt/studio-sandbox/runtime/local-arm64-entrypoint`,它设置已有的 `CODEX_REAL_BIN` 覆盖变量并统一 fnm 命令入口,再执行原始启动脚本
该入口随镜像提供,不是镜像默认入口

建议本地虚拟机至少提供 4 CPU / 12 GB 内存,构建时避免并行运行多个编辑器窗口
本地运行设置 `DISABLE_BROWSER=true`,避免 x64 浏览器在 QEMU 下反复崩溃
运行示例中的模型环境文件应设置为仅当前用户可读

```sh
docker run -d --name studio-sandbox-local --platform linux/amd64 \
--entrypoint /opt/studio-sandbox/runtime/local-arm64-entrypoint \
--ulimit core=0 --shm-size=512m \
--env-file /path/to/model.env \
-e AIO_USER=gem -e DISABLE_BROWSER=true \
-e DISABLE_DEEPSEEK_HARNESS_WEBUI=true \
-e DISABLE_CODEX_APP_SERVER=true -e DISABLE_CODEX_MCP_SERVER=true \
-p 127.0.0.1:18080:8080 studio-sandbox:local
```

项目的 `.git` 在资源管理器中默认可见
`AGENTS.md` 仅包含 Python 开发规范、项目目录说明和 VeADK / AgentKit 文档链接
项目技能可放在 `.agents/skills/<name>/SKILL.md`,不默认复制个人技能

## 云端默认镜像与资源加载

镜像内置云端会话资源路由:主题、语法文件、语言包、工作台脚本、字体和欢迎页的
Service Worker 使用当前页面的 `Authorization`、`faasInstanceName`,不向外部域名转发
鉴权参数;本地地址不带这些参数时保持原有访问方式
无需在 Tool 的启动命令里再注入编辑器补丁,直接使用 `/opt/gem/run.sh`

终端仅在项目首次打开时自动初始化,后续刷新交给 VS Code 恢复,不因恢复较慢重复创建
手动关闭后不会在刷新时重新打开;需要时通过命令面板执行 `Studio: Open Bash and Codex / 打开终端`
现有用户自行创建的终端不会被删除

文件监听排除 `.venv`、Python 系统依赖、`__pycache__` 和 `node_modules`,减少云端
inotify 配额占用;目录仍可见,项目源码仍被监听,Python 补全仍可读取依赖类型信息

基于已经发布的 Studio 镜像更新编辑器时,可以使用 `Dockerfile.update`,`BASE_IMAGE`
应固定为已验证镜像的 SHA256 digest;全量构建继续使用 `Dockerfile`
更新过程只在构建镜像时执行,不覆盖挂载进来的用户设置和项目文件

```sh
docker build --platform linux/amd64 -f Dockerfile.update \
--build-arg BASE_IMAGE='<Studio 镜像@sha256:digest>' \
-t studio-sandbox:updated .
node --test tests/test_terminals.cjs
```

Tool 建议保持已验证的 4 CPU / 8 GB 内存、8080 端口和快照能力,模型环境变量在
创建 Tool 时传入;火山引擎默认中文,BytePlus 设置 `VSCODE_LANG=en`
67 changes: 67 additions & 0 deletions frontend/sandbox-image/assets.lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[
{
"file": "donjayamanne.githistory-0.6.20.vsix",
"url": "https://open-vsx.org/api/donjayamanne/githistory/0.6.20/file/donjayamanne.githistory-0.6.20.vsix",
"sha256": "aaea597276f089922e5b785f5c1ca1f1bef523ee17d6766889b67c0c76c35104"
},
{
"file": "codezombiech.gitignore-0.10.0.vsix",
"url": "https://open-vsx.org/api/codezombiech/gitignore/0.10.0/file/codezombiech.gitignore-0.10.0.vsix",
"sha256": "0c13696b23838c6523f1e4eba8427bc5a3082f50cd8ee63072f3e0335fb4e95b"
},
{
"file": "unifiedjs.vscode-mdx-1.8.18.vsix",
"url": "https://open-vsx.org/api/unifiedjs/vscode-mdx/1.8.18/file/unifiedjs.vscode-mdx-1.8.18.vsix",
"sha256": "1e3c27c6c66d11ab2333362ec4a6255741a57ca6d226b33315308beaff634c85"
},
{
"file": "ggfincke.vsc-mdx-preview-1.7.0.vsix",
"url": "https://open-vsx.org/api/ggfincke/vsc-mdx-preview/1.7.0/file/ggfincke.vsc-mdx-preview-1.7.0.vsix",
"sha256": "de677b31a443ade525bf2ec8d28d4ab03112bfc8647fa55a3c23b8f30e89a7ed"
},
{
"file": "ms-python.python-2026.4.0.vsix",
"url": "https://open-vsx.org/api/ms-python/python/2026.4.0/file/ms-python.python-2026.4.0.vsix",
"sha256": "232aeafb01f069824fdd92d3e628c1c442bbcfa1d3cc945ff97076340bb2b4a6"
},
{
"file": "detachhead.basedpyright-1.40.0.vsix",
"url": "https://open-vsx.org/api/detachhead/basedpyright/1.40.0/file/detachhead.basedpyright-1.40.0.vsix",
"sha256": "67e47122039ab2a687dd31e470eaa282093efefe7ad20f502c76331b8d058333"
},
{
"file": "ms-python.debugpy-2026.6.0-linux-x64.vsix",
"url": "https://open-vsx.org/api/ms-python/debugpy/linux-x64/2026.6.0/file/ms-python.debugpy-2026.6.0@linux-x64.vsix",
"sha256": "c7744af4bf72978f5792624a71c80e2b622a1118574fada3a903d70ac03d5bca"
},
{
"file": "charliermarsh.ruff-2026.78.0-linux-x64.vsix",
"url": "https://open-vsx.org/api/charliermarsh/ruff/linux-x64/2026.78.0/file/charliermarsh.ruff-2026.78.0@linux-x64.vsix",
"sha256": "d127e787181cc2cfcd939ee5175515ec3421da9ab9389945a5168f1e14920258"
},
{
"file": "tamasfe.even-better-toml-0.21.2.vsix",
"url": "https://open-vsx.org/api/tamasfe/even-better-toml/0.21.2/file/tamasfe.even-better-toml-0.21.2.vsix",
"sha256": "f3dc44f1c551edef397a79f0f8c5db4066c6a547e210b5c3cec4400bf173b008"
},
{
"file": "MapleMono-Woff2.zip",
"url": "https://github.com/subframe7536/maple-font/releases/download/v7.9/MapleMono-Woff2.zip",
"sha256": "5e38e83b007e7157c253c3f57c0a6f80415378f4859d43eb3cf4b1d858001681"
},
{
"file": "MS-CEINTL.vscode-language-pack-zh-hans-1.104.0.vsix",
"url": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-zh-hans/1.104.0/file/MS-CEINTL.vscode-language-pack-zh-hans-1.104.0.vsix",
"sha256": "eed5d80fb1b319f35ad984bbaa78e4122c43c9dcee1df8780fd8c30fcea9fe09"
},
{
"file": "blesh-0.4.0-devel3.tar.xz",
"url": "https://github.com/akinomyoga/ble.sh/releases/download/v0.4.0-devel3/ble-0.4.0-devel3.tar.xz",
"sha256": "c8612ee612bc6b10dbfd6e85c6cbdfd7caf152a12d1f9de22ea0a9d735b3080c"
},
{
"file": "codex-0.139.0-linux-arm64.tgz",
"url": "https://registry.npmjs.org/@openai/codex/-/codex-0.139.0-linux-arm64.tgz",
"sha256": "6195677e4ba51f22a9a1b5f0e2a01a255a42a5755b740123ce68f530ed2dd3ca"
}
]
Loading
Loading