Skill: rockytian-top/rocky-minimax-media (version 1.0.0)

--- name: rocky_minimax_media description: MiniMax 媒体生成插件 - 图片/视频/TTS/音乐生成，支持交互式选择模型 plugin: true metadata: openclaw: type: plugin requires: models: - minimax-portal/MiniMax-M2.7-highspeed bins: - curl - bash version: 1.3.0 --- # MiniMax 媒体生成插件 v1.3.0 > ⚠️ **前置要求**: 必须先配置 MiniMax API Key ## 安装步骤 ### 1. 放置插件 ```bash # 把插件放到 skills 目录 cp -r rocky-minimax-media/ ~/.openclaw/skills/ ``` ### 2. 添加到 openclaw.json 在 `skills.entries` 中添加： ```json "rocky-minimax-media": { "enabled": true } ``` ### 3. 运行安装脚本（输入 API Key） ```bash cd ~/.openclaw/skills/rocky-minimax-media/scripts ./install.sh ``` → 交互式输入 MiniMax API Key → 自动写入 openclaw.json ### 4. 重启网关 ```bash openclaw gateway restart ``` ## 功能特性 | 功能 | 模型 | 说明 | |------|------|------| | 🎨 图片生成 | `image-01` | 交互式输入描述 | | 🎬 视频生成 | `MiniMax-Hailuo-2.3` / `2.3-Fast` | 用户可选 | | 🔊 TTS语音 | `speech-2.8-hd` | 3种音色可选 | | 🎵 音乐生成 | `music-2.6` / `music-2.5` | 用户可选 | ## 前置配置 ### 在 OpenClaw 中配置 MiniMax 获取 API Key: https://platform.minimaxi.com/ 安装时会自动提示输入，或手动在 `openclaw.json` 添加： ```json { "models": { "providers": { "minimax-portal": { "apiKey": "你的MiniMax API Key", "baseUrl": "https://api.minimaxi.com/anthropic", "api": "anthropic-messages", "models": [ { "id": "MiniMax-M2.7-highspeed", "name": "MiniMax-M2.7-highspeed" } ] } } } } ``` ## 调用方式 插件读取 `~/.openclaw/openclaw.json` 中的 MiniMax 配置。 输出目录可通过环境变量指定： ```bash MINIMAX_OUTPUT_DIR=/path/to/output ~/.openclaw/skills/rocky-minimax-media/scripts/minimax.sh image ``` ## 命令 ```bash ./minimax.sh test # 测试所有API ./minimax.sh image # 生成图片 ./minimax.sh tts # TTS语音 ./minimax.sh video # 视频生成 ./minimax.sh music # 音乐生成 ``` ## 交互选项 ### 视频模型选择 ``` 1) MiniMax-Hailuo-2.3 - 文生视频 2) MiniMax-Hailuo-2.3-Fast - 图生视频 ``` ### 音乐模型选择 ``` 1) music-2.6 - 最新版本 2) music-2.5 - 经典版本 ``` ### TTS音色选择 ``` 1) male-qn-qingse - 男声-青年-青涩 2) female-tianmei - 女声-甜妹 3) female-yujie - 女声-御姐 ``` ## API信息 - **API Base URL**: `https://api.minimaxi.com` - **TTS API**: `POST /v1/t2a_v2` - **图片API**: `POST /v1/image_generation` - **视频API**: `POST /v1/video_generation` - **音乐API**: `POST /v1/music_generation`

path: API.md
content: # MiniMax API 文档

## 环境配置

插件需要设置环境变量 `MINIMAX_API_KEY`：

```bash
export MINIMAX_API_KEY=你的MiniMax_API_Key
```

## API 端点

| 功能 | 端点 | 模型 |
|------|------|------|
| 图片生成 | `POST /v1/image_generation` | `image-01` |
| 视频生成 | `POST /v1/video_generation` | `MiniMax-Hailuo-2.3` / `MiniMax-Hailuo-2.3-Fast` |
| TTS语音 | `POST /v1/t2a_v2` | `speech-2.8-hd` |
| 音乐生成 | `POST /v1/music_generation` | `music-2.6` / `music-2.5` |

## API Base URL

```
https://api.minimaxi.com
```

## 模型说明

### 图片模型
- `image-01` - 通用图片生成模型

### 视频模型
- `MiniMax-Hailuo-2.3` - 文生视频，肢体动作/物理表现全面升级
- `MiniMax-Hailuo-2.3-Fast` - 图生视频，生成速度更快

