@j-o-r/hello-dave 0.1.1 → 0.1.5
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/CHANGELOG.md +42 -25
- package/README.md +81 -221
- package/TODO.md +173 -35
- package/agents/agent_creator.js +105 -0
- package/agents/agent_creator.prompt.md +371 -0
- package/agents/ask_agent.js +64 -127
- package/agents/claude_agent.js +68 -0
- package/agents/code_agent.js +55 -135
- package/agents/code_agent.prompt.md +50 -0
- package/agents/echo_agent.js +76 -0
- package/agents/financial_expert.js +75 -0
- package/agents/gpt_agent.js +52 -103
- package/agents/gpt_code.js +81 -0
- package/agents/grok_agent.js +58 -114
- package/agents/minimax_agent.js +92 -0
- package/agents/mureka_agent.js +77 -0
- package/agents/planner_agent.js +172 -0
- package/agents/stability_agent.js +87 -0
- package/agents/test_agent.js +75 -157
- package/agents/weather_agent.js +73 -0
- package/agents/workflow_agent.js +189 -0
- package/bin/dave.js +436 -184
- package/docs/bin-dave.md +85 -35
- package/docs/cdn-ssh.md +100 -0
- package/docs/creating-agents.md +301 -0
- package/docs/creating-toolsets.md +336 -0
- package/docs/docs-organization.md +48 -0
- package/docs/project-overview.md +86 -51
- package/lib/API/elevenlabs.io/music.compose.md +441 -0
- package/lib/API/elevenlabs.io/music.create-composition-plan.md +370 -0
- package/lib/API/elevenlabs.io/music.stream.md +425 -0
- package/lib/API/lalal.ai/lalal.js +445 -0
- package/lib/API/lalal.ai/openapi.json +2614 -0
- package/lib/API/minimax/ImageToolset.js +82 -37
- package/lib/API/minimax/MusicToolset.js +125 -79
- package/lib/API/minimax/VideoToolset.js +170 -167
- package/lib/API/minimax/image.js +5 -1
- package/lib/API/minimax/music.js +210 -23
- package/lib/API/minimax/video.js +242 -53
- package/lib/API/mureka/MusicToolset.js +646 -0
- package/lib/API/mureka/README.md +41 -0
- package/lib/API/mureka/index.js +7 -0
- package/lib/API/mureka/music.js +658 -0
- package/lib/API/openai.com/index.js +7 -0
- package/lib/API/openai.com/{reponses/text.js → responses.js} +64 -18
- package/lib/API/openai.com/video.create.character.md +40 -0
- package/lib/API/openai.com/video.create.md +219 -0
- package/lib/API/openai.com/video.delete.md +44 -0
- package/lib/API/openai.com/video.download.md +31 -0
- package/lib/API/openai.com/video.edit.md +155 -0
- package/lib/API/openai.com/video.extend.md +166 -0
- package/lib/API/openai.com/video.fetch.character.md +43 -0
- package/lib/API/openai.com/video.js +784 -0
- package/lib/API/openai.com/video.list.md +201 -0
- package/lib/API/openai.com/video.remix.md +175 -0
- package/lib/API/openai.com/video.retrieve.md +139 -0
- package/lib/API/openai.com/videoToolset.js +616 -0
- package/lib/API/stability.ai/ImageToolset.js +131 -40
- package/lib/API/stability.ai/MusicToolset.js +79 -47
- package/lib/API/stability.ai/audio.js +63 -131
- package/lib/API/x.ai/chat.responses.md +1040 -0
- package/lib/API/x.ai/image.js +229 -59
- package/lib/API/x.ai/imageToolset.js +376 -0
- package/lib/API/x.ai/index.js +1 -1
- package/lib/API/x.ai/responses.js +9 -18
- package/lib/Agent.js +271 -0
- package/lib/Agent.js.old +284 -0
- package/lib/AgentLauncher.js +593 -0
- package/lib/Cli.js +87 -13
- package/lib/Prompt.js +23 -1
- package/lib/Session.js +5 -4
- package/lib/ToolSet.js +102 -6
- package/lib/agentLoader.js +369 -0
- package/lib/cdn.js +67 -231
- package/lib/{CdnToolset.js → cdnToolset.js} +47 -64
- package/lib/defaultToolsets.js +43 -0
- package/lib/fafs.js +1 -1
- package/lib/genericToolset.js +442 -119
- package/lib/handOffToolset.js +179 -0
- package/lib/index.js +34 -27
- package/lib/toolsetLoader.js +248 -0
- package/package.json +10 -4
- package/types/API/lalal.ai/lalal.d.ts +116 -0
- package/types/API/minimax/image.d.ts +2 -1
- package/types/API/minimax/music.d.ts +189 -26
- package/types/API/minimax/video.d.ts +100 -31
- package/types/API/mureka/index.d.ts +7 -0
- package/types/API/mureka/music.d.ts +472 -0
- package/types/API/openai.com/index.d.ts +7 -0
- package/types/API/openai.com/{reponses/text.d.ts → responses.d.ts} +11 -11
- package/types/API/openai.com/video.d.ts +409 -0
- package/types/API/openai.com/videoToolset.d.ts +24 -0
- package/types/API/stability.ai/audio.d.ts +14 -103
- package/types/API/stability.ai/image.d.ts +2 -2
- package/types/API/x.ai/image.d.ts +138 -26
- package/types/API/x.ai/imageToolset.d.ts +3 -0
- package/types/API/x.ai/index.d.ts +1 -1
- package/types/API/x.ai/responses.d.ts +4 -4
- package/types/Agent.d.ts +123 -0
- package/types/AgentLauncher.d.ts +250 -0
- package/types/Cli.d.ts +28 -8
- package/types/Prompt.d.ts +23 -5
- package/types/Session.d.ts +1 -1
- package/types/ToolSet.d.ts +10 -0
- package/types/agentLoader.d.ts +78 -0
- package/types/cdn.d.ts +15 -90
- package/types/defaultToolsets.d.ts +9 -0
- package/types/fafs.d.ts +1 -1
- package/types/genericToolset.d.ts +1 -1
- package/types/handOffToolset.d.ts +28 -0
- package/types/index.d.ts +19 -17
- package/types/toolsetLoader.d.ts +114 -0
- package/utils/format_log.js +101 -23
- package/utils/launch_agent.js +18 -0
- package/utils/list_sessions.sh +13 -5
- package/utils/search_sessions.sh +65 -29
- package/utils/toolsets.js +33 -0
- package/README.md.bak.1779452127 +0 -240
- package/agents/codeserver.sh +0 -47
- package/agents/daisy_agent.js +0 -173
- package/agents/docs_agent.js +0 -148
- package/agents/memory_agent.js +0 -263
- package/agents/minimax.js +0 -173
- package/agents/npm_agent.js +0 -202
- package/agents/prompt_agent.js +0 -133
- package/agents/readme_agent.js +0 -148
- package/agents/spawn_agent.js +0 -160
- package/agents/stability.js +0 -173
- package/agents/todo_agent.js +0 -175
- package/bin/codeDave +0 -58
- package/docs/agent-dave-websocket-protocol.md +0 -180
- package/docs/agent-manager.md +0 -244
- package/docs/codeserver-pattern.md +0 -191
- package/docs/generic-toolset.md +0 -326
- package/docs/howtos/agent-networking.md +0 -253
- package/docs/howtos/spawn-agents.md.bak +0 -200
- package/docs/howtos/spawn-agents.md.bak_new +0 -200
- package/docs/multi-agent-clusters.md +0 -265
- package/docs/music-toolsets.md +0 -137
- package/docs/path-resolution-best-practices.md +0 -104
- package/docs/plans/minimax-music-generation.md +0 -80
- package/docs/plans/unified-agent-architecture.md +0 -146
- package/docs/plans/websocket-streaming-plan.md.bak +0 -317
- package/docs/prompt/spawn_agent.md +0 -175
- package/docs/prompt/spawn_agent.md.bak +0 -201
- package/docs/prompt/task_clarification_and_documentation.md +0 -35
- package/docs/prompt-class.md +0 -141
- package/docs/todo-archive-infra-2026-04-21.md +0 -15
- package/docs/todo-archive-v0.0.8.md +0 -1
- package/docs/todo-archive-v0.1.0.md +0 -32
- package/docs/todo-archive.md +0 -44
- package/docs/tools-syntax-validation.md +0 -121
- package/docs/toolset.md +0 -164
- package/docs/xai-responses.md +0 -111
- package/docs/xai_collections.md +0 -106
- package/lib/API/x.ai/ImageToolset.js +0 -165
- package/lib/API/x.ai/text.js +0 -415
- package/lib/AgentClient.js +0 -248
- package/lib/AgentManager.js +0 -245
- package/lib/AgentServer.js +0 -404
- package/lib/wsCli.js +0 -287
- package/lib/wsIO.js +0 -90
- package/types/API/x.ai/text.d.ts +0 -286
- package/types/AgentClient.d.ts +0 -109
- package/types/AgentManager.d.ts +0 -100
- package/types/AgentServer.d.ts +0 -89
- package/types/wsCli.d.ts +0 -17
- package/types/wsIO.d.ts +0 -30
- package/utils/test.sh +0 -46
- /package/docs/{suggestions.md → _notes/token-counts.md} +0 -0
- /package/lib/API/openai.com/{reponses/MESSAGES.md → MESSAGES.md} +0 -0
- /package/types/API/{x.ai/ImageToolset.d.ts → mureka/MusicToolset.d.ts} +0 -0
- /package/types/{CdnToolset.d.ts → cdnToolset.d.ts} +0 -0
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
* @module minimax/ImageToolset
|
|
4
4
|
* @description Comprehensive ToolSet for the Minimax Image Generation API.
|
|
5
5
|
*
|
|
6
|
-
* This ToolSet exposes the
|
|
7
|
-
* and
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* This ToolSet exposes the Minimax Image API with descriptive function-call
|
|
7
|
+
* schemas and compact, self-describing function responses. Tool responses
|
|
8
|
+
* preserve durable references such as local paths, temporary image URLs, seeds,
|
|
9
|
+
* trace IDs, and source image references so the assistant can repeat those
|
|
10
|
+
* values in a normal assistant message before old raw tool I/O is pruned.
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* import imageToolset from './lib/API/minimax/ImageToolset.js';
|
|
14
14
|
*
|
|
15
|
-
* // Use in an agent:
|
|
16
15
|
* const toolset = agent.getToolset();
|
|
17
16
|
* toolset.merge(imageToolset);
|
|
18
17
|
*/
|
|
@@ -22,6 +21,54 @@ import * as minimax from './image.js';
|
|
|
22
21
|
|
|
23
22
|
const tools = new ToolSet('auto');
|
|
24
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Serialize a tool response as pretty JSON.
|
|
26
|
+
*
|
|
27
|
+
* @param {Record<string, unknown>} value Response payload to serialize.
|
|
28
|
+
* @returns {string} Pretty JSON response for function-calling output.
|
|
29
|
+
*/
|
|
30
|
+
function json(value) {
|
|
31
|
+
return JSON.stringify(value, null, 2);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build a compact, self-describing Minimax image tool response.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} tool Tool/function name that produced the response.
|
|
38
|
+
* @param {Record<string, unknown>} params Original tool parameters.
|
|
39
|
+
* @param {Record<string, unknown>} result Wrapper result object.
|
|
40
|
+
* @returns {string} JSON response containing durable references and assistant instructions.
|
|
41
|
+
*/
|
|
42
|
+
function imageToolResponse(tool, params, result) {
|
|
43
|
+
const imageUrls = Array.isArray(result.image_urls) ? result.image_urls : [];
|
|
44
|
+
const imageBase64 = Array.isArray(result.image_base64) ? result.image_base64 : [];
|
|
45
|
+
const localPaths = Array.isArray(result.local_paths) ? result.local_paths : [];
|
|
46
|
+
|
|
47
|
+
return json({
|
|
48
|
+
tool,
|
|
49
|
+
success: true,
|
|
50
|
+
trace_id: result.id,
|
|
51
|
+
prompt: params.prompt,
|
|
52
|
+
model: params.model || 'image-01',
|
|
53
|
+
aspect_ratio: params.aspect_ratio || '1:1',
|
|
54
|
+
response_format: params.response_format || 'url',
|
|
55
|
+
seed: params.seed,
|
|
56
|
+
image_urls: imageUrls,
|
|
57
|
+
image_url: imageUrls[0],
|
|
58
|
+
image_url_count: imageUrls.length,
|
|
59
|
+
has_base64_output: imageBase64.length > 0,
|
|
60
|
+
image_base64_count: imageBase64.length,
|
|
61
|
+
local_paths: localPaths,
|
|
62
|
+
local_path: localPaths[0],
|
|
63
|
+
metadata: result.metadata,
|
|
64
|
+
duration_ms: result.duration,
|
|
65
|
+
source_subject_reference: params.subject_reference,
|
|
66
|
+
note:
|
|
67
|
+
'Assistant: tell the user the exact local_path/local_paths and, when present, image_url/image_urls, trace_id, and seed in your normal response. ' +
|
|
68
|
+
'Use local_path as the durable local reference for follow-up file/CDN operations. Minimax image URLs are temporary and may expire.'
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
25
72
|
/* ============================================================
|
|
26
73
|
CORE IMAGE GENERATION (Text-to-Image + Image-to-Image)
|
|
27
74
|
============================================================ */
|
|
@@ -29,22 +76,23 @@ const tools = new ToolSet('auto');
|
|
|
29
76
|
tools.add(
|
|
30
77
|
'generate_image',
|
|
31
78
|
'Generate images using the Minimax Image Generation API. ' +
|
|
32
|
-
'Supports both Text-to-Image and Image-to-Image
|
|
33
|
-
'All generated images are automatically saved locally in .cache/minimax/.'
|
|
79
|
+
'Supports both Text-to-Image and Image-to-Image via subject_reference. ' +
|
|
80
|
+
'All generated images are automatically saved locally in .cache/minimax/. ' +
|
|
81
|
+
'After success, include the exact local_path/local_paths in your assistant response. ' +
|
|
82
|
+
'If image_url/image_urls are returned, include them too, but mention they are temporary. ' +
|
|
83
|
+
'Also preserve trace_id and seed when present for reproducibility or debugging.',
|
|
34
84
|
{
|
|
35
85
|
type: 'object',
|
|
36
86
|
properties: {
|
|
37
87
|
prompt: {
|
|
38
88
|
type: 'string',
|
|
39
|
-
description: 'Text description of the image, max 1500 characters. '
|
|
40
|
-
'Example: "A serene mountain landscape at sunset, photorealistic, cinematic lighting"'
|
|
89
|
+
description: 'Text description of the image, max 1500 characters. Example: "A serene mountain landscape at sunset, photorealistic, cinematic lighting".'
|
|
41
90
|
},
|
|
42
91
|
model: {
|
|
43
92
|
type: 'string',
|
|
44
93
|
enum: ['image-01', 'image-01-live'],
|
|
45
94
|
default: 'image-01',
|
|
46
|
-
description: 'Model to use. "image-01" = standard
|
|
47
|
-
'"image-01-live" = optimized for image-to-image.'
|
|
95
|
+
description: 'Model to use. "image-01" = standard text-to-image and image-to-image. "image-01-live" = optimized for image-to-image.'
|
|
48
96
|
},
|
|
49
97
|
aspect_ratio: {
|
|
50
98
|
type: 'string',
|
|
@@ -54,8 +102,7 @@ tools.add(
|
|
|
54
102
|
},
|
|
55
103
|
width: {
|
|
56
104
|
type: 'integer',
|
|
57
|
-
description: 'Image width in pixels (512-2048,
|
|
58
|
-
'Only effective for model "image-01". aspect_ratio takes priority if both are provided.'
|
|
105
|
+
description: 'Image width in pixels (512-2048, divisible by 8). Only effective for model "image-01". aspect_ratio takes priority if both are provided.'
|
|
59
106
|
},
|
|
60
107
|
height: {
|
|
61
108
|
type: 'integer',
|
|
@@ -65,8 +112,7 @@ tools.add(
|
|
|
65
112
|
type: 'string',
|
|
66
113
|
enum: ['url', 'base64'],
|
|
67
114
|
default: 'url',
|
|
68
|
-
description: 'Output format. "url"
|
|
69
|
-
'"base64" returns raw base64 data. Default is "url" (user preference).'
|
|
115
|
+
description: 'Output format. Prefer "url" where possible. URL links are temporary and expire after about 24 hours. Generated output is also saved to local_path.'
|
|
70
116
|
},
|
|
71
117
|
seed: {
|
|
72
118
|
type: 'integer',
|
|
@@ -89,16 +135,19 @@ tools.add(
|
|
|
89
135
|
items: {
|
|
90
136
|
type: 'object',
|
|
91
137
|
properties: {
|
|
92
|
-
type: {
|
|
138
|
+
type: {
|
|
139
|
+
type: 'string',
|
|
140
|
+
enum: ['character'],
|
|
141
|
+
description: 'Subject type. Currently only "character" supported.'
|
|
142
|
+
},
|
|
93
143
|
image_file: {
|
|
94
144
|
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).'
|
|
145
|
+
description: 'Reference image URL or Base64 data URL (data:image/jpeg;base64,...). Prefer image_url/public URL where possible. Best results with front-facing portrait photos (JPG/PNG < 10MB).'
|
|
97
146
|
}
|
|
98
147
|
},
|
|
99
148
|
required: ['type', 'image_file']
|
|
100
149
|
},
|
|
101
|
-
description: 'For Image-to-Image generation. Array of subject references
|
|
150
|
+
description: 'For Image-to-Image generation. Array of subject references. Preserve the exact source image_file in the final assistant response when it matters for follow-up.'
|
|
102
151
|
},
|
|
103
152
|
extra: {
|
|
104
153
|
type: 'object',
|
|
@@ -109,18 +158,7 @@ tools.add(
|
|
|
109
158
|
},
|
|
110
159
|
async (params) => {
|
|
111
160
|
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);
|
|
161
|
+
return imageToolResponse('generate_image', params, result);
|
|
124
162
|
}
|
|
125
163
|
);
|
|
126
164
|
|
|
@@ -131,13 +169,14 @@ tools.add(
|
|
|
131
169
|
tools.add(
|
|
132
170
|
'save_image_to_local',
|
|
133
171
|
'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.'
|
|
172
|
+
'Useful when you already have image data from another source or previous generation. ' +
|
|
173
|
+
'After success, include the exact local_path in your assistant response so it remains available after function-call history is pruned.',
|
|
135
174
|
{
|
|
136
175
|
type: 'object',
|
|
137
176
|
properties: {
|
|
138
177
|
image_data: {
|
|
139
178
|
type: 'string',
|
|
140
|
-
description: 'Either
|
|
179
|
+
description: 'Either an image URL or a base64-encoded image string (with or without data: prefix). Prefer URL/image_url where possible.'
|
|
141
180
|
},
|
|
142
181
|
filename_prefix: {
|
|
143
182
|
type: 'string',
|
|
@@ -159,11 +198,17 @@ tools.add(
|
|
|
159
198
|
params.index ?? 0
|
|
160
199
|
);
|
|
161
200
|
|
|
162
|
-
return
|
|
201
|
+
return json({
|
|
202
|
+
tool: 'save_image_to_local',
|
|
203
|
+
success: true,
|
|
163
204
|
local_path: localPath,
|
|
164
|
-
|
|
205
|
+
localPath,
|
|
206
|
+
filename_prefix: params.filename_prefix || 'minimax-image',
|
|
207
|
+
index: params.index ?? 0,
|
|
208
|
+
source_image_data_type: typeof params.image_data === 'string' && params.image_data.startsWith('http') ? 'url' : 'base64',
|
|
209
|
+
note: 'Assistant: tell the user the exact local_path in your normal response. Use local_path as the durable reference for follow-up file/CDN operations.'
|
|
165
210
|
});
|
|
166
211
|
}
|
|
167
212
|
);
|
|
168
213
|
|
|
169
|
-
export default tools;
|
|
214
|
+
export default tools;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Exposes four clear workflows matching the underlying music.js design:
|
|
7
7
|
* - create_music → text-to-music (music-2.6 / music-2.6-free)
|
|
8
|
-
* - change_music → cover generation (music-cover)
|
|
9
|
-
* - analyze_music → preprocess reference audio for two-step covers
|
|
8
|
+
* - change_music → cover generation (music-cover) — model fixed to 'music-cover'
|
|
9
|
+
* - analyze_music → preprocess reference audio for two-step covers (model fixed to 'music-cover')
|
|
10
10
|
* - lyrics → generate, edit or continue song lyrics
|
|
11
11
|
*
|
|
12
12
|
* Designed for direct use by AI agents.
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
* Important notes:
|
|
15
15
|
* - Lyrics are optional for both instrumental and non-instrumental music generation.
|
|
16
16
|
* - Streaming is not supported; the `stream` parameter is always false and not exposed as an option.
|
|
17
|
+
* - For change_music and analyze_music: model is fixed to 'music-cover' (recommended paid model).
|
|
18
|
+
* - For change_music (music-cover models): prompt is strictly limited to 300 characters.
|
|
19
|
+
* - audio_setting is fixed internally (44100 Hz / 256 kbps / mp3) — not exposed to users.
|
|
20
|
+
* - **Critical for two-step covers**: When using `cover_feature_id` + non-instrumental (`is_instrumental: false`), the `lyrics` parameter is **mandatory**.
|
|
17
21
|
*/
|
|
18
22
|
|
|
19
23
|
import ToolSet from '../../ToolSet.js';
|
|
@@ -21,6 +25,49 @@ import * as minimax from './music.js';
|
|
|
21
25
|
|
|
22
26
|
const tools = new ToolSet('auto');
|
|
23
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Serialize a tool response as pretty JSON.
|
|
30
|
+
*
|
|
31
|
+
* @param {Record<string, unknown>} value Response payload to serialize.
|
|
32
|
+
* @returns {string} Pretty JSON response for function-calling output.
|
|
33
|
+
*/
|
|
34
|
+
function json(value) {
|
|
35
|
+
return JSON.stringify(value, null, 2);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Build a compact, self-describing music-generation tool response.
|
|
40
|
+
*
|
|
41
|
+
* The response intentionally keeps durable follow-up references and avoids the
|
|
42
|
+
* full raw API response so old function-call transcripts can be pruned safely
|
|
43
|
+
* after the assistant has repeated the important values in normal text.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} tool Tool/function name that produced the result.
|
|
46
|
+
* @param {Record<string, unknown>} params Tool parameters supplied by the model.
|
|
47
|
+
* @param {{audio_url?: string, local_path?: string, duration?: number}} result Wrapper result.
|
|
48
|
+
* @param {string} note Assistant-facing preservation note.
|
|
49
|
+
* @returns {string} Pretty JSON response for function-calling output.
|
|
50
|
+
*/
|
|
51
|
+
function musicToolResponse(tool, params, result, note) {
|
|
52
|
+
return json({
|
|
53
|
+
tool,
|
|
54
|
+
success: true,
|
|
55
|
+
audio_url: result.audio_url,
|
|
56
|
+
audioUrl: result.audio_url,
|
|
57
|
+
local_path: result.local_path,
|
|
58
|
+
localPath: result.local_path,
|
|
59
|
+
duration_ms: result.duration,
|
|
60
|
+
model: tool === 'change_music' ? 'music-cover' : (params.model || 'music-2.6'),
|
|
61
|
+
prompt: params.prompt,
|
|
62
|
+
is_instrumental: params.is_instrumental ?? false,
|
|
63
|
+
output_format: params.output_format || 'url',
|
|
64
|
+
source_audio_url: params.audio_url,
|
|
65
|
+
has_audio_base64: Boolean(params.audio_base64),
|
|
66
|
+
cover_feature_id: params.cover_feature_id,
|
|
67
|
+
note
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
24
71
|
/* ============================================================
|
|
25
72
|
WORKFLOW 1: CREATE MUSIC (Text-to-Music)
|
|
26
73
|
============================================================ */
|
|
@@ -29,8 +76,9 @@ tools.add(
|
|
|
29
76
|
'create_music',
|
|
30
77
|
'Create original music from a text prompt and optional lyrics. ' +
|
|
31
78
|
'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.'
|
|
79
|
+
'Uses minimax music-2.6 or music-2.6-free models. ' +
|
|
80
|
+
'No reference audio is allowed — this is pure text-to-music generation. ' +
|
|
81
|
+
'After success, include the returned local_path and audio_url exactly in your assistant response; these are needed for download/playback or follow-up audio operations.',
|
|
34
82
|
{
|
|
35
83
|
type: 'object',
|
|
36
84
|
properties: {
|
|
@@ -65,16 +113,7 @@ tools.add(
|
|
|
65
113
|
type: 'string',
|
|
66
114
|
enum: ['url', 'hex'],
|
|
67
115
|
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.'
|
|
116
|
+
description: 'Output format. Default "url". Prefer "url" for durable assistant-visible references.'
|
|
78
117
|
},
|
|
79
118
|
extra: { type: 'object', description: 'Additional parameters.' }
|
|
80
119
|
},
|
|
@@ -83,60 +122,71 @@ tools.add(
|
|
|
83
122
|
async (params) => {
|
|
84
123
|
const result = await minimax.createMusic(params.prompt, params);
|
|
85
124
|
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'Audio saved to local_path.'
|
|
93
|
-
}, null, 2);
|
|
125
|
+
return musicToolResponse(
|
|
126
|
+
'create_music',
|
|
127
|
+
params,
|
|
128
|
+
result,
|
|
129
|
+
'Music created successfully with create_music. Assistant: tell the user the exact local_path and audio_url. Use local_path/audio_url as durable references after raw function-call history is pruned.'
|
|
130
|
+
);
|
|
94
131
|
}
|
|
95
132
|
);
|
|
96
133
|
|
|
97
134
|
/* ============================================================
|
|
98
|
-
WORKFLOW 2: CHANGE MUSIC (Cover Generation)
|
|
135
|
+
WORKFLOW 2: CHANGE MUSIC (Cover Generation) — MODEL FIXED
|
|
99
136
|
============================================================ */
|
|
100
137
|
|
|
101
138
|
tools.add(
|
|
102
139
|
'change_music',
|
|
103
|
-
'Generate a cover version of a reference song or track. ' +
|
|
104
|
-
'Uses music-cover
|
|
140
|
+
'Generate a cover version of a reference song or track with minimax.io. ' +
|
|
141
|
+
'Uses the music-cover model (fixed — the recommended paid model; music-cover-free is not supported). ' +
|
|
105
142
|
'**Strict rules**: Provide exactly ONE of audio_url/audio_base64 (direct one-step) ' +
|
|
106
143
|
'OR cover_feature_id (two-step from analyze_music). Never both. ' +
|
|
144
|
+
'**Critical rule**: When using `cover_feature_id` + non-instrumental (`is_instrumental: false`), ' +
|
|
145
|
+
'the `lyrics` parameter is **MANDATORY**. ' +
|
|
107
146
|
'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.'
|
|
147
|
+
'Lyrics are optional for both instrumental and non-instrumental covers. ' +
|
|
148
|
+
'**Important**: There are NO dedicated settings or parameters to control how closely the cover stays faithful to the original reference (e.g. no "strength", "fidelity", or "similarity" sliders). ' +
|
|
149
|
+
'The `prompt` parameter fully controls the degree of adherence to the reference audio. ' +
|
|
150
|
+
'To stay close to the original, craft detailed (but short) prompts such as:\n' +
|
|
151
|
+
'- "faithful cover, identical melody and arrangement to the original"\n' +
|
|
152
|
+
'- "very close vocal and instrumental cover, minimal changes"\n' +
|
|
153
|
+
'- "exact replica of the reference track"\n' +
|
|
154
|
+
'Vague prompts may lead to more creative reinterpretations. ' +
|
|
155
|
+
'**Prompt limit**: Maximum 300 characters (enforced). ' +
|
|
156
|
+
'**audio_setting**: Fixed internally to 44100 Hz / 256 kbps / mp3 — not configurable. ' +
|
|
157
|
+
'Model parameter is ignored (always "music-cover"). ' +
|
|
158
|
+
'After success, include the returned local_path/audio_url and the source audio_url or cover_feature_id exactly in your assistant response.',
|
|
109
159
|
{
|
|
110
160
|
type: 'object',
|
|
111
161
|
properties: {
|
|
112
162
|
prompt: {
|
|
113
163
|
type: 'string',
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
description: 'Cover model to use.'
|
|
164
|
+
maxLength: 300,
|
|
165
|
+
description: 'Target style/mood for the cover AND instructions for fidelity to the reference. ' +
|
|
166
|
+
'Examples for staying faithful: "faithful cover, identical melody and arrangement to the original", ' +
|
|
167
|
+
'"very close vocal and instrumental cover, minimal changes", "exact replica of the reference track". ' +
|
|
168
|
+
'No other parameters control closeness — the prompt is the only control. ' +
|
|
169
|
+
'Maximum 300 characters. Required.'
|
|
121
170
|
},
|
|
122
171
|
audio_url: {
|
|
123
172
|
type: 'string',
|
|
124
173
|
description: 'Public URL of reference audio for direct one-step cover. ' +
|
|
125
|
-
'Mutually exclusive with cover_feature_id.'
|
|
174
|
+
'Mutually exclusive with cover_feature_id. Prefer audio_url where possible because it is assistant-visible and durable.'
|
|
126
175
|
},
|
|
127
176
|
audio_base64: {
|
|
128
177
|
type: 'string',
|
|
129
|
-
description: 'Base64-encoded reference audio (alternative to audio_url).'
|
|
178
|
+
description: 'Base64-encoded reference audio (alternative to audio_url). Prefer audio_url where possible.'
|
|
130
179
|
},
|
|
131
180
|
cover_feature_id: {
|
|
132
181
|
type: 'string',
|
|
133
182
|
description: 'Feature ID from analyze_music() for two-step cover with modified lyrics. ' +
|
|
134
|
-
'
|
|
183
|
+
'**Requires lyrics** when is_instrumental=false. ' +
|
|
184
|
+
'Mutually exclusive with audio_url/audio_base64. Include this exact ID in the assistant response when it is used.'
|
|
135
185
|
},
|
|
136
186
|
lyrics: {
|
|
137
187
|
type: 'string',
|
|
138
188
|
description: 'New or modified structured lyrics. ' +
|
|
139
|
-
'
|
|
189
|
+
'**MANDATORY** when using cover_feature_id + non-instrumental (`is_instrumental: false`). ' +
|
|
140
190
|
'Optional when using direct audio_url (API can extract). ' +
|
|
141
191
|
'Optional for both instrumental and non-instrumental covers.'
|
|
142
192
|
},
|
|
@@ -148,22 +198,13 @@ tools.add(
|
|
|
148
198
|
is_instrumental: {
|
|
149
199
|
type: 'boolean',
|
|
150
200
|
default: false,
|
|
151
|
-
description: 'Generate instrumental cover.'
|
|
201
|
+
description: 'Generate instrumental cover. When false + cover_feature_id, lyrics are required.'
|
|
152
202
|
},
|
|
153
203
|
output_format: {
|
|
154
204
|
type: 'string',
|
|
155
205
|
enum: ['url', 'hex'],
|
|
156
206
|
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.'
|
|
207
|
+
description: 'Output format. Default "url". Prefer "url" for durable assistant-visible references.'
|
|
167
208
|
},
|
|
168
209
|
extra: { type: 'object', description: 'Additional parameters.' }
|
|
169
210
|
},
|
|
@@ -172,45 +213,38 @@ tools.add(
|
|
|
172
213
|
async (params) => {
|
|
173
214
|
const result = await minimax.changeMusic(params.prompt, params);
|
|
174
215
|
|
|
175
|
-
return
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
: 'Direct one-step cover generated using audio_url/audio_base64. ' +
|
|
184
|
-
'Audio saved to local_path.'
|
|
185
|
-
}, null, 2);
|
|
216
|
+
return musicToolResponse(
|
|
217
|
+
'change_music',
|
|
218
|
+
params,
|
|
219
|
+
result,
|
|
220
|
+
params.cover_feature_id
|
|
221
|
+
? 'Two-step cover generated using cover_feature_id. Assistant: tell the user the exact cover_feature_id, local_path, and audio_url. Use local_path/audio_url as durable references after pruning.'
|
|
222
|
+
: 'Direct one-step cover generated using audio_url/audio_base64. Assistant: tell the user the exact source_audio_url when available, plus local_path and audio_url for the generated cover.'
|
|
223
|
+
);
|
|
186
224
|
}
|
|
187
225
|
);
|
|
188
226
|
|
|
189
227
|
/* ============================================================
|
|
190
|
-
WORKFLOW 3: ANALYZE MUSIC (Preprocess for Cover)
|
|
228
|
+
WORKFLOW 3: ANALYZE MUSIC (Preprocess for Cover) — MODEL FIXED
|
|
191
229
|
============================================================ */
|
|
192
230
|
|
|
193
231
|
tools.add(
|
|
194
232
|
'analyze_music',
|
|
195
233
|
'Preprocess a reference audio file to extract voice features, structure, and lyrics. ' +
|
|
196
234
|
'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.'
|
|
235
|
+
'Returns a cover_feature_id that can be used with change_music for lyric modifications. ' +
|
|
236
|
+
'Model is fixed to "music-cover". ' +
|
|
237
|
+
'After success, include the exact cover_feature_id, trace_id, and source audio_url in your assistant response; cover_feature_id is valid for 24 hours and is required for follow-up two-step cover calls.',
|
|
198
238
|
{
|
|
199
239
|
type: 'object',
|
|
200
240
|
properties: {
|
|
201
241
|
audio_url: {
|
|
202
242
|
type: 'string',
|
|
203
|
-
description: 'Public URL of the reference audio (6 seconds to 6 minutes, max 50MB).'
|
|
243
|
+
description: 'Public URL of the reference audio (6 seconds to 6 minutes, max 50MB). Prefer audio_url where possible.'
|
|
204
244
|
},
|
|
205
245
|
audio_base64: {
|
|
206
246
|
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".'
|
|
247
|
+
description: 'Base64-encoded reference audio (alternative to audio_url). Prefer audio_url where possible.'
|
|
214
248
|
}
|
|
215
249
|
},
|
|
216
250
|
required: ['audio_url']
|
|
@@ -218,16 +252,21 @@ tools.add(
|
|
|
218
252
|
async (params) => {
|
|
219
253
|
const result = await minimax.analyzeMusic(params.audio_url, params);
|
|
220
254
|
|
|
221
|
-
return
|
|
255
|
+
return json({
|
|
256
|
+
tool: 'analyze_music',
|
|
257
|
+
success: true,
|
|
222
258
|
cover_feature_id: result.cover_feature_id,
|
|
259
|
+
coverFeatureId: result.cover_feature_id,
|
|
260
|
+
source_audio_url: params.audio_url,
|
|
261
|
+
has_audio_base64: Boolean(params.audio_base64),
|
|
223
262
|
formatted_lyrics: result.formatted_lyrics,
|
|
224
263
|
structure_result: result.structure_result,
|
|
225
264
|
audio_duration_seconds: result.audio_duration,
|
|
226
265
|
trace_id: result.trace_id,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
266
|
+
model: 'music-cover',
|
|
267
|
+
expires_in: '24 hours',
|
|
268
|
+
note: 'Assistant: tell the user the exact cover_feature_id and trace_id. Use cover_feature_id with change_music for two-step covers with custom lyrics. Preserve the exact source_audio_url if present.'
|
|
269
|
+
});
|
|
231
270
|
}
|
|
232
271
|
);
|
|
233
272
|
|
|
@@ -242,7 +281,8 @@ tools.add(
|
|
|
242
281
|
'• mode = "write_full_song" (default) + no existing lyrics → creates a complete song with title, style tags, and full structured lyrics.\n' +
|
|
243
282
|
'• Short prompt only → generates a short snippet, hook, verse, or chorus idea.\n' +
|
|
244
283
|
'• mode = "edit" + existing lyrics → edits, rewrites, continues, or modifies the provided lyrics.\n' +
|
|
245
|
-
'• title parameter → keeps the specified song title in the output
|
|
284
|
+
'• title parameter → keeps the specified song title in the output.\n\n' +
|
|
285
|
+
'After success, include the exact song_title and generated lyrics in your assistant response if they are needed for create_music or change_music follow-up calls.',
|
|
246
286
|
{
|
|
247
287
|
type: 'object',
|
|
248
288
|
properties: {
|
|
@@ -278,13 +318,19 @@ tools.add(
|
|
|
278
318
|
},
|
|
279
319
|
async (params) => {
|
|
280
320
|
const result = await minimax.generateLyrics(params.prompt, params);
|
|
281
|
-
return
|
|
321
|
+
return json({
|
|
322
|
+
tool: 'lyrics',
|
|
323
|
+
success: true,
|
|
282
324
|
song_title: result.song_title,
|
|
325
|
+
songTitle: result.song_title,
|
|
283
326
|
style_tags: result.style_tags,
|
|
284
327
|
lyrics: result.lyrics,
|
|
285
|
-
|
|
286
|
-
|
|
328
|
+
mode: params.mode || 'write_full_song',
|
|
329
|
+
title: params.title,
|
|
330
|
+
prompt: params.prompt,
|
|
331
|
+
note: 'Assistant: preserve the exact song_title, style_tags, and lyrics in your normal response if they are needed for follow-up create_music/change_music calls.'
|
|
332
|
+
});
|
|
287
333
|
}
|
|
288
334
|
);
|
|
289
335
|
|
|
290
|
-
export default tools;
|
|
336
|
+
export default tools;
|