# Grok Media Skill for Codex

面向 Codex 的中文 Skill，通过用户配置的 Sub2API `base_url` 和 API Key 使用 Grok 媒体能力。

当前对话第一次使用 Skill 时，会先检查 Python 运行环境，再在后台静默检查本地是否能连接 `api.x.ai`、`imgen.x.ai` 和 `vidgen.x.ai`。成功结果在同一对话中复用，不会为每次生成重复提示；只有运行环境或网络变化后才重新检查。网络通过后，Skill 在普通对话中逐轮询问并收窄创作目标，不要求用户切换 Codex 模式。

脚本自动读取 `GROK_MEDIA_PROXY`、标准 HTTP(S) 代理环境变量以及 Python 可见的 Windows/macOS 系统代理，并将同一代理用于网络预检、Sub2API 请求和媒体下载。所有请求还会统一发送标准浏览器格式的 `User-Agent`，减少 Python 默认签名触发 Cloudflare 403/1010 的情况；特殊节点可通过 `GROK_MEDIA_USER_AGENT` 环境变量覆盖。代理地址和认证信息不会输出或写入状态文件。`config.json` 仍只需要 `base_url` 和 `key`。

所有图片生成、图片编辑、视频生成、视频编辑、单次续写和连续续写需求都会经过逐轮收窄流程，不设轻量或清晰请求快速通道。Skill 每轮只问 1 至 3 个高价值问题，使用数字编号问题和字母编号选项，用户可以用 `1A 2B` 快速回答，也可以自由描述。从用途与主体、视觉方向、内容边界、动态设计和输出规格逐步缩小范围，直到形成可执行创作简报。用户确认前不会运行 `config check`、读取媒体文件或提交生成请求。

## Sub2API 能力

- 同步文生图：`POST /v1/images/generations`
- 同步图片编辑和最多 3 张参考图：`POST /v1/images/edits`
- 异步文生视频、图生视频和 1 至 7 张参考图视频：`POST /v1/videos/generations`
- 异步视频编辑：`POST /v1/videos/edits`
- 异步视频续写：`POST /v1/videos/extensions`
- 连续续写：合法时长内复用官方 URL，超出 15 秒后截取动态尾段，重复调用 `/v1/videos/extensions` 并保存本地完整视频
- 视频状态查询：`GET /v1/videos/{request_id}`
- 成品 URL 下载、SSL 临时错误重试和无计费下载恢复

视频生成、编辑和续写都是异步任务，POST 返回的 `request_id` 统一通过视频状态接口轮询。连续续写每轮对应一次独立计费请求，CLI 最多接受 10 轮，不提供无限循环。视频编辑和续写会使用原视频，不会用重新生成冒充用户要求的操作。

图片请求本身是同步的。CLI 的 `--detach` 仅是可选的本地后台包装，不是 Sub2API 异步任务；默认前台执行图片命令。视频生成、编辑和续写任务则是异步的，POST 返回 `request_id` 后需要轮询状态。

HTTP 4xx 只结束当前一次尝试，不会锁住后续操作。Skill 不会自动重试或擅自更换格式、模型和生成方式；但用户明确说“重试”“继续生成”或“重试生成第 02 段”时，该指令视为一次新的提交与计费确认。方案不变则直接重试一次，方案有调整则只确认相关变更。只有结果不确定的网络中断才需要额外提示重复计费风险。

## 安装

让 Codex 使用内置 `skill-installer` 从本仓库安装 `grok-media`：

```powershell
python "$HOME\.codex\skills\.system\skill-installer\scripts\install-skill-from-github.py" `
  --repo happy-loki/grok-media-skill `
  --path grok-media
```

也可以把仓库中的 `grok-media` 目录复制到 `$CODEX_HOME/skills/grok-media`。未设置 `CODEX_HOME` 时，默认目录是 `$HOME/.codex/skills/grok-media`。

## 配置

编辑已安装 Skill 的 `config.json`：

```json
{
  "base_url": "https://your-sub2api.example/v1",
  "key": "your-api-key"
}
```

生成的图片和视频默认保存到 Codex 当前 workspace，也就是执行命令时的当前目录。无需在 Skill 配置中设置输出路径；需要分类存放时可传 `--output-dir`，相对路径仍以当前 workspace 为基准。脚本使用 Python `pathlib` 返回适合 Codex Markdown 渲染的跨平台绝对路径：Windows 为 `C:/...`，macOS 和 Linux 为 `/...`。Skill 会直接展示每个成品，而不是只打印文件名。

验证配置不会创建媒体任务：

```powershell
$skillDir = "$HOME\.codex\skills\grok-media"
python "$skillDir\scripts\grok_media.py" config check
```

## 运行环境预检

Skill 需要 Python 3.10 或更高版本。找到实际 Python 命令后先运行：

```powershell
python "$skillDir\scripts\grok_media.py" runtime check
```

普通图片和单次视频操作只依赖 Python。连续续写还要求 `ffmpeg`、`ffprobe`、`libx264` 和 AAC；结果必须为 `ready_for_video_continue: true`。缺失时 Skill 会先展示准确安装命令并征求用户同意，不会静默修改系统。Windows、macOS 和常见 Linux 发行版的流程见 [运行环境安装指引](grok-media/references/runtime-install.md)。

## 后台网络预检

网络检查不读取配置、不携带 API Key，也不产生媒体费用：

```powershell
python "$skillDir\scripts\grok_media.py" network check
```

这是当前对话首次媒体请求的后台步骤，必须早于参数确认和 `config check`，但成功时不需要向用户报告。同一对话后续操作复用成功结果。检查失败时不允许继续提交图片或视频请求；切换网络或代理后重新执行即可。