### TTS模型
- `speech-2.8-hd` - 高清语音合成

### 音乐模型
- `music-2.6` - 最新版本，音质更好
- `music-2.5` - 经典版本

## TTS 可用音色

| voice_id | 说明 |
|----------|------|
| `male-qn-qingse` | 男声-青年-青涩 |
| `female-tianmei` | 女声-甜妹 |
| `female-yujie` | 女声-御姐 |

## API Key格式

MiniMax API Key 通常以 `sk-cp-` 开头，这是 Coding Plan Key。

## 错误码

| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 1004 | 登录失败 |
| 2013 | 参数错误 |
| 2056 |额度用尽 |
| 2061 | Token Plan 不支持该模型 |


path: README.md
content: # MiniMax Media Plugin

> Media generation plugin for OpenClaw - images, videos, TTS, and music

## Features

| Feature | Model | Description |
|---------|-------|-------------|
| 🖼️ Image | `image-01` | Interactive prompt input |
| 🎬 Video | `MiniMax-Hailuo-2.3` / `2.3-Fast` | Optional model selection |
| 🔊 TTS | `speech-2.8-hd` | 3 voice options |
| 🎵 Music | `music-2.6` / `music-2.5` | Optional model selection |

## Requirements

- OpenClaw gateway installed
- MiniMax API Key (configured during installation)

## Installation

### 1. Place the plugin
```bash
cp -r rocky-minimax-media/ ~/.openclaw/skills/
```

### 2. Add to openclaw.json
Add to `skills.entries`:
```json
"rocky-minimax-media": {
  "enabled": true
}
```

### 3. Run installation script
```bash
cd ~/.openclaw/skills/rocky-minimax-media/scripts
./install.sh
```
→ Enter your MiniMax API Key when prompted
→ Key will be automatically saved to openclaw.json

### 4. Restart gateway
```bash
openclaw gateway restart
```

## Configuration

### Get MiniMax API Key
Visit https://platform.minimaxi.com/ to register and get your API key.

The plugin reads the API key from `~/.openclaw/openclaw.json`. During installation, the script will automatically add the necessary configuration.

### Output Directory
```bash
# Default: ~/.openclaw/output
MINIMAX_OUTPUT_DIR=/path/to/output ~/.openclaw/skills/rocky-minimax-media/scripts/minimax.sh image
```

## Usage

```bash
./minimax.sh test   # Test all APIs
./minimax.sh image  # Generate image
./minimax.sh tts    # TTS voice synthesis
./minimax.sh video  # Video generation
./minimax.sh music  # Music generation
```

## Interactive Options

### Video Model
```
1) MiniMax-Hailuo-2.3        - Text-to-video, upgraded physical performance
2) MiniMax-Hailuo-2.3-Fast  - Image-to-video, faster generation
```

### Music Model
```
1) music-2.6  - Latest version, better quality
2) music-2.5  - Classic version
```

### TTS Voice
```
1) male-qn-qingse   - Male, young, inexperienced
2) female-tianmei   - Female, sweet
3) female-yujie     - Female, mature
```

## API Endpoints

- **Base URL**: `https://api.minimaxi.com`
- **TTS**: `POST /v1/t2a_v2`
- **Image**: `POST /v1/image_generation`
- **Video**: `POST /v1/video_generation`
- **Music**: `POST /v1/music_generation`

## Uninstall

Remove from `skills.entries` in openclaw.json and delete the plugin directory:
```bash
rm -rf ~/.openclaw/skills/rocky-minimax-media
```

Then restart the gateway.

---

**Version**: 1.3.0  
**For OpenClaw**: https://openclaw.ai


path: README.zh_CN.md
content: # MiniMax 媒体生成插件

> OpenClaw 媒体生成插件 - 图片、视频、TTS语音、音乐

## 功能特性

| 功能 | 模型 | 说明 |
|------|------|------|
| 🖼️ 图片生成 | `image-01` | 交互式输入描述 |
| 🎬 视频生成 | `MiniMax-Hailuo-2.3` / `2.3-Fast` | 可选模型 |
| 🔊 TTS语音 | `speech-2.8-hd` | 3种音色可选 |
| 🎵 音乐生成 | `music-2.6` / `music-2.5` | 可选模型 |

## 环境要求

- 已安装 OpenClaw 网关
- MiniMax API Key（在安装时配置）

