@j-o-r/hello-dave 0.0.9 → 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 +31 -20
- package/agents/code_agent.js +6 -6
- package/agents/daisy_agent.js +10 -7
- package/agents/minimax.js +173 -0
- package/agents/spawn_agent.js +33 -10
- package/agents/stability.js +173 -0
- package/bin/codeDave +1 -1
- package/bin/dave.js +1 -1
- package/docs/dependencies.md +7 -0
- 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/spawn_agent.md +46 -44
- package/docs/prompt/task_clarification_and_documentation.md +35 -0
- package/docs/todo-archive-infra-2026-04-21.md +15 -0
- package/docs/todo-archive-v0.1.0.md +32 -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 +5 -3
- package/lib/genericToolset.js +75 -210
- 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/utils/syntax_check.sh +59 -15
- package/docs/multi-agent-clusters.md.bak +0 -229
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lib/API/minimax/ImageToolset.js
|
|
3
|
+
* @module minimax/ImageToolset
|
|
4
|
+
* @description Comprehensive ToolSet for the Minimax Image Generation API.
|
|
5
|
+
*
|
|
6
|
+
* This ToolSet exposes the full Minimax Image API with every available option
|
|
7
|
+
* and detailed return values, following the same pattern as lib/genericToolset.js
|
|
8
|
+
* and MusicToolset.js.
|
|
9
|
+
*
|
|
10
|
+
* It is designed to be used directly by AI agents or merged into larger toolsets.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* import imageToolset from './lib/API/minimax/ImageToolset.js';
|
|
14
|
+
*
|
|
15
|
+
* // Use in an agent:
|
|
16
|
+
* const toolset = agent.getToolset();
|
|
17
|
+
* toolset.merge(imageToolset);
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import ToolSet from '../../ToolSet.js';
|
|
21
|
+
import * as minimax from './image.js';
|
|
22
|
+
|
|
23
|
+
const tools = new ToolSet('auto');
|
|
24
|
+
|
|
25
|
+
/* ============================================================
|
|
26
|
+
CORE IMAGE GENERATION (Text-to-Image + Image-to-Image)
|
|
27
|
+
============================================================ */
|
|
28
|
+
|
|
29
|
+
tools.add(
|
|
30
|
+
'generate_image',
|
|
31
|
+
'Generate images using the Minimax Image Generation API. ' +
|
|
32
|
+
'Supports both Text-to-Image and Image-to-Image (via subject_reference). ' +
|
|
33
|
+
'All generated images are automatically saved locally in .cache/minimax/.',
|
|
34
|
+
{
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
prompt: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Text description of the image, max 1500 characters. ' +
|
|
40
|
+
'Example: "A serene mountain landscape at sunset, photorealistic, cinematic lighting"'
|
|
41
|
+
},
|
|
42
|
+
model: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
enum: ['image-01', 'image-01-live'],
|
|
45
|
+
default: 'image-01',
|
|
46
|
+
description: 'Model to use. "image-01" = standard (text-to-image and img2img). ' +
|
|
47
|
+
'"image-01-live" = optimized for image-to-image.'
|
|
48
|
+
},
|
|
49
|
+
aspect_ratio: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
enum: ['1:1', '16:9', '4:3', '3:2', '2:3', '3:4', '9:16', '21:9'],
|
|
52
|
+
default: '1:1',
|
|
53
|
+
description: 'Image aspect ratio. Default "1:1" (1024x1024).'
|
|
54
|
+
},
|
|
55
|
+
width: {
|
|
56
|
+
type: 'integer',
|
|
57
|
+
description: 'Image width in pixels (512-2048, must be divisible by 8). ' +
|
|
58
|
+
'Only effective for model "image-01". aspect_ratio takes priority if both are provided.'
|
|
59
|
+
},
|
|
60
|
+
height: {
|
|
61
|
+
type: 'integer',
|
|
62
|
+
description: 'Image height in pixels (same rules as width).'
|
|
63
|
+
},
|
|
64
|
+
response_format: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
enum: ['url', 'base64'],
|
|
67
|
+
default: 'url',
|
|
68
|
+
description: 'Output format. "url" returns temporary signed links (expire after 24h). ' +
|
|
69
|
+
'"base64" returns raw base64 data. Default is "url" (user preference).'
|
|
70
|
+
},
|
|
71
|
+
seed: {
|
|
72
|
+
type: 'integer',
|
|
73
|
+
description: 'Random seed for reproducible results. Omit for random seed per image.'
|
|
74
|
+
},
|
|
75
|
+
n: {
|
|
76
|
+
type: 'integer',
|
|
77
|
+
minimum: 1,
|
|
78
|
+
maximum: 9,
|
|
79
|
+
default: 1,
|
|
80
|
+
description: 'Number of images to generate per request (1-9).'
|
|
81
|
+
},
|
|
82
|
+
prompt_optimizer: {
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
default: false,
|
|
85
|
+
description: 'Enable automatic prompt optimization.'
|
|
86
|
+
},
|
|
87
|
+
subject_reference: {
|
|
88
|
+
type: 'array',
|
|
89
|
+
items: {
|
|
90
|
+
type: 'object',
|
|
91
|
+
properties: {
|
|
92
|
+
type: { type: 'string', enum: ['character'], description: 'Subject type. Currently only "character" supported.' },
|
|
93
|
+
image_file: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'Reference image URL or Base64 data URL (data:image/jpeg;base64,...). ' +
|
|
96
|
+
'Best results with front-facing portrait photos (JPG/PNG < 10MB).'
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
required: ['type', 'image_file']
|
|
100
|
+
},
|
|
101
|
+
description: 'For Image-to-Image generation. Array of subject references (currently supports character portraits).'
|
|
102
|
+
},
|
|
103
|
+
extra: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
description: 'Additional parameters not yet documented.'
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
required: ['prompt']
|
|
109
|
+
},
|
|
110
|
+
async (params) => {
|
|
111
|
+
const result = await minimax.requestImage(params.prompt, params);
|
|
112
|
+
|
|
113
|
+
return JSON.stringify({
|
|
114
|
+
image_urls: result.image_urls,
|
|
115
|
+
image_base64: result.image_base64,
|
|
116
|
+
local_paths: result.local_paths,
|
|
117
|
+
metadata: result.metadata,
|
|
118
|
+
trace_id: result.id,
|
|
119
|
+
duration_ms: result.duration,
|
|
120
|
+
raw_response: result.raw,
|
|
121
|
+
note: 'Images have been automatically saved to local_paths. ' +
|
|
122
|
+
'Use response_format="base64" if you need the raw data instead of URLs.'
|
|
123
|
+
}, null, 2);
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
/* ============================================================
|
|
128
|
+
HELPER: DIRECT LOCAL SAVE
|
|
129
|
+
============================================================ */
|
|
130
|
+
|
|
131
|
+
tools.add(
|
|
132
|
+
'save_image_to_local',
|
|
133
|
+
'Save image data (URL or base64) to a local file in .cache/minimax/. ' +
|
|
134
|
+
'Useful when you already have image data from another source or previous generation.',
|
|
135
|
+
{
|
|
136
|
+
type: 'object',
|
|
137
|
+
properties: {
|
|
138
|
+
image_data: {
|
|
139
|
+
type: 'string',
|
|
140
|
+
description: 'Either a URL or a base64-encoded image string (with or without data: prefix).'
|
|
141
|
+
},
|
|
142
|
+
filename_prefix: {
|
|
143
|
+
type: 'string',
|
|
144
|
+
default: 'minimax-image',
|
|
145
|
+
description: 'Prefix for the generated filename.'
|
|
146
|
+
},
|
|
147
|
+
index: {
|
|
148
|
+
type: 'integer',
|
|
149
|
+
default: 0,
|
|
150
|
+
description: 'Index suffix for multiple images (avoids filename collisions).'
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
required: ['image_data']
|
|
154
|
+
},
|
|
155
|
+
async (params) => {
|
|
156
|
+
const localPath = await minimax.saveImageToLocal(
|
|
157
|
+
params.image_data,
|
|
158
|
+
params.filename_prefix,
|
|
159
|
+
params.index ?? 0
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
return JSON.stringify({
|
|
163
|
+
local_path: localPath,
|
|
164
|
+
note: 'File saved successfully.'
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
export default tools;
|
|
@@ -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;
|