cortico-world-image 0.3.1 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ENV_PROMPT.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## 四个工具
4
4
 
5
5
  - `image_draw`:按一段文字描述画一张新图。图会存到磁盘、附加进本次对话(你自己看得到)、并显示在控制台「图片工坊 → 作品」页。
6
- - `image_edit`:拿一张已有的图按指令改(换风格、改细节)。`image` 给绝对路径,或 `image_gallery` 里的编号。服务端支不支持改图由接口决定,报错就照实告诉用户。
6
+ - `image_edit`:拿一张已有的图按指令改(换风格、改细节)。`image` 给绝对路径,或 `image_gallery` 里的编号。`size` 一般不传(本地 ComfyUI 那档会照参考图的比例出图);要固定尺寸就写 `宽x高`。服务端支不支持改图由接口决定,报错就照实告诉用户。
7
7
  - `image_gallery`:列出画过的图,最新的在前,带编号和绝对路径。编号可以交给 `image_show` 或 `image_edit`。
8
8
  - `image_show`:把一张旧图重新放回眼前(重新附加进对话,并在作品页高亮)。
9
9
 
@@ -11,6 +11,11 @@
11
11
 
12
12
  当前接口状态:`{{image.ready | 未知。不确定就别调用,先告诉用户去控制台「图片工坊 → 状态」看看。}}`
13
13
 
14
+ ## 模型链
15
+
16
+ 后台可能配了一串模型(「图片工坊 → 状态 → 模型链」),本地 ComfyUI 和云端接口都在里面,按顺序试:
17
+ 前一档连不上、超时、额度用完、模型没装,就自动换下一档;回执里会写「前几档没成」和最后用的是哪一档。
18
+
14
19
  ## 规矩
15
20
 
16
21
  1. **别每轮都画。** 用户明确想看/想让你画,或者确实需要一张图来解释、来送人,才调用。闲聊、讨论、解释概念都不需要配图。
package/README.md CHANGED
@@ -22,8 +22,8 @@
22
22
 
23
23
  | 工具 | 标签 | 作用 |
24
24
  | --- | --- | --- |
25
- | `image_draw` | `act` | 按文字描述画一张新图,落盘、记进索引 |
26
- | `image_edit` | `act` | 拿一张已有的图按指令改(支持上传改图,或阿里云百炼式的 `image` 扩展字段) |
25
+ | `image_draw` | `act` | 按文字描述画一张新图,落盘、记进索引(可带 `model` 点名用哪一档) |
26
+ | `image_edit` | `act` | 拿一张已有的图按指令改(支持上传改图,或阿里云百炼式的 `image` 扩展字段;同样能带 `model`) |
27
27
  | `image_gallery` | `read` | 列出画过的图,带编号与绝对路径 |
28
28
  | `image_show` | `speak` | 把一张旧图重新放回对话与作品页 |
29
29
 
@@ -167,9 +167,9 @@ pet_say({ script: '看,画好了。', images: ['<句柄>'] }) // 气泡里说
167
167
  修法是抬版本 + 重启,主程序会在 Core 就绪时自动重载控制台外壳(
168
168
  `resources\app\app\main.cjs:285` `if (settings) settings.loadURL(consoleUrl());`):
169
169
 
170
- 1. 把 `package.json` 的 `version` 抬一格(例如 `0.3.1` → `0.3.2`);
170
+ 1. 把 `package.json` 的 `version` 抬一格(例如 `0.5.0` → `0.5.1`);
171
171
  2. 重启控制台(状态页「重启控制台」或 `node tools/patch.mjs --restart`);
172
- 3. 程序内窗口自动重载 → 新的 URL `/assets/extensions/cortico-world-image/0.3.1/webui.js`
172
+ 3. 程序内窗口自动重载 → 新的 URL `/assets/extensions/cortico-world-image/0.5.1/webui.js`
173
173
  取到新脚本,旧 URL 立刻变 404。
174
174
 
175
175
  不想抬版本也行,但要**先完全退出程序**再删缓存目录:`<安装>\data\Cache`、
