Funai-skill

ClawSkills 作者 amireux0013 v1.0.6

橙星梦工厂AI视频制作工具,通过对话式操作,用户可以创建项目、配置剧本、生成角色/分镜/视频、查询任务状态。当用户要求使用橙星梦工厂平台、创建 AI 漫剧项目、或通过 API 与平台交互时使用。触发词:橙星梦工厂、ai.fun.tv、漫剧制作、AI漫剧、FunAI。

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install clawskills:amireux0013~funai-skill
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aamireux0013~funai-skill/file -o funai-skill.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/26e1766f98459e997f9490d4e4857f75f49c4251
# 橙星梦工厂 Agent Skill

橙星梦工厂是一个 AI 驱动的漫剧制作平台。通过 API 创建项目、提交剧本、提取角色、生成分镜、配置成片并最终合成视频。

> **内测提示**
>
> 当前您正在使用的是 **Funai-skill 内测版**。
> Agent 在与用户交互时,应明确告知当前处于内测阶段。

> **重要结论**
>
> 真实后端不是“只看 `workflow.currentStep` 的线性流程”,而是:
>
> - 一层是项目级步骤:`workflow.currentStep`
> - 一层是章节级隐藏任务:`comicPreset.data.chapters[]` 中的 `sceneCaptionsTaskStatus`、`dialogTaskStatus`、`sceneTaskStatus`
>
> Agent 如果只看 `currentStep` 就继续调用下一步,非常容易报错。

## Skill 更新约束(创建类操作前必须执行)

**本地机器可读版本文件**:`VERSION`

> 说明:对外文案不再重复写死版本号;实际版本以本地 `VERSION` 与远端 setup 元数据中的 `latest_version / minimum_required_version` 为准。

每当 Agent 准备调用本 Skill 执行任何会创建、推进、修改平台任务的操作前,**必须先访问固定更新入口**:

`https://neirong.funshion.net/skills/setup-skill.md`

至少检查以下字段:

- `latest_version`
- `minimum_required_version`
- `force_update`
- `skill_package_url`

执行规则:

1. 如果本地尚未安装本 Skill,必须先自动安装。
2. 如果远端要求强制更新,或本地版本低于 `minimum_required_version`,必须先自动更新。
3. 版本检查完成后,才能继续执行创建项目、提交剧本、推进步骤、生图、生视频、回退、合成等操作。

## 快速配置

### 1. 获取 Token

引导用户访问 `https://ai.fun.tv/#/openclaw` 并登录,获取 Token 后由 Agent 代为写入配置文件。

### 2. 配置 Token

```bash
cp config/.env.example config/.env
# 编辑 config/.env
# AIFUN_TOKEN=...
```

### 3. 验证配置

```bash
./scripts/api-client.sh setup-check
./scripts/api-client.sh check
```

### 4. 运行完整自检示例

```bash
./examples/create-comic.sh
```

> 示例脚本是**自检脚本**,会使用 `select-options` 返回的实时默认值自动创建测试项目。
>
> 面向真实用户的 Agent 交互中,仍然必须先读取实时可选项;其中 `aspect / style` 必须展示给用户并让用户选择,`generateType / scriptType` 可按当前默认值静默使用,`model / videoModel` 在用户未指定时可继续使用实时默认值。
>
> 另外,示例脚本为了验证整条链路,会在自检场景下先提交剧本再展示“确认点”;这不代表真实用户交互可以跳过“先确认再继续”的节奏要求。

## Agent 必须遵守的执行规则

### 0. 默认模式静默使用,不要主动向用户解释

除非用户明确提出要切换模式,否则 Agent 应直接使用平台默认模式:

- `generateType = 1`(文生图)
- `scriptType = 解说漫模式`(以 `select-options` 返回的默认剧本模式为准)

但这条“静默默认”**只适用于模式层级**,不适用于项目视觉配置。

创建项目时,以下两个字段**不能静默默认**,必须让用户明确选择:

- `aspect`(画面比例)
- `style`(风格)

**重要**:

- 这是 Agent 的内部默认决策,不要主动把“现在默认使用文生图 / 解说漫模式”当成一个需要告诉用户的配置项。
- 只有当用户明确要求切换到其他模式时,才需要说明并调整。
- 即使静默使用默认模式,底层仍然必须先调 `select-options`,并使用当次接口返回的默认值,而不是写死常量。
- `aspect / style` 不能因为接口返回了 `isDefault` 就直接替用户决定,必须向用户展示可选项并让用户确认。

### 1. 创建项目前必须先调 `select-options`

```bash
POST /service/workflow/project/story/select-options
{"appCode":"ai-story","generateType":"1"}
```

规则:

