Skip to content

feat(skills): image-generation 增加 API 网关路径 — 无原生出图能力的猫也能画图 - #1237

Open
whutzefengxie-ops wants to merge 2 commits into
zts212653:mainfrom
whutzefengxie-ops:feat/gateway-image-gen-skill
Open

feat(skills): image-generation 增加 API 网关路径 — 无原生出图能力的猫也能画图#1237
whutzefengxie-ops wants to merge 2 commits into
zts212653:mainfrom
whutzefengxie-ops:feat/gateway-image-gen-skill

Conversation

@whutzefengxie-ops

@whutzefengxie-ops whutzefengxie-ops commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

背景

image-generation skill 原本只有两条路径:原生 tool call(Codex/Antigravity)与浏览器自动化(Gemini/ChatGPT)。没有原生出图能力、也不方便开浏览器的猫(Claude / Kimi / opencode 系)实际无路可走。

本 PR 补上第三条:OpenAI 兼容图像网关路径。链路已在真实网关实测通过(gpt-image-2 单张 1024×1024,95.83s,响应 1594736 bytes,解码得合法 PNG,/uploads/ 静态服务 200)。

改了什么

  • cat-cafe-skills/image-generation/scripts/imggen-call.mjs(新增)— 网关出图脚本:prompt 走 stdin、env 守卫、b64 解码落盘、打印 /uploads/ 相对路径
  • cat-cafe-skills/image-generation/SKILL.md — 新增「API 网关路径」一节(决策树分支、平台表一行、模型分工、GOTCHA)
  • cat-cafe-skills/manifest.yaml — image-generation 条目的 description / output
  • cat-cafe-skills/refs/capability-wakeup-index.md — 唤醒索引补上网关路径(原文只列两条路径)

关键设计取舍

为什么不直接调 publishGeneratedImage()(F172 共享发布合约)

审查提出应复用 F172 而非在 skill 里手写落盘。方向认同,但该合约目前只有进程内调用方(codex-image-scanner.ts:48antigravity-image-publisher.ts:80/187),没有 MCP 工具也没有 HTTP 端点暴露它;而本路径的执行者是 CLI 子进程里的猫,只有 bash + MCP,无法 import TS 模块。硬编码 dist/ 相对路径同样不可行——worktree 内不存在 dist/(只有 runtime 有)。

因此本 PR 的取法是在脚本层对齐合约语义,而不是复刻或绕过它:

  • 幂等命名沿用 buildPublicationStem 的 sha256 前 8 位约定(generated-image-publication.ts:92-96),同 prompt+model+size 重复出图复用同一文件
  • UPLOAD_DIR 改为必填且必须绝对路径,不再兜底 packages/api/uploads 相对路径——后者按 cwd 解析,猫在 worktree 里跑就会写到 API 没在服务的副本,气泡直接裂图(refs/rich-blocks.md:65 记过这条教训)
  • provider: 'skill' 已在 GeneratedImagePublicationInput 联合类型里预留,后续若给合约加 MCP/HTTP 暴露面,脚本可平滑切过去

/simplify 四角度收敛(家规必跑)

四个角度共 24 条 findings,去重后按"会烧掉一整轮 invocation"优先级修:

类别 修法
实现细节下沉 curl + 内联 python 抽成 scripts/imggen-call.mjs,照 ttfund-skills/scripts/ttfund-call.mjs 先例;SKILL.md 只留三行调用(净减约 16 行/次注入)
prompt 引号破 JSON 原写法把 prompt 内联进单引号 -d '{...}',长 prompt 必然带 don't/中文引号 → 400。改为 stdin heredoc
env 缺失不中止 原为 [ -n ... ] || echo(退出码 0),脚本会继续 curl 并在 python 里抛 traceback。改为立即 exit 1
幂等 date +%s-$RANDOM → sha256 stem,重试不再重复落盘;顺带去掉 bash 专有的 $RANDOM
临时文件冲突 固定 /tmp/imggen-resp.json 与"可批量出图"的宣传冲突;改为不落中间文件
python 依赖 项目栈是 Node 20+,python 未声明为依赖;改为 node
/v1 口径矛盾 平台表/manifest 写 /v1/images/generations、脚本拼 $BASE/images/generations,operator 无从判断 base URL 含不含 /v1。统一钉死在脚本 --help 与 404 提示里
单一真相源 手写 media_gallery JSON 与 refs/rich-blocks.md:43-54 字段顺序都不一致 → 改为引用
抽象层次 manifest 去掉端点细节;「首选」补前提(依赖部署注入的 key,不该无条件承诺)
索引层遗漏 capability-wakeup-index.md:81 补第三条路径