@@ -205,7 +205,7 @@ registry 上有版本时直接从 npm 装;想自己改代码、或者 `npm vie
205
205
  或者用命令行,在 `data/extensions` 目录里(`extensions/package.json` 所在处)执行:
206
206
 
207
207
  ```powershell
208
- pnpm add cortico-world-image --ignore-workspace # 想钉住版本就写 cortico-world-image@0.3.1
208
+ pnpm add cortico-world-image --ignore-workspace # 想钉住版本就写 cortico-world-image@0.5.1
209
209
  ```
210
210
 
211
211
  装完重启。升级同理:重跑一遍(控制台的「扩展」页会显示已装版本与最新版本),装完同样要重启。
@@ -266,10 +266,11 @@ pnpm add "D:\path\to\cortico-world-image" --ignore-workspace
266
266
  | 键 | 默认 | 说明 |
267
267
  | --- | --- | --- |
268
268
  | `enabled` | `false` | 是否把四个工具挂给桌宠 |
269
- | `baseUrl` | `https://api.openai.com/v1` | OpenAI 兼容的图片接口根地址 |
269
+ | `baseUrl` | `https://api.openai.com/v1` | OpenAI 兼容的图片接口根地址(没配 `models` 时用它) |
270
270
  | `apiKeySecret` | `IMAGE_API_KEY` | 密钥的**变量名**:先看部署 `.env`,再退到同级的端点 `.env` |
271
- | `model` | `gpt-image-1` | 模型名 |
272
- | `size` | `1024x1024` | 尺寸,`auto` 或留空就不发这个参数 |
271
+ | `model` | `gpt-image-1` | 模型名(没配 `models` 时用它) |
272
+ | `models` | 空 | 模型链:一串后端按优先级顺序试,见下面「模型链」(0.4.0 起) |
273
+ | `size` | `1024x1024` | 尺寸:`1024x1536`、比例 `16:9`/`4:3`、或 `square`/`portrait`/`landscape`;`auto` 或留空=不指定(云端不发这个参数,本地按图生图规则处理) |
273
274
  | `quality` | `auto` | `low`/`medium`/`high` 或 `standard`/`hd`;`auto` 不发 |
274
275
  | `format` | `png` | 接口没给格式时按这个存盘(`png`/`jpeg`/`webp`) |
275
276
  | `timeoutMs` | `180000` | 单次画图等待上限 |
@@ -277,6 +278,71 @@ pnpm add "D:\path\to\cortico-world-image" --ignore-workspace
277
278
  | `keep` | `200` | 超出后自动删最旧的,`0` = 不清理 |
278
279
  | `pushToConsole` | `true` | 画完实时推给「作品」页 |
279
280
 