- 必须使用接口返回的 `ratios`、`generateTypes`、`models`、`videoModels`、`styles`、`scriptTypes`
- **禁止**硬编码风格、模型、比例、剧本类型
- `isDefault` 是**请求相关**的,不要把历史默认值写死在代码或文档里
- 如果用户没有明确要求切换模式,则直接静默使用当次接口返回的默认 `generateType / scriptType`
- 但 `aspect / style` 必须向用户展示并让用户选择,不能静默默认
- `model / videoModel` 若用户没有额外要求,可以继续使用 `select-options` 返回的当前默认值
- 面向用户交互时,不需要主动把“文生图 / 解说漫模式”当作默认项拿出来解释;但必须明确让用户选择 `aspect / style`

### 2. 解说剧 / 解说漫模式下,AI 代写剧本必须写成旁白叙述式小说体

如果用户让 AI 帮忙写剧本,而当前走的是**解说剧 / 解说漫模式**,Agent 必须把剧本写成**旁白叙述式的小说 / 故事正文**,而不是分镜脚本。

必须符合:

- 连续叙事
- 以旁白持续讲述故事推进为主
- 可以穿插少量自然对白,但整体仍应是讲述型正文
- 适合后续交给平台自动拆分角色、分镜与解说

禁止出现这类写法:

- `镜头1` / `镜头2`
- `旁白:...` 这种显式台本标签
- `林舟说:...`
- `【音效:脚步声】` / `砰!` / `咚——` 这类音效描述
- 舞台说明式条目
- 分镜表 / 台本格式

正确风格示意:

```text
清晨,城市公园的林荫道上,年轻人林舟正在慢跑。阳光穿过树叶,在青石板路上投下斑驳的金色光影。

他刚想加快脚步,一只金毛犬忽然从灌木旁窜了出来,差点撞上他的膝盖。林舟猛地停住脚步,呼吸一乱,循声抬头望去。

不远处,一个扎着马尾的女孩正快步跑来。她一边抓紧手里的牵引绳,一边有些不好意思地朝林舟笑了笑。
```

错误风格示意:

```text
镜头1:公园远景。
旁白:清晨的城市公园里,林舟正在跑步。
林舟说:今天一定要把状态跑出来。
镜头2:金毛犬冲出。
```

### 3. 创建项目成功后,先展示项目链接

创建成功后必须立即把项目链接告诉用户:

```text
https://ai.fun.tv/#/comic/multiple?projectId={projectId}
```

### 4. 不要只看 `workflow.currentStep`

以下三类 readiness 都要检查:

| 场景 | 检查位置 | 继续条件 |
|------|----------|----------|
| 项目处于哪个大步骤 | `GET /project/{projectId}` → `workflow.currentStep` | 当前步骤正确 |
| 角色图是否完成 | `GET /comic/roles/{presetResourceId}` → `roles[].taskStatus` / `imgUrl` | 全部 `SUCCESS` 且 `imgUrl` 非空 |
| 章节级隐藏任务是否完成 | `GET /resource/comicPreset/{presetResourceId}` → `chapters[]` | 对应状态字段为 `SUCCESS` |

### 5. 不要硬编码 `tts` / `voice-clone-select` 输入

`novel_extract_roles` 不是只传 `chapterNum` 就够。真实可运行的做法是:

1. 先调 `GET /comic/roles/{presetResourceId}`
2. 从 `data.voiceInputs[0]` 或 `data.roles[0].inputs[0]` 取出 live 的 `tts` 输入对象
3. 将它和 `chapterNum` 一起提交

### 6. 不要把 `sceneUuid` 当 `sceneId`

`scene-list` 里的 `sceneUuid` 只是短 ID,不能直接用于分镜/视频接口。

正确流程:

```text
comicPreset/{presetResourceId}
→ chapters[].sceneTaskId
→ GET /task/{sceneTaskId}
→ data.resourceId (storyboardId)
→ GET /resource/{storyboardId}
→ data.data.scenes[].id (完整 sceneId)
```

### 7. 优先向用户返回 `videoPlayUrl`

如果后端返回了新的可播放字段:

- scene 视频资源:`videoPlayUrl`
- 最终成片资源:`videoPlayUrl`

则正确做法是:

- 对外只返回 `videoPlayUrl`
- 高层 helper、示例脚本、模型可见输出中不要暴露原始视频 `url`
- 项目链接仍可作为补充入口一起返回

### 8. `scene/ai/video` 必须使用 scene 当前基准分镜图

图转视频的正确图片来源是当前 scene 的**基准分镜图**:

- 优先使用 `GET /storyboard/scene/{sceneId}/prompt/detail?sceneId={sceneId}` 中的 `video.imageId`
- 再到 `GET /storyboard/scene/{sceneId}/resources` 中找到与这个 `imageId` 对应的 image 资源
- 如果当前仍有 `selected == true` 的 image,它通常就是同一张图

不要直接使用:

- `GET /comic/roles/{presetResourceId}` 返回的 `roles[].imgUrl`

**重要**:这不是“后端一定会报错”的约束,而是“Agent 必须主动保证语义正确”的约束。

live 测试里,后端接受了 `roles[].imgUrl + roles[].imageResourceId`,并成功生成了一条 video 资源。也就是说,传错图时接口可能仍然返回 `200 success`,但生成出来的是**语义错误的视频**。

所以:

