Metadata-Version: 2.4
Name: bizyair-cloudberry
Version: 0.3.2
Summary: ComfyUI custom node for cloud-based workflow execution via BizyAir API
Author-email: Lei Fengxiang <leifengxiang@siliconflow.cn>, Feng Wen <fengwen@siliconflow.cn>
Project-URL: Repository, https://github.com/siliconflow/BizyAir-CloudBerry
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: websockets>=12.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: aiohttp>=3.9
Requires-Dist: requests>=2.28
Requires-Dist: bizytrd~=0.1.15
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"

# ☁️ BizyAirPlus（BizyAir-CloudBerry）

BizyAirPlus 是一个 ComfyUI 自定义节点插件，通过 BizyAir API 将工作流提交到云端执行，并把任务进度和结果实时同步回本地 ComfyUI。

## 功能

- **一键切换云端执行**：通过 ComfyUI action bar 中的 BizyAirPlus ON/OFF 按钮切换，不修改原生 Queue 菜单。
- **云端模型选择**：在支持的模型 widget 中直接打开 BizyAir 模型选择器。
- **子图支持**：支持 promoted model widget、嵌套子图和同一子图的多实例隔离。
- **新前端兼容**：兼容 LiteGraph 节点和 Vue Nodes（Node 2.0）的模型选择交互。
- **实时状态与取消**：通过 Draft WebSocket 和 Task WebSocket 接收任务状态、执行进度与结果，并在本地取消时清理云端任务。
- **自动资源处理**：自动处理输入文件上传、模型映射和输出文件下载。
- **中英文界面**：跟随 ComfyUI 的 `Comfy.Locale` 设置，支持中文和英文。

## 安装

```bash
pip install bizyair-cloudberry
```

安装完成后重启 ComfyUI。

## 快速开始