281
+ ### 模型链:一串后端按顺序试(0.4.0)
282
+
283
+ `worlds.image.models` 是一份 JSON 数组,**数组顺序就是优先级**。前档连不上、超时、额度用完、
284
+ 模型没装、参数不支持时自动换下一档;只有「内容审核拦了提示词」这类换谁都一样的错才不换。
285
+ 状态页的「模型链」卡片里它就是**一串小卡片**(见下),不用手写 JSON。
286
+
287
+ ```json
288
+ [
289
+ { "name": "local", "preset": "comfyui", "baseUrl": "http://127.0.0.1:8188", "ckpt": "sd_xl_base_1.0.safetensors" },
290
+ { "name": "cloud", "preset": "openai", "baseUrl": "https://api.openai.com/v1", "model": "gpt-image-1" }
291
+ ]
292
+ ```
293
+
294
+ 留空 = 用上面那套单档 `baseUrl` + `model`。两种 `preset`:
295
+
296
+ - `openai`:原有的 OpenAI 兼容接口(`/images/generations`、`/images/edits`),要密钥。
297
+ - `comfyui`:本地 ComfyUI(默认 `http://127.0.0.1:8188`),**不要密钥**,但要写模型文件:
298
+ `ckpt`(checkpoint 文件名,就是 `ComfyUI/models/checkpoints/` 里那个),或者 **裸 UNet 三件套**
299
+ `unet` + `textEncoder` + `vaeName`(Anima、Flux 这类不是 all-in-one 的模型;填了 `unet` 就不看 `ckpt`)。
300
+
301
+ 每档都能写这些。`baseUrl` / `model` / `apiKeySecret` / `size` / `quality` / `format` / `timeoutMs` 不写就继承
302
+ `worlds.image` 的单档设置;其余(`ckpt`、`loras`、采样参数等)只有链里的档才有,按下面的默认值走:
303
+
304
+ | 键 | 说明 |
305
+ | --- | --- |
306
+ | `name` | 这一档的名字;面板与报错里用它,工具参数 `model` 也按它点名 |
307
+ | `preset` | `openai` / `comfyui` |
308
+ | `baseUrl` / `model` / `apiKeySecret` / `size` / `quality` / `format` / `timeoutMs` | 同上面那张表 |
309
+ | `ckpt` | ComfyUI 的 checkpoint 文件名(`comfyui` 必填,除非写了 `unet`) |
310
+ | `unet` / `textEncoder` / `vaeName` | 裸 UNet 三件套:`ComfyUI/models/diffusion_models`、`text_encoders`、`vae` 里的文件名。**填了 `unet` 就顶掉 `ckpt`**,只出裸 UNet 那份工作流 |
311
+ | `textEncoderType` | `unet` 的文本编码器类型,默认 `stable_diffusion`;Qwen 系编码器填 `qwen_image`(还认 `sd3` / `flux` / `cosmos` / `lumina2`) |
312
+ | `loras` | ComfyUI 的 LoRA:`["add_detail.safetensors:0.6", {"name":"x.safetensors","strength":0.4,"clipStrength":0.25}]`(名字带扩展名,文件得先在 ComfyUI 的 `models/loras` 里) |
313
+ | `steps` / `cfg` / `sampler` / `scheduler` / `denoise` / `negative` | ComfyUI 采样参数(默认 25 / 7 / euler / normal / 0.6)。`denoise` 在改图时就是改动幅度:0.6 起改得明显,只微调用 0.2~0.35 |
314
+ | `workflow` | 自定义 ComfyUI API 工作流(对象)。给了就整份替换内置模板,占位符见下 |
315
+ | `edit` | `false` = 这一档只用来画、不接改图(改图会跳到下一档) |
316
+ | `enabled` | `false` = 跳过这一档 |
317
+
318
+ 工具参数 `model` 可以点名某一档(`name`、`ckpt` 或 `model` 三者之一):点了名就**只用那一档**,
319
+ 失败了直接报错、不偷偷换——想让它自己挑就别传 `model`。
320
+
321
+ 状态页的「模型链」卡片默认就是友好编辑:一档一张小卡片,填「名称 / 类型 / 地址 / 模型或 ckpt」,
322
+ 用「上移 / 下移」调优先级、「删除」去掉一档,「+ 本地 ComfyUI」「+ 云端接口」加档。
323
+ 本地 ComfyUI 那档还多一个「高级参数」按钮:能加**多行 LoRA**(文件名 / 强度 / CLIP 强度,文件名要带
324
+ 扩展名、可带子目录),也能改 `negative`、`steps`、`cfg`、`sampler`、`scheduler`、`denoise`,
325
+ 以及**裸 UNet 三件套**(`unet` / `textEncoder` / `textEncoderType` / `vaeName`;填了它就忽略这一档的 `ckpt`)
326
+ ——存的就是该档的 `loras`、`negative`、`steps`、`unet` 这些字段,等于面板版的「高级:JSON」。
327
+ 保存就是写 `worlds.image.models`;`workflow` 这类只能手写的字段仍点「高级:JSON」改原文——**链还空着时它自带一份现成范例**
328
+ (一档本地 ComfyUI,带 `ckpt`、两条 LoRA、采样参数与负面提示;一档云端),
329
+ 把 `ckpt` / `loras` 换成自己 `models` 里的文件名,「应用 JSON」再「保存模型链」就能用。
330
+ 「测试模型链」会挨档探活:ComfyUI 看 `/system_stats`,再用 `/object_info` 一次性核对 `ckpt`(或
331
+ `unet` / `textEncoder` / `vaeName`)在不在;OpenAI 兼容看 `/models`(端点没这条路由也算在线)。
332
+ 探活每档最多等 6 秒;链上有没保存的改动时会先拦住。
333
+
334
+ #### ComfyUI 这档会调哪些路
335
+
336
+ `POST /prompt`(提交工作流)、`GET /history/<prompt_id>`(轮询等结果)、`GET /view?filename=…`
337
+ (取成品图)、`POST /upload/image`(改图时把参考图放进 `input/`)、`POST /interrupt`(超时收尾)、
338
+ `GET /system_stats`、`GET /object_info`(核对模型文件名,拿不到就跳过核对)。
339
+
340
+ 不会替你去下模型:checkpoint 与 LoRA 得先放进 ComfyUI 的 `models/checkpoints` 与 `models/loras`,
341
+ `ckpt` 写文件名(在子目录里就写相对路径);裸 UNet 的三个文件放进 `models/diffusion_models`、
342
+ `models/text_encoders`、`models/vae`。自定义 `workflow` 里可用的占位符:
343
+ `prompt`、`negative`、`ckpt`、`width`、`height`、`size`、`steps`、`cfg`、`sampler`、`scheduler`、
344
+ `seed`、`denoise`、`image`、`loras`、`prefix`、`filename`(写成 `{{prompt}}` 这样,认不出的原样留着)。
345
+
280
346
  ### 密钥
