| name | codex-image |
| label | 本机 Codex 图片 |
| summary | 调度本机 Codex 生成图片或基于现有图片修改 |
| description | 通过沙箱后台运行本机 codex exec 生成或修改图片,将产物安全导入 uploads,并按 DOC-FIRST 规范插入、替换或回传。 |
本机 Codex 生成或修改图片
本子技能用于母技能已经完成方式选择或图片修改确认后,调度用户本机的 Codex 非交互生成图片,或基于用户指定的现有图片修改。从零生成与位图修改每张产物只启动一次有界任务;SVG 修改的每个 Codex 步骤最多一次简短重试,仍失败立即自动回落。不得无限轮询、自动重跑或隐瞒失败。SVG 源图走源码级定点编辑;位图修改仍走图生图,不能用 SVG 重画冒充成功。
一、前置与 DOC-FIRST
- 沿用母技能刚完成的 Codex 探测结果,不得在问卷恢复后重复探测。只有子技能被独立恢复、上下文里确实没有探测结果时,才补做一次确认:POSIX 用
command -v codex,Windows 用 where codex,timeoutSeconds 设为 5。
- 从零生成失败时可提议改用“内置 SVG 插画”。
- 修改位图时,失败就停止本路线,说明本机 Codex 当前不可用、原图未被覆盖。
- 修改 SVG 时,先用
skill_read 读取 svg/SKILL.md,再调用 editSvgWithCodexFallback。该工具在执行层覆盖指令写入、Codex 启动/运行、产物核验与导入;任一步骤失败最多重试一次,仍失败立即自动回落到原生 SVG 定点编辑并导入。全程不再反问,不把换路责任交给用户。
- 从零生成配图:新文档先用
writeDraft 完成全文;已有文档先用 readDraft 读取最新结构和目标 blockId。不要在正文落地前先等几分钟生图。
- 修改现有图片:先锁定用户明确指定的唯一源图引用,不要猜图。
- 刚上传的图片:使用当轮附件上下文给出的
fileId。
- 文档内图片:先用
readDraft 读取目标图片块,保留它的 ref,从 <img src="..."> 取得真实 src。
- 素材区图片:使用系统列出的图片素材
materialId;不要拿素材摘要、识图文本或文件名冒充源图。
- 多张图而用户没有指明目标时,先让用户明确选哪一张;不得自行挑选。
- 每张图都要有明确用途和插入或回传位置。优先只处理 1 张,一轮最多 3 张;正文已经足够清楚时不为了装饰堆图。
二、修改现有图片时先把源图落入会话工作区
本节只适用于换色、改背景、局部替换、修图、P 图等现有图片修改;从零生成直接进入下一节。
-
优先复用母技能已经返回的 prepareImageEditSource 结果;只有上下文确实没有结果时才调用:
prepareImageEditSource({image:"<fileId、文档图片 src 或图片 materialId>"})
-
工具会解析实际图片、校验大小与格式,并把副本写进当前会话沙箱工作区。只能使用工具真实返回的绝对 path 作为 Codex 源图路径;不得把 /api/v1/files/...、materialId、识图文字或猜测的宿主路径直接交给 Codex。SVG 还会返回与源图逐字节相同的 editablePath,它是唯一允许修改的输出副本。
-
工具失败时:位图路线停止,不得绕过它用 shell 读取 uploads、宿主任意路径或把图片转成 base64 拼进命令;SVG 路线没有可回落的已准备副本,也只能用中性短句收口。不得暴露内部路径或原始错误。
-
源图副本只读作输入;为产物另选唯一输出路径,绝不能覆盖源图。
三、准备安全的生成或修改指令
-
本节第 1-3、5-6 步只适用于从零生成或修改位图:先用工作区命令取得当前工作目录的绝对路径,POSIX 用 pwd,Windows 用 cd。在该目录内为本次产物选择唯一的绝对路径,默认使用 .png,例如 <工作目录绝对路径>/codex-image-<短标识>.png。修改 SVG 不取得工作目录、不自行写指令文件,直接执行第 4 步的受控工具流程。
-
从零生成时,把用户的画面诉求整理成一份中文生图指令,内容只包括:
- 用户要求的主体、场景、构图和必须出现的文字;
- 目标尺寸或宽高比;
- 风格、光线、色彩、材质等画面要求;
- 明确要求“使用可用的生图能力生成图片,并把最终产物写到指定绝对路径;结束前确认该文件存在;不要只在回复中描述图片”。
-
修改现有位图时,指令必须明确给出工具返回的源图绝对路径、另选的产物绝对路径和用户的修改要求,并使用以下约束模板:
这是修改现有图片,不是从零生成。
源图:<prepareImageEditSource 返回的绝对 path>
修改要求:<只写用户明确要求的修改>
保持要求:除上述修改外,尽量保持原图的人物身份、姿态、构图、背景关系、光线与其他未点名细节不变。
输出要求:使用可用的图片编辑/图生图能力,以源图为视觉基础完成修改;把最终完整图片写到 <另选的产物绝对路径>,不要覆盖源图;结束前确认产物文件存在;不要只在回复中描述图片。
-
修改现有 SVG 时,不使用图片编辑/图生图能力,也不手工调用 mastra_workspace_write_file、mastra_workspace_execute_command、mastra_workspace_get_process_output 或 importGeneratedImage。按以下固定序列执行:
-
用 skill_read 读取 svg/SKILL.md,复用母技能已经返回的 workspacePath、editableWorkspacePath、path 与 editablePath;不得再次调用 prepareImageEditSource。
-
按 svg/SKILL.md 用 mastra_workspace_read_file 读取 workspacePath,从源图逐字取得唯一、最小的 oldString,并生成只含用户点名改动的 newString。不唯一时先增加最少父级上下文;仍不能唯一定位才用中性短句收口,不能猜测重画。
-
只调用一次:
editSvgWithCodexFallback({
sourcePath:"<prepareImageEditSource 返回的绝对 path>",
editablePath:"<prepareImageEditSource 返回的绝对 editablePath>",
changeRequest:"<只写用户明确要求的修改>",
oldString:"<源图中唯一的最小完整片段>",
newString:"<只含目标改动的新片段>",
alt:"<简短说明>"
})
工具会把指令写到会话真实工作区根目录,并只用受控相对文件名启动 Codex,避免 Windows 盘符或宿主绝对路径被当作 /workspace 虚拟路径解析。指令写入、Codex 运行/核验或导入任一步骤失败都只重试一次;仍失败时,工具用同一 oldString/newString 自动执行原生 SVG 定点编辑并导入。不得在工具外再次重试 Codex 或写指令文件。
-
ok:true 时只使用工具返回的真实 src、imageId 与 via;via:"svg-fallback" 表示已经完成自动回落,不得再重复编辑或导入。ok:false 时用工具的中性中文 message 收口,不展示内部错误,不让会话停在“思考中”。
四、后台调度与轮询
本节只适用于从零生成或修改位图。SVG 修改的 Codex 调度、一次重试和原生回落全部由 editSvgWithCodexFallback 封装,主 agent 不得进入本节手工调度。使用 codex exec 非交互运行,并通过 -C 锁定工作目录。推荐命令模板:
codex exec --ephemeral --skip-git-repo-check -s workspace-write -C "<工作目录绝对路径>" - < "<生图指令文件绝对路径>"
执行纪律:
- 调用
mastra_workspace_execute_command 时必须传 background:true,并给出有界总超时(建议 timeoutSeconds:600)。codex exec 完成会自行退出;不要以前台调用长时间阻塞主链。
- 从启动结果取得 PID,用
mastra_workspace_get_process_output 携带 pid 和合理的 tail 反复轮询;省略 wait 或显式传 wait:false,避免单次工具调用长时间阻塞。
- 轮询到明确退出码就立即停止。退出码为 0 后仍以目标图片文件实际存在且能被后续导入为准;非 0、达到总超时、进程消失或持续无结果都视为失败。
- 同一张从零图片或位图最多启动一次 Codex 任务。失败时保留诚实错误摘要;从零生成可告诉用户改走 SVG,位图修改说明本机处理未成功、原图未被覆盖。禁止无上限重试、换命令盲跑或假报已有图片。
五、产物入库
本节的手工导入只适用于从零生成或修改位图;SVG 修改已经由 editSvgWithCodexFallback 完成导入,不得重复调用 importGeneratedImage。
- 只接受
.png、.jpg、.jpeg、.webp 或 .svg 产物;不要把文本、日志、JSON、HTML 或其他扩展名伪装成图片。
- Codex 成功退出后,调用
importGeneratedImage:
importGeneratedImage({path:"<图片绝对路径>",alt:"<简短说明>"})
- 只能使用工具真实返回的
imageId 和 src。工具会校验当前会话沙箱路径、扩展名、文件大小和真实图片字节;导入失败就按失败处理,不得编造 /api/v1/files/... 路径。
width、height 只在工具实际返回时使用;未返回时省略,让文档和前端采用默认尺寸。
六、插入、替换或回传并核对
拿到真实 src 后,按来源与用户意图选择唯一落点:
- 从零生成的文档配图:调用
editDraft 的 insertBlock 插入图片 QingML。
- 修改的是文档内现有图片,且用户要更新原位置:使用第一节保留的图片块
ref,调用 editDraft 的 replaceBlock,用新 <img> 替换该图片块;不要在旁边再插一张造成新旧重复。
- 修改的是聊天上传图或素材,当前没有文档落点:最终回复里用工具返回的真实
src 作为 Markdown 图片地址回给用户,例如 ;不得只说“已完成”却不给结果。
图片 QingML:
<img src="/api/v1/files/真实ID/generated-image.png" alt="简短说明" width="工具返回宽度" height="工具返回高度"/>
- 工具未返回尺寸时省略
width、height,不得猜数。
- 插入时
position 用 after/before 配合目标块 ref,或用 start/end。
- 插入或替换后必须调用
readDiff 核对实际改动;不要再次调用 writeDraft 重发整篇来塞图。