- 正确图源 = scene 当前基准分镜图(优先 `video.imageId` 对应的 image)
- 错误图源 = 角色图 / 其他非当前 scene 图片
- 不要依赖后端帮你兜底

## 面向 Agent 的权威执行顺序

### 第 0 步:先做 setup 检查

先读取 `https://neirong.funshion.net/skills/setup-skill.md`,确认本地 skill 版本可用。

### 第 1 步:获取项目可选项

```bash
POST /service/workflow/project/story/select-options
{"appCode":"ai-story","generateType":"1"}
```

### 第 2 步:创建项目

使用上一步接口返回的实时值创建项目。

> live 后端通常会让 `novel_config` 自动完成,所以项目创建后常见的 `currentStep` 是 `novel_input`,这是正常现象。

> 如果用户没有特别说明,不要额外告诉用户“当前默认使用文生图 / 解说漫模式”。
>
> 但在真正创建项目之前,必须先让用户明确选择:
>
> - 画面比例 `aspect`
> - 风格 `style`
>
> 只有这两个字段确认后,才可以结合实时默认的 `generateType / scriptType / model / videoModel` 创建项目。

### 第 3 步:提交剧本

```bash
POST /service/workflow/project/step/next
{
  "userProjectId": "项目ID",
  "step": "novel_input",
  "inputs": [
    {"name": "content", "type": "text", "value": "剧本内容"},
    {"name": "scriptType", "type": "text", "value": "0"},
    {"name": "isSplit", "type": "text", "value": "0"}
  ]
}
```

返回 `resultId` 后轮询 `GET /task/{resultId}`。

如果剧本是 AI 代写,并且当前是解说剧 / 解说漫模式,则剧本正文必须保持**旁白叙述式小说体**,不要写成分镜脚本,也不要写音效描述。

### 第 4 步:智能分集

```bash
POST /service/workflow/project/step/next
{"userProjectId":"项目ID","step":"novel_opt","inputs":[]}
```

返回 `resultId` 后轮询任务。

### 第 5 步:等待角色图完成,再执行角色步骤

先调:

```bash
GET /service/workflow/comic/roles/{presetResourceId}
```

必须满足:

- `roles[].taskStatus == SUCCESS`
- `roles[].imgUrl` 非空

然后再调:

```json
POST /service/workflow/project/step/next
{
  "userProjectId": "项目ID",
  "step": "novel_extract_roles",
  "inputs": [
    {"type": "number", "name": "chapterNum", "value": 1},
    { ...来自 roles/voiceInputs 的 tts 输入对象... }
  ]
}
```

如果跳过这一步,常见报错是:

- `角色 [xxx] 图片未完成`

如果用户在这一阶段要求修改角色形象,则必须满足:

1. 当前 `workflow.currentStep == novel_extract_roles`
2. 先对目标角色发起新图生成
3. 等待新图在角色候选图列表里变成 `SUCCESS` 且 `imgUrl` 非空
4. 再显式应用这张新图
5. 最后重新读取角色列表,确认角色主图已切换,并把新的图片 URL 返回给用户

只生图不应用,不算修改完成。

### 第 6 步:等待 `sceneCaptionsTaskStatus=SUCCESS`,再执行智能分镜

先调:

```bash
GET /service/workflow/resource/comicPreset/{presetResourceId}
```

等待:

```text
chapters[chapterNum].sceneCaptionsTaskStatus == SUCCESS
```

补充说明:live 数据里,这类章节字段在短时间内可能先出现空值,再进入 `RUNNING / SUCCESS`。空值不一定代表异常,更不能据此提前推进下一步。

然后再调:

```json
POST /service/workflow/project/step/next
{
  "userProjectId": "项目ID",
  "step": "novel_scene_captions",
  "inputs": [
    {"type": "number", "name": "chapterNum", "value": 1},
    {"name": "imgGenTypeRef", "value": 1}
  ]
}
```

这个步骤返回的是 **`dialogTaskId`**,不是 `resultId`。

如果调早了,常见报错是:

- `该章节提取分镜场景任务未完成,请稍后再试`

### 第 7 步:轮询 `dialogTaskId` 后,还要再等 `sceneTaskStatus=SUCCESS`

轮询 `dialogTaskId` 成功后,仍然不能立刻推进到成片。

还需要再看:

```text
chapters[chapterNum].sceneTaskStatus == SUCCESS
```

补充说明:live 数据里,`sceneTaskStatus` 在一段时间内可能为空,再变成 `SUCCESS`;判断 readiness 时应继续轮询,而不是把空值直接当失败。

如果调早了,常见报错是:

- `该章节分镜图任务未完成,请稍后再试`

### 第 8 步:推进到成片步骤

等 `sceneTaskStatus=SUCCESS` 后,再调:

```json
POST /service/workflow/project/step/next
{
  "userProjectId": "项目ID",
  "step": "novel_chapter_scenes",
  "inputs": [{"type": "number", "name": "chapterNum", "value": 1}]
}
```

### 第 9 步:解析 st