明确未改:实测参数(~100s、>1.5MB、300s 超时)、三模型分工表、凭据只从环境注入的纪律。

留给后续 PRanime-forge/SKILL.md:46 的中文乱码规则与本 skill 重复,理应由生产方单点持有;但该表同时覆盖 i2v 视频路由(不属本 skill 管辖),改它会削掉视频侧信息,且超出本 PR 范围。

验证

相关

…on skill

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/<file>.

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.
- 出图实现下沉到 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 网关路径
@whutzefengxie-ops whutzefengxie-ops changed the title feat(skills): image-generation adds an API-gateway path — cats without a native image tool can draw via curl feat(skills): image-generation 增加 API 网关路径 — 无原生出图能力的猫也能画图 Jul 30, 2026
@zts212653

Copy link
Copy Markdown
Owner

感谢把“没有原生出图工具的猫如何调用图像网关”这条缺口整理成实现。这个方向有价值,但当前 PR 在 maintainer gate 先标记为 NEEDS-INFO / HOLD / DO NOT MERGE,核验 HEAD 为 a8619da12e2b141c666d13b12ca0e1d2910ced6e

原因有两层:

  1. 这不是小型 skill 文案修补,而是新增一条跨 skill、部署环境变量、网关凭据、图片落盘与 /uploads/ 发布语义的产品能力。目前没有关联的 accepted issue,尚未钉住 consumer、部署 owner、凭据边界,以及与 F172 共享发布合约的长期关系。
  2. 当前 required Lint check 失败;直接原因是新增 imggen-call.mjs 未通过 Biome 格式检查。其余 checks 通过不能替代这个 gate。

请先开或链接一张聚焦 issue,至少说明:

  • 哪些 runtime / 猫是明确 consumer,为什么原生工具与浏览器路径都不足;
  • IMAGE_GATEWAY_BASE_URL、key、UPLOAD_DIR 分别由谁配置和维护;
  • 为什么当前必须由脚本直写 uploadDir,以及后续如何收敛到 F172 的统一发布面;
  • 失败、重试、凭据泄漏和双仓同步边界。

issue 经 maintainer 接纳、CI 修绿后,我们再进入正式代码 review。新 push 会使本 exact-HEAD 初判失效。

[小太阳·砚砚/GPT-5.6 Sol🐾]

@zts212653 zts212653 added enhancement New feature or request triaged Maintainer reviewed, replied, and made an initial triage decision needs-info Waiting for additional information from reporter labels Jul 30, 2026
@whutzefengxie-ops

Copy link
Copy Markdown
Collaborator Author

Focused contract issue opened per maintainer direction: #1251. It covers explicit consumers, deployment ownership for IMAGE_GATEWAY_BASE_URL / key / active UPLOAD_DIR, the transitional direct-write boundary, F172 convergence, failure/retry/credential safety, and skill-sync ownership. This PR remains unchanged and on HOLD. I will not push a lint-only update before the issue is accepted; after acceptance I will run Biome, re-run the skill checks, push a fresh HEAD, and request a new exact-HEAD review.

@zts212653 zts212653 added needs-maintainer-decision Triaged issue awaiting maintainer decision on scope or direction and removed needs-info Waiting for additional information from reporter labels Aug 4, 2026
@zts212653

Copy link
Copy Markdown
Owner

Maintainer state update — NEEDS-DECISION / NO FURTHER AUTHOR ACTION YET

The information gap is closed: clowder-ai#1251 now names the consumers, credential ownership, retry discipline, sync ownership, and F172 convergence boundary. The stale needs-info label has been removed and replaced with needs-maintainer-decision.

Current decision:

  • the gateway generation entry is valuable;
  • direct writing from the skill process into an injected UPLOAD_DIR would create a second publication contract and bypass F172 runtime path resolution, media validation, provenance, and canonical rich-block persistence;
  • current cat-cafe main still has only in-process publishGeneratedImage() consumers and no authenticated out-of-process publication surface;
  • therefore exact HEAD a8619da12e2b141c666d13b12ca0e1d2910ced6e remains HOLD / DO NOT MERGE. Its red Lint check is secondary to the direction gate.

No further push is requested from the external author until the F172 boundary is decided. If an authenticated F172 surface is approved and implemented, this PR should be narrowed to a consumer of that surface, then formatted and freshly reviewed. No Strategy B fixup is authorized.

[小太阳·砚砚/GPT-5.6 Sol🐾]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request needs-maintainer-decision Triaged issue awaiting maintainer decision on scope or direction triaged Maintainer reviewed, replied, and made an initial triage decision

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants