@j-o-r/hello-dave 0.0.10 → 0.1.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.
- package/README.md +2 -0
- package/README.md.bak.1779452127 +240 -0
- package/TODO.md +30 -8
- package/agents/code_agent.js +6 -6
- package/agents/daisy_agent.js +10 -7
- package/agents/minimax.js +173 -0
- package/agents/stability.js +173 -0
- package/bin/codeDave +1 -1
- package/bin/dave.js +1 -1
- package/docs/music-toolsets.md +137 -0
- package/docs/plans/minimax-music-generation.md +80 -0
- package/docs/plans/unified-agent-architecture.md +146 -0
- package/docs/plans/websocket-streaming-plan.md.bak +317 -0
- package/docs/prompt/task_clarification_and_documentation.md +35 -0
- package/lib/API/minimax/ImageToolset.js +169 -0
- package/lib/API/minimax/MusicToolset.js +290 -0
- package/lib/API/minimax/VideoToolset.js +296 -0
- package/lib/API/minimax/image.generation.md +239 -0
- package/lib/API/minimax/image.js +219 -0
- package/lib/API/minimax/image.to.image.md +257 -0
- package/lib/API/minimax/index.js +16 -0
- package/lib/API/minimax/music.cover.preprocess.md +206 -0
- package/lib/API/minimax/music.generation.md +346 -0
- package/lib/API/minimax/music.js +257 -0
- package/lib/API/minimax/music.lyrics.generation.md +205 -0
- package/lib/API/minimax/video.download.md +133 -0
- package/lib/API/minimax/video.first.last.image.md +186 -0
- package/lib/API/minimax/video.from.image.md +206 -0
- package/lib/API/minimax/video.from.subject.md +164 -0
- package/lib/API/minimax/video.generation.md +192 -0
- package/lib/API/minimax/video.js +339 -0
- package/lib/API/minimax/video.query.md +128 -0
- package/lib/API/stability.ai/ImageToolset.js +357 -0
- package/lib/API/stability.ai/MusicToolset.js +302 -0
- package/lib/API/stability.ai/audio-3.md +205 -0
- package/lib/API/stability.ai/audio.js +679 -0
- package/lib/API/stability.ai/image.js +911 -0
- package/lib/API/stability.ai/image.md +271 -0
- package/lib/API/stability.ai/index.js +11 -0
- package/lib/API/stability.ai/openapi.json +17118 -0
- package/lib/API/x.ai/ImageToolset.js +165 -0
- package/lib/API/x.ai/image.editing.md +86 -0
- package/lib/API/x.ai/image.js +393 -0
- package/lib/API/x.ai/image.md +213 -0
- package/lib/API/x.ai/image.to.generation.md +494 -0
- package/lib/API/x.ai/image.to.video.md +23 -0
- package/lib/API/x.ai/index.js +9 -0
- package/lib/AgentManager.js +1 -1
- package/lib/CdnToolset.js +191 -0
- package/lib/ToolSet.js +19 -1
- package/lib/cdn.js +373 -0
- package/lib/fafs.js +3 -1
- package/lib/genericToolset.js +43 -166
- package/lib/index.js +9 -1
- package/package.json +2 -2
- package/types/API/minimax/ImageToolset.d.ts +3 -0
- package/types/API/minimax/MusicToolset.d.ts +3 -0
- package/types/API/minimax/VideoToolset.d.ts +3 -0
- package/types/API/minimax/image.d.ts +109 -0
- package/types/API/minimax/index.d.ts +15 -0
- package/types/API/minimax/music.d.ts +46 -0
- package/types/API/minimax/video.d.ts +165 -0
- package/types/API/stability.ai/ImageToolset.d.ts +3 -0
- package/types/API/stability.ai/MusicToolset.d.ts +3 -0
- package/types/API/stability.ai/audio.d.ts +193 -0
- package/types/API/stability.ai/image.d.ts +274 -0
- package/types/API/stability.ai/index.d.ts +11 -0
- package/types/API/x.ai/ImageToolset.d.ts +3 -0
- package/types/API/x.ai/image.d.ts +82 -0
- package/types/API/x.ai/index.d.ts +9 -0
- package/types/AgentManager.d.ts +1 -1
- package/types/CdnToolset.d.ts +20 -0
- package/types/ToolSet.d.ts +8 -0
- package/types/cdn.d.ts +141 -0
- package/types/index.d.ts +8 -2
- package/docs/multi-agent-clusters.md.bak +0 -229
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lib/API/minimax/MusicToolset.js
|
|
3
|
+
* @module minimax/MusicToolset
|
|
4
|
+
* @description Comprehensive ToolSet for the Minimax Music Generation API.
|
|
5
|
+
*
|
|
6
|
+
* Exposes four clear workflows matching the underlying music.js design:
|
|
7
|
+
* - create_music → text-to-music (music-2.6 / music-2.6-free)
|
|
8
|
+
* - change_music → cover generation (music-cover) with strict reference rules
|
|
9
|
+
* - analyze_music → preprocess reference audio for two-step covers
|
|
10
|
+
* - lyrics → generate, edit or continue song lyrics
|
|
11
|
+
*
|
|
12
|
+
* Designed for direct use by AI agents.
|
|
13
|
+
*
|
|
14
|
+
* Important notes:
|
|
15
|
+
* - Lyrics are optional for both instrumental and non-instrumental music generation.
|
|
16
|
+
* - Streaming is not supported; the `stream` parameter is always false and not exposed as an option.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import ToolSet from '../../ToolSet.js';
|
|
20
|
+
import * as minimax from './music.js';
|
|
21
|
+
|
|
22
|
+
const tools = new ToolSet('auto');
|
|
23
|
+
|
|
24
|
+
/* ============================================================
|
|
25
|
+
WORKFLOW 1: CREATE MUSIC (Text-to-Music)
|
|
26
|
+
============================================================ */
|
|
27
|
+
|
|
28
|
+
tools.add(
|
|
29
|
+
'create_music',
|
|
30
|
+
'Create original music from a text prompt and optional lyrics. ' +
|
|
31
|
+
'Lyrics are optional for both instrumental and non-instrumental tracks. ' +
|
|
32
|
+
'Uses music-2.6 or music-2.6-free models. ' +
|
|
33
|
+
'No reference audio is allowed — this is pure text-to-music generation.',
|
|
34
|
+
{
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
prompt: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Description of style, mood, and scenario (1–2000 characters). ' +
|
|
40
|
+
'Example: "Indie folk, melancholic, introspective, longing, solitary walk, coffee shop"'
|
|
41
|
+
},
|
|
42
|
+
lyrics: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Song lyrics using \\n for line breaks. Supports structure tags: ' +
|
|
45
|
+
'[Intro], [Verse], [Pre Chorus], [Chorus], [Interlude], [Bridge], [Outro], [Post Chorus], [Transition], [Break], [Hook], [Build Up], [Inst], [Solo]. ' +
|
|
46
|
+
'Length: 1–3500 characters. Optional for both instrumental and non-instrumental generation.'
|
|
47
|
+
},
|
|
48
|
+
model: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
enum: ['music-2.6', 'music-2.6-free'],
|
|
51
|
+
default: 'music-2.6',
|
|
52
|
+
description: 'Model to use. "music-2.6" recommended.'
|
|
53
|
+
},
|
|
54
|
+
is_instrumental: {
|
|
55
|
+
type: 'boolean',
|
|
56
|
+
default: false,
|
|
57
|
+
description: 'Generate instrumental music (no vocals). Lyrics are still optional.'
|
|
58
|
+
},
|
|
59
|
+
lyrics_optimizer: {
|
|
60
|
+
type: 'boolean',
|
|
61
|
+
default: false,
|
|
62
|
+
description: 'Auto-generate lyrics from prompt when lyrics is empty.'
|
|
63
|
+
},
|
|
64
|
+
output_format: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
enum: ['url', 'hex'],
|
|
67
|
+
default: 'url',
|
|
68
|
+
description: 'Output format. Default "url".'
|
|
69
|
+
},
|
|
70
|
+
audio_setting: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
sample_rate: { type: 'integer', enum: [16000, 24000, 32000, 44100], default: 44100 },
|
|
74
|
+
bitrate: { type: 'integer', enum: [32000, 64000, 128000, 256000], default: 256000 },
|
|
75
|
+
format: { type: 'string', enum: ['mp3', 'wav', 'pcm'], default: 'mp3' }
|
|
76
|
+
},
|
|
77
|
+
description: 'Audio output configuration.'
|
|
78
|
+
},
|
|
79
|
+
extra: { type: 'object', description: 'Additional parameters.' }
|
|
80
|
+
},
|
|
81
|
+
required: ['prompt']
|
|
82
|
+
},
|
|
83
|
+
async (params) => {
|
|
84
|
+
const result = await minimax.createMusic(params.prompt, params);
|
|
85
|
+
|
|
86
|
+
return JSON.stringify({
|
|
87
|
+
audio_url: result.audio_url,
|
|
88
|
+
local_path: result.local_path,
|
|
89
|
+
duration_ms: result.duration,
|
|
90
|
+
raw_response: result.raw,
|
|
91
|
+
note: 'Music created successfully with create_music (text-to-music workflow). ' +
|
|
92
|
+
'Audio saved to local_path.'
|
|
93
|
+
}, null, 2);
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
/* ============================================================
|
|
98
|
+
WORKFLOW 2: CHANGE MUSIC (Cover Generation)
|
|
99
|
+
============================================================ */
|
|
100
|
+
|
|
101
|
+
tools.add(
|
|
102
|
+
'change_music',
|
|
103
|
+
'Generate a cover version of a reference song or track. ' +
|
|
104
|
+
'Uses music-cover or music-cover-free models. ' +
|
|
105
|
+
'**Strict rules**: Provide exactly ONE of audio_url/audio_base64 (direct one-step) ' +
|
|
106
|
+
'OR cover_feature_id (two-step from analyze_music). Never both. ' +
|
|
107
|
+
'Lyrics are optional for direct reference (API can extract), required/recommended for cover_feature_id. ' +
|
|
108
|
+
'Lyrics are optional for both instrumental and non-instrumental covers.',
|
|
109
|
+
{
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
prompt: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Target style/mood for the cover (e.g. "same melody but jazz style"). Required.'
|
|
115
|
+
},
|
|
116
|
+
model: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
enum: ['music-cover', 'music-cover-free'],
|
|
119
|
+
default: 'music-cover',
|
|
120
|
+
description: 'Cover model to use.'
|
|
121
|
+
},
|
|
122
|
+
audio_url: {
|
|
123
|
+
type: 'string',
|
|
124
|
+
description: 'Public URL of reference audio for direct one-step cover. ' +
|
|
125
|
+
'Mutually exclusive with cover_feature_id.'
|
|
126
|
+
},
|
|
127
|
+
audio_base64: {
|
|
128
|
+
type: 'string',
|
|
129
|
+
description: 'Base64-encoded reference audio (alternative to audio_url).'
|
|
130
|
+
},
|
|
131
|
+
cover_feature_id: {
|
|
132
|
+
type: 'string',
|
|
133
|
+
description: 'Feature ID from analyze_music() for two-step cover with modified lyrics. ' +
|
|
134
|
+
'Mutually exclusive with audio_url/audio_base64.'
|
|
135
|
+
},
|
|
136
|
+
lyrics: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'New or modified structured lyrics. ' +
|
|
139
|
+
'Required/recommended when using cover_feature_id. ' +
|
|
140
|
+
'Optional when using direct audio_url (API can extract). ' +
|
|
141
|
+
'Optional for both instrumental and non-instrumental covers.'
|
|
142
|
+
},
|
|
143
|
+
lyrics_optimizer: {
|
|
144
|
+
type: 'boolean',
|
|
145
|
+
default: false,
|
|
146
|
+
description: 'Auto-optimize lyrics (limited support on cover models).'
|
|
147
|
+
},
|
|
148
|
+
is_instrumental: {
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
default: false,
|
|
151
|
+
description: 'Generate instrumental cover.'
|
|
152
|
+
},
|
|
153
|
+
output_format: {
|
|
154
|
+
type: 'string',
|
|
155
|
+
enum: ['url', 'hex'],
|
|
156
|
+
default: 'url',
|
|
157
|
+
description: 'Output format. Default "url".'
|
|
158
|
+
},
|
|
159
|
+
audio_setting: {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
sample_rate: { type: 'integer', default: 44100 },
|
|
163
|
+
bitrate: { type: 'integer', default: 256000 },
|
|
164
|
+
format: { type: 'string', default: 'mp3' }
|
|
165
|
+
},
|
|
166
|
+
description: 'Audio output settings.'
|
|
167
|
+
},
|
|
168
|
+
extra: { type: 'object', description: 'Additional parameters.' }
|
|
169
|
+
},
|
|
170
|
+
required: ['prompt']
|
|
171
|
+
},
|
|
172
|
+
async (params) => {
|
|
173
|
+
const result = await minimax.changeMusic(params.prompt, params);
|
|
174
|
+
|
|
175
|
+
return JSON.stringify({
|
|
176
|
+
audio_url: result.audio_url,
|
|
177
|
+
local_path: result.local_path,
|
|
178
|
+
duration_ms: result.duration,
|
|
179
|
+
raw_response: result.raw,
|
|
180
|
+
note: params.cover_feature_id
|
|
181
|
+
? 'Two-step cover generated using cover_feature_id (from analyze_music). ' +
|
|
182
|
+
'Lyrics were applied. Audio saved to local_path.'
|
|
183
|
+
: 'Direct one-step cover generated using audio_url/audio_base64. ' +
|
|
184
|
+
'Audio saved to local_path.'
|
|
185
|
+
}, null, 2);
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
/* ============================================================
|
|
190
|
+
WORKFLOW 3: ANALYZE MUSIC (Preprocess for Cover)
|
|
191
|
+
============================================================ */
|
|
192
|
+
|
|
193
|
+
tools.add(
|
|
194
|
+
'analyze_music',
|
|
195
|
+
'Preprocess a reference audio file to extract voice features, structure, and lyrics. ' +
|
|
196
|
+
'This is the first step of the advanced two-step cover workflow. ' +
|
|
197
|
+
'Returns a cover_feature_id that can be used with change_music for lyric modifications.',
|
|
198
|
+
{
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
audio_url: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'Public URL of the reference audio (6 seconds to 6 minutes, max 50MB).'
|
|
204
|
+
},
|
|
205
|
+
audio_base64: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'Base64-encoded reference audio (alternative to audio_url).'
|
|
208
|
+
},
|
|
209
|
+
model: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
enum: ['music-cover'],
|
|
212
|
+
default: 'music-cover',
|
|
213
|
+
description: 'Must be "music-cover".'
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
required: ['audio_url']
|
|
217
|
+
},
|
|
218
|
+
async (params) => {
|
|
219
|
+
const result = await minimax.analyzeMusic(params.audio_url, params);
|
|
220
|
+
|
|
221
|
+
return JSON.stringify({
|
|
222
|
+
cover_feature_id: result.cover_feature_id,
|
|
223
|
+
formatted_lyrics: result.formatted_lyrics,
|
|
224
|
+
structure_result: result.structure_result,
|
|
225
|
+
audio_duration_seconds: result.audio_duration,
|
|
226
|
+
trace_id: result.trace_id,
|
|
227
|
+
raw_response: result.raw,
|
|
228
|
+
note: 'Use this cover_feature_id with change_music for two-step covers with custom lyrics. ' +
|
|
229
|
+
'Valid for 24 hours. Same audio always returns the same ID.'
|
|
230
|
+
}, null, 2);
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
/* ============================================================
|
|
235
|
+
WORKFLOW 4: LYRICS (Generate / Edit / Snippet)
|
|
236
|
+
============================================================ */
|
|
237
|
+
|
|
238
|
+
tools.add(
|
|
239
|
+
'lyrics',
|
|
240
|
+
'Generate, edit, or continue song lyrics.\n\n' +
|
|
241
|
+
'Behavior depends on the parameters you provide:\n' +
|
|
242
|
+
'• mode = "write_full_song" (default) + no existing lyrics → creates a complete song with title, style tags, and full structured lyrics.\n' +
|
|
243
|
+
'• Short prompt only → generates a short snippet, hook, verse, or chorus idea.\n' +
|
|
244
|
+
'• mode = "edit" + existing lyrics → edits, rewrites, continues, or modifies the provided lyrics.\n' +
|
|
245
|
+
'• title parameter → keeps the specified song title in the output.',
|
|
246
|
+
{
|
|
247
|
+
type: 'object',
|
|
248
|
+
properties: {
|
|
249
|
+
prompt: {
|
|
250
|
+
type: 'string',
|
|
251
|
+
description: 'Theme, style, mood, or editing instruction.\n' +
|
|
252
|
+
'Examples:\n' +
|
|
253
|
+
'• "Energetic 80s new-wave synth-pop about longing and distant love"\n' +
|
|
254
|
+
'• "Make the bridge more emotional and add one final chorus repeat"\n' +
|
|
255
|
+
'• "Write a short melancholic verse in the style of Yazoo"'
|
|
256
|
+
},
|
|
257
|
+
mode: {
|
|
258
|
+
type: 'string',
|
|
259
|
+
enum: ['write_full_song', 'edit'],
|
|
260
|
+
default: 'write_full_song',
|
|
261
|
+
description: 'Generation mode.\n' +
|
|
262
|
+
'• "write_full_song" = create a full song or a short snippet.\n' +
|
|
263
|
+
'• "edit" = modify, continue, or rewrite existing lyrics (requires the lyrics parameter).'
|
|
264
|
+
},
|
|
265
|
+
lyrics: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
description: 'Existing lyrics to edit or continue.\n' +
|
|
268
|
+
'Only used when mode = "edit". ' +
|
|
269
|
+
'Can contain structure tags like [Verse], [Chorus], [Bridge], etc.'
|
|
270
|
+
},
|
|
271
|
+
title: {
|
|
272
|
+
type: 'string',
|
|
273
|
+
description: 'Optional song title. ' +
|
|
274
|
+
'If provided, the generated lyrics will keep this exact title.'
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
required: ['prompt']
|
|
278
|
+
},
|
|
279
|
+
async (params) => {
|
|
280
|
+
const result = await minimax.generateLyrics(params.prompt, params);
|
|
281
|
+
return JSON.stringify({
|
|
282
|
+
song_title: result.song_title,
|
|
283
|
+
style_tags: result.style_tags,
|
|
284
|
+
lyrics: result.lyrics,
|
|
285
|
+
note: `Lyrics generated using mode: ${params.mode || 'write_full_song'}`
|
|
286
|
+
}, null, 2);
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
export default tools;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lib/API/minimax/VideoToolset.js
|
|
3
|
+
* @module minimax/VideoToolset
|
|
4
|
+
* @description Comprehensive ToolSet for the Minimax Video Generation API.
|
|
5
|
+
*
|
|
6
|
+
* This ToolSet exposes the full Minimax Video API with every available option
|
|
7
|
+
* and detailed return values, following the same pattern as lib/genericToolset.js,
|
|
8
|
+
* MusicToolset.js, and ImageToolset.js.
|
|
9
|
+
*
|
|
10
|
+
* It is designed to be used directly by AI agents or merged into larger toolsets.
|
|
11
|
+
*
|
|
12
|
+
* Video generation is asynchronous. The main `generate_video` tool automatically
|
|
13
|
+
* waits for completion and downloads the MP4 to .cache/minimax/.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import videoToolset from './lib/API/minimax/VideoToolset.js';
|
|
17
|
+
*
|
|
18
|
+
* // Use in an agent:
|
|
19
|
+
* const toolset = agent.getToolset();
|
|
20
|
+
* toolset.merge(videoToolset);
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import ToolSet from '../../ToolSet.js';
|
|
24
|
+
import * as minimax from './video.js';
|
|
25
|
+
|
|
26
|
+
const tools = new ToolSet('auto');
|
|
27
|
+
|
|
28
|
+
/* ============================================================
|
|
29
|
+
CORE VIDEO GENERATION (Full async flow with auto-download)
|
|
30
|
+
============================================================ */
|
|
31
|
+
|
|
32
|
+
tools.add(
|
|
33
|
+
'generate_video',
|
|
34
|
+
'Generate a video using the Minimax Video Generation API. ' +
|
|
35
|
+
'Supports Text-to-Video, Image-to-Video, First & Last Frame, and Subject-Reference modes. ' +
|
|
36
|
+
'Automatically polls until the video is ready, then downloads the MP4 to .cache/minimax/. ' +
|
|
37
|
+
'This is the recommended high-level tool for video generation.',
|
|
38
|
+
{
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
prompt: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: 'Text description of the video, up to 2000 characters. ' +
|
|
44
|
+
'Supports camera movement commands in [brackets] for supported models. ' +
|
|
45
|
+
'Example: "A cute cat jumping on a wooden table [Static shot]"'
|
|
46
|
+
},
|
|
47
|
+
model: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
enum: [
|
|
50
|
+
'MiniMax-Hailuo-2.3',
|
|
51
|
+
'MiniMax-Hailuo-02',
|
|
52
|
+
'T2V-01-Director',
|
|
53
|
+
'T2V-01',
|
|
54
|
+
'MiniMax-Hailuo-2.3-Fast',
|
|
55
|
+
'I2V-01-Director',
|
|
56
|
+
'I2V-01-live',
|
|
57
|
+
'I2V-01',
|
|
58
|
+
'S2V-01'
|
|
59
|
+
],
|
|
60
|
+
default: 'MiniMax-Hailuo-2.3',
|
|
61
|
+
description: 'Video generation model. ' +
|
|
62
|
+
'"MiniMax-Hailuo-2.3" = recommended for text-to-video and image-to-video. ' +
|
|
63
|
+
'"MiniMax-Hailuo-02" = good for first-last frame. ' +
|
|
64
|
+
'"S2V-01" = subject reference mode.'
|
|
65
|
+
},
|
|
66
|
+
first_frame_image: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'Public URL or data: URL of the first frame image (for Image-to-Video or First-Last mode). ' +
|
|
69
|
+
'Formats: JPG, JPEG, PNG, WebP. Size < 20MB. Short side > 300px.'
|
|
70
|
+
},
|
|
71
|
+
last_frame_image: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'Public URL or data: URL of the last frame image (for First & Last Frame mode only).'
|
|
74
|
+
},
|
|
75
|
+
subject_reference: {
|
|
76
|
+
type: 'array',
|
|
77
|
+
items: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: {
|
|
80
|
+
type: { type: 'string', enum: ['character'], description: 'Subject type. Currently only "character" supported.' },
|
|
81
|
+
image: {
|
|
82
|
+
type: 'array',
|
|
83
|
+
items: { type: 'string' },
|
|
84
|
+
description: 'Array of reference image URLs (usually one image).'
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
required: ['type', 'image']
|
|
88
|
+
},
|
|
89
|
+
description: 'For Subject-Reference to Video (S2V-01 model). Array of character references.'
|
|
90
|
+
},
|
|
91
|
+
prompt_optimizer: {
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
default: true,
|
|
94
|
+
description: 'Automatically optimize the prompt. Default true.'
|
|
95
|
+
},
|
|
96
|
+
fast_pretreatment: {
|
|
97
|
+
type: 'boolean',
|
|
98
|
+
default: false,
|
|
99
|
+
description: 'Reduces optimization time when prompt_optimizer is enabled (Hailuo models only).'
|
|
100
|
+
},
|
|
101
|
+
duration: {
|
|
102
|
+
type: 'integer',
|
|
103
|
+
enum: [6, 10],
|
|
104
|
+
default: 6,
|
|
105
|
+
description: 'Video duration in seconds. Available values depend on model and resolution.'
|
|
106
|
+
},
|
|
107
|
+
resolution: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
enum: ['512P', '720P', '768P', '1080P'],
|
|
110
|
+
description: 'Video resolution. Options depend on model and duration. ' +
|
|
111
|
+
'Example: "768P" or "1080P".'
|
|
112
|
+
},
|
|
113
|
+
callback_url: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Optional callback URL for async status updates.'
|
|
116
|
+
},
|
|
117
|
+
max_wait_ms: {
|
|
118
|
+
type: 'integer',
|
|
119
|
+
default: 300000,
|
|
120
|
+
description: 'Maximum wait time for polling (default 5 minutes).'
|
|
121
|
+
},
|
|
122
|
+
poll_interval_ms: {
|
|
123
|
+
type: 'integer',
|
|
124
|
+
default: 5000,
|
|
125
|
+
description: 'Polling interval in milliseconds (default 5 seconds).'
|
|
126
|
+
},
|
|
127
|
+
extra: {
|
|
128
|
+
type: 'object',
|
|
129
|
+
description: 'Additional parameters not yet documented.'
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
required: ['prompt']
|
|
133
|
+
},
|
|
134
|
+
async (params) => {
|
|
135
|
+
const result = await minimax.generateVideo(params.prompt, params);
|
|
136
|
+
|
|
137
|
+
return JSON.stringify({
|
|
138
|
+
task_id: result.task_id,
|
|
139
|
+
file_id: result.file_id,
|
|
140
|
+
video_url: result.video_url,
|
|
141
|
+
local_path: result.local_path,
|
|
142
|
+
video_width: result.video_width,
|
|
143
|
+
video_height: result.video_height,
|
|
144
|
+
total_duration_ms: result.duration,
|
|
145
|
+
raw_responses: result.raw,
|
|
146
|
+
note: 'Video has been automatically saved to local_path. ' +
|
|
147
|
+
'The generation was polled until completion. Use max_wait_ms to adjust timeout.'
|
|
148
|
+
}, null, 2);
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
/* ============================================================
|
|
153
|
+
LOW-LEVEL: CREATE TASK ONLY
|
|
154
|
+
============================================================ */
|
|
155
|
+
|
|
156
|
+
tools.add(
|
|
157
|
+
'create_video_task',
|
|
158
|
+
'Create a video generation task without waiting. ' +
|
|
159
|
+
'Returns a task_id that can be polled manually with query_video_task. ' +
|
|
160
|
+
'Useful for advanced workflows or when using callbacks.',
|
|
161
|
+
{
|
|
162
|
+
type: 'object',
|
|
163
|
+
properties: {
|
|
164
|
+
prompt: {
|
|
165
|
+
type: 'string',
|
|
166
|
+
description: 'Text description of the video.'
|
|
167
|
+
},
|
|
168
|
+
model: {
|
|
169
|
+
type: 'string',
|
|
170
|
+
default: 'MiniMax-Hailuo-2.3',
|
|
171
|
+
description: 'Video model to use.'
|
|
172
|
+
},
|
|
173
|
+
first_frame_image: { type: 'string' },
|
|
174
|
+
last_frame_image: { type: 'string' },
|
|
175
|
+
subject_reference: { type: 'array' },
|
|
176
|
+
prompt_optimizer: { type: 'boolean', default: true },
|
|
177
|
+
duration: { type: 'integer', default: 6 },
|
|
178
|
+
resolution: { type: 'string' },
|
|
179
|
+
callback_url: { type: 'string' },
|
|
180
|
+
extra: { type: 'object' }
|
|
181
|
+
},
|
|
182
|
+
required: ['prompt']
|
|
183
|
+
},
|
|
184
|
+
async (params) => {
|
|
185
|
+
const result = await minimax.createVideoGenerationTask(params.prompt, params);
|
|
186
|
+
|
|
187
|
+
return JSON.stringify({
|
|
188
|
+
task_id: result.task_id,
|
|
189
|
+
duration_ms: result.duration,
|
|
190
|
+
raw_response: result.raw,
|
|
191
|
+
note: 'Use query_video_task with this task_id to check status.'
|
|
192
|
+
}, null, 2);
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
/* ============================================================
|
|
197
|
+
LOW-LEVEL: QUERY TASK STATUS
|
|
198
|
+
============================================================ */
|
|
199
|
+
|
|
200
|
+
tools.add(
|
|
201
|
+
'query_video_task',
|
|
202
|
+
'Query the current status of a video generation task. ' +
|
|
203
|
+
'Returns status (Preparing, Queueing, Processing, Success, Fail) and file_id when ready.',
|
|
204
|
+
{
|
|
205
|
+
type: 'object',
|
|
206
|
+
properties: {
|
|
207
|
+
task_id: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
description: 'The task_id returned by create_video_task or generate_video.'
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
required: ['task_id']
|
|
213
|
+
},
|
|
214
|
+
async (params) => {
|
|
215
|
+
const result = await minimax.queryVideoGenerationTask(params.task_id);
|
|
216
|
+
|
|
217
|
+
return JSON.stringify({
|
|
218
|
+
task_id: result.task_id,
|
|
219
|
+
status: result.status,
|
|
220
|
+
file_id: result.file_id,
|
|
221
|
+
video_width: result.video_width,
|
|
222
|
+
video_height: result.video_height,
|
|
223
|
+
raw_response: result.raw,
|
|
224
|
+
note: 'Poll this until status === "Success" to get the file_id.'
|
|
225
|
+
}, null, 2);
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
/* ============================================================
|
|
230
|
+
LOW-LEVEL: RETRIEVE FILE
|
|
231
|
+
============================================================ */
|
|
232
|
+
|
|
233
|
+
tools.add(
|
|
234
|
+
'retrieve_video_file',
|
|
235
|
+
'Retrieve the download URL and metadata for a completed video using its file_id.',
|
|
236
|
+
{
|
|
237
|
+
type: 'object',
|
|
238
|
+
properties: {
|
|
239
|
+
file_id: {
|
|
240
|
+
type: 'string',
|
|
241
|
+
description: 'The file_id returned when a video task reaches Success status.'
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
required: ['file_id']
|
|
245
|
+
},
|
|
246
|
+
async (params) => {
|
|
247
|
+
const result = await minimax.retrieveVideoFile(params.file_id);
|
|
248
|
+
|
|
249
|
+
return JSON.stringify({
|
|
250
|
+
file_id: result.file_id,
|
|
251
|
+
filename: result.filename,
|
|
252
|
+
download_url: result.download_url,
|
|
253
|
+
bytes: result.bytes,
|
|
254
|
+
raw_response: result.raw,
|
|
255
|
+
note: 'Use save_video_to_local with the download_url to download the file.'
|
|
256
|
+
}, null, 2);
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
/* ============================================================
|
|
261
|
+
HELPER: DIRECT LOCAL SAVE
|
|
262
|
+
============================================================ */
|
|
263
|
+
|
|
264
|
+
tools.add(
|
|
265
|
+
'save_video_to_local',
|
|
266
|
+
'Save a video from a download URL to a local file in .cache/minimax/. ' +
|
|
267
|
+
'Useful when you already have a download_url from retrieve_video_file.',
|
|
268
|
+
{
|
|
269
|
+
type: 'object',
|
|
270
|
+
properties: {
|
|
271
|
+
video_url: {
|
|
272
|
+
type: 'string',
|
|
273
|
+
description: 'Public download URL of the video (from retrieve_video_file).'
|
|
274
|
+
},
|
|
275
|
+
filename_prefix: {
|
|
276
|
+
type: 'string',
|
|
277
|
+
default: 'minimax-video',
|
|
278
|
+
description: 'Prefix for the generated filename.'
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
required: ['video_url']
|
|
282
|
+
},
|
|
283
|
+
async (params) => {
|
|
284
|
+
const localPath = await minimax.saveVideoToLocal(
|
|
285
|
+
params.video_url,
|
|
286
|
+
params.filename_prefix
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
return JSON.stringify({
|
|
290
|
+
local_path: localPath,
|
|
291
|
+
note: 'Video file saved successfully.'
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
export default tools;
|