1. 打开 ComfyUI，在 action bar 中点击 **BizyAirPlus** 按钮。
2. 首次启用时，根据弹窗填写 BizyAir API Key；可以前往 [bizyair.ai](https://bizyair.ai) 获取。
3. 在工作流的模型 widget 中选择 BizyAir 模型。子图提升到宿主节点的模型输入也可以直接选择。
4. 提交工作流。按钮显示 **ON** 时使用云端执行，切换为 **OFF** 后恢复本地执行。

> 为保证云端模型与版本一致，promoted model widget 必须通过 BizyAir 模型选择器修改。绕过选择器手动改值时，插件会拒绝提交并提示重新选择。

## 配置

### API Key

使用云端执行必须配置 BizyAir API Key。

推荐通过 ComfyUI 中的 BizyAirPlus 开关或 `Settings > BizyAirPlus > ApiKey` 配置。API Key 会保存在：

```text
~/.BizyAirPlus/apikey.ini
```

也可以使用环境变量；环境变量的优先级高于本地配置文件：

```bash
# Linux/macOS
export BIZYAIR_API_KEY=sk-xxxxxx

# Windows PowerShell
$env:BIZYAIR_API_KEY="sk-xxxxxx"
```

### 服务域名

| 变量名 | 是否必填 | 默认值 | 说明 |
|--------|----------|--------|------|
| `BIZYAIR_API_KEY` | 否 | - | API Key 的环境变量配置方式；未设置时读取 ComfyUI 中保存的 Key |
| `BIZYAIR_BASE_URL` | 否 | `bizyair.ai` | BizyAir 基础域名，API、元数据、存储和分享地址均由它派生；UAT 环境使用 `bizyair.vip` |

`BIZYAIR_BASE_URL` 只接受域名，不要包含协议、路径或末尾斜杠。例如：

```bash
export BIZYAIR_BASE_URL=bizyair.vip
```

## v0.3.0 更新

本版本对应 [PR #52](https://github.com/siliconflow/BizyAir-CloudBerry/pull/52)，主要变化如下：

- 将用户可见品牌、节点包装类型和设置项统一为 **BizyAirPlus**。
- 将旧的 Queue 下拉菜单入口替换为 action bar 中独立的 ON/OFF 按钮。
- 新增运行时 i18n 桥，按钮、提示、API Key 弹窗和模型徽章支持中英文，并跟随 ComfyUI locale。
- 重构 promoted model widget 处理，兼容 ComfyUI 前端 1.47.1 与 1.47.2+ 的两种投影机制，支持嵌套子图、扇出同步和实例隔离。
- 新增 Vue Nodes（Node 2.0）交互桥，使 DOM 渲染的 combo widget 也能打开 BizyAir 模型选择器。
- 云端执行接口切换到 `/workflow/task/openapi/*`，以 `request_id` 标识任务，并使用创建任务响应中的 `wss_url` 监听实时事件。
- 使用 `BIZYAIR_BASE_URL` 统一派生 API、元数据、存储和分享服务地址。

## 开发

### 后端

```bash
# 安装开发依赖
pip install -e ".[dev]"

# 格式化
ruff format .

# 运行 Python 测试；部分集成测试需要 BIZYAIR_API_KEY
PYTHONPATH=src python -m pytest tests/ -v
```

### Vue 3 前端

模型选择对话框是独立的 Vue 3 + TypeScript 应用：

```bash
cd frontend
npm ci
npm run dev     # 开发服务器，默认端口 5175
npm run build   # 构建到 ../src/bizyair_cloudberry/web/
```

构建产物为 UMD 格式的 `bizyair_cloudberry_ui.js`，通过 `window.bizyairCBLib.showModelSelect()` 调用。

技术栈：Vue 3、TypeScript、Tailwind CSS、naive-ui、vue-i18n。

### UI 测试

```bash
cd tests/ui
npm ci

# 原生 JS 单元测试
npm run test:unit

# Playwright 端到端测试
npx playwright install --with-deps
npx playwright test
```

Playwright 测试需要先启动 ComfyUI 实例（`localhost:8188`）。

### 构建打包

前端必须先构建，产物 `bizyair_cloudberry_ui.js` 会被打包进 wheel：

```bash
# 1. 构建前端
cd frontend
npm ci
npm run build

# 2. 返回仓库根目录并构建 Python 包
cd ..
pip install build
python -m build
```

## 架构

```text
ComfyUI action bar
        │
        ▼
cloudberry.js / logic.js ──► cloudberry_mode
        │
        ▼
hijack.py ──► BizyAirPlusNodeWrapper
        │
        ▼
InputHandler / process_transform.py
        │
        ▼
SCXAPIExecutor ──► OpenAPI create（request_id + wss_url）
        │
        ├── Draft WebSocket ──► 任务终态
        └── Task WebSocket  ──► 进度、预览与输出 ──► ComfyUI
```

### 关键组件

#### 后端（`src/bizyair_cloudberry/`）

- `cloudberry_node.py`：BizyAirPlus 包装节点入口。
- `hijack.py`：拦截启用云端模式的 prompt，并包装为 `BizyAirPlusNodeWrapper`。
- `input_handler.py`：处理文件和模型映射，上传输入图片。
- `process_transform.py`：生成云端执行所需的模型版本转换信息，并支持子图展平后的节点 ID。
- `file_utils.py`：处理上传凭证、OSS 上传、提交与下载。
- `event_processor.py`：将远程事件转换为本地 ComfyUI 事件。
- `env.py`：管理 API Key、基础域名及派生服务地址。
- `scx_executor/`：协调 OpenAPI 请求、Draft WebSocket、Task WebSocket 和任务取消。
- `routes/community.py`：提供模型浏览、API Key 和前端配置代理等本地 API。

#### ComfyUI 前端扩展（`src/bizyair_cloudberry/web/`）

- `cloudberry.js`：注册 BizyAirPlus 扩展、设置项和 action bar 按钮。
- `model_apply.js`：绑定模型 widget 的 BizyAir 选择行为。
- `modules/logic.js`：拦截 `graphToPrompt` 并注入云端执行标记及模型版本。
- `modules/model.js`：模型选择与徽章逻辑。
- `modules/subgraphModel.js`：处理 promoted model widget、嵌套子图和实例状态隔离。
- `modules/vueWidgetBridge.js`：桥接 Vue Nodes（Node 2.0）的 DOM 交互。
- `modules/i18n.js`：原生扩展的运行时中英文支持。
- `modules/ui.js`：加载样式并提供 API Key 弹窗。

#### Vue 前端（`frontend/`）

- Vue 3 + TypeScript 独立包，构建为 UMD 格式。
- `showModelSelect()` 导出到 `window.bizyairCBLib`，由原生 JS 扩展调用。
- 通过 `/bizyair/*` 本地 API 与后端通信。
- 每次打开弹窗时从原生运行时桥同步 locale。