281
347
 
282
348
  密钥**不写进 `config.json`**。两种填法:
@@ -392,6 +458,8 @@ cortico-world-image/
392
458
  │ ├─ definition.js # id/label/defaults/preflight/create
393
459
  │ ├─ config.js # worlds.image 默认值、中英文案、配置组 schema
394
460
  │ ├─ world.js # ImageWorld:工具、控制台面板、流式推送、生命周期
461
+ │ ├─ chain.js # 模型链:解析 worlds.image.models、排序、逐档回退、报错归纳
462
+ │ ├─ comfyui.js # 本地 ComfyUI 适配器(内置工作流 / 自定义 workflow / 改图 / 探活)
395
463
  │ ├─ chat-image-patch.js # QQ 发图路径的 2 处可选补丁、旧桌宠补丁还原、状态文件、重启请求(自愈核心)
396
464
  │ ├─ api.js # OpenAI 兼容客户端的取图/落盘/错误归一化
397
465
  │ ├─ gallery.js # 作品仓库:目录 + index.json
@@ -418,6 +486,20 @@ cortico-world-image/
418
486
  - `image_edit` 先走 `/images/edits`(multipart 上传);端点没这条路由(404/405)时自动退回
419
487
  `/images/generations` 的 `image` 扩展字段(data URI,阿里云百炼那类)。两条路都不通时会回一条
420
488
  带 HTTP 码的错误,不是静默失败。
