# 字字视频插件完整接口文档

> 对应插件版本：`3.3.13`  
> 整理依据：当前插件 `main.py` 与 `ui/index.html`。  
> 默认中转：`https://api.aicopy.top`；除素材上传接口外，提交与查询均使用用户填写的 Base URL。

## 1. 通用配置

| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---:|---|
| `api_key` | string | 空 | 必填，作为 Bearer Token |
| `base_url` | string | `https://api.aicopy.top` | 用户填写的中转，不固定 |
| `proxy_url` | string | 空 | 可选，同时用于 HTTP/HTTPS |
| `model` | string | `grok-imagine-1.0-video` | UI 分支内部值 |
| `variant` | string | `grok-1.0-video（按次）` | 变体通常决定实际模型名 |
| `aspect_ratio` | string | `16:9` | 各分支支持范围不同 |
| `video_length` | int | `6` | 秒数；各分支会再次校验或强制固定 |
| `resolution` | string | `720p` | 各分支可能由变体强制决定 |
| `generation_mode` | string | `文生视频` | 文生、首帧、首尾帧、多参考图、视频编辑等 |
| `timeout` | int | `3600` | 整体等待上限，单位秒；异步分支至少等待 120 秒 |

通用鉴权：

```http
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

## 2. 当前 UI 分组

| UI 分组 | 内部 model | 协议 |
|---|---|---|
| GROK 1.0-video（可多参） | `grok-imagine-1.0-video` | Grok JSON 异步 |
| GROK 1.5-fast（可多参） | `grok-imagine-video-1.5-fast` | Grok JSON 异步 |
| GROK 1.5-Preview（仅首帧） | `grok-imagine-video-1.5-preview` | Grok 首帧异步 |
| GROK-特价 | `grok-1.5-低价渠道` | Grok 低价兼容协议 |
| grok-1.5支持16秒 | `grok-1.5支持16秒` | `/v1/videos` 标准异步 |
| HappyHorse官方快乐马（可多参） | `happyhorse-video` | HappyHorse `/v1/videos` |
| sd2.0-720官方稳定版（按秒） | `seedance2.0-720官方稳定版（按秒）` | Seedance9 JSON 异步 |
| sd2.0全系列(按秒) | `sd2.0全系列(按秒)` | SD2 JSON 异步 |
| 低价渠道sd2.0-全系（按次） | `低价渠道sd2.0-全系（按次）` | Seedance 按次 JSON |
| sd轮换渠道 | `sd轮换渠道` | Canvas JSON / 渠道2协议 |
| omni | `omni` | Omni JSON 异步 |

当前下拉框合计 `11` 个分支、`43` 个可选变体。除第 16 节明确标注的后端兼容配置外，其余旧渠道名称不属于当前可选模型。

### 2.1 接口与轮询速查

| 协议族 | 提交 | 查询 | 轮询间隔 | 创建成功 HTTP | 无结果 URL 时的处理 |
|---|---|---|---:|---|---|
| Grok 1.0 / 1.5 fast | `POST /v1/videos` | `GET /v1/videos/{id}` | 5 秒 | 200/201/202 | 报错或等待，取决于具体变体 |
| Grok 1.5 Preview | `POST /v1/videos` | `GET /v1/videos/{id}` | 5 秒 | 200/202 | 必须从查询响应取得 URL |
| GROK-特价 / 16 秒 | `POST /v1/videos` | `status_url` 或 `GET /v1/videos/{id}` | 3 秒 | 200/201/202 | 必须从响应取得 URL |
| HappyHorse | `POST /v1/videos` | `GET /v1/videos/{id}` | 5 秒 | 200/201/202 | `GET /v1/videos/{id}/content` |
| Seedance/SD2/Canvas | `POST /v1/videos` | `GET /v1/videos/{id}` | 5 秒 | 200/201/202 | SD2 可回退 `/content?variant=video`，其他分支按各节说明 |
| Omni | `POST /v1/videos` | `GET /v1/videos/{id}` | 6 秒 | 200/201/202 | `GET /v1/videos/{id}/content` |
| 隐藏 Firefly Chat | `POST /v1/chat/completions` | 无独立查询 | SSE 持续读取 | 200 | SSE 中必须提取视频 URL |

## 3. 通用异步查询与返回兼容

大部分视频分支采用以下流程：

```text
POST {BASE_URL}/v1/videos
  -> 读取 task_id/id/request_id/video_id
  -> GET {BASE_URL}/v1/videos/{task_id}
  -> 成功后读取视频 URL
  -> 下载并保存 mp4
```

### 3.1 可识别的任务 ID

插件会在顶层及 `data/result/output` 中查找：

```text
id / request_id / task_id / video_id
```

以上字段支持顶层以及 `data/result/output` 对象。当前实现**不读取**驼峰字段 `taskId`；中转若只返回 `taskId` 而没有上述任一字段，插件会报“创建视频任务后未返回 task_id”。

接受示例：

```json
{"task_id":"task_xxx","status":"processing"}
```

```json
{
  "ok": true,
  "data": {
    "id": "task_xxx",
    "task_id": "task_xxx",
    "status": "running"
  }
}
```

### 3.2 状态字段

插件会读取顶层或 `data` 中的：

```text
status / state / task_status / taskStatus / job_status / jobStatus
```

成功状态：

```text
SUCCESS / SUCCEEDED / COMPLETED / COMPLETE / DONE / FINISHED / OK
```

失败状态：

```text
FAILURE / FAILED / ERROR / CANCELLED / CANCELED / TIMEOUT
```

其他状态按生成中处理。没有状态但存在结果 URL 时，也可判定成功。

### 3.3 可识别的视频 URL

插件兼容以下位置：

```text
result_url / video_url / url / download_url
result.video_url / result.result_url / result.download_url / result.url
output.video_url / output.result_url / output.download_url / output.url
video.url
metadata.result_url / metadata.download_url / metadata.url
data.video_url / data.result_url / data.download_url / data.url
```

Omni 还支持：

```json
{"data":[{"url":"/v1/videos/task_xxx/content"}]}
```

### 3.4 通用查询示例

```bash
curl "${BASE_URL}/v1/videos/task_xxx" \
  -H "Authorization: Bearer ${API_KEY}"
