Files
Popiai-skill/ai-editing/relight/SKILL.md
T

147 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: relight
summary-en: Smart relighting — freely adjust light direction, intensity, and color.
summary-cn: 智能重打光,自由调整光线方向、强度和色彩
display-name-zh: 光影工作室
trigger-words: [重打光, 改打光, 打光, relight, change lighting, re-light]
description: |
上传图片后,通过 3D 灯光球面板控制光线方向 / 强度 / 色彩,选择背景模式与氛围特效,一键重新照亮画面。提供 20 种风格预设和 25 种氛围特效,也支持自由编辑最多 3 盏灯源(类型 / 角度 / 色温或 HEX)
allowed-tools: hub_open_remote_tool_gui, hub_submit_dag, hub_upload_to_cdn
version: 1.0.5
tags: [Image, Creative]
tags-cn: [图片, 创意]
exported-by: MiniMax-hub
---
# Relight
智能重打光,自由调整光线方向、强度和色彩
## 参数
| ID | 类型 | 必填 | 取值约束 | 说明 |
|----|------|------|---------|------|
| input_img | file(image/*) | 是 | — | 用户上传的原图,要被重打光的目标图片。可由主站通过 params:inject 预填 CDN URL(string,以 https:// 开头),GUI 会渲染为已上传态 |
| reference_img | file(image/png) | 是 | — | (GUI 内部自动生成)客户端用 three.js 离屏渲染当前 3D 灯光球状态后导出的 PNG。GUI 在 emit |
| light1 | string | 是 | — | (GUI 内部自动生成)第 1 盏灯的 JSON 串,形如 {\ |
| light2 | string | 是 | — | (GUI 内部自动生成)第 2 盏灯的 JSON 串,格式同 light1,无第 2 盏灯时传空字符串占位。**禁止主站通过 params:inject 注入此字段** |
| light3 | string | 是 | — | (GUI 内部自动生成)第 3 盏灯的 JSON 串,格式同 light1,无第 3 盏灯时传空字符串占位。**禁止主站通过 params:inject 注入此字段** |
| background | string | 是 | — | (GUI 内部自动生成)背景模式:default 保留原背景,black 纯黑背景,white 纯白背景。**禁止主站通过 params:inject 注入此字段** |
| effect | string | 是 | — | (GUI 内部自动生成)氛围特效业务值字符串,如 |
| user_intent | string | 否 | — | 用户的附加要求(可选,中英文均可),GUI 暴露一个输入框让用户填(如\ |
## 执行流程
### STEP 1: 打开 GUI 收集参数
调用 `hub_open_remote_tool_gui`,入参:
```ts
{
tool_name: "relight",
entry: "scripts/index.js",
initial_params?: { /* 可选,用户在对话里已经给出的具体参数,key 对齐"参数"表里的 id */ },
}
```
**预填规则**:如果用户在对话中已经明确给出某个参数的具体值,把它们打包进 `initial_params` 一并传入,GUI 挂载后会自动预填,用户无需再次输入。没明确给值的参数不要瞎猜,留给 GUI 表单收集即可。
**附件预填(本工具的 file 参数:`input_img`)**:
用户消息可能以系统自动注入的 `[User attached files: <path1>, <path2>, ...]` 开头 —— 这是文件路径,不是用户手打的文字。出现这种情况时**必须**按下表把附件路径塞进 `initial_params`,即使用户文字里没说"用这张图":
| 参数 id | accept | 取值规则 |
|---------|--------|----------|
| `input_img` | `image/*` | 附件列表中第一个匹配该 MIME 的路径 |
补充约束:
- 匹配到的本地路径先调 `hub_upload_to_cdn({ file_path: "<本地路径>" })` 获取 CDN URL,再把 URL 塞进 `initial_params[<id>]`
- 没匹配到的 file 字段:不传(留给 GUI 表单让用户上传)
- 同一字段有多张匹配:只取第一个,其余交给 GUI
示例:
- 用户消息: `[User attached files: /Users/me/face.webp]\n\n/relight`
- 先上传: `hub_upload_to_cdn({ file_path: "/Users/me/face.webp" })` → 返回 CDN URL
- 再调用: `hub_open_remote_tool_gui({ tool_name: "relight", entry: "scripts/index.js", initial_params: { input_img: "<CDN URL>" } })`
`initial_params` 仅用于调用时的预填。GUI 打开后由用户操作,不要尝试再用其他方式去操控 GUI。
GUI 提交后,系统会注入一条 user message,形如:
```
User submitted GUI form for tool "relight". Form data:
{ "params": { ... }, "files": [{ "param_id": "...", "url": "...", "name": "...", "type": "..." }] }
```
`files[].url``param_id` 匹配到对应字段(`params[<param_id>] = files[i].url`),组装出完整的 DAG inputs。**无需再次上传文件**(GUI 已通过 `sdk.uploadFile` 上传到 CDN)。
#### 收到 form data 后直接进入下一步,严格禁令
- ❌ **禁止**重新调用 `hub_open_remote_tool_gui`(无论是否改 `initial_params`)—— 用户已经在 GUI 里确认过参数,你不是产品经理,不要替用户改主意。同一 turn 内重开 GUI 会让新 link 覆盖旧 pending、UI 永远停在 "Thinking..."、用户被迫重填,直接死循环
- ❌ **禁止**在对话流输出"本次方案 / 这版思路 / 我再帮你调整一版 / 我重新设计一下"之类的二次提案文本 —— 参数已经 lock,不要"反悔"
如果你判断 GUI 提交的参数确实不合理,只有两个合法选项:(a) 照常进入下一步,让后端报错后再用错误信息向用户解释;(b) 完全终止本次任务并向用户说明原因。**绝对不是悄悄重开 GUI**。
### STEP 2: 执行 relight
**前置条件**:收到 `collect` GUI 表单提交数据。
**文件参数处理**:以下参数值若为本地路径(非 https URL),先调 `hub_upload_to_cdn({ file_path: "<本地路径>" })` 获取 CDN URL 再填入 inputs
- `input_img`
- `reference_img`
调用 `hub_submit_dag`
| 字段 | 值 |
|------|----|
| dag_id | `"510954878823452675"` |
| inputs | `{ "input_img": <params.input_img>, "reference_img": <params.reference_img>, "light1": <params.light1>, "light2": <params.light2>, "light3": <params.light3>, "background": <params.background>, "effect": <params.effect>, "user_intent": <params.user_intent> }` |
| asset_keys | `["relight_image_v4"]` |
提交后**立即结束当前 turn**(gateway 后台轮询,完成时自动注入新 user message 唤醒)。
### STEP 3: 渲染资产
收到最后一步完成消息后,注入的 user message 形如:
```
Async task completed:
{
"task_id": "<run_id>",
"status": "succeeded" | "failed" | "timeout",
"outputs": { ... },
"asset_outputs": [
{ "key": "image", "status": "finished", "url": "https://cdn...", "local_path": "..." }
],
"error_message": null
}
```
#### `status: "succeeded"`
用 markdown 媒体语法插入资产,从 `asset_outputs` 中遍历 `status == "finished"` 的条目。优先用 `local_path`(gateway 已下载到 workspace 并通过 `recordAsset` 注册到画布);若该条目无 `local_path`(本步骤未声明该 key 为 asset_keys),fallback 用 `url`
- 图片:`![描述](<asset_outputs[i].local_path \|\| asset_outputs[i].url>)`
- 视频:`![描述](<asset_outputs[i].local_path \|\| asset_outputs[i].url>)` 或链接 `[查看视频](<...>)`
- 其他文件:`[<描述>](<...>)`
⚠️ 纯文本(如「已生成」「已保存」)不会渲染媒体,**必须用 markdown 语法**。
#### `status: "failed"`
向用户报告 `error_message`,建议调整输入后重试。**不要**自动 retry。
#### `status: "timeout"`
任务已被 gateway abort(30 分钟未完成),向用户报告超时并建议稍后重试。
#### 严格禁令(适用所有步骤)
- ❌ **禁止**重新调用 `hub_open_remote_tool_gui` —— 流水线在跑,再开 GUI = 旧 link 被覆盖 + UI 卡在 "Thinking..." + 用户被迫重填,死循环
- ❌ **禁止**用 `question` / `ask` 工具通知用户等待 — UI 已有 loading 反馈
- ❌ **禁止**主动调用 `hub_query_dag_result` — gateway 会回调,主动查会浪费 turn 还可能 race condition
- ❌ **禁止**重复 `submit_dag` — 会在后端创建多个任务,消耗用户配额
-**禁止** sleep / 自旋 — 事件驱动,等待靠 gateway 注入