489
+ - 尺寸:`size` 能写 `1024x1536`、比例 `16:9` / `4:3`、或 `square` / `portrait` / `landscape`(中文
490
+ `竖图` / `横图` / `方图` 也认),比例会换成一套对齐好的尺寸(16:9 → 1344×768,4:3 → 1152×864);
491
+ 写死的数字只按 latent 要求对齐到 8,不动你写的整数。
492
+ - 改图的尺寸:ComfyUI 那档**不传 `size`、或写 `auto`,就照参考图的比例**出图(最长边压到 1536、对齐
493
+ 16),传了 `size` 就按给的;云端那档走接口自己的默认(一般不传尺寸)。所以改一张 1600×1200 的图
494
+ 会出 1536×1152,不会变成方图。图生图的回执/作品页记的是**实际出的尺寸**,不再是 `auto`。
495
+ - 模型链的 ComfyUI 那档**不会替你下模型**:checkpoint / LoRA 得先放进 ComfyUI 的
496
+ `models/checkpoints`、`models/loras`,`ckpt` 写文件名;本机没开 ComfyUI 时这档直接算不可用,
497
+ 链会落到下一档。**裸 UNet 要放 `models/diffusion_models`**(老版本是 `models/unet`),放错到
498
+ `checkpoints` 里会被当成 checkpoint、`UNETLoader` 那边永远看不到——这种时候插件会把 ComfyUI 的
499
+ 校验错误翻成人话:缺哪个字段、给了什么值、它现在认哪些名字、文件该放哪个目录。
500
+ - 用错加载方式也会解释:拿 checkpoint 节点去开一个没有 CLIP / VAE 的裸模型时,ComfyUI 只丢一句
501
+ `clip input is invalid: None`,插件会说明「这是裸模型 → 改用模型文件三件套、文件放 diffusion_models」;
502
+ 显存不足、缺自定义节点也各有对应的一句话。
421
503
  - 只有 Windows 上的「打开文件夹」会真的弹资源管理器;其他平台返回一句说明。
422
504
  - 画图本身要联网,只有自检样图是纯本地的。
423
505
 
