From de8661e727f339f34bd291b70261b39374d44653 Mon Sep 17 00:00:00 2001 From: lang <39692836+mindfn@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:59:48 +0800 Subject: [PATCH 1/2] feat(skills): add API-gateway image generation path to image-generation skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cats without a native image tool (Claude / Kimi / opencode-family) previously had only two options: borrow another engine's CLI (nested session, no bubble publication) or drive a browser. Deployments that already have an OpenAI-compatible image gateway get a third, scriptable path: curl /v1/images/generations -> decode b64_json into the uploads dir -> attach a media_gallery rich block pointing at /uploads/. The section documents the verified operational profile: ~100s per 1024x1024 image and >1.5MB responses (so --max-time 300, never echo the b64 into context), model split between the OpenAI-family and Gemini-family image models (Chinese text must go OpenAI-family), and the model_not_found gotcha — the key's gateway group decides which models are reachable, so check GET /models instead of retrying (clowder-ai#1236). Gateway base URL and key come from deployment env (IMAGE_GATEWAY_BASE_URL / IMAGE_GATEWAY_API_KEY), never hardcoded. Decision tree, platform table, frontmatter, and the manifest entry are updated so the router can surface the new path. --- cat-cafe-skills/image-generation/SKILL.md | 66 +++++++++++++++++++++-- cat-cafe-skills/manifest.yaml | 7 +-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/cat-cafe-skills/image-generation/SKILL.md b/cat-cafe-skills/image-generation/SKILL.md index f181095c09..c86367db45 100644 --- a/cat-cafe-skills/image-generation/SKILL.md +++ b/cat-cafe-skills/image-generation/SKILL.md @@ -1,7 +1,7 @@ --- name: image-generation description: > - AI 图片生成:原生 tool call(Codex/Antigravity)或浏览器自动化(Gemini/ChatGPT)。 + AI 图片生成:原生 tool call(Codex/Antigravity)、OpenAI 兼容图像网关(curl,无原生 tool 的猫首选)或浏览器自动化(Gemini/ChatGPT)。 Use when: 需要 AI 生成概念图、UI 参考、像素画素材、完整 PPT 页面、复杂架构图、信息图或视觉 mock。 Not for: 已有图片的展示(用 media_gallery rich block)、硬要求可编辑/native text 的 PPT/图表(用 PPT/HTML 管线)。 Output: 生成图片自动发布,或作为完整视觉 mock / 图像素材进入后续交付。 @@ -9,7 +9,7 @@ description: > # AI 图片生成 Skill -> 用途:生成 AI 图片——优先原生 tool call,降级浏览器自动化 +> 用途:生成 AI 图片——优先原生 tool call,无原生 tool 走 API 网关,最后降级浏览器自动化 > 适用猫猫:所有猫 ## 何时使用 @@ -73,9 +73,12 @@ Codex `image_gen` 不只是“概念图/素材生成器”。当前实测能力 ├─ 是(Codex / Antigravity)→ 用原生 tool call(§ 原生路径) │ 优势:快、自动发布到气泡、无需浏览器 │ -├─ 否(Claude / 其他)→ 能 shell out 到有能力的 CLI 吗? -│ ├─ 是 → 借用(§ 跨引擎借用) -│ └─ 否 → 浏览器自动化(§ 浏览器路径) +├─ 否(Claude / Kimi / 其他)→ 部署配置了图像网关 key 吗? +│ ├─ 是 → API 网关出图(§ API 网关路径) +│ │ 优势:纯 curl,无浏览器依赖,可脚本化批量出图 +│ ├─ 否 → 能 shell out 到有能力的 CLI 吗? +│ │ ├─ 是 → 借用(§ 跨引擎借用) +│ │ └─ 否 → 浏览器自动化(§ 浏览器路径) │ └─ 需要特定风格控制 / inpainting / 局部编辑? └─ 是 → 即使有原生能力也走浏览器路径 @@ -86,6 +89,7 @@ Codex `image_gen` 不只是“概念图/素材生成器”。当前实测能力 |------|------|------|---------|-------------| | **原生** | **Codex CLI** | 内置 `image_gen` tool call | `~/.codex/generated_images//` | ✅ scanner 自动拾取 | | **原生** | **Antigravity** | 内置 `generate_image` tool call | `~/.gemini/antigravity/brain//` | ✅ GENERATE_IMAGE step 自动拾取 | +| **API 网关** | OpenAI 兼容网关 | `curl /v1/images/generations` | 直接写入 uploadDir | 需手动发 `media_gallery` 富块 | | 浏览器 | Gemini Web | Chrome MCP 自动化 | 本地下载目录 | 需手动 `publishGeneratedImage()` | | 浏览器 | ChatGPT Web | Chrome MCP 自动化 | 本地下载目录 | 需手动 `publishGeneratedImage()` | @@ -144,6 +148,58 @@ codex exec "生成一张猫咖全景图,手绘水彩风格" --- +## API 网关路径(无原生 tool 的猫首选) + +**谁能用**:任何能跑 Bash 的猫(Claude / Kimi / opencode 系),前提是部署配置了图像网关。 + +**前提检查**(缺一即停,向 operator 报告缺口,不要猜 key): + +```bash +# 网关地址与 key 由部署者通过账号 envVars 或系统环境注入 +[ -n "$IMAGE_GATEWAY_BASE_URL" ] && [ -n "$IMAGE_GATEWAY_API_KEY" ] || echo "缺少 IMAGE_GATEWAY_BASE_URL / IMAGE_GATEWAY_API_KEY,无法走 API 网关路径" +``` + +**模型分工**(以 `GET $IMAGE_GATEWAY_BASE_URL/models` 实际返回为准——key 属于哪个分组决定能用哪些模型,用错报 `model_not_found`): + +| 模型 | 引擎 | 何时选 | +|------|------|--------| +| `gpt-image-2` | OpenAI 系 | 默认;含中文文字必选(Google 系中文乱码,实测) | +| `gpt-image-gemini-3-flash` | Gemini 系 | 快速草图 / 批量变体 | +| `gpt-image-gemini-3-pro` | Gemini 系 | 高质量成稿、无中文文字 | + +**出图脚本**(实测单张 ~100s、响应 >1.5MB,务必管道落盘,禁止把 b64 echo 进上下文): + +```bash +UPLOAD_DIR="${UPLOAD_DIR:-packages/api/uploads}" # /uploads/ 静态服务的根 +STEM="gen-$(date +%s)-$RANDOM" +curl -sS --max-time 300 "$IMAGE_GATEWAY_BASE_URL/images/generations" \ + -H "Authorization: Bearer $IMAGE_GATEWAY_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"model":"gpt-image-2","prompt":"<你的完整 prompt>","n":1,"size":"1024x1024"}' \ + -o /tmp/imggen-resp.json +python -c " +import json,base64,sys +d=json.load(open('/tmp/imggen-resp.json')) +if 'error' in d: sys.exit('imggen failed: '+d['error'].get('message','?')+' — check model name via GET /models, or key group') +b=base64.b64decode(d['data'][0]['b64_json']) +open('$UPLOAD_DIR/$STEM.png','wb').write(b) +print('/uploads/$STEM.png', len(b), 'bytes') +" +``` + +**进气泡**:拿到 `/uploads/<文件名>.png` 后,用 `cat_cafe_create_rich_block` 发 media_gallery(url 必须是 `/uploads/` 相对路径,不要本地绝对路径): + +```json +{ "v": 1, "id": "<唯一id>", "kind": "media_gallery", "items": [{ "url": "/uploads/<文件名>.png", "alt": "<描述>" }] } +``` + +**GOTCHA**: +- 出图慢是常态(~100s/张),`--max-time` 给 300s;120s 会在下载途中被掐断 +- `model_not_found` ≠ 网关挂了:是**这把 key 的分组**没有该模型渠道,先 `GET /models` 核对(不要重试硬闯——参见 clowder-ai#1236 的卡死教训) +- 失败要向 operator 报三要素:什么失败(模型/端点)、为什么(网关错误原文)、如何修(换模型名 / 核对 key 分组) + +--- + ## 浏览器路径(降级 / 需要风格控制时使用) ### Gemini 画图(浏览器) diff --git a/cat-cafe-skills/manifest.yaml b/cat-cafe-skills/manifest.yaml index a93a0b108f..4177e1eac5 100644 --- a/cat-cafe-skills/manifest.yaml +++ b/cat-cafe-skills/manifest.yaml @@ -1133,10 +1133,11 @@ skills: image-generation: category: "创作与媒体" description: > - 通过 Chrome MCP 浏览器自动化,在 Gemini / ChatGPT 上生成图片并下载。 + AI 图片生成三路径:原生 tool call(Codex/Antigravity)、OpenAI 兼容图像网关 + (curl /v1/images/generations,无原生 tool 的猫首选)、Chrome MCP 浏览器自动化(Gemini/ChatGPT)。 Use when: 需要生成概念图、UI 参考图、像素画素材、猫猫头像、任何图片资产。 Not for: Pencil .pen 文件内的简单形状/布局(用 pencil-design)。 - Output: 生成的图片文件(PNG)保存到项目 assets/ 目录。 + Output: 生成的图片发布到 /uploads/ 并以 media_gallery 进气泡,或保存到项目 assets/ 目录。 triggers: - "生成图片" - "画一张" @@ -1147,7 +1148,7 @@ skills: not_for: - "Pencil 内部设计" - "简单形状布局" - output: "Generated PNG saved to assets/" + output: "Generated image published to /uploads/ (media_gallery) or saved to assets/" next: [] sop_step: null merged_from: null From a8619da12e2b141c666d13b12ca0e1d2910ced6e Mon Sep 17 00:00:00 2001 From: lang <39692836+mindfn@users.noreply.github.com> Date: Thu, 30 Jul 2026 18:19:43 +0800 Subject: [PATCH 2/2] refactor(skills): converge image-gateway path per /simplify review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 出图实现下沉到 scripts/imggen-call.mjs(照 ttfund-skills 先例),SKILL.md 只留调用 - prompt 走 stdin:含引号/换行的长 prompt 不再破坏 JSON body - env 缺失即 exit 1(原为 echo 后继续跑,会白烧 ~100s 再抛 traceback) - UPLOAD_DIR 必须绝对路径 + mkdir -p:避免写到 API 未服务的 worktree 副本导致气泡裂图 - 幂等 stem 对齐 F172 sha256 约定,替换 date+RANDOM(重试即重复落盘) - 错误消息补齐三要素,HTTP 404 指向 base URL 缺 /v1 - 手写 media_gallery JSON 改为引用 refs/rich-blocks.md(单一真相源) - manifest/frontmatter 去掉端点细节,首选改为带前提;补 capability-wakeup-index 网关路径 --- cat-cafe-skills/image-generation/SKILL.md | 45 ++---- .../image-generation/scripts/imggen-call.mjs | 142 ++++++++++++++++++ cat-cafe-skills/manifest.yaml | 2 +- .../refs/capability-wakeup-index.md | 2 +- 4 files changed, 155 insertions(+), 36 deletions(-) create mode 100644 cat-cafe-skills/image-generation/scripts/imggen-call.mjs diff --git a/cat-cafe-skills/image-generation/SKILL.md b/cat-cafe-skills/image-generation/SKILL.md index c86367db45..947f9289f6 100644 --- a/cat-cafe-skills/image-generation/SKILL.md +++ b/cat-cafe-skills/image-generation/SKILL.md @@ -1,7 +1,7 @@ --- name: image-generation description: > - AI 图片生成:原生 tool call(Codex/Antigravity)、OpenAI 兼容图像网关(curl,无原生 tool 的猫首选)或浏览器自动化(Gemini/ChatGPT)。 + AI 图片生成:原生 tool call(Codex/Antigravity)、OpenAI 兼容图像网关(无原生 tool 的猫在已注入网关 key 时首选)或浏览器自动化(Gemini/ChatGPT)。 Use when: 需要 AI 生成概念图、UI 参考、像素画素材、完整 PPT 页面、复杂架构图、信息图或视觉 mock。 Not for: 已有图片的展示(用 media_gallery rich block)、硬要求可编辑/native text 的 PPT/图表(用 PPT/HTML 管线)。 Output: 生成图片自动发布,或作为完整视觉 mock / 图像素材进入后续交付。 @@ -75,7 +75,6 @@ Codex `image_gen` 不只是“概念图/素材生成器”。当前实测能力 │ ├─ 否(Claude / Kimi / 其他)→ 部署配置了图像网关 key 吗? │ ├─ 是 → API 网关出图(§ API 网关路径) -│ │ 优势:纯 curl,无浏览器依赖,可脚本化批量出图 │ ├─ 否 → 能 shell out 到有能力的 CLI 吗? │ │ ├─ 是 → 借用(§ 跨引擎借用) │ │ └─ 否 → 浏览器自动化(§ 浏览器路径) @@ -89,7 +88,7 @@ Codex `image_gen` 不只是“概念图/素材生成器”。当前实测能力 |------|------|------|---------|-------------| | **原生** | **Codex CLI** | 内置 `image_gen` tool call | `~/.codex/generated_images//` | ✅ scanner 自动拾取 | | **原生** | **Antigravity** | 内置 `generate_image` tool call | `~/.gemini/antigravity/brain//` | ✅ GENERATE_IMAGE step 自动拾取 | -| **API 网关** | OpenAI 兼容网关 | `curl /v1/images/generations` | 直接写入 uploadDir | 需手动发 `media_gallery` 富块 | +| **API 网关** | OpenAI 兼容网关 | `scripts/imggen-call.mjs`(需注入网关 key) | 直接写入 uploadDir | 需手动发 `media_gallery` 富块 | | 浏览器 | Gemini Web | Chrome MCP 自动化 | 本地下载目录 | 需手动 `publishGeneratedImage()` | | 浏览器 | ChatGPT Web | Chrome MCP 自动化 | 本地下载目录 | 需手动 `publishGeneratedImage()` | @@ -148,18 +147,11 @@ codex exec "生成一张猫咖全景图,手绘水彩风格" --- -## API 网关路径(无原生 tool 的猫首选) +## API 网关路径(无原生 tool 且已注入网关 key 时首选) **谁能用**:任何能跑 Bash 的猫(Claude / Kimi / opencode 系),前提是部署配置了图像网关。 -**前提检查**(缺一即停,向 operator 报告缺口,不要猜 key): - -```bash -# 网关地址与 key 由部署者通过账号 envVars 或系统环境注入 -[ -n "$IMAGE_GATEWAY_BASE_URL" ] && [ -n "$IMAGE_GATEWAY_API_KEY" ] || echo "缺少 IMAGE_GATEWAY_BASE_URL / IMAGE_GATEWAY_API_KEY,无法走 API 网关路径" -``` - -**模型分工**(以 `GET $IMAGE_GATEWAY_BASE_URL/models` 实际返回为准——key 属于哪个分组决定能用哪些模型,用错报 `model_not_found`): +**模型分工**(以 `GET $IMAGE_GATEWAY_BASE_URL/models` 实际返回为准——key 属于哪个分组决定能用哪些模型): | 模型 | 引擎 | 何时选 | |------|------|--------| @@ -167,36 +159,21 @@ codex exec "生成一张猫咖全景图,手绘水彩风格" | `gpt-image-gemini-3-flash` | Gemini 系 | 快速草图 / 批量变体 | | `gpt-image-gemini-3-pro` | Gemini 系 | 高质量成稿、无中文文字 | -**出图脚本**(实测单张 ~100s、响应 >1.5MB,务必管道落盘,禁止把 b64 echo 进上下文): +**出图**(prompt 走 stdin,避免引号/换行破坏 JSON body): ```bash -UPLOAD_DIR="${UPLOAD_DIR:-packages/api/uploads}" # /uploads/ 静态服务的根 -STEM="gen-$(date +%s)-$RANDOM" -curl -sS --max-time 300 "$IMAGE_GATEWAY_BASE_URL/images/generations" \ - -H "Authorization: Bearer $IMAGE_GATEWAY_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"model":"gpt-image-2","prompt":"<你的完整 prompt>","n":1,"size":"1024x1024"}' \ - -o /tmp/imggen-resp.json -python -c " -import json,base64,sys -d=json.load(open('/tmp/imggen-resp.json')) -if 'error' in d: sys.exit('imggen failed: '+d['error'].get('message','?')+' — check model name via GET /models, or key group') -b=base64.b64decode(d['data'][0]['b64_json']) -open('$UPLOAD_DIR/$STEM.png','wb').write(b) -print('/uploads/$STEM.png', len(b), 'bytes') -" +node cat-cafe-skills/image-generation/scripts/imggen-call.mjs --model gpt-image-2 <<'PROMPT' +<你的完整 prompt,引号和换行随便写> +PROMPT ``` -**进气泡**:拿到 `/uploads/<文件名>.png` 后,用 `cat_cafe_create_rich_block` 发 media_gallery(url 必须是 `/uploads/` 相对路径,不要本地绝对路径): +脚本负责:缺 env 立即中止、按需选模型、`--max-time 300` 等价超时、b64 解码落盘到 uploadDir(不进上下文)、打印 `/uploads/` 相对路径。参数与错误处理见 `scripts/imggen-call.mjs --help`。 -```json -{ "v": 1, "id": "<唯一id>", "kind": "media_gallery", "items": [{ "url": "/uploads/<文件名>.png", "alt": "<描述>" }] } -``` +**进气泡**:把脚本打印的 `/uploads/<文件名>.png` 交给 `cat_cafe_create_rich_block` 发 media_gallery,块结构见 `refs/rich-blocks.md`(url 必须是 `/uploads/` 相对路径,不要本地绝对路径)。 **GOTCHA**: -- 出图慢是常态(~100s/张),`--max-time` 给 300s;120s 会在下载途中被掐断 +- 出图慢是常态(实测单张 ~100s、响应 >1.5MB),脚本超时给 300s;120s 会在下载途中被掐断 - `model_not_found` ≠ 网关挂了:是**这把 key 的分组**没有该模型渠道,先 `GET /models` 核对(不要重试硬闯——参见 clowder-ai#1236 的卡死教训) -- 失败要向 operator 报三要素:什么失败(模型/端点)、为什么(网关错误原文)、如何修(换模型名 / 核对 key 分组) --- diff --git a/cat-cafe-skills/image-generation/scripts/imggen-call.mjs b/cat-cafe-skills/image-generation/scripts/imggen-call.mjs new file mode 100644 index 0000000000..f351681b37 --- /dev/null +++ b/cat-cafe-skills/image-generation/scripts/imggen-call.mjs @@ -0,0 +1,142 @@ +#!/usr/bin/env node +// OpenAI 兼容图像网关出图:prompt 从 stdin 读,图片落到 uploadDir,打印 /uploads/ 相对路径。 +// 用法:node imggen-call.mjs [--model ] [--size 1024x1024] [--upload-dir ] <<'PROMPT' ... PROMPT + +import { createHash } from 'node:crypto'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { isAbsolute, join, resolve } from 'node:path'; + +const TIMEOUT_MS = 300_000; // 实测单张 ~100s、响应 >1.5MB,120s 会在下载途中被掐断 +const DEFAULT_MODEL = 'gpt-image-2'; +const DEFAULT_SIZE = '1024x1024'; + +function fail(what, why, how) { + console.error(`imggen 失败:${what}\n原因:${why}\n修复:${how}`); + process.exit(1); +} + +if (process.argv.includes('--help')) { + console.log( + [ + '用法:node imggen-call.mjs [选项] <<\'PROMPT\' ... PROMPT', + '', + ' --model 默认 gpt-image-2;含中文文字必选 gpt-image-2(Google 系中文乱码)', + ' --size 默认 1024x1024', + ' --upload-dir 绝对路径,覆盖 UPLOAD_DIR;必须是当前 API 正在服务的那一份 uploads/', + '', + '环境变量(由部署者通过账号 envVars 注入,脚本不含任何硬编码凭据):', + ' IMAGE_GATEWAY_BASE_URL OpenAI 兼容网关根,需含 /v1,例 https://host/v1', + ' IMAGE_GATEWAY_API_KEY 该网关的 key;key 所属分组决定可用模型', + ' UPLOAD_DIR /uploads/ 静态服务的根目录(绝对路径)', + ].join('\n'), + ); + process.exit(0); +} + +function readFlag(name) { + const i = process.argv.indexOf(name); + return i === -1 ? undefined : process.argv[i + 1]; +} + +const baseUrl = process.env.IMAGE_GATEWAY_BASE_URL?.replace(/\/+$/, ''); +if (!baseUrl) { + fail( + 'API 网关路径不可用', + '未注入 IMAGE_GATEWAY_BASE_URL', + '向 operator 报告网关未配置(账号 envVars),不要猜地址;或改走原生/浏览器路径', + ); +} +if (!process.env.IMAGE_GATEWAY_API_KEY) { + fail( + 'API 网关路径不可用', + '未注入 IMAGE_GATEWAY_API_KEY', + '向 operator 报告网关 key 未配置(账号 envVars),不要猜 key', + ); +} + +const uploadDir = readFlag('--upload-dir') ?? process.env.UPLOAD_DIR; +if (!uploadDir) { + fail( + '无法确定落盘目录', + '未注入 UPLOAD_DIR,且未传 --upload-dir', + '传当前 API 正在服务的 uploads/ 绝对路径(默认为 <运行时>/packages/api/uploads);不要用 worktree 内的副本,否则气泡里会裂图', + ); +} +if (!isAbsolute(uploadDir)) { + fail( + '落盘目录不合法', + `UPLOAD_DIR/--upload-dir 必须是绝对路径,收到 "${uploadDir}"`, + '相对路径按当前 cwd 解析,会写到 API 没在服务的目录;改传绝对路径', + ); +} + +const prompt = await new Promise((res, rej) => { + let buf = ''; + process.stdin.setEncoding('utf8'); + process.stdin.on('data', (c) => { + buf += c; + }); + process.stdin.on('end', () => res(buf.trim())); + process.stdin.on('error', rej); +}); +if (!prompt) { + fail('没有 prompt', 'stdin 为空', "用 heredoc 传入:node imggen-call.mjs <<'PROMPT' ... PROMPT"); +} + +const model = readFlag('--model') ?? DEFAULT_MODEL; +const size = readFlag('--size') ?? DEFAULT_SIZE; +const endpoint = `${baseUrl}/images/generations`; + +let payload; +try { + const res = await fetch(endpoint, { + method: 'POST', + headers: { + Authorization: `Bearer ${process.env.IMAGE_GATEWAY_API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ model, prompt, n: 1, size }), + signal: AbortSignal.timeout(TIMEOUT_MS), + }); + const text = await res.text(); + try { + payload = JSON.parse(text); + } catch { + fail( + `网关返回非 JSON(${endpoint}, HTTP ${res.status})`, + text.slice(0, 300), + 'HTTP 404 通常是 IMAGE_GATEWAY_BASE_URL 少了 /v1;其他状态码把原文报给 operator', + ); + } +} catch (err) { + const why = err?.name === 'TimeoutError' ? `超过 ${TIMEOUT_MS / 1000}s 未返回` : String(err?.message ?? err); + fail(`请求网关失败(${endpoint})`, why, '确认网关可达与 base URL 正确后重试一次;连续失败报给 operator,不要循环硬闯'); +} + +if (payload.error) { + const msg = payload.error.message ?? JSON.stringify(payload.error); + fail( + `模型 ${model} 出图被网关拒绝`, + msg, + `model_not_found 表示这把 key 的分组没有该渠道:先 GET ${baseUrl}/models 核对逐字模型名,换模型或换 key 分组;不要重试硬闯(clowder-ai#1236)`, + ); +} + +const b64 = payload.data?.[0]?.b64_json; +if (!b64) { + fail( + `模型 ${model} 未返回图片数据`, + `响应缺少 data[0].b64_json,顶层字段:${Object.keys(payload).join(', ') || '(空)'}`, + '确认该模型走 b64 返回;若网关只给 url,把响应结构报给 operator', + ); +} + +// 幂等 stem:同一 prompt+model+size 重复出图复用同一文件,对齐 F172 buildPublicationStem 的 sha256 前 8 位约定 +const stem = `imggen-${model}-${createHash('sha256').update(`${model}|${size}|${prompt}`).digest('hex').slice(0, 8)}`.replace( + /[^a-zA-Z0-9._-]/g, + '-', +); +const bytes = Buffer.from(b64, 'base64'); +await mkdir(uploadDir, { recursive: true }); +await writeFile(join(resolve(uploadDir), `${stem}.png`), bytes); +console.log(`/uploads/${stem}.png ${bytes.length} bytes`); diff --git a/cat-cafe-skills/manifest.yaml b/cat-cafe-skills/manifest.yaml index 4177e1eac5..471473192c 100644 --- a/cat-cafe-skills/manifest.yaml +++ b/cat-cafe-skills/manifest.yaml @@ -1134,7 +1134,7 @@ skills: category: "创作与媒体" description: > AI 图片生成三路径:原生 tool call(Codex/Antigravity)、OpenAI 兼容图像网关 - (curl /v1/images/generations,无原生 tool 的猫首选)、Chrome MCP 浏览器自动化(Gemini/ChatGPT)。 + (需部署注入网关 key)、Chrome MCP 浏览器自动化(Gemini/ChatGPT)。 Use when: 需要生成概念图、UI 参考图、像素画素材、猫猫头像、任何图片资产。 Not for: Pencil .pen 文件内的简单形状/布局(用 pencil-design)。 Output: 生成的图片发布到 /uploads/ 并以 media_gallery 进气泡,或保存到项目 assets/ 目录。 diff --git a/cat-cafe-skills/refs/capability-wakeup-index.md b/cat-cafe-skills/refs/capability-wakeup-index.md index 829816f58b..b498e89893 100644 --- a/cat-cafe-skills/refs/capability-wakeup-index.md +++ b/cat-cafe-skills/refs/capability-wakeup-index.md @@ -78,7 +78,7 @@ opus-47 原把 `workspace-navigator` / `rich-messaging` / `browser-preview` 一 - PPT 内容页配图 - 信息图 / 像素画素材 -**Backend 路由**:原生 tool call (Codex/Antigravity) / 浏览器自动化 (Gemini/ChatGPT) +**Backend 路由**:原生 tool call (Codex/Antigravity) / API 图像网关(需部署注入网关 key)/ 浏览器自动化 (Gemini/ChatGPT) **边界**:硬要求可编辑 / native text → 用 PPT/HTML 管线,不用 image-generation ### 4. `workspace-navigator` — 程式打开文件到 Workspace panel