```

生成中：

```json
{
  "ok": true,
  "data": {
    "task_id": "task_xxx",
    "status": "running",
    "progress": 35
  }
}
```

生成成功：

```json
{
  "ok": true,
  "data": {
    "task_id": "task_xxx",
    "status": "succeeded",
    "video_url": "https://example.com/video.mp4"
  }
}
```

生成失败：

```json
{
  "ok": true,
  "data": {
    "task_id": "task_xxx",
    "status": "failed",
    "error": "失败原因",
    "upstream_error": "上游失败原因"
  }
}
```

### 3.5 创建、直返和退款外层格式

标准异步创建响应可以是扁平结构：

```json
{
  "task_id": "task_xxx",
  "status": "processing"
}
```

也可以是带计费信息的 Canvas 外层结构；插件从 `data` 中继续提取任务 ID：

```json
{
  "ok": true,
  "model": {
    "id": "sd-720-fast-渠道16:9（按次）",
    "type": "video",
    "name": "视频模型"
  },
  "charged_cents": 100,
  "balance_cents": 900,
  "data": {
    "task_id": "task_xxx",
    "status": "processing",
    "message": "任务已提交，请轮询查询结果"
  }
}
```

如果创建响应已经含有可识别视频 URL，多数异步分支会跳过轮询直接下载：

```json
{
  "status": "completed",
  "video_url": "https://example.com/video.mp4"
}
```

失败退款信息可以与失败任务一起返回：

```json
{
  "ok": true,
  "data": {
    "task_id": "task_xxx",
    "status": "failed",
    "error": "失败原因",
    "upstream_error": "上游返回的失败原因"
  },
  "refunded": {
    "refunded_cents": 100
  },
  "message": "任务失败，已退余额"
}
```

插件不计算退款金额，也不发起退款请求，只解析失败并把错误返回给宿主；实际退款由中转服务完成。

## 4. 素材识别与上传

### 4.1 字字动画帧字段

插件兼容中文和英文别名，包括：

```text
首帧 / 首帧图片 / 起始帧 / 开始帧
first / start / first_frame / start_frame / first_image
尾帧 / 尾帧图片 / 结束帧 / 末帧
last / end / tail / last_frame / end_frame / last_image
首尾帧 / frames / frame_images / first_last_frames
```

参考图主要来自 `参考图片MAP`，并按键排序。部分分支还会从项目 `data.ini` 恢复当前查看器保存的首尾帧。

### 4.2 内置图片上传接口

需要公网 URL 的分支会把本地图片上传至插件自带上传服务：

```text
POST https://api.aione.help/v1/uploads
失败时回退 POST https://api.aione.help/v1/upload
multipart 字段：image
鉴权：Authorization: Bearer <同一 API_KEY>
```

限制：

- 图片最大 15MB；
- 扩展名：PNG/JPG/JPEG/WebP/GIF；
- 返回需包含公网 URL；
- 兼容 `image_url/url/image_urls/urls`，也兼容嵌套 `data`。

### 4.3 Base64 图片

Grok 通用接口使用 Data URL：

- 图片转 RGB；
- 可按目标比例居中裁剪；
- 最长边缩到 1024；
- JPEG 质量 85；
- 结果为 `data:image/jpeg;base64,...`。

## 5. GROK 1.0-video（可多参）

### 5.1 变体映射

| UI 变体 | 实际 API model |
|---|---|
| `grok-1.0-video（按次）` | `grok-imagine-1.0-video` |
| `grok-1.0-官转接口（按秒）` | `grok-1.0-官转接口` |
| `grok-1.0-备用接口（按秒）` | `grok-1.0-备用接口` |

参数：

- 比例：`16:9`、`9:16`、`3:2`
- 秒数：`6`、`10`
- 分辨率：固定 `720p`，提交为 `HD`
- 模式：文生、首帧、多参考图
- 多参考图：最多 7 张

### 5.2 请求体

```bash
curl "${BASE_URL}/v1/videos" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-1.0-video",
    "prompt": "人物缓慢转身，镜头稳定",
    "duration": 6,
    "video_length": 6,
    "aspect_ratio": "16:9",
    "resolution": "HD",
    "video_config": {
      "video_length": 6,
      "aspect_ratio": "16:9",
      "resolution": "HD",
      "preset": "normal"
    }
  }'
