diff --git a/scripts/i18n/translate.py b/scripts/i18n/translate.py index 62a1ed2..8c3057d 100755 --- a/scripts/i18n/translate.py +++ b/scripts/i18n/translate.py @@ -248,6 +248,13 @@ def _post_with_retries(url: str, headers: dict, payload: dict, *, extract) -> st try: with httpx.Client(timeout=HTTP_TIMEOUT) as client: resp = client.post(url, headers=headers, json=payload) + # Don't retry on 413: payload won't get smaller on next attempt. + if resp.status_code == 413: + raise RuntimeError( + f"413 Payload Too Large from {url} — skill body too big for this backend. " + f"Switch backend (TRANSLATE_BACKEND=anthropic), use a model with larger input budget, " + f"or set translated_by: human to lock the locale." + ) if resp.status_code == 429 or resp.status_code >= 500: raise httpx.HTTPStatusError(f"{resp.status_code}", request=resp.request, response=resp) resp.raise_for_status() @@ -499,11 +506,19 @@ def main(argv: list[str]) -> int: if not (skill_dir.is_dir() and (skill_dir / "SKILL.md").is_file()): continue for tl in target_locales: - plans.append(translate_skill( - skill_dir, tl, - check_only=args.check, mark_human=args.human, - backend=backend, model=model, endpoint=endpoint, - )) + try: + plans.append(translate_skill( + skill_dir, tl, + check_only=args.check, mark_human=args.human, + backend=backend, model=model, endpoint=endpoint, + )) + except Exception as e: # don't let one bad skill abort the entire run + plans.append({ + "skill": skill_dir.name, + "target": tl, + "actions": [], + "errors": [f"unhandled exception: {e}"], + }) needs = [p for p in plans if p.get("needs_translation")] errs = [p for p in plans if p.get("errors")] @@ -514,7 +529,7 @@ def main(argv: list[str]) -> int: for p in errs: for e in p["errors"]: print(f" ERROR [{p['skill']}/{p['target']}]: {e}") - return 1 if needs else 0 + return 1 if (needs or errs) else 0 print(f"Backend: {backend} Model: {model} Endpoint: {endpoint}\n") for p in plans: diff --git a/skills/dashscope-image-gen/SKILL.md b/skills/dashscope-image-gen/SKILL.md index cd79e87..a1e21f4 100644 --- a/skills/dashscope-image-gen/SKILL.md +++ b/skills/dashscope-image-gen/SKILL.md @@ -29,6 +29,24 @@ metadata: i18n: default_locale: en-US source_locale: zh-CN + locales: + - zh-CN + - en-US + zh-CN: + name: 阿里云 文生图 + short_desc: 基于阿里云通义万相的文本生成图片技能 + description: >- + 当用户希望使用阿里云 DashScope 的通义万相系列模型生成图片时使用此技能。支持多种模型层级(wan2.7-image-pro / wan2.7-image)的文生图,通过 OpenAI 兼容的 chat/completions API 同步生成图片。用户提到 生成图片、画图、文生图、创建图片、AI 绘画、生成插图、画一张、帮我画、设计图片、通义万相、万相、阿里云画图、dashscope 画图。 + body: ./SKILL.zh-CN.md + source_hash: sha256:d24415cd18ebf5d2 + translated_by: human + en-US: + name: DashScope Image Generation + short_desc: Text-to-image generation using Alibaba Cloud Wan (通义万相) models + description: "Use this skill when the user wants to generate images using Alibaba Cloud DashScope's Wan (通义万相) series models. Supports text-to-image with multiple model tiers (wan2.7-image-pro, wan2.7-image) via the OpenAI-compatible chat/completions API. Trigger keywords: generate image, draw, text-to-image, create image, AI painting, illustration, design picture, Wan, Tongyi Wanxiang, DashScope." + body: ./SKILL.md + source_hash: sha256:d24415cd18ebf5d2 + translated_by: human market: icon: >- 1` 时,`choices` 数组会有多个元素,每个 `message.content` 中都有一张图片。需要为每张图片执行下载+上传,然后逐一展示: +When `n > 1`, the `choices` array contains multiple entries, each with an image inside `message.content`. Download and upload each image, then render them one by one: ``` -![图片1描述](dc-media://mediaId1) -![图片2描述](dc-media://mediaId2) +![Image 1 description](dc-media://mediaId1) +![Image 2 description](dc-media://mediaId2) ``` -## 错误处理 +## Error Handling -- `success: false` + `error: "未找到匹配的供应商"`:未配置 DashScope Provider 或未启用 -- `success: false` + `error: "未配置 API Key"`:未填写 API Key -- `statusCode: 401`:API Key 无效或已过期 -- `statusCode: 429`:频率限制,稍后重试 -- `statusCode: 400` + `InvalidParameter`:参数错误(如尺寸不支持) -- `statusCode: 403` + `AccessDenied.Unpurchased`:模型未开通,需要在阿里云控制台开通 +- `success: false` + `error: "No matching provider"`: DashScope provider not configured or disabled +- `success: false` + `error: "API Key not configured"`: API Key missing +- `statusCode: 401`: API Key invalid or expired +- `statusCode: 429`: rate limited, retry later +- `statusCode: 400` + `InvalidParameter`: bad parameters (e.g. unsupported size) +- `statusCode: 403` + `AccessDenied.Unpurchased`: model not activated; enable it in the Alibaba Cloud console -## 注意事项 +## Notes -- 通过 compatible-mode 调用是同步的,通常 10-60 秒返回(wan2.7-image-pro 可能更长) -- 结果图片 URL 有时效,必须及时下载 -- 提示词建议用英文以获得最佳效果,中文也支持 -- 如果用户未明确要求模型/尺寸,默认使用 `wan2.7-image` + `1024x1024` +- compatible-mode calls are synchronous and typically return in 10–60 seconds (wan2.7-image-pro can take longer) +- Image URLs expire; download promptly +- English prompts usually produce the best results; Chinese is also supported +- When the user does not specify a model or size, default to `wan2.7-image` + `1024x1024` diff --git a/skills/dashscope-image-gen/SKILL.zh-CN.md b/skills/dashscope-image-gen/SKILL.zh-CN.md new file mode 100644 index 0000000..ed01ba6 --- /dev/null +++ b/skills/dashscope-image-gen/SKILL.zh-CN.md @@ -0,0 +1,161 @@ + + +# dashscope-image-gen 技能 + +## 强制规则(违反将导致功能失败) + +1. **必须用 HTTPS 访问 agent-service** — `https://127.0.0.1:${PORT}` 加 `-k` 跳过证书验证 +2. **必须通过 `/api/media/upload` 上传到 media-store** — /tmp 仅作下载/解码中转,不可直接以本地路径作为最终输出 +3. **必须使用 `dc-media://` 协议展示图片** — 唯一能让前端正确渲染的方式 +4. **全程使用 Bash curl** — 不要使用 HttpRequest 工具或 Python +5. **使用 compatible-mode(/chat/completions)** — 同步调用,响应直接包含图片 URL + +## 模型选择指南 + +| 模型 | 特点 | 适用场景 | +|------|------|---------| +| wan2.7-image-pro | 旗舰,4K 分辨率,thinking_mode | 用户要求最高画质、4K、细节丰富 | +| wan2.7-image | 标准高画质,thinking_mode | **默认首选**,无特殊要求时使用 | + +**默认规则**:用户未指定模型时,使用 `wan2.7-image`。 + +## 完整执行流程(严格按此三步执行) + +### 前置条件 + +- 用户已在资源管理器-算力中配置阿里云 DashScope Provider 并填写 API Key +- agent-service 正在运行 + +### 第一步:调用文生图 API(同步) + +通过 media-proxy 的 compatible-mode 端点生成图片,响应直接包含图片 URL: + +```bash +PORT=$(cat ~/.desirecore/agent-service.port) +curl -sk -X POST "https://127.0.0.1:${PORT}/api/media-proxy" \ + -H "Content-Type: application/json" \ + -d '{ + "provider": "dashscope", + "serviceType": "image_gen", + "endpoint": "/chat/completions", + "body": { + "model": "wan2.7-image", + "messages": [ + { + "role": "user", + "content": [ + {"type": "text", "text": "这里替换为图片描述(建议英文效果更好)"} + ] + } + ] + }, + "responseType": "json" + }' +``` + +**响应示例**: +```json +{ + "success": true, + "data": { + "request_id": "...", + "output": { + "choices": [ + { + "message": { + "role": "assistant", + "content": [ + { + "type": "image", + "image": "https://dashscope-result.oss.aliyuncs.com/..." + } + ] + }, + "finish_reason": "stop" + } + ] + } + }, + "statusCode": 200 +} +``` + +从 `data.output.choices[0].message.content` 中找到 `type: "image"` 的项,提取其 `image` URL。 + +### 第二步:下载并上传到 media-store + +图片 URL 有时效,必须立即下载并保存到本地 media-store: + +```bash +PORT=$(cat ~/.desirecore/agent-service.port) +IMAGE_URL="第一步响应中的 image URL" +curl -sL "$IMAGE_URL" -o /tmp/dashscope-gen.png && \ +curl -sk -X POST "https://127.0.0.1:${PORT}/api/media/upload" \ + -F "file=@/tmp/dashscope-gen.png;type=image/png" +``` + +从 JSON 响应中提取 `mediaId` 字段(格式如 `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.png`)。 + +### 第三步:用 dc-media 协议展示图片 + +在你的回复文本中直接写 Markdown 图片语法: + +``` +![图片描述](dc-media://这里替换为mediaId) +``` + +例如:`![森林中的白色狐狸](dc-media://a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6.png)` + +前端会自动将 `dc-media://` 转为可访问的图片 URL 并渲染出来。 + +## 参数映射 + +### 尺寸选择 + +通义万相通过 compatible-mode 调用时,尺寸通过 `size` 参数传入(放在请求体顶层): + +```json +{ + "model": "wan2.7-image", + "size": "1024x1024", + "messages": [...] +} +``` + +| 用户意图 | size 参数 | +|---------|-----------| +| 正方形/头像/默认 | "1024x1024" | +| 横版/风景/壁纸 | "1792x1024" | +| 竖版/手机/海报 | "1024x1792" | + +### 可选参数(加入请求体顶层) + +| 参数 | 说明 | +|------|------| +| `n` | 生成数量 1-4,默认 1 | +| `size` | 图片尺寸,如 "1024x1024" | + +## 多图生成 + +当 `n > 1` 时,`choices` 数组会有多个元素,每个 `message.content` 中都有一张图片。需要为每张图片执行下载+上传,然后逐一展示: + +``` +![图片1描述](dc-media://mediaId1) +![图片2描述](dc-media://mediaId2) +``` + +## 错误处理 + +- `success: false` + `error: "未找到匹配的供应商"`:未配置 DashScope Provider 或未启用 +- `success: false` + `error: "未配置 API Key"`:未填写 API Key +- `statusCode: 401`:API Key 无效或已过期 +- `statusCode: 429`:频率限制,稍后重试 +- `statusCode: 400` + `InvalidParameter`:参数错误(如尺寸不支持) +- `statusCode: 403` + `AccessDenied.Unpurchased`:模型未开通,需要在阿里云控制台开通 + +## 注意事项 + +- 通过 compatible-mode 调用是同步的,通常 10-60 秒返回(wan2.7-image-pro 可能更长) +- 结果图片 URL 有时效,必须及时下载 +- 提示词建议用英文以获得最佳效果,中文也支持 +- 如果用户未明确要求模型/尺寸,默认使用 `wan2.7-image` + `1024x1024` diff --git a/skills/manage-skills/SKILL.md b/skills/manage-skills/SKILL.md index 4e51529..65cdcf8 100644 --- a/skills/manage-skills/SKILL.md +++ b/skills/manage-skills/SKILL.md @@ -38,9 +38,8 @@ metadata: description: >- Manage the Skill lifecycle of an Agent: import, install, update, and delete Skills via HTTP API, or directly author standards-compliant SKILL.md files via the AgentFS filesystem. Use when the user requests to install Skills, import Skills from URL/Git, author new Skills, or manage existing Skills. body: ./SKILL.md - source_hash: sha256:7f116cc5de352822 - translated_by: ai:claude-opus-4-7 - translated_at: '2026-05-03' + source_hash: sha256:e67016840ba430ae + translated_by: human market: icon: >- - /tmp/xiaomi-tts-response.json -# 提取 base64 音频数据并解码 +# Extract and decode the base64 audio data cat /tmp/xiaomi-tts-response.json | jq -r '.data.choices[0].message.audio.data' | base64 -d > /tmp/xiaomi-tts.mp3 -# 上传到 media-store +# Upload to media-store curl -sk -X POST "https://127.0.0.1:${PORT}/api/media/upload" \ -F "file=@/tmp/xiaomi-tts.mp3;type=audio/mpeg" ``` -从 JSON 响应中提取 `mediaId` 字段(格式如 `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.mp3`)。 +Pick the `mediaId` field from the JSON response (format `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.mp3`). -### 第三步:用 dc-media 协议展示音频 +### Step 3: Render the audio via the dc-media protocol -在你的回复文本中直接写 Markdown 语法: +In your reply text, write Markdown syntax directly: ``` -![语音合成结果](dc-media://这里替换为mediaId) +![TTS result](dc-media://replace-with-mediaId) ``` -例如:`![TTS: 你好世界](dc-media://a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6.mp3)` +For example: `![TTS: Hello world](dc-media://a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6.mp3)` -前端会自动检测 `.mp3` 扩展名并渲染为音频播放器。 +The frontend detects the `.mp3` extension and renders an audio player. -## 参数映射 +## Parameter Mapping -### 请求体参数(放在 body 中) +### Request body parameters (inside `body`) -| 参数 | 说明 | 默认值 | +| Parameter | Description | Default | |------|------|--------| -| `model` | 模型名称 | "mimo-v2.5-tts" | -| `messages[0].role` | **必须为 "assistant"** | "assistant"(固定) | -| `messages[0].content` | 要合成的文本 | 必填 | -| `voice` | 音色 ID | "Bingtang"(中文)/ "Mia"(英文) | -| `audio.format` | 音频格式 | "mp3"(可选 "wav") | +| `model` | Model name | "mimo-v2.5-tts" | +| `messages[0].role` | **Must be "assistant"** | "assistant" (fixed) | +| `messages[0].content` | Text to synthesize | required | +| `voice` | Voice ID | "Bingtang" (Chinese) / "Mia" (English) | +| `audio.format` | Audio format | "mp3" (also accepts "wav") | -### 用户意图映射 +### User intent mapping -| 用户意图 | 参数选择 | +| User intent | Parameter | |---------|---------| -| 甜美/可爱 | voice: "Bingtang" | -| 温柔/知性 | voice: "Moli" | -| 年轻男声 | voice: "Suda" | -| 成熟男声 | voice: "Baihua" | -| 英文女声 | voice: "Mia" 或 "Chloe" | -| 英文男声 | voice: "Milo" 或 "Dean" | -| 高音质/无损 | response_format: "wav" | +| Sweet / cute | voice: "Bingtang" | +| Gentle / refined | voice: "Moli" | +| Young male | voice: "Suda" | +| Mature male | voice: "Baihua" | +| English female | voice: "Mia" or "Chloe" | +| English male | voice: "Milo" or "Dean" | +| High fidelity / lossless | audio.format: "wav" | -## 错误处理 +## Error Handling -- `success: false` + `error: "未找到匹配的供应商"`:未配置小米 MiMo Provider 或未启用 -- `success: false` + `error: "未配置 API Key"`:未填写 API Key -- `statusCode: 401`:API Key 无效或已过期 -- `statusCode: 429`:频率限制,稍后重试 -- `statusCode: 400`:参数错误(如 voice 不存在、文本为空) -- `statusCode: 403`:模型未开通或权限不足 +- `success: false` + `error: "No matching provider"`: Xiaomi MiMo provider not configured or disabled +- `success: false` + `error: "API Key not configured"`: API Key missing +- `statusCode: 401`: API Key invalid or expired +- `statusCode: 429`: rate limited, retry later +- `statusCode: 400`: bad parameters (e.g. unknown voice, empty text) +- `statusCode: 403`: model not activated or insufficient permission -## 注意事项 +## Notes -- 调用是同步的,通常 3-15 秒返回(视文本长度而定) -- 音频以 base64 返回,无外部 URL 时效问题,但数据量较大时注意 shell 参数长度限制 -- 长文本建议分段合成(每段不超过 500 字),然后逐段上传展示 -- 如果用户未明确要求音色/格式,默认使用 `mimo-v2.5-tts` + 按语言选音色 + `mp3` -- Token Plan 密钥(tp- 前缀)使用 `https://token-plan-cn.xiaomimimo.com/v1` 端点 -- 按量付费密钥使用 `https://api.xiaomimimo.com/v1` 端点 -- media-proxy 会自动根据配置选择正确的端点,技能无需区分 +- Calls are synchronous, typically 3–15 seconds depending on text length +- Audio is returned as base64, so URL expiry is not a concern, but watch shell argument length on long responses +- For long text, split into segments (no more than ~500 chars each), then upload and render each segment +- When the user doesn't specify, default to `mimo-v2.5-tts` + auto-selected voice by language + `mp3` +- Token Plan keys (prefix `tp-`) use the `https://token-plan-cn.xiaomimimo.com/v1` endpoint +- Pay-as-you-go keys use the `https://api.xiaomimimo.com/v1` endpoint +- media-proxy picks the correct endpoint based on configuration; the skill does not need to differentiate diff --git a/skills/xiaomi-tts/SKILL.zh-CN.md b/skills/xiaomi-tts/SKILL.zh-CN.md new file mode 100644 index 0000000..8987041 --- /dev/null +++ b/skills/xiaomi-tts/SKILL.zh-CN.md @@ -0,0 +1,192 @@ + + +# xiaomi-tts 技能 + +## 强制规则(违反将导致功能失败) + +1. **必须用 HTTPS 访问 agent-service** — `https://127.0.0.1:${PORT}` 加 `-k` 跳过证书验证 +2. **必须通过 `/api/media/upload` 上传到 media-store** — /tmp 仅作下载/解码中转,不可直接以本地路径作为最终输出 +3. **必须使用 `dc-media://` 协议展示音频** — 唯一能让前端正确渲染的方式 +4. **全程使用 Bash curl** — 不要使用 HttpRequest 工具或 Python +5. **使用 /chat/completions 端点** — 小米 MiMo TTS 使用 OpenAI 兼容格式 + +## 模型选择指南 + +| 模型 | 特点 | 适用场景 | +|------|------|---------| +| mimo-v2.5-tts | 标准 TTS,多种预置音色 | **默认首选**,常规语音合成 | +| mimo-v2.5-tts-voicedesign | 自定义音色设计 | 需要特定音色描述生成 | +| mimo-v2.5-tts-voiceclone | 声音克隆 | 需要克隆特定人声(需上传参考音频) | + +**默认规则**:用户未指定模型时,使用 `mimo-v2.5-tts`。 + +## 音色选择指南 + +### 预置音色 + +| voice_id | 名称 | 特点 | +|----------|------|------| +| default_zh | 默认中文 | 中文通用女声 | +| default_en | 默认英文 | 英文通用女声 | +| mimo_default | MiMo 默认 | MiMo 特色音色 | +| Bingtang | 冰糖 | 甜美女声 | +| Moli | 茉莉 | 温柔女声 | +| Suda | 苏打 | 年轻男声 | +| Baihua | 白桦 | 成熟男声 | +| Mia | Mia | 英文女声 | +| Chloe | Chloe | 英文女声 | +| Milo | Milo | 英文男声 | +| Dean | Dean | 英文男声 | + +**默认规则**:中文内容用 `Bingtang`,英文内容用 `Mia`,用户未指定时按内容语言自动选择。 + +## 完整执行流程(严格按此三步执行) + +### 前置条件 + +- 用户已在资源管理器-算力中配置小米 MiMo Provider 并填写 API Key +- agent-service 正在运行 + +### 第一步:调用 TTS API + +通过 media-proxy 的 /chat/completions 端点生成语音。 + +**重要**:messages 必须使用 `assistant` role(不是 user),要合成的文本放在 assistant 消息的 content 中。 + +```bash +PORT=$(cat ~/.desirecore/agent-service.port) +curl -sk -X POST "https://127.0.0.1:${PORT}/api/media-proxy" \ + -H "Content-Type: application/json" \ + -d '{ + "provider": "xiaomi", + "serviceType": "tts", + "endpoint": "/chat/completions", + "body": { + "model": "mimo-v2.5-tts", + "messages": [ + { + "role": "assistant", + "content": "这里替换为要合成的文本内容" + } + ], + "voice": "Bingtang", + "audio": {"format": "mp3"} + }, + "responseType": "json" + }' +``` + +**响应示例**: +```json +{ + "success": true, + "data": { + "id": "chatcmpl-...", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "audio": { + "data": "base64编码的音频数据...", + "format": "mp3" + } + }, + "finish_reason": "stop" + } + ] + }, + "statusCode": 200 +} +``` + +从 `data.choices[0].message.audio.data` 提取 base64 编码的音频数据。 + +### 第二步:解码并上传到 media-store + +音频以 base64 返回,需要解码后保存到本地 media-store。 + +**推荐方式**(先保存完整响应到文件,避免 shell 参数过长): + +```bash +PORT=$(cat ~/.desirecore/agent-service.port) +# 将完整请求和响应保存到文件 +curl -sk -X POST "https://127.0.0.1:${PORT}/api/media-proxy" \ + -H "Content-Type: application/json" \ + -d '{ + "provider": "xiaomi", + "serviceType": "tts", + "endpoint": "/chat/completions", + "body": { + "model": "mimo-v2.5-tts", + "messages": [{"role": "assistant", "content": "要合成的文本"}], + "voice": "Bingtang", + "audio": {"format": "mp3"} + }, + "responseType": "json" + }' > /tmp/xiaomi-tts-response.json + +# 提取 base64 音频数据并解码 +cat /tmp/xiaomi-tts-response.json | jq -r '.data.choices[0].message.audio.data' | base64 -d > /tmp/xiaomi-tts.mp3 + +# 上传到 media-store +curl -sk -X POST "https://127.0.0.1:${PORT}/api/media/upload" \ + -F "file=@/tmp/xiaomi-tts.mp3;type=audio/mpeg" +``` + +从 JSON 响应中提取 `mediaId` 字段(格式如 `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.mp3`)。 + +### 第三步:用 dc-media 协议展示音频 + +在你的回复文本中直接写 Markdown 语法: + +``` +![语音合成结果](dc-media://这里替换为mediaId) +``` + +例如:`![TTS: 你好世界](dc-media://a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6.mp3)` + +前端会自动检测 `.mp3` 扩展名并渲染为音频播放器。 + +## 参数映射 + +### 请求体参数(放在 body 中) + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `model` | 模型名称 | "mimo-v2.5-tts" | +| `messages[0].role` | **必须为 "assistant"** | "assistant"(固定) | +| `messages[0].content` | 要合成的文本 | 必填 | +| `voice` | 音色 ID | "Bingtang"(中文)/ "Mia"(英文) | +| `audio.format` | 音频格式 | "mp3"(可选 "wav") | + +### 用户意图映射 + +| 用户意图 | 参数选择 | +|---------|---------| +| 甜美/可爱 | voice: "Bingtang" | +| 温柔/知性 | voice: "Moli" | +| 年轻男声 | voice: "Suda" | +| 成熟男声 | voice: "Baihua" | +| 英文女声 | voice: "Mia" 或 "Chloe" | +| 英文男声 | voice: "Milo" 或 "Dean" | +| 高音质/无损 | audio.format: "wav" | + +## 错误处理 + +- `success: false` + `error: "未找到匹配的供应商"`:未配置小米 MiMo Provider 或未启用 +- `success: false` + `error: "未配置 API Key"`:未填写 API Key +- `statusCode: 401`:API Key 无效或已过期 +- `statusCode: 429`:频率限制,稍后重试 +- `statusCode: 400`:参数错误(如 voice 不存在、文本为空) +- `statusCode: 403`:模型未开通或权限不足 + +## 注意事项 + +- 调用是同步的,通常 3-15 秒返回(视文本长度而定) +- 音频以 base64 返回,无外部 URL 时效问题,但数据量较大时注意 shell 参数长度限制 +- 长文本建议分段合成(每段不超过 500 字),然后逐段上传展示 +- 如果用户未明确要求音色/格式,默认使用 `mimo-v2.5-tts` + 按语言选音色 + `mp3` +- Token Plan 密钥(tp- 前缀)使用 `https://token-plan-cn.xiaomimimo.com/v1` 端点 +- 按量付费密钥使用 `https://api.xiaomimimo.com/v1` 端点 +- media-proxy 会自动根据配置选择正确的端点,技能无需区分