@ohmygame/minimax 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "https://www.ohmygame.ai/schema/plugin-2.json",
3
3
  "id": "ohmygame/minimax",
4
- "version": "0.1.2",
4
+ "version": "0.2.0",
5
5
  "engines": {
6
- "ohmygame-api": "^2.8.0"
6
+ "ohmygame-api": "^2.26.0"
7
7
  },
8
8
  "displayName": "%plugin.name%",
9
9
  "description": "%plugin.description%",
@@ -35,6 +35,101 @@
35
35
  "apiKey": "cnApiKey",
36
36
  "media": {
37
37
  "adapter": "./media/adapter.js",
38
+ "audio": {
39
+ "listVoices": true,
40
+ "models": [
41
+ {
42
+ "id": "speech-2.8-hd",
43
+ "title": "Speech 2.8 HD",
44
+ "kinds": [
45
+ "speech"
46
+ ],
47
+ "readsText": true,
48
+ "speaker": true,
49
+ "pitch": true,
50
+ "volume": true,
51
+ "formats": [
52
+ "mp3",
53
+ "wav"
54
+ ],
55
+ "sampleRatesByFormat": {
56
+ "mp3": [
57
+ 8000,
58
+ 16000,
59
+ 22050,
60
+ 24000,
61
+ 32000,
62
+ 44100
63
+ ],
64
+ "wav": [
65
+ 8000,
66
+ 16000,
67
+ 22050,
68
+ 24000,
69
+ 32000,
70
+ 44100
71
+ ]
72
+ },
73
+ "channels": [
74
+ 1,
75
+ 2
76
+ ],
77
+ "speedRange": [
78
+ -50,
79
+ 100
80
+ ],
81
+ "maxTextCharacters": 9999,
82
+ "data": {
83
+ "region": "cn"
84
+ }
85
+ },
86
+ {
87
+ "id": "speech-2.8-turbo",
88
+ "title": "Speech 2.8 Turbo",
89
+ "kinds": [
90
+ "speech"
91
+ ],
92
+ "readsText": true,
93
+ "speaker": true,
94
+ "pitch": true,
95
+ "volume": true,
96
+ "formats": [
97
+ "mp3",
98
+ "wav"
99
+ ],
100
+ "sampleRatesByFormat": {
101
+ "mp3": [
102
+ 8000,
103
+ 16000,
104
+ 22050,
105
+ 24000,
106
+ 32000,
107
+ 44100
108
+ ],
109
+ "wav": [
110
+ 8000,
111
+ 16000,
112
+ 22050,
113
+ 24000,
114
+ 32000,
115
+ 44100
116
+ ]
117
+ },
118
+ "channels": [
119
+ 1,
120
+ 2
121
+ ],
122
+ "speedRange": [
123
+ -50,
124
+ 100
125
+ ],
126
+ "maxTextCharacters": 9999,
127
+ "data": {
128
+ "region": "cn"
129
+ }
130
+ }
131
+ ]
132
+ },
38
133
  "video": {
39
134
  "models": [
40
135
  {
@@ -92,6 +187,101 @@
92
187
  "apiKey": "globalApiKey",
93
188
  "media": {
94
189
  "adapter": "./media/adapter.js",
190
+ "audio": {
191
+ "listVoices": true,
192
+ "models": [
193
+ {
194
+ "id": "speech-2.8-hd",
195
+ "title": "Speech 2.8 HD",
196
+ "kinds": [
197
+ "speech"
198
+ ],
199
+ "readsText": true,
200
+ "speaker": true,
201
+ "pitch": true,
202
+ "volume": true,
203
+ "formats": [
204
+ "mp3",
205
+ "wav"
206
+ ],
207
+ "sampleRatesByFormat": {
208
+ "mp3": [
209
+ 8000,
210
+ 16000,
211
+ 22050,
212
+ 24000,
213
+ 32000,
214
+ 44100
215
+ ],
216
+ "wav": [
217
+ 8000,
218
+ 16000,
219
+ 22050,
220
+ 24000,
221
+ 32000,
222
+ 44100
223
+ ]
224
+ },
225
+ "channels": [
226
+ 1,
227
+ 2
228
+ ],
229
+ "speedRange": [
230
+ -50,
231
+ 100
232
+ ],
233
+ "maxTextCharacters": 9999,
234
+ "data": {
235
+ "region": "global"
236
+ }
237
+ },
238
+ {
239
+ "id": "speech-2.8-turbo",
240
+ "title": "Speech 2.8 Turbo",
241
+ "kinds": [
242
+ "speech"
243
+ ],
244
+ "readsText": true,
245
+ "speaker": true,
246
+ "pitch": true,
247
+ "volume": true,
248
+ "formats": [
249
+ "mp3",
250
+ "wav"
251
+ ],
252
+ "sampleRatesByFormat": {
253
+ "mp3": [
254
+ 8000,
255
+ 16000,
256
+ 22050,
257
+ 24000,
258
+ 32000,
259
+ 44100
260
+ ],
261
+ "wav": [
262
+ 8000,
263
+ 16000,
264
+ 22050,
265
+ 24000,
266
+ 32000,
267
+ 44100
268
+ ]
269
+ },
270
+ "channels": [
271
+ 1,
272
+ 2
273
+ ],
274
+ "speedRange": [
275
+ -50,
276
+ 100
277
+ ],
278
+ "maxTextCharacters": 9999,
279
+ "data": {
280
+ "region": "global"
281
+ }
282
+ }
283
+ ]
284
+ },
95
285
  "video": {
96
286
  "models": [
97
287
  {
package/README.md CHANGED
@@ -1,11 +1,15 @@
1
- # MiniMax Video
1
+ # MiniMax Video and Speech (Beta)
2
2
 
3
3
  Optional MiniMax H3 and H3 Max video provider for OhMyGame, with independent China
4
4
  and Global API keys. Includes text-to-video, first/last frames and up to nine
5
5
  reference images. The provider and plugin details use the MiniMax logo.
6
6
 
7
- This is an optional beta plugin. It needs OhMyGame API 2.8 with durable retry ownership
8
- ([app #848](https://github.com/WhiteTowerAI/ohmygame/pull/848)).
7
+ Version 0.2.0 adds Speech 2.8 HD/Turbo with six reviewed system voice presets,
8
+ speed, pitch, volume and MP3/WAV output. Both regions reuse their existing keys.
9
+
10
+ This is an optional beta plugin. It needs OhMyGame API 2.26 for nested speech
11
+ response decoding ([app #908](https://github.com/WhiteTowerAI/ohmygame/pull/908));
12
+ video task recovery uses the existing durable retry ownership.
9
13
  Install it from the plugin catalog in a compatible app. It is not preinstalled.
10
14
  Apps with MiniMax migration support can move existing keys, switches, global and
11
15
  project defaults, and saved canvas selections to this plugin. Migration requires
@@ -26,7 +30,7 @@ starting a new generation. Plugin jobs retain the recovery behavior below.
26
30
 
27
31
  ## Local testing / 本地测试
28
32
 
29
- 1. Use an app with OhMyGame API 2.8. In Plugins, install this `plugins/minimax`
33
+ 1. Use an app with OhMyGame API 2.26. In Plugins, install this `plugins/minimax`
30
34
  folder, review its three network hosts, then enable it for every project.
31
35
  在配套应用分支中,打开插件页,安装本目录并启用;检查图标和中英文说明。
32
36
  2. Set either **China API key** from [platform.minimax.cn](https://platform.minimax.cn/)
@@ -62,7 +66,54 @@ regional secret lookup and durable journals with mocked HTTP. They cover request
62
66
  roles and ratios, restart, ambiguous submission, transient checks, rejected CDN
63
67
  hosts and downloads without keys. They make no live or paid vendor requests.
64
68
 
65
- ## Protocol and release notes
69
+ ## Speech / 配音
70
+
71
+ Create an Audio node, choose Speech and the MiniMax China/Global Speech 2.8 HD or
72
+ Turbo model, then choose a voice and enter the actual words to speak. The picker
73
+ provides six reviewed Chinese, Cantonese, English and Japanese system presets,
74
+ with local name/ID search. It is not your complete account voice list. Agent audio
75
+ requests can also supply an existing voice ID accepted by the host (letters,
76
+ numbers, `_` and `-`); IDs containing spaces or parentheses are not yet supported.
77
+
78
+ 在音频节点选择“语音”和 MiniMax 对应区域模型,选择音色后输入台词。首版提供六个
79
+ 经过文档核对的系统音色,不等于完整账号音色库。音色与音频参数保存在节点中。
80
+
81
+ The official account voice-list endpoint uses POST. The host's voice-query API
82
+ allows only reads via GET/HEAD; this release does not weaken that boundary or
83
+ claim to load private/cloned voices. Voice creation/cloning, mixing, subtitles,
84
+ streaming playback, music and sound effects are outside this increment.
85
+
86
+ Speech accepts fewer than 10,000 characters per request, speed 0.5–2×, pitch
87
+ −12…12 and the app's volume range −50…100 (mapped to gain 0.5–2×). MP3/WAV accept
88
+ 8/16/22.05/24/32/44.1 kHz and mono/stereo; unspecified output uses 32 kHz mono.
89
+ The host decodes MiniMax's nested hexadecimal response outside the plugin sandbox,
90
+ checks the business status and keeps the confirmed file for recovery. A lost or
91
+ invalid response cannot silently become another billable request. This is complete
92
+ file generation, not live playback. Speech quota/model-access depends on your
93
+ account and is separate from previously accepted video testing.
94
+
95
+ Additional local acceptance / 新增本地验收:
96
+
97
+ 1. Update using an API 2.26 app. Confirm the Beta badge/logo, existing region keys,
98
+ global/project switches and saved video model choices are preserved.
99
+ 2. In each region you use, generate a short Chinese/English line with HD/Turbo.
100
+ Check the selected voice, speed/pitch/volume, playback and Library/canvas asset.
101
+ 3. Try MP3 44.1 kHz and WAV 16 kHz, mono/stereo. Save/reopen and confirm selections.
102
+ 4. Quit during synthesis. A confirmed response should recover; an uncertain
103
+ response should be reported without automatically submitting another request.
104
+ 5. Existing H3/H3 Max video nodes should still generate/query their original jobs.
105
+ Migration from built-in settings still requires the app's reviewed npm package
106
+ list; this new release alone does not authorize a new migration target.
107
+
108
+ Official speech contracts checked 2026-11-15:
109
+ [Global TTS](https://platform.minimax.io/docs/api-reference/speech-t2a-http),
110
+ [China TTS](https://platform.minimax.cn/docs/api-reference/speech-t2a-http),
111
+ [Global voices](https://platform.minimax.io/docs/faq/system-voice-id),
112
+ [China voices](https://platform.minimax.cn/docs/faq/system-voice-id),
113
+ [account voice query](https://platform.minimax.io/docs/api-reference/voice-management-get).
114
+ Automated checks use synthetic audio and mocked HTTP, not live quality/availability.
115
+
116
+ ## Video protocol and release notes
66
117
 
67
118
  The sandbox cannot read keys or local files. The app adds the selected region's
68
119
  Bearer key to API requests and downloads outputs without it. Allowed hosts are
package/locales/en.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "plugin.name": "MiniMax Video",
3
- "plugin.description": "Make videos with MiniMax H3 and H3 Max using your own API key.",
4
- "plugin.longDescription": "Adds separate China and Global video providers. Supports text, first/last frames and up to nine reference images. Stop ends local waiting; the remote task may continue and incur charges. Compatible app versions can move existing MiniMax settings into this plugin.",
2
+ "plugin.name": "MiniMax",
3
+ "plugin.description": "Generate videos and character speech with your MiniMax account.",
4
+ "plugin.longDescription": "Adds separate China and Global video providers. Supports text, first/last frames and up to nine reference images. Stop ends local waiting; the remote task may continue and incur charges. Compatible app versions can move existing MiniMax settings into this plugin. Speech 2.8 HD/Turbo adds single-speaker speech, six system voice presets, speed/pitch/volume and MP3/WAV. China and Global retain separate keys. Account voice discovery, cloning and music are not included.",
5
5
  "provider.cn": "MiniMax China (plugin)",
6
6
  "provider.global": "MiniMax Global (plugin)",
7
7
  "config.cn.title": "China API key",
@@ -1,7 +1,7 @@
1
1
  {
2
- "plugin.name": "MiniMax 视频",
3
- "plugin.description": "使用自己的 API 密钥,通过 MiniMax H3 和 H3 Max 生成视频。",
4
- "plugin.longDescription": "提供独立的中国区和国际区视频服务,支持文字、首尾帧和最多九张参考图。停止只结束本地等待,远端任务可能继续运行并计费。支持迁移的应用版本可将原有 MiniMax 设置迁入本插件。",
2
+ "plugin.name": "MiniMax",
3
+ "plugin.description": "使用自己的 MiniMax 账号生成视频和角色配音。",
4
+ "plugin.longDescription": "提供独立的中国区和国际区视频服务,支持文字、首尾帧和最多九张参考图。停止只结束本地等待,远端任务可能继续运行并计费。支持迁移的应用版本可将原有 MiniMax 设置迁入本插件。新增 Speech 2.8 HD/Turbo 单人配音、六个系统音色预设、语速/音高/音量和 MP3/WAV。中国区与国际区仍使用独立密钥。暂不包含账号音色列表、克隆音色或音乐生成。",
5
5
  "provider.cn": "MiniMax 中国区(插件)",
6
6
  "provider.global": "MiniMax 国际区(插件)",
7
7
  "config.cn.title": "中国区 API 密钥",
package/media/adapter.js CHANGED
@@ -39,7 +39,53 @@ function retryAfter(response) {
39
39
  : 5;
40
40
  }
41
41
 
42
+ // A small reviewed set shared by the official China/Global system-voice lists.
43
+ // Account voice discovery is a POST endpoint; do not bypass the host's read-only voice-query boundary.
44
+ const SPEECH_VOICES = [
45
+ { id: "Robot_Armor", name: "机械战甲 · Robot Armor", labels: { language: "Chinese" } },
46
+ { id: "Arrogant_Miss", name: "嚣张小姐 · Arrogant Miss", labels: { language: "Chinese" } },
47
+ { id: "Cantonese_GentleLady", name: "温柔女声 · Cantonese Gentle Lady", labels: { language: "Cantonese" } },
48
+ { id: "English_Graceful_Lady", name: "Graceful Lady", labels: { language: "English" } },
49
+ { id: "English_Gentle-voiced_man", name: "Gentle-voiced Man", labels: { language: "English" } },
50
+ { id: "Japanese_LoyalKnight", name: "Loyal Knight", labels: { language: "Japanese" } },
51
+ ];
52
+
42
53
  export default {
54
+ audio: {
55
+ async start(input, host) {
56
+ const url = base(input.modelData?.region);
57
+ if (!["speech-2.8-hd", "speech-2.8-turbo"].includes(input.model))
58
+ return { error: "The selected MiniMax speech model is unavailable." };
59
+ if (!input.voiceId) return { error: "Choose a MiniMax speech voice." };
60
+ if (input.prompt.length >= 10000) return { error: "MiniMax speech takes fewer than 10,000 characters." };
61
+ const response = await host.submit("speech", url + "/v1/t2a_v2", {
62
+ method: "POST", auth: true, responseType: "file",
63
+ json: {
64
+ model: input.model, text: input.prompt, stream: false, output_format: "hex", language_boost: "auto",
65
+ voice_setting: { voice_id: input.voiceId, speed: 1 + (input.speed ?? 0) / 100, pitch: input.pitch ?? 0, vol: 1 + (input.volume ?? 0) / 100 },
66
+ audio_setting: { format: input.format, sample_rate: input.sampleRate ?? 32000, channel: input.channels ?? 1 },
67
+ },
68
+ decode: { format: "json", encoding: "hex", audioField: ["data", "audio"], statusField: ["base_resp", "status_code"], messageField: ["base_resp", "status_msg"], successCodes: [0] },
69
+ });
70
+ if (!response.ok) {
71
+ const body = await response.json().catch(() => null);
72
+ const detail = body?.base_resp?.status_msg ?? body?.error?.message;
73
+ return { error: `MiniMax speech HTTP ${response.status}${typeof detail === "string" ? ": " + detail.slice(0, 700) : ""}` };
74
+ }
75
+ const metadata = response.metadata;
76
+ if (metadata.data?.status !== 2) return { error: "MiniMax returned incomplete speech audio." };
77
+ return { outputs: [{ ...await response.file(),
78
+ ...(metadata.trace_id ? { requestId: metadata.trace_id } : {}),
79
+ ...(metadata.extra_info?.usage_characters !== undefined ? { usageCharacters: metadata.extra_info.usage_characters } : {}),
80
+ ...(metadata.extra_info?.audio_length !== undefined ? { originalDurationMs: metadata.extra_info.audio_length } : {}),
81
+ }] };
82
+ },
83
+ voices(input) {
84
+ if (input.pageToken) return { error: "MiniMax preset voices have no next page." };
85
+ const search = input.search?.trim().toLowerCase();
86
+ return { voices: SPEECH_VOICES.filter(voice => !search || `${voice.id} ${voice.name} ${voice.labels.language}`.toLowerCase().includes(search)) };
87
+ },
88
+ },
43
89
  video: {
44
90
  async start(input, host) {
45
91
  const region = input.modelData && input.modelData.region;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ohmygame/minimax",
3
- "version": "0.1.2",
4
- "description": "MiniMax H3 video models for China and Global accounts.",
3
+ "version": "0.2.0",
4
+ "description": "MiniMax video and speech generation for OhMyGame.",
5
5
  "keywords": [
6
6
  "ohmygame-plugin",
7
7
  "model-provider",