```

首帧或多参考图在本分支都放入：

```json
{
  "reference_images": [
    "data:image/jpeg;base64,..."
  ]
}
```

轮询间隔 5 秒，查询 `GET /v1/videos/{task_id}`。

## 6. GROK 1.5-fast（可多参）

### 6.1 变体映射

| UI 变体 | 实际 API model |
|---|---|
| `grok-video-1.5-fast（按次）` | `grok-imagine-video-1.5-fast` |
| `grok-1.5-fast-官转接口` | `grok-1.5-fast-官转接口` |
| `grok-1.5-fast-备用接口` | `grok-1.5-fast-备用接口` |

- 比例：`16:9`、`9:16`、`3:2`
- 秒数：`6`、`10`
- 分辨率：固定 `720p/HD`
- 模式：文生、首帧、多参考图
- 多参考图最多 7 张

请求体主体与 GROK 1.0 相同。区别是首帧模式使用独立字段：

```json
{
  "model": "grok-imagine-video-1.5-fast",
  "prompt": "让画面自然运动",
  "duration": 10,
  "video_length": 10,
  "aspect_ratio": "9:16",
  "resolution": "HD",
  "video_config": {
    "video_length": 10,
    "aspect_ratio": "9:16",
    "resolution": "HD",
    "preset": "normal"
  },
  "image": "data:image/jpeg;base64,..."
}
```

多参考图仍使用 `reference_images`。

## 7. GROK 1.5-Preview（仅首帧）

### 7.1 变体映射

| UI 变体 | 实际 API model |
|---|---|
| `GROK 1.5 Preview（按次）` | `grok-imagine-video-1.5-preview` |
| `grok-1.5-官转接口（按秒）` | `grok-1.5-官转接口` |
| `grok-1.5-备用接口（按秒）` | `grok-1.5-备用接口` |

- 有效秒数：`10`、`15`
- 模式：只允许首帧
- 比例：`16:9`、`9:16`、`3:2`
- `size` 映射：`16:9 -> 1280x720`，`9:16 -> 720x1280`，`3:2 -> 1792x1024`

请求示例：

```json
{
  "model": "grok-imagine-video-1.5-preview",
  "prompt": "镜头缓慢推进",
  "seconds": "10",
  "size": "1280x720",
  "images": [
    "data:image/jpeg;base64,...",
    "data:image/jpeg;base64,..."
  ]
}
```

按次 Preview 变体会把同一首帧放入 `images` 两次；官转/备用模型只放一次。提交 `POST /v1/videos`，轮询间隔 5 秒。

## 8. GROK-特价

### 8.1 变体

| 实际 API model | 秒数 | 有效模式 |
|---|---|---|
| `grok-1.5-fast-低价渠道` | 6、10 | 文生、首帧、多参考图 |
| `grok-1.0-低价渠道` | 6、10 | 文生、首帧、多参考图 |
| `grok-1.5-低价渠道` | 6、10、15 | 强制首帧 |

比例：`16:9`、`9:16`、`3:2`；分辨率固定 720p。

本地参考图先上传到插件图片上传接口，最终只提交第一张图片。即使 UI 选择多参考图，本协议也不会把 2-7 张全部送给上游。

```json
{
  "model": "grok-1.5-fast-低价渠道",
  "prompt": "人物自然走动",
  "seconds": "10",
  "size": "1280x720",
  "image": "https://public.example/ref.jpg"
}
```

提交：`POST /v1/videos`；查询：`GET /v1/videos/{task_id}`；轮询间隔 3 秒。

## 9. grok-1.5支持16秒

### 9.1 参数

| 变体/实际模型 | 模式 |
|---|---|
| `grok-1.5-支持16s` | 强制首帧图生视频 |
| `grok-1.0-支持16s` | 强制文生视频 |

- 秒数：`6`、`10`、`12`、`16`、`20`
- 提示词上限：4500 字符
- 比例/size：

| 比例 | size |
|---|---|
| `9:16` | `720x1280` |
| `16:9` | `1280x720` |
| `1:1` | `1024x1024` |
| `4:7` | `1024x1792` |
| `7:4` | `1792x1024` |

### 9.2 1.5 首帧请求

```json
{
  "model": "grok-1.5-支持16s",
  "prompt": "轻微镜头推移，画面自然生动",
  "seconds": "16",
  "size": "1280x720",
  "image_reference": "https://public.example/first.jpg"
}
```

### 9.3 1.0 文生请求

```json
{
  "model": "grok-1.0-支持16s",
  "prompt": "灯塔在日落时分，海浪拍打礁石",
  "seconds": "16",
  "size": "1280x720"
}
```

提交响应还可提供 `status_url`；插件优先按该 URL 查询，否则查询 `/v1/videos/{task_id}`。

## 10. HappyHorse官方快乐马（可多参）

### 10.1 变体即模型

```text
happyhorse-1.1-t2v-720p
happyhorse-1.1-t2v-1080p
happyhorse-1.1-i2v-720p
happyhorse-1.1-i2v-1080p
happyhorse-1.1-r2v-720p
happyhorse-1.1-r2v-1080p
```

规则：

- `t2v`：文生视频；
- `i2v`：首帧生成视频；
- `r2v`：多参考图，最多 9 张；
- 分辨率由模型后缀固定；
- 秒数：4-15；
- 文生/参考生比例：`16:9`、`9:16`、`1:1`、`4:3`、`3:4`、`4:5`、`5:4`、`9:21`、`21:9`；
- 首帧模式不提交比例，跟随首帧；
- `watermark=false`。

### 10.2 请求示例

```bash
curl "${BASE_URL}/v1/videos" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1-r2v-720p",
    "prompt": "保持主体一致，镜头缓慢环绕",
    "parameters": {
      "duration": 10,
      "resolution": "720P",
      "watermark": false,
      "ratio": "16:9"
    },
    "reference_images": [
      "data:image/jpeg;base64,...",
      "https://example.com/ref2.jpg"
    ]
  }'