查看脚本实际执行的参数范围不需要配置或密钥：

```powershell
python "$skillDir\scripts\grok_media.py" capabilities
```

能力表和请求前校验共用同一组脚本常量，并已按 2026-07-15 的 xAI 官方 REST 文档复核。图片生成和编辑支持 `n: 1..10`、规定画幅、`1k|2k`、`url|b64_json`；视频生成支持 1 至 15 秒、规定画幅和 `480p|720p`，仅 `grok-imagine-video-1.5`、preview 和日期别名的图生视频支持 `1080p`。参考图视频支持 1 至 7 张图且最长 10 秒。视频编辑输入必须是最长 8.7 秒的 MP4，并继承输入规格；视频续写输入必须是 2 至 15 秒的 MP4，新增时长为 2 至 10 秒。连续续写接受本地 MP4、MP4 data URI 或公开 MP4 URL，支持 1 至 10 轮，每轮独立调用一次续写接口。

脚本只发送当前模式允许的字段。视频生成未显式指定可选规格时，字段会从请求体省略并沿用 xAI 官方默认值：8 秒、480p；文生视频默认 `16:9`，图生视频默认沿用输入图画幅。直连 `api.x.ai` 的图片对象使用 `url`，Sub2API 使用其解析器可识别且 xAI 官方兼容的 `image_url`；视频编辑与续写固定使用官方 `video.url` 对象。模型名、模式组合、字段名、data URI、非空输入文件、MP4 容器和可解析的本地视频时长都会在 POST 前校验。

## 执行语义

图片同步执行一次：

```powershell
python "$skillDir\scripts\grok_media.py" image edit `
  --prompt "保持人物不变，改为汉服和江南雨景" `
  --image "C:\path\source.png" --resolution 2k --name "hanfu-edit"
```

图片命令会在请求前校验模型、数量、画幅、分辨率、返回格式、输入字段和素材编码。`4:5` 会直接被拒绝并建议使用最接近的 `3:4` 或 `2:3`，不会向 Sub2API 提交无效请求；`2k` 是受支持的分辨率。`size` 会被 Sub2API 删除，`mask` 也不在当前 xAI 图片编辑参数中，因此 CLI 不再暴露这两个无效选项。

如果 Sub2API 已返回图片 URL，但本地下载失败，结果仍为 `status: completed`，并包含 `urls` 和 `download_error`。只重试下载，不重新生成：

```powershell
python "$skillDir\scripts\grok_media.py" download `
  --url "<返回的图片 URL>" --kind image --name "hanfu-edit"
```

视频生成只提交一次：

```powershell
python "$skillDir\scripts\grok_media.py" video generate `
  --prompt "烟雨江南中的人物缓慢转身" `
  --duration 5 --resolution 720p --aspect-ratio 16:9 --no-wait
```

图生视频未指定画幅时会保留输入图比例，不再默认强制 `16:9`。未指定时长或分辨率时也不会再硬编码旧的 `5` 秒和 `720p`。无效视频模型、画幅、分辨率、时长、模式组合以及 `1080p` 与模型别名不匹配都会在 POST 前终止。

视频编辑只接受 MP4，且不允许设置时长、画幅或分辨率：

```powershell
python "$skillDir\scripts\grok_media.py" video edit `
  --prompt "只把人物外套改为红色，保留其余内容" `
  --video "C:\path\source.mp4" --no-wait
```

视频续写的输入原片为 2 至 15 秒，`--duration` 表示新增的 2 至 10 秒；省略时使用官方默认 6 秒：

```powershell
python "$skillDir\scripts\grok_media.py" video extend `
  --prompt "镜头继续向右平移，人物走入雨巷" `
  --video "C:\path\source.mp4" --duration 6 --no-wait
```

连续续写接受本地 MP4、MP4 data URI 或公开 HTTP(S) MP4 URL：

```powershell
python "$skillDir\scripts\grok_media.py" video continue `
  --prompt "镜头继续向右平移，人物沿雨巷前行" `
  --video "C:\path\source.mp4" --duration 5 --rounds 3 `
  --context-duration 10 --name "rain-alley-continued"
```

该命令会等待每轮完成，不支持 `--no-wait`。`--rounds` 限制为 1 至 10，每轮是一次独立计费请求。当前输入不超过 15 秒时，会优先把官方返回的 URL 直接用于下一轮，不裁剪也不重编码；15 秒限制约束下一轮输入，而不是本轮输出总长。只有候选输入超过 15 秒且仍需续写时，才截取末尾动态视频，实际最多 14.9 秒，再把新增部分拼回本地完整母版。不会只取最后一帧或自动退化为图生视频。官方 URL 仍会及时下载，因为它是临时地址；中途失败会保留上一轮成功的本地检查点。

生成、编辑和续写都使用返回的 `request_id` 查询：

```powershell
python "$skillDir\scripts\grok_media.py" video status "<request_id>"
```

## 开发与测试

```text
grok-media-skill/
├── grok-media/
│   ├── SKILL.md
│   ├── config.json
│   ├── config.example.json
│   ├── agents/openai.yaml
│   ├── references/runtime-install.md
│   └── scripts/grok_media.py
└── tests/test_grok_media.py
```

运行离线测试：

```powershell
python -m unittest discover -s tests -v
```

测试使用本地模拟 HTTP 服务，不连接真实 API，不产生媒体费用；检测到 FFmpeg 时还会运行本地标准化、拼接和两轮模拟续写测试。公开仓库的 `config.json` 只保留虚拟地址和虚拟密钥；不要提交真实配置、生成结果或包含密钥的日志。