## 安装步骤

### 1. 放置插件
```bash
cp -r rocky-minimax-media/ ~/.openclaw/skills/
```

### 2. 添加到 openclaw.json
在 `skills.entries` 中添加：
```json
"rocky-minimax-media": {
  "enabled": true
}
```

### 3. 运行安装脚本
```bash
cd ~/.openclaw/skills/rocky-minimax-media/scripts
./install.sh
```
→ 提示输入 MiniMax API Key
→ 自动写入 openclaw.json

### 4. 重启网关
```bash
openclaw gateway restart
```

## 配置说明

### 获取 MiniMax API Key
访问 https://platform.minimaxi.com/ 注册并获取 API Key

插件会从 `~/.openclaw/openclaw.json` 读取 API Key。安装时脚本会自动添加必要配置。

### 输出目录
```bash
# 默认: ~/.openclaw/output
MINIMAX_OUTPUT_DIR=/path/to/output ~/.openclaw/skills/rocky-minimax-media/scripts/minimax.sh image
```

## 使用方法

```bash
./minimax.sh test   # 测试所有API
./minimax.sh image  # 生成图片
./minimax.sh tts    # TTS语音合成
./minimax.sh video  # 视频生成
./minimax.sh music  # 音乐生成
```

## 交互选项

### 视频模型
```
1) MiniMax-Hailuo-2.3        - 文生视频，肢体动作/物理表现全面升级
2) MiniMax-Hailuo-2.3-Fast  - 图生视频，生成速度更快
```

### 音乐模型
```
1) music-2.6  - 最新版本，音质更好
2) music-2.5  - 经典版本
```

### TTS音色
```
1) male-qn-qingse   - 男声-青年-青涩
2) female-tianmei   - 女声-甜妹
3) female-yujie     - 女声-御姐
```

## API 接口

- **基础地址**: `https://api.minimaxi.com`
- **TTS**: `POST /v1/t2a_v2`
- **图片**: `POST /v1/image_generation`
- **视频**: `POST /v1/video_generation`
- **音乐**: `POST /v1/music_generation`

## 卸载

从 openclaw.json 的 `skills.entries` 中移除配置，并删除插件目录：
```bash
rm -rf ~/.openclaw/skills/rocky-minimax-media
```

然后重启网关。

---

**版本**: 1.3.0  
**OpenClaw**: https://openclaw.ai


path: generate.sh
content: #!/bin/bash
# MiniMax 媒体生成工具
# 用法: ./generate.sh [image|video|tts|music] [参数...]

[REDACTED_SECRET]"
BASE_URL="https://api.minimaxi.com"
OUTPUT_DIR="/Users/rocky/Desktop"

case "$1" in
  image)
    prompt="${2:-未来科技风格的大脑神经网络}"
    filename="${3:-output.jpg}"
    echo "生成图片: $prompt"
    url=$(curl -s -X POST "$BASE_URL/v1/image_generation" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"image-01\",\"prompt\":\"$prompt\",\"extra_params\":{\"image_size\":\"16:9\"}}" \
      | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('image_urls',[''])[0])")
    if [ -n "$url" ] && [ "$url" != "" ]; then
      curl -s -L "$url" -o "$OUTPUT_DIR/$filename"
      echo "✅ 已保存: $OUTPUT_DIR/$filename"
    else
      echo "❌ 生成失败"
    fi
    ;;
  tts)
    text="${2:-欢迎使用语音合成}"
    voice="${3:-male-qn-qingse}"
    filename="${4:-output.mp3}"
    echo "生成语音: $text"
    curl -s -X POST "$BASE_URL/v1/t2a_v2" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"speech-2.8-hd\",\"text\":\"$text\",\"stream\":false,\"voice_setting\":{\"voice_id\":\"$voice\"},\"audio_setting\":{\"format\":\"mp3\"}}" \
      > /tmp/tts_resp.json
    python3 << 'PYEOF'
import json
with open('/tmp/tts_resp.json') as f:
    d = json.load(f)
audio_hex = d.get('data',{}).get('audio','')
if audio_hex:
    with open('/Users/rocky/Desktop/output.mp3','wb') as f:
        f.write(bytes.fromhex(audio_hex))
    print("✅ 已保存: /Users/rocky/Desktop/output.mp3")