package/describe.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "tools": [
3
3
  {
4
4
  "name": "image_draw",
5
- "description": "Draw a picture from a text description through the configured image API. The picture is saved to disk, attached to this conversation so you can see it, and shown in the Image Studio console page. The reply carries the absolute file path; hand that path to a channel tool such as qq_send_image to actually deliver the picture to someone.",
5
+ "description": "Draw a picture from a text description through the configured model chain (a local ComfyUI, an OpenAI-compatible cloud endpoint, or both in priority order). The picture is saved to disk, attached to this conversation so you can see it, and shown in the Image Studio console page. The reply carries the absolute file path; hand that path to a channel tool such as qq_send_image to actually deliver the picture to someone.",
6
6
  "parameters": {
7
7
  "type": "object",
8
8
  "properties": {
@@ -10,17 +10,21 @@
10
10
  "type": "string",
11
11
  "description": "What to draw: subject, style, composition, lighting. Any language."
12
12
  },
13
+ "model": {
14
+ "type": "string",
15
+ "description": "Optional chain entry name (for example \"local\" or \"cloud\"). Leave empty to try the chain in priority order."
16
+ },
13
17
  "note": {
14
18
  "type": "string",
15
19
  "description": "Short label for this picture in the studio list."
16
20
  },
17
21
  "size": {
18
22
  "type": "string",
19
- "description": "Override the configured size, e.g. 1024x1024 or 1024x1536."
23
+ "description": "Override the configured size: \"1024x1536\", a ratio like \"16:9\" or \"4:3\", or \"square\" / \"portrait\" / \"landscape\"."
20
24
  },
21
25
  "quality": {
22
26
  "type": "string",
23
- "description": "Override the configured quality, e.g. low / medium / high."
27
+ "description": "Override the configured quality, e.g. low / medium / high. Ignored by ComfyUI."
24
28
  }
25
29
  },
26
30
  "required": [
@@ -31,13 +35,13 @@
31
35
  "act"
32
36
  ],
33
37
  "summary": {
34
- "zh": "按一段文字描述画一张新图,存到磁盘、贴进对话,并显示在作品页。",
35
- "en": "Draw a new picture from a text description, save it to disk and show it in the conversation."
38
+ "zh": "按一段文字描述画一张新图(本地 ComfyUI 或云端接口,按模型链的顺序),存到磁盘、贴进对话,并显示在作品页。",
39
+ "en": "Draw a new picture from a text description through the model chain, save it to disk and show it in the conversation."
36
40
  }
37
41
  },
38
42
  {
39
43
  "name": "image_edit",
40
- "description": "Redraw an existing local picture with the image API, following a text instruction. `image` takes an absolute file path, or a picture id from image_gallery. Works with endpoints that implement /images/edits (multipart upload) and with those that take a base64 `image` field on /images/generations instead (e.g. Aliyun Bailian).",
44
+ "description": "Redraw an existing local picture following a text instruction, through the same model chain as image_draw. `image` takes an absolute file path, or a picture id from image_gallery. OpenAI-compatible entries use /images/edits (multipart upload) or a base64 `image` field on /images/generations (e.g. Aliyun Bailian); ComfyUI entries upload the picture and run an img2img workflow.",
41
45
  "parameters": {
42
46
  "type": "object",
43
47
  "properties": {
@@ -49,17 +53,21 @@
49
53
  "type": "string",
50
54
  "description": "Absolute path of the source picture, or a picture id from image_gallery."
51
55
  },
56
+ "model": {
57
+ "type": "string",
58
+ "description": "Optional chain entry name. Leave empty to try the chain in priority order."
59
+ },
52
60
  "note": {
53
61
  "type": "string",
54
62
  "description": "Short label for the result in the studio list."
55
63
  },
56
64
  "size": {
57
65
  "type": "string",
58
- "description": "Override the configured size."
66
+ "description": "Override the output size: \"1024x1024\", a ratio like \"16:9\", or \"square\" / \"portrait\" / \"landscape\". Leave it empty to keep the source picture ratio (local ComfyUI) — that is the usual choice for edits."
59
67
  },
60
68
  "quality": {
61
69
  "type": "string",
62
- "description": "Override the configured quality."
70
+ "description": "Override the configured quality. Ignored by ComfyUI."
63
71
  }
64
72
  },
65
73
  "required": [
@@ -126,7 +134,7 @@
126
134
  "key": "worlds.image.envPrompt",
127
135
  "title": "环境说明(图片工坊)",
128
136
  "role": "envPrompt",
129
- "content": "你可以作画。这一节说明工具箱和规矩。\n\n## 四个工具\n\n- `image_draw`:按一段文字描述画一张新图。图会存到磁盘、附加进本次对话(你自己看得到)、并显示在控制台「图片工坊 → 作品」页。\n- `image_edit`:拿一张已有的图按指令改(换风格、改细节)。`image` 给绝对路径,或 `image_gallery` 里的编号。服务端支不支持改图由接口决定,报错就照实告诉用户。\n- `image_gallery`:列出画过的图,最新的在前,带编号和绝对路径。编号可以交给 `image_show` 或 `image_edit`。\n- `image_show`:把一张旧图重新放回眼前(重新附加进对话,并在作品页高亮)。\n\n图片保存目录:`{{image.dir | 尚未确定;先看控制台「图片工坊 → 状态」。}}`\n\n当前接口状态:`{{image.ready | 未知。不确定就别调用,先告诉用户去控制台「图片工坊 → 状态」看看。}}`\n\n## 规矩\n\n1. **别每轮都画。** 用户明确想看/想让你画,或者确实需要一张图来解释、来送人,才调用。闲聊、讨论、解释概念都不需要配图。\n2. **一次画一张。** 想要不同方向就画一张、看一眼、再决定要不要重画或改。不要一次调好几个 `image_draw` 碰运气。\n3. **描述要具体。** 主体、画风、构图、光线、色调、背景,一句到位;别只给两三个词,也别把整段聊天记录塞进去。\n4. **说人话,不念路径。** 回执里的绝对路径是给工具用的,不是给用户看的。画完就用一句自然的话告诉用户画了什么,像 `pet_say` 那样说话。不要把路径、编号、`blobs`、JSON 念出来,也不要贴 Markdown 图片语法。\n5. **发到别处要另走一步。** 图默认只在你自己的界面里。\n - 想让主人在控制台的「对话」页看到它,画完之后调桌宠的 `pet_say`,`images` 填回执里 `[blob …]` 行的句柄(就是 `[blob ` 后面那一串),`script` 给空串就只贴图不出声;想配一句话就写进 `script`(那句话会在气泡里说出来)。图只进「对话」页,不进气泡。\n - 要发到 QQ 会话:把回执里 `[blob …]` 行的句柄交给 QQ 世界的发图工具。官方 QQ 扩展用 `qq_draft`(`image` 填句柄,`to` 填 `group:<群号>` 或 `private:<QQ号>`,再用 `qq_confirm` 确认发送);旧版 QQ 扩展(`qqbot`)用 `qq_send_image`,`image` 填回执里的绝对路径。\n6. **失败就停。** 如果回执说没配密钥、接口报错、超时,不要换个说法反复重试。把情况告诉用户,让他去控制台「图片工坊 → 状态」里填密钥或改接口地址。\n7. **别凭空说画好了。** 只有工具回执真的带着图回来,才算画好了。\n"
137
+ "content": "你可以作画。这一节说明工具箱和规矩。\n\n## 四个工具\n\n- `image_draw`:按一段文字描述画一张新图。图会存到磁盘、附加进本次对话(你自己看得到)、并显示在控制台「图片工坊 → 作品」页。\n- `image_edit`:拿一张已有的图按指令改(换风格、改细节)。`image` 给绝对路径,或 `image_gallery` 里的编号。`size` 一般不传(本地 ComfyUI 那档会照参考图的比例出图);要固定尺寸就写 `宽x高`。服务端支不支持改图由接口决定,报错就照实告诉用户。\n- `image_gallery`:列出画过的图,最新的在前,带编号和绝对路径。编号可以交给 `image_show` 或 `image_edit`。\n- `image_show`:把一张旧图重新放回眼前(重新附加进对话,并在作品页高亮)。\n\n图片保存目录:`{{image.dir | 尚未确定;先看控制台「图片工坊 → 状态」。}}`\n\n当前接口状态:`{{image.ready | 未知。不确定就别调用,先告诉用户去控制台「图片工坊 → 状态」看看。}}`\n\n## 模型链\n\n后台可能配了一串模型(「图片工坊 → 状态 → 模型链」),本地 ComfyUI 和云端接口都在里面,按顺序试:\n前一档连不上、超时、额度用完、模型没装,就自动换下一档;回执里会写「前几档没成」和最后用的是哪一档。\n\n## 规矩\n\n1. **别每轮都画。** 用户明确想看/想让你画,或者确实需要一张图来解释、来送人,才调用。闲聊、讨论、解释概念都不需要配图。\n2. **一次画一张。** 想要不同方向就画一张、看一眼、再决定要不要重画或改。不要一次调好几个 `image_draw` 碰运气。\n3. **描述要具体。** 主体、画风、构图、光线、色调、背景,一句到位;别只给两三个词,也别把整段聊天记录塞进去。\n4. **说人话,不念路径。** 回执里的绝对路径是给工具用的,不是给用户看的。画完就用一句自然的话告诉用户画了什么,像 `pet_say` 那样说话。不要把路径、编号、`blobs`、JSON 念出来,也不要贴 Markdown 图片语法。\n5. **发到别处要另走一步。** 图默认只在你自己的界面里。\n - 想让主人在控制台的「对话」页看到它,画完之后调桌宠的 `pet_say`,`images` 填回执里 `[blob …]` 行的句柄(就是 `[blob ` 后面那一串),`script` 给空串就只贴图不出声;想配一句话就写进 `script`(那句话会在气泡里说出来)。图只进「对话」页,不进气泡。\n - 要发到 QQ 会话:把回执里 `[blob …]` 行的句柄交给 QQ 世界的发图工具。官方 QQ 扩展用 `qq_draft`(`image` 填句柄,`to` 填 `group:<群号>` 或 `private:<QQ号>`,再用 `qq_confirm` 确认发送);旧版 QQ 扩展(`qqbot`)用 `qq_send_image`,`image` 填回执里的绝对路径。\n6. **失败就停。** 如果回执说没配密钥、接口报错、超时,不要换个说法反复重试。把情况告诉用户,让他去控制台「图片工坊 → 状态」里填密钥或改接口地址。\n7. **别凭空说画好了。** 只有工具回执真的带着图回来,才算画好了。\n"
130
138
  }
131
139
  ]
132
140
  }