```

首帧模式字段：

```json
{"image_url":"data:image/jpeg;base64,..."}
```

如果 Base URL 已以 `/v1` 结尾，插件不会重复添加 `/v1`。查询为 `GET /v1/videos/{task_id}`；成功但没有 URL 时下载 `/v1/videos/{task_id}/content`。

## 11. sd2.0-720官方稳定版（按秒）

### 11.1 模型映射

| UI 变体 | 实际 API model |
|---|---|
| `720-fast稳定版（按秒）` | `官方稳定seedance-2.0-720p-fast` |
| `720-max稳定版（按秒）` | `官方稳定seedance-2.0-720p-max` |

- 比例：`16:9`、`9:16`、`1:1`
- 秒数：4-15
- 分辨率：固定 720p
- 模式：文生、首帧、首尾帧、多参考图、首帧+参考图
- 最多 9 张图片

### 11.2 请求体

```json
{
  "model": "官方稳定seedance-2.0-720p-fast",
  "prompt": "人物自然转身",
  "seconds": "10",
  "metadata": {
    "ratio": "16:9",
    "resolution": "720p"
  },
  "images": [
    "https://public.example/first.jpg",
    "https://public.example/ref2.jpg"
  ]
}
```

请求头额外携带随机 `Idempotency-Key: plugin-...`。首帧、尾帧和参考图最终统一按顺序放入 `images`，提交端点为 `/v1/videos`。

查询成功 URL 除通用字段外，还兼容：

```text
data.data.content.video_url
```

## 12. sd2.0全系列(按秒)

### 12.1 变体即模型

```text
sd2-1080p
sd2-1080p-fast
sd2-1080p-mini
sd2-720p
sd2-720p-fast
sd2-720p-mini
```

- 分辨率由变体前缀固定；
- 比例：`16:9`、`9:16`、`1:1`；
- 秒数：4-15；
- 图片最多 9 张；
- 音频 URL 最多 3 条；
- 默认开启声音。

### 12.2 请求示例

```json
{
  "model": "sd2-1080p-fast",
  "prompt": "人物沿街道缓慢行走",
  "duration": 10,
  "metadata": {
    "modeType": "image2video",
    "ratio": "16:9",
    "enableSound": "on"
  },
  "images": ["https://public.example/ref.jpg"],
  "audios": ["https://public.example/audio.mp3"]
}
```

`modeType` 规则：

| 条件 | modeType |
|---|---|
| 文生、没有图片 | `text2video` |
| 首尾帧模式 | `frames2video` |
| 其他带图片模式 | `image2video` |

成功但没有返回 URL 时，插件下载：

```text
GET /v1/videos/{task_id}/content?variant=video
```

## 13. 低价渠道sd2.0-全系（按次）

### 13.1 变体固定规格

| 实际 API model | 比例 | 分辨率 | 秒数 |
|---|---|---|---:|
| `sd-480-fast-渠道9:16（按次）` | 9:16 | 480p | 15 |
| `sd-480-fast-渠道16:9（按次）` | 16:9 | 480p | 15 |
| `sd-720-fast-渠道9:16（按次）` | 9:16 | 720p | 15 |
| `sd-720-fast-渠道16:9（按次）` | 16:9 | 720p | 15 |
| `sd-720-max-渠道9:16（按次）` | 9:16 | 720p | 15 |
| `sd-720-max-渠道16:9（按次）` | 16:9 | 720p | 15 |

模式：文生、首帧、首尾帧、多参考图；多参考图最多 9 张。

尺寸映射：

```text
480p 9:16 -> 480x854
480p 16:9 -> 854x480
720p 9:16 -> 720x1280
720p 16:9 -> 1280x720
```

### 13.2 请求体

```json
{
  "model": "sd-720-fast-渠道16:9（按次）",
  "prompt": "保持人物一致，缓慢走动",
  "input": {
    "prompt": "保持人物一致，缓慢走动",
    "media": [
      {"type":"reference_image","url":"https://public.example/ref.jpg"}
    ]
  },
  "seconds": "15",
  "size": "1280x720"
}
```

注意：首帧和尾帧虽然按顺序优先加入，但最终也使用 `input.media[].type=reference_image`，没有提交独立的 `first_frame_url/last_frame_url` 字段。

## 14. sd轮换渠道

### 14.1 变体与秒数

| 实际 API model | 秒数 |
|---|---|
| `sd-720fast-较稳定（按次）` | 固定 15 |
| `sd-720满血-较慢（按次）` | 固定 15 |
| `sd-720fast（按秒）` | 4-15 |
| `sd-720-fast-渠道1` | 固定 15 |
| `sd-720-fast-渠道2（按秒）` | 10、15 |

统一分辨率 720p；比例 `16:9`、`9:16`；模式为文生、首帧、首尾帧、多参考图。

### 14.2 普通轮换变体：Canvas 格式

除渠道2外，其余变体使用：

```json
{
  "model": "sd-720fast-较稳定（按次）",
  "prompt": "从首帧自然运动",
  "aspect_ratio": "16:9",
  "seconds": "15",
  "resolution": "720p",
  "first_frame_url": "https://public.example/first.jpg"
}
```

模式字段：

| 模式 | 附加字段 |
|---|---|
| 首帧 | `first_frame_url`，必须 1 张 |
| 首尾帧 | `first_frame_url` + `last_frame_url`，必须 2 张 |
| 多参考图 | `reference_image_urls` |

### 14.3 渠道2格式

`sd-720-fast-渠道2（按秒）` 使用另一套请求体：

```json
{
  "model": "sd-720-fast-渠道2（按秒）",
  "prompt": "从首帧自然运动",
  "duration": 15,
  "video_config": {
    "aspect_ratio": "16:9",
    "resolution_name": "720p",
    "reference_mode": "start_frame"
  },
  "reference_images": [
    "https://public.example/first.jpg"
  ]
}
```

`reference_mode`：

```text
首帧 -> start_frame
首尾帧 -> start_end
多参考图 -> image_reference
```

多参考图必须 1-4 张。

## 15. Omni

### 15.1 变体

```text
omni-fast-视频生成（无水印）
omni-fast-视频生成（带水印）
omni-fast-视频编辑（无水印）
omni-fast-视频编辑（带水印）
```

共同参数：

- 比例：`16:9`、`9:16`
- 分辨率：固定 720p
- 秒数：固定 `10`
- 生成变体：文生、首帧、首尾帧、最多 5 张参考图
- 编辑变体：强制视频编辑，最多 2 个参考视频
- 图片、视频单文件最大 8MB

### 15.2 文生

```json
{
  "model": "omni-fast-视频生成（带水印）",
  "prompt": "雨夜霓虹街道，镜头缓慢推进",
  "aspect_ratio": "16:9",
  "seconds": "10"
}
```

### 15.3 首帧/首尾帧

```json
{
  "model": "omni-fast-视频生成（无水印）",
  "prompt": "从首帧自然过渡到尾帧",
  "aspect_ratio": "16:9",
  "seconds": "10",
  "first_image_url": "https://public.example/first.jpg",
  "last_image_url": "https://public.example/last.jpg"
}
```

### 15.4 多参考图

```json
{
  "model": "omni-fast-视频生成（无水印）",
  "prompt": "保持主体一致",
  "aspect_ratio": "9:16",
  "seconds": "10",
  "images": [
    "https://public.example/ref1.jpg",
    "https://public.example/ref2.jpg"
  ]
}
```

### 15.5 视频编辑

一条视频：

```json
{
  "model": "omni-fast-视频编辑（无水印）",
  "prompt": "转换为赛博朋克风格",
  "aspect_ratio": "16:9",
  "seconds": "10",
  "video_url": "https://public.example/source.mp4"
}
```

两条视频时使用：

```json
{"videos":["https://public.example/a.mp4","https://public.example/b.mp4"]}
```

本地视频上传：

```text
POST https://api.aione.help/v1/uploads
multipart 字段：video
```

轮询间隔 6 秒；成功但没有 URL 时使用 `/v1/videos/{task_id}/content`。

## 16. 当前 UI 未展示的后端配置

下列配置仍存在于 `main.py`，但当前模型下拉框不展示。它们不应当按“当前用户可选分支”对外宣传。

### 16.1 Grok 兼容配置

```text
grok-1.0-官转接口
grok-1.0-备用接口
grok-imagine-video-preview
grok-1.5-官转接口
grok-1.5-备用接口
```

这些配置主要用于旧配置兼容或由当前 UI 变体映射进入对应实际模型。

### 16.2 待接入流式 Chat 模型

| 后端 key | 显示名 | 实际模型规则 |
|---|---|---|
| `firefly-sora2` | Sora | `firefly-sora2[-pro]-{duration}s-{ratio}` |
| `firefly-veo31` | VEO3.1 | `firefly-veo31[-ref/-fast]-{duration}s-{ratio}-{resolution}` |
| `firefly-kling3-15s-16x9-1080p` | 可灵3.0（未接通） | `firefly-kling3-{duration}s-{ratio}-{resolution}` |
| `firefly-kling3omni-10s-16x9-1080p` | 可灵3.0 Omni（未接通） | `firefly-kling3omni-{duration}s-{ratio}-{resolution}` |
| `firefly-runway45` | Runway Gen-4.5（未接通） | `firefly-runway45-{duration}s-{ratio}-720p` |

配置中保留的参数范围如下；这些模型没有出现在当前模型下拉框中：

| 后端 key | 比例 | 秒数 | 分辨率 | 变体 | 模式 |
|---|---|---|---|---|---|
| `firefly-sora2` | 16:9、9:16 | 4、8、12 | 配置占位值 `-` | 普通、pro | 文生、单参考图 |
| `firefly-veo31` | 16:9、9:16 | 4、6、8 | 1080p、720p | 普通、ref、fast | 文生、首帧、首尾帧、多参考图 |
| `firefly-kling3-15s-16x9-1080p` | 16:9、9:16 | 固定 15 | 720p、1080p | 默认 | 文生、首帧、首尾帧 |
| `firefly-kling3omni-10s-16x9-1080p` | 16:9、9:16 | 5、8、10 | 720p、1080p | 默认 | 文生、首帧、首尾帧 |
| `firefly-runway45` | 21:9、16:9、4:3、1:1、3:4、9:16、9:21 | 5、10 | 固定 720p | 默认 | 仅文生 |

它们使用：

```http
POST {BASE_URL}/v1/chat/completions
```

请求格式：

```json
{
  "model": "firefly-veo31-ref-8s-16x9-1080p",
  "messages": [{
    "role": "user",
    "content": [
      {"type":"image_url","image_url":{"url":"data:image/jpeg;base64,..."}},
      {"type":"text","text":"生成视频"}
    ]
  }],
  "stream": true,
  "aspect_ratio": "16:9",
  "video_length": 8,
  "resolution": "1080p"
}
```

SSE 返回从 `choices[0].delta.content` 中提取 `<video src>`、`<source src>` 或任意 HTTPS URL。

### 16.3 旧代码残留但当前不可调用的渠道

下列名称仍能在常量、模型映射或协议函数中找到，但它们不在 `_MODEL_CONFIG`，也不在当前模型下拉框：

```text
sd-720-特价渠道（900）
低价渠道sd-720-较稳定（按次）
sd-720-特价渠道（431）
可灵+快乐马+omni低价渠道（按次）
```

`generate()` 会先检查 `base_model` 是否存在于 `_MODEL_CONFIG`。直接从旧配置传入上述名称时，会被改成默认 `grok-imagine-1.0-video`，因此这些残留函数不能视为当前有效接口，也不应继续按其旧字段提交。

## 17. 错误返回与本地校验

### 17.1 API 错误

```json
{
  "error": {
    "message": "invalid API key",
    "type": "invalid_request_error",
    "code": 401
  }
}
```

错误字段并非每个协议完全相同，当前实现的精确范围是：

| 解析位置 | 适用范围 |
|---|---|
| 顶层 `fail_reason`、`error.message`、字符串 `error` | Grok 通用状态解析及多数异步分支 |
| `data.error`、`data.error_message` | Grok 通用状态解析 |
| 顶层 `message/detail/reason/fail_reason`、`data.message/detail/error/error_message` | Omni |
| 顶层或 `data` 中的 `upstream_error/fail_reason/error` | 低价渠道 SD2 按次分支 |
| 创建响应的 `error.message` 或顶层 `message` | 大多数创建请求 |

特别注意：`upstream_error` 不是所有 Grok/HappyHorse 查询分支的通用字段。如果中转只返回该字段，最好同时返回标准 `error.message` 或 `data.error`，确保插件能展示失败原因。

### 17.2 创建阶段

不同分支接受 HTTP `200/201/202` 的组合；非接受状态会返回：

```text
创建视频任务失败 (<HTTP状态>): <错误内容>
```

非 JSON 响应会返回：

```text
创建视频任务返回非 JSON: <响应前200字符>
```

### 17.3 查询阶段

- 查询网络错误、非 200、非 JSON：记录日志后继续轮询；
- 明确失败状态：立即返回上游错误；
- 超过总 timeout：返回“等待任务超时（轮询 N 次）”；
- 成功但没有结果 URL：部分协议使用 `/content` 兜底，部分协议明确报错。

### 17.4 常见本地拦截

| 错误 | 触发条件 |
|---|---|
| `API Key 未设置` | 没有密钥 |
| `prompt 不能为空` | 没有提示词 |
| `必须提供首帧图片` | 首帧模式未读到首帧 |
| `必须同时提供首帧和尾帧` | 首尾帧缺一张 |
| `多参考图最多支持N张` | 超过该分支限制 |
| `提示词不能超过4500个字符` | Grok 16秒分支超长 |
| `图片超过15MB/视频超过8MB` | 本地素材超限 |
| `上传后未返回公网 URL` | 插件上传接口返回结构不符合预期 |

## 18. 视频下载

插件取得结果 URL 后：

1. 相对路径拼接 Base URL；
2. 仅当下载 URL 与 Base URL 同源时携带 Bearer Token；
3. 同源鉴权下载失败时再尝试无鉴权下载；
4. 流式写入 `.part` 临时文件；
5. 完成后原子改名为 `.mp4`；
6. 文件名格式：`{viewer_index}_video_{timestamp}.mp4`。

Grok 包装下载还支持：

```text
GET {BASE_URL}/v1/videos/{task_id}/content
```

如果返回 `Task is not completed yet` 或 `NOT_START`，最多重试 20 次。

## 19. 完整调用流程

```text
读取插件和宿主参数
  -> 规范化首帧/尾帧/参考图/参考视频
  -> 根据分支和变体强制比例、秒数、分辨率、模式
  -> 映射实际 API model
  -> 本地检查素材数量和格式
  -> Base64 编码或上传到 api.aione.help 获取公网 URL
  -> POST /v1/videos 或 POST /v1/chat/completions
  -> 直接结果或提取 task_id
  -> 轮询任务状态
  -> 提取 video_url/result_url/url
  -> 下载并保存 MP4
  -> 更新本地 SQLite 任务日志
```