PYEOF
    ;;
  video)
    prompt="${2:-大脑神经元活动}"
    echo "生成视频: $prompt"
    task_id=$(curl -s -X POST "$BASE_URL/v1/video_generation" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"MiniMax-Hailuo-2.3\",\"prompt\":\"$prompt\"}" \
      | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('task_id',''))")
    echo "task_id: $task_id"
    echo "等待生成完成..."
    for i in {1..30}; do
      sleep 5
      status=$(curl -s "$BASE_URL/v1/query/video_generation?task_id=$task_id" \
        -H "Authorization: Bearer $API_KEY" \
        | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status',''))")
      echo "状态: $status"
      if [ "$status" = "Success" ]; then
        file_id=$(curl -s "$BASE_URL/v1/query/video_generation?task_id=$task_id" \
          -H "Authorization: Bearer $API_KEY" \
          | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_id',''))")
        download_url=$(curl -s "$BASE_URL/v1/files/retrieve?file_id=$file_id" \
          -H "Authorization: Bearer $API_KEY" \
          | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file',{}).get('download_url',''))")
        curl -s -L "$download_url" -o "$OUTPUT_DIR/video.mp4"
        echo "✅ 已保存: $OUTPUT_DIR/video.mp4"
        break
      fi
    done
    ;;
  music)
    prompt="${2:-欢快轻松的背景音乐}"
    lyrics="${3:-无歌词}"
    echo "生成音乐: $prompt"
    curl -s -X POST "$BASE_URL/v1/music_generation" \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"music-2.6\",\"prompt\":\"$prompt\",\"lyrics\":\"$lyrics\"}" \
      > /tmp/music_resp.json
    python3 << 'PYEOF'
import json
with open('/tmp/music_resp.json') as f:
    d = json.load(f)
audio_hex = d.get('data',{}).get('audio','')
if audio_hex:
    with open('/Users/rocky/Desktop/music.mp3','wb') as f:
        f.write(bytes.fromhex(audio_hex))
    print("✅ 已保存: /Users/rocky/Desktop/music.mp3")
PYEOF
    ;;
  *)
    echo "用法: $0 [image|tts|video|music] [参数...]"
    echo ""
    echo "示例:"
    echo "  $0 image \"未来科技风格的大脑\" output.jpg"
    echo "  $0 tts \"欢迎使用语音合成\" male-qn-qingse voice.mp3"
    echo "  $0 video \"大脑神经元活动\""
    echo "  $0 music \"欢快轻松\" \"歌词内容\""
    ;;
esac


path: manifest.json
content: {
  "name": "rocky-minimax-media",
  "version": "1.3.0",
  "description": "MiniMax 媒体生成插件 - 图片/视频/TTS/音乐（无硬编码）",
  "author": "rocky",
  "enabled": true,
  "requirements": {
    "MINIMAX_API_KEY": "必填！使用前必须先配置 MiniMax API Key"
  },
  "features": {
    "image": "✅ 图片生成 (image-01)",
    "video": "✅ 视频生成 (MiniMax-Hailuo-2.3 / MiniMax-Hailuo-2.3-Fast)",
    "tts": "✅ TTS语音 (speech-2.8-hd, 3种音色可选)",
    "music": "✅ 音乐生成 (music-2.6 / music-2.5, 用户可选)"
  },
  "config": {
    "MINIMAX_API_KEY": "必填，用户自己的API Key（必须先配置！）",
    "MINIMAX_OUTPUT_DIR": "可选，默认为 Agent工作区/output"
  },
  "last_updated": "2026-04-16"
}


path: scripts/install.sh
content: #!/bin/bash
# MiniMax 媒体生成插件安装脚本 v1.3.0
# 
# 功能：
# 1. 检查 OpenClaw 是否已配置 minimax 模型
# 2. 如未配置，交互式输入 API Key
# 3. 将配置写入 openclaw.json
#

set -e

# 颜色
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'

log() { echo -e "${GREEN}[✓]${NC} $1"; }
err() { echo -e "${RED}[✗]${NC} $1"; }
info() { echo -e "${YELLOW}[i]${NC} $1"; }
step() { echo -e "${BLUE}[➤]${NC} $1"; }

OPENCLAW_JSON="$HOME/.openclaw/openclaw.json"

echo ""
echo "=========================================="
echo "  MiniMax 媒体生成插件 - 安装向导"
echo "=========================================="
echo ""

# 步骤1：检查是否已有 minimax 配置
step "检查 OpenClaw 配置..."
echo ""

if [ ! -f "$OPENCLAW_JSON" ]; then
  err "未找到 openclaw.json 文件: $OPENCLAW_JSON"
  echo "请先安装并配置 OpenClaw"
  exit 1
fi

# 检查是否有 minimax-portal 配置
MINIMAX_CONFIG=$(python3 -c "
import json
with open('$OPENCLAW_JSON') as f:
    config = json.load(f)
providers = config.get('models', {}).get('providers', {})
minimax = providers.get('minimax-portal', {})
print('FOUND' if minimax.get('apiKey') else 'NOT_FOUND')
" 2>/dev/null)

if [ "$MINIMAX_CONFIG" = "FOUND" ]; then
  log "检测到已配置的 MiniMax 模型"
  info "API Key 已存在于 openclaw.json"
  echo ""
  echo "安装完成！插件将自动从 openclaw.json 读取 API Key"
  exit 0
fi

# 步骤2：检查是否需要 MiniMax 模型
info "未检测到 MiniMax API Key"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "  ⚠️  使用本插件需要 MiniMax API Key"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "获取方式:"
echo "  1. 访问 https://platform.minimaxi.com/"
echo "  2. 注册/登录账号"
echo "  3. 在 API Keys 页面创建新的 API Key"
echo ""
read -p "请输入您的 MiniMax API Key: " API_KEY

if [ -z "$API_KEY" ]; then
  err "API Key 不能为空，安装取消"
  exit 1
fi

# 步骤3：写入 openclaw.json
step "配置 MiniMax 模型..."

# 使用 python 来安全地修改 JSON
python3 << PYEOF
import json
import os

config_path = os.path.expanduser('$OPENCLAW_JSON')

with open(config_path) as f:
    config = json.load(f)

# 确保 models.providers 结构存在
if 'models' not in config:
    config['models'] = {}
if 'providers' not in config['models']:
    config['models']['providers'] = {}

# 添加 minimax-portal 配置
config['models']['providers']['minimax-portal'] = {
    "baseUrl": "https://api.minimaxi.com/anthropic",
    "apiKey": "$API_KEY",
    "api": "anthropic-messages",
    "authHeader": True,
    "models": [
        {
            "id": "MiniMax-M2.7-highspeed",
            "name": "MiniMax-M2.7-highspeed",
            "contextWindow": 131072,
            "maxTokens": 8192
        }
    ]
}

# 写回文件
with open(config_path, 'w') as f:
    json.dump(config, f, indent=2, ensure_ascii=False)

print('SUCCESS')
PYEOF

if [ $? -eq 0 ]; then
  log "API Key 已保存到 openclaw.json"
else
  err "保存失败，请手动配置"
  exit 1
fi

echo ""
echo "=========================================="
log "安装完成！"
echo "=========================================="
echo ""
echo "下一步:"
echo "  重启 OpenClaw 网关使配置生效"
echo "  命令: openclaw gateway restart"
echo ""


path: scripts/minimax.sh
content: #!/bin/bash
# MiniMax API 媒体生成插件 v1.3.0
# 
# 环境变量配置:
#   MINIMAX_OUTPUT_DIR - 输出目录（默认: ~/.openclaw/output）
#
# 用法: ./minimax.sh [test|image|tts|video|music]
#

# ============ 配置 ============
MINIMAX_OUTPUT_DIR="${MINIMAX_OUTPUT_DIR:-$HOME/.openclaw/output}"
BASE_URL="https://api.minimaxi.com"

# 确保输出目录存在
mkdir -p "$MINIMAX_OUTPUT_DIR"

# 颜色
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'

log() { echo -e "${GREEN}[✓]${NC} $1"; }
err() { echo -e "${RED}[✗]${NC} $1"; }
info() { echo -e "${YELLOW}[i]${NC} $1"; }

# ============ 从 openclaw.json 读取 MiniMax API Key ============
read_minimax_key() {
  local openclaw_json="$HOME/.openclaw/openclaw.json"
  
  # 尝试从 openclaw.json 读取 minimax apiKey
  if [ -f "$openclaw_json" ]; then
    # 使用 python3 解析 JSON（macOS 自带）
    MINIMAX_API_KEY=$(python3 -c "
import json, sys
try:
    with open('$openclaw_json') as f:
        config = json.load(f)
    # 尝试多种路径
    key = None
    
    # 路径1: models.providers.minimax-portal.apiKey
    try:
        key = config.get('models', {}).get('providers', {}).get('minimax-portal', {}).get('apiKey')
    except: pass
    
    # 路径2: providers.minimax.apiKey
    if not key:
        try:
            key = config.get('providers', {}).get('minimax', {}).get('apiKey')
        except: pass
    
    # 路径3: env 中的 MINIMAX_API_KEY (展开后的)
    if not key:
        try:
            env_vars = config.get('env', {})
            if isinstance(env_vars, dict):
                key = env_vars.get('MINIMAX_API_KEY')
            elif isinstance(env_vars, list):
                for item in env_vars:
                    if isinstance(item, dict) and item.get('key') == 'MINIMAX_API_KEY':
                        key = item.get('value')
                        break
        except: pass
    
    if key:
        print(key)
    else:
        print('')
except Exception as e:
    print('')
" 2>/dev/null)
    
    if [ -n "$MINIMAX_API_KEY" ]; then
      export MINIMAX_API_KEY
      return 0
    fi
  fi
  
  # 回退：从环境变量读取
  if [ -n "$MINIMAX_API_KEY" ]; then
    return 0
  fi
  
  return 1
}

# ============ 检查配置 ============
check_config() {
  # 尝试读取 openclaw.json 中的 key
  if ! read_minimax_key; then
    err "❌ MiniMax API 未配置！"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "  ⚠️  使用本插件前必须先配置 MiniMax 模型"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
    echo "📝 配置步骤:"
    echo ""
    echo "1. 确保已在 OpenClaw 中配置 MiniMax 模型"
    echo "   (在 openclaw.json 的 models.providers.minimax-portal)"
    echo ""
    echo "2. 如果是手动配置，添加 API Key:"
    echo "   {"
    echo "     \"models\": {"
    echo "       \"providers\": {"
    echo "         \"minimax-portal\": {"
    echo "           \"apiKey\": \"你的MiniMax API Key\""
    echo "         }"
    echo "       }"
    echo "     }"
    echo "   }"
    echo ""
    echo "3. 或设置环境变量:"
    echo "   export MINIMAX_API_KEY=你的API_Key"
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    exit 1
  fi
}

# ============ 测试所有功能 ============
test_all() {
  check_config
  echo "=========================================="
  echo "  MiniMax API 媒体生成测试"
  echo "=========================================="
  echo "输出目录: $MINIMAX_OUTPUT_DIR"
  echo ""
  
  echo "1. 图片生成..."
  resp=$(curl -s --max-time 15 -X POST "$BASE_URL/v1/image_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"image-01","prompt":"test","extra_params":{"image_size":"1:1"}}')
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  [ "$code" = "0" ] && log "图片生成 ✅" || err "图片生成 ❌ ($code)"
  
  echo "2. TTS语音..."
  resp=$(curl -s --max-time 10 -X POST "$BASE_URL/v1/t2a_v2" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"speech-2.8-hd","text":"test","stream":false,"voice_setting":{"voice_id":"male-qn-qingse"}}')
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  [ "$code" = "0" ] && log "TTS语音 ✅" || err "TTS语音 ❌ ($code)"
  
  echo "3. 视频生成 (MiniMax-Hailuo-2.3)..."
  resp=$(curl -s --max-time 10 -X POST "$BASE_URL/v1/video_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"MiniMax-Hailuo-2.3","prompt":"test"}')
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  [ "$code" = "0" ] && log "视频生成 ✅" || err "视频生成 ❌ ($code)"
  
  echo "4. 视频生成 (MiniMax-Hailuo-2.3-Fast)..."
  resp=$(curl -s --max-time 10 -X POST "$BASE_URL/v1/video_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"MiniMax-Hailuo-2.3-Fast","prompt":"test"}')
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  [ "$code" = "0" ] && log "视频生成-Fast ✅" || err "视频生成-Fast ❌ ($code)"
  
  echo "5. 音乐生成 (music-2.6)..."
  resp=$(curl -s --max-time 10 -X POST "$BASE_URL/v1/music_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"music-2.6","prompt":"test","lyrics":"test"}')
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  [ "$code" = "0" ] && log "音乐生成 ✅" || err "音乐生成 ❌ ($code)"
  
  echo ""
  echo "测试完成！"
}

# ============ 生成图片 ============
do_image() {
  check_config
  info "图片生成..."
  read -p "请输入图片描述 [默认: 科技感大脑]: " PROMPT
  PROMPT=${PROMPT:-科技感大脑}
  
  resp=$(curl -s --max-time 30 -X POST "$BASE_URL/v1/image_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"image-01\",\"prompt\":\"$PROMPT\",\"extra_params\":{\"image_size\":\"16:9\"}}")
  url=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('image_urls',[''])[0])" 2>/dev/null)
  if [ -n "$url" ]; then
    filename="minimax-image-$(date +%Y%m%d-%H%M%S).jpg"
    curl -s -L "$url" -o "$MINIMAX_OUTPUT_DIR/$filename"
    log "图片已保存: $MINIMAX_OUTPUT_DIR/$filename"
  else
    err "生成失败: $(echo $resp | head -c 100)"
  fi
}

# ============ TTS语音 ============
do_tts() {
  check_config
  info "TTS语音合成..."
  read -p "请输入要朗读的文本: " TEXT
  if [ -z "$TEXT" ]; then
    err "文本不能为空"
    exit 1
  fi
  
  echo "选择音色:"
  echo "  1) male-qn-qingse   - 男声-青年-青涩"
  echo "  2) female-tianmei   - 女声-甜妹"
  echo "  3) female-yujie     - 女声-御姐"
  read -p "请输入选项 [1-3，默认1]: " voice_choice
  voice_choice=${voice_choice:-1}
  case $voice_choice in
    2) VOICE_ID="female-tianmei" ;;
    3) VOICE_ID="female-yujie" ;;
    *) VOICE_ID="male-qn-qingse" ;;
  esac
  
  resp=$(curl -s --max-time 15 -X POST "$BASE_URL/v1/t2a_v2" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"speech-2.8-hd\",\"text\":\"$TEXT\",\"stream\":false,\"voice_setting\":{\"voice_id\":\"$VOICE_ID\"}}")
  
  filename="minimax-tts-$(date +%Y%m%d-%H%M%S).mp3"
  echo "$resp" | python3 -c "
import sys,json
content = sys.stdin.read()
try:
    idx = content.find('{')
    if idx >= 0:
        d = json.loads(content[idx:])
        audio_hex = d.get('data',{}).get('audio','')
        if audio_hex:
            audio = bytes.fromhex(audio_hex)
            with open('$MINIMAX_OUTPUT_DIR/$filename','wb') as f:
                f.write(audio)
            print('已保存: $MINIMAX_OUTPUT_DIR/$filename')
        else:
            print('失败:', d.get('base_resp',{}))
except Exception as e:
    print('解析失败:', e)
"
}

# ============ 视频生成 ============
do_video() {
  check_config
  echo "🎬 视频生成"
  echo ""
  echo "请选择视频模型："
  echo "  1) MiniMax-Hailuo-2.3        - 文生视频，肢体动作/物理表现全面升级"
  echo "  2) MiniMax-Hailuo-2.3-Fast  - 图生视频，生成速度更快"
  echo ""
  read -p "请输入选项 [1/2，默认1]: " choice
  choice=${choice:-1}
  
  if [ "$choice" = "2" ]; then
    MODEL="MiniMax-Hailuo-2.3-Fast"
  else
    MODEL="MiniMax-Hailuo-2.3"
  fi
  info "已选择: $MODEL"
  echo ""
  
  read -p "请输入视频描述 [默认: 神经元活动动画]: " PROMPT
  PROMPT=${PROMPT:-神经元活动动画}
  
  info "正在创建视频任务..."
  resp=$(curl -s --max-time 10 -X POST "$BASE_URL/v1/video_generation" \
    -H "Authorization: Bearer $MINIMAX_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"$MODEL\",\"prompt\":\"$PROMPT\"}")
  
  code=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('base_resp',{}).get('status_code',999))" 2>/dev/null)
  if [ "$code" != "0" ]; then
    err "创建失败: $(echo $resp | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("base_resp",{}).get("status_msg",d))' 2>/dev/null)"
    exit 1
  fi
  
  task_id=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('task_id',''))" 2>/dev/null)
  log "task_id: $task_id"
  info "等待视频生成（约60秒）..."
  for i in {1..12}; do
    sleep 5
    status=$(curl -s "$BASE_URL/v1/query/video_generation?task_id=$task_id" \
      -H "Authorization: Bearer $MINIMAX_API_KEY" \
      | python3 -c "import sys,json; print(json.load(sys.stdin).get('status',''))" 2>/dev/null)
    echo -n "."
    [ "$status" = "Success" ] && break
  done
  echo ""
  if [ "$status" = "Success" ]; then
    file_id=$(curl -s "$BASE_URL/v1/query/video_generation?task_id=$task_id" \
      -H "Authorization: Bearer $MINIMAX_API_KEY" \
      | python3 -c "import sys,json; print(json.load(sys.stdin).get('file_id',''))" 2>/dev/null)
    url=$(curl -s "$BASE_URL/v1/files/retrieve?file_id=$file_id" \
      -H "Authorization: Bearer $MINIMAX_API_KEY" \
      | python3 -c "import sys,json; print(json.load(sys.stdin).get('file',{}).get('download_url',''))" 2>/dev/null)
    filename="minimax-video-$(date +%Y%m%d-%H%M%S).mp4"
    curl -s -L "$url" -o "$MINIMAX_OUTPUT_DIR/$filename"
    log "视频已保存: $MINIMAX_OUTPUT_DIR/$filename"
  else
    err "视频生成失败或超时"
  fi
}

# ============ 音乐生成 ============
do_music() {
  check_config
  echo "🎵 音乐生成"
  echo ""
  echo "请选择音乐模型："
  echo "  1) music-2.6  - 最新版本，音质更好"
  echo "  2) music-2.5  - 经典版本"
  echo ""
  read -p "请输入选项 [1/2，默认1]: " choice
  choice=${choice:-1}
  
  if [ "$choice" = "2" ]; then
    MUSIC_MODEL="music-2.5"
  else
    MUSIC_MODEL="music-2.6"
  fi
  info "已选择: $MUSIC_MODEL"
  echo ""
  
  read -p "请输入音乐描述 [默认: 欢快轻松的背景音乐]: " PROMPT
  PROMPT=${PROMPT:-欢快轻松的背景音乐}
  
  read -p "请输入歌词（可选）: " LYRICS
  LYRICS=${LYRICS:-}
  
  info "正在生成音乐（可能需要30-120秒）..."
  if [ -n "$LYRICS" ]; then
    resp=$(curl -s --max-time 120 -X POST "$BASE_URL/v1/music_generation" \
      -H "Authorization: Bearer $MINIMAX_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"$MUSIC_MODEL\",\"prompt\":\"$PROMPT\",\"lyrics\":\"$LYRICS\"}")
  else
    resp=$(curl -s --max-time 120 -X POST "$BASE_URL/v1/music_generation" \
      -H "Authorization: Bearer $MINIMAX_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"model\":\"$MUSIC_MODEL\",\"prompt\":\"$PROMPT\"}")
  fi
  
  filename="minimax-music-$(date +%Y%m%d-%H%M%S).mp3"
  echo "$resp" | python3 -c "
import sys,json
content = sys.stdin.read()
try:
    idx = content.find('{')
    if idx >= 0:
        d = json.loads(content[idx:])
        audio_hex = d.get('data',{}).get('audio','')
        if audio_hex:
            audio = bytes.fromhex(audio_hex)
            with open('$MINIMAX_OUTPUT_DIR/$filename','wb') as f:
                f.write(audio)
            print('已保存: $MINIMAX_OUTPUT_DIR/$filename')
        else:
            print('失败:', d.get('base_resp',{}))
except Exception as e:
    print('解析失败:', e)
"
}

# ============ 主入口 ============
CMD=$1

case "$CMD" in
  test)   test_all ;;
  image)  do_image ;;
  tts)    do_tts ;;
  video)  do_video ;;
  music)  do_music ;;
  *)
    echo "MiniMax API 媒体生成工具 v1.3.0"
    echo ""
    echo "用法: $0 <命令>"
    echo ""
    echo "命令:"
    echo "  test   - 测试所有API"
    echo "  image  - 生成图片（交互式）"
    echo "  tts    - TTS语音合成（交互式）"
    echo "  video  - 视频生成（交互式选择模型）"
    echo "  music  - 音乐生成（交互式选择模型）"
    echo ""
    echo "环境变量:"
    echo "  MINIMAX_OUTPUT_DIR - 输出目录（默认: ~/.openclaw/output）"
    echo ""
    echo "前置要求:"
    echo "  - 必须在 OpenClaw 中配置 MiniMax 模型"
    echo "  - API Key 从 ~/.openclaw/openclaw.json 自动读取"
    echo ""
    echo "示例:"
    echo "  MINIMAX_OUTPUT_DIR=~/output $0 image"
    ;;
esac


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)