@elizaos/plugin-suno 1.0.6-alpha.3 → 2.0.0-beta.1
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/auto-enable.ts +18 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +242 -371
- package/dist/index.js.map +1 -1
- package/package.json +62 -35
- package/biome.json +0 -41
- package/src/actions/customGenerate.ts +0 -156
- package/src/actions/extend.ts +0 -134
- package/src/actions/generate.ts +0 -145
- package/src/index.ts +0 -22
- package/src/providers/suno.ts +0 -78
- package/src/types/index.ts +0 -34
- package/tsconfig.json +0 -24
- package/tsup.config.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// src/providers/suno.ts
|
|
2
|
+
import {
|
|
3
|
+
recordLlmCall
|
|
4
|
+
} from "@elizaos/core";
|
|
2
5
|
var SunoProvider = class _SunoProvider {
|
|
3
6
|
apiKey;
|
|
4
7
|
baseUrl;
|
|
5
8
|
static async get(runtime, _message, _state) {
|
|
6
9
|
const apiKey = runtime.getSetting("SUNO_API_KEY");
|
|
7
|
-
if (!apiKey) {
|
|
10
|
+
if (typeof apiKey !== "string" || !apiKey) {
|
|
8
11
|
throw new Error("SUNO_API_KEY is required");
|
|
9
12
|
}
|
|
10
13
|
return new _SunoProvider({ apiKey });
|
|
@@ -16,425 +19,293 @@ var SunoProvider = class _SunoProvider {
|
|
|
16
19
|
async get(_runtime, _message, _state) {
|
|
17
20
|
return { status: "ready" };
|
|
18
21
|
}
|
|
19
|
-
async request(endpoint, options = {}) {
|
|
22
|
+
async request(runtime, endpoint, options = {}) {
|
|
20
23
|
const url = `${this.baseUrl}${endpoint}`;
|
|
21
24
|
const headers = {
|
|
22
|
-
|
|
25
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
23
26
|
"Content-Type": "application/json",
|
|
24
27
|
...options.headers
|
|
25
28
|
};
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const body = typeof options.body === "string" ? options.body : "";
|
|
30
|
+
const details = {
|
|
31
|
+
model: "suno",
|
|
32
|
+
modelVersion: "api-v1",
|
|
33
|
+
systemPrompt: "Suno music generation API request",
|
|
34
|
+
userPrompt: body,
|
|
35
|
+
temperature: readTemperature(body),
|
|
36
|
+
maxTokens: 0,
|
|
37
|
+
purpose: "action",
|
|
38
|
+
actionType: `suno.fetch${endpoint}`
|
|
39
|
+
};
|
|
40
|
+
return recordLlmCall(runtime, details, async () => {
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
...options,
|
|
43
|
+
headers
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
throw new Error(`Suno API error: ${response.statusText}`);
|
|
47
|
+
}
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
details.response = JSON.stringify({ suno_response: data });
|
|
50
|
+
return data;
|
|
29
51
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function readTemperature(body) {
|
|
55
|
+
if (!body) return 0;
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(body);
|
|
58
|
+
return typeof parsed.temperature === "number" ? parsed.temperature : 0;
|
|
59
|
+
} catch {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
var sunoStatusProvider = {
|
|
64
|
+
name: "SUNO_STATUS",
|
|
65
|
+
description: "Suno music generation status",
|
|
66
|
+
descriptionCompressed: "Suno generation availability.",
|
|
67
|
+
contexts: ["media"],
|
|
68
|
+
contextGate: { anyOf: ["media"] },
|
|
69
|
+
cacheStable: false,
|
|
70
|
+
cacheScope: "turn",
|
|
71
|
+
get: async (runtime) => {
|
|
72
|
+
const configured = Boolean(runtime.getSetting("SUNO_API_KEY"));
|
|
73
|
+
return {
|
|
74
|
+
text: JSON.stringify(
|
|
75
|
+
{
|
|
76
|
+
suno: {
|
|
77
|
+
configured,
|
|
78
|
+
status: configured ? "ready" : "missing_api_key",
|
|
79
|
+
action: "MUSIC_GENERATION",
|
|
80
|
+
subactions: ["generate", "custom", "extend"]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
null,
|
|
84
|
+
2
|
|
85
|
+
),
|
|
86
|
+
data: { configured },
|
|
87
|
+
values: { sunoConfigured: configured }
|
|
88
|
+
};
|
|
34
89
|
}
|
|
35
90
|
};
|
|
36
91
|
|
|
37
|
-
// src/actions/
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
|
|
92
|
+
// src/actions/musicGeneration.ts
|
|
93
|
+
var SUNO_ACTION_TIMEOUT_MS = 3e4;
|
|
94
|
+
var MAX_SUNO_RESPONSE_BYTES = 4e3;
|
|
95
|
+
function paramsFromMessageAndOptions(message, options) {
|
|
96
|
+
const content = message.content && typeof message.content === "object" ? message.content : {};
|
|
97
|
+
const parameters = (options == null ? void 0 : options.parameters) && typeof options.parameters === "object" ? options.parameters : {};
|
|
98
|
+
return { ...content, ...options, ...parameters };
|
|
99
|
+
}
|
|
100
|
+
function normalizeSubaction(value) {
|
|
101
|
+
const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
102
|
+
if (normalized === "generate" || normalized === "custom" || normalized === "extend") {
|
|
103
|
+
return normalized;
|
|
104
|
+
}
|
|
105
|
+
if (normalized === "custom_generate" || normalized === "custom-generate") return "custom";
|
|
106
|
+
if (normalized === "extend_audio" || normalized === "extend-audio") return "extend";
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
function inferSubaction(message, params) {
|
|
110
|
+
var _a;
|
|
111
|
+
const explicit = normalizeSubaction(params.action ?? params.subaction ?? params.operation);
|
|
112
|
+
if (explicit) return explicit;
|
|
113
|
+
const text = (((_a = message.content) == null ? void 0 : _a.text) ?? "").toLowerCase();
|
|
114
|
+
if (params.audio_id || /\b(extend|lengthen|longer|add \d+.*seconds?)\b/.test(text)) {
|
|
115
|
+
return "extend";
|
|
116
|
+
}
|
|
117
|
+
if (params.reference_audio || params.style || params.bpm || params.key || params.mode || /\b(custom|style|bpm|key|mode|reference)\b/.test(text)) {
|
|
118
|
+
return "custom";
|
|
119
|
+
}
|
|
120
|
+
return "generate";
|
|
121
|
+
}
|
|
122
|
+
function promptFromParams(message, params) {
|
|
123
|
+
var _a;
|
|
124
|
+
const prompt = typeof params.prompt === "string" ? params.prompt.trim() : "";
|
|
125
|
+
if (prompt) return prompt;
|
|
126
|
+
return (((_a = message.content) == null ? void 0 : _a.text) ?? "").trim();
|
|
127
|
+
}
|
|
128
|
+
function numberOrDefault(value, fallback) {
|
|
129
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
130
|
+
}
|
|
131
|
+
function generationBody(params, prompt) {
|
|
132
|
+
return {
|
|
133
|
+
prompt,
|
|
134
|
+
duration: numberOrDefault(params.duration, 30),
|
|
135
|
+
temperature: numberOrDefault(params.temperature, 1),
|
|
136
|
+
top_k: numberOrDefault(params.topK, 250),
|
|
137
|
+
top_p: numberOrDefault(params.topP, 0.95),
|
|
138
|
+
classifier_free_guidance: numberOrDefault(params.classifier_free_guidance, 3)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
var musicGeneration = {
|
|
142
|
+
name: "MUSIC_GENERATION",
|
|
143
|
+
contexts: ["media"],
|
|
144
|
+
contextGate: { anyOf: ["media"] },
|
|
145
|
+
roleGate: { minRole: "USER" },
|
|
146
|
+
description: "Generate music through Suno. Use action generate for a simple prompt, custom for style/BPM/key/reference parameters, or extend for an existing audio_id and duration.",
|
|
147
|
+
descriptionCompressed: "Suno music generation router action: generate, custom, extend.",
|
|
41
148
|
similes: [
|
|
149
|
+
"GENERATE_MUSIC",
|
|
42
150
|
"CREATE_MUSIC",
|
|
43
151
|
"MAKE_MUSIC",
|
|
44
152
|
"COMPOSE_MUSIC",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"MAKE_SONG"
|
|
153
|
+
"CUSTOM_GENERATE_MUSIC",
|
|
154
|
+
"EXTEND_AUDIO"
|
|
48
155
|
],
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
callback({
|
|
80
|
-
text: `Failed to extend audio: ${error.message}`,
|
|
81
|
-
error
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
156
|
+
parameters: [
|
|
157
|
+
{
|
|
158
|
+
name: "action",
|
|
159
|
+
description: "Suno operation: generate, custom, or extend.",
|
|
160
|
+
required: false,
|
|
161
|
+
schema: { type: "string", enum: ["generate", "custom", "extend"] }
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "subaction",
|
|
165
|
+
description: "Legacy alias for action.",
|
|
166
|
+
required: false,
|
|
167
|
+
schema: { type: "string" }
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "prompt",
|
|
171
|
+
description: "Music prompt for generate/custom.",
|
|
172
|
+
required: false,
|
|
173
|
+
schema: { type: "string" }
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "audio_id",
|
|
177
|
+
description: "Existing Suno audio id for extend.",
|
|
178
|
+
required: false,
|
|
179
|
+
schema: { type: "string" }
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "duration",
|
|
183
|
+
description: "Generation duration or extension seconds.",
|
|
184
|
+
required: false,
|
|
185
|
+
schema: { type: "number", default: 30 }
|
|
85
186
|
}
|
|
86
|
-
},
|
|
87
|
-
examples: [
|
|
88
|
-
[
|
|
89
|
-
{
|
|
90
|
-
user: "{{user1}}",
|
|
91
|
-
content: {
|
|
92
|
-
text: "Create a happy and energetic song",
|
|
93
|
-
prompt: "A cheerful and energetic melody with upbeat rhythm",
|
|
94
|
-
duration: 30,
|
|
95
|
-
temperature: 1
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
user: "{{agent}}",
|
|
100
|
-
content: {
|
|
101
|
-
text: "I'll generate a happy and energetic song for you.",
|
|
102
|
-
action: "generate-music"
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
user: "{{agent}}",
|
|
107
|
-
content: {
|
|
108
|
-
text: "Successfully generated your upbeat and energetic song."
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
[
|
|
113
|
-
{
|
|
114
|
-
user: "{{user1}}",
|
|
115
|
-
content: {
|
|
116
|
-
text: "Generate a relaxing ambient track",
|
|
117
|
-
prompt: "A peaceful ambient soundscape with gentle waves and soft pads",
|
|
118
|
-
duration: 45,
|
|
119
|
-
temperature: 0.8,
|
|
120
|
-
classifier_free_guidance: 4
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
user: "{{agent}}",
|
|
125
|
-
content: {
|
|
126
|
-
text: "I'll create a calming ambient piece for you.",
|
|
127
|
-
action: "generate-music"
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
user: "{{agent}}",
|
|
132
|
-
content: {
|
|
133
|
-
text: "Successfully generated your relaxing ambient soundscape."
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
|
-
[
|
|
138
|
-
{
|
|
139
|
-
user: "{{user1}}",
|
|
140
|
-
content: {
|
|
141
|
-
text: "Make a short jingle for my podcast",
|
|
142
|
-
prompt: "A catchy and professional podcast intro jingle",
|
|
143
|
-
duration: 15,
|
|
144
|
-
temperature: 1.2,
|
|
145
|
-
top_k: 300
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
user: "{{agent}}",
|
|
150
|
-
content: {
|
|
151
|
-
text: "I'll generate a podcast jingle for you.",
|
|
152
|
-
action: "generate-music"
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
user: "{{agent}}",
|
|
157
|
-
content: {
|
|
158
|
-
text: "Successfully generated your podcast jingle."
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
]
|
|
163
|
-
};
|
|
164
|
-
var generate_default = generateMusic;
|
|
165
|
-
|
|
166
|
-
// src/actions/customGenerate.ts
|
|
167
|
-
var customGenerateMusic = {
|
|
168
|
-
name: "custom-generate-music",
|
|
169
|
-
description: "Generate music with custom parameters using Suno AI",
|
|
170
|
-
similes: [
|
|
171
|
-
"CREATE_CUSTOM_MUSIC",
|
|
172
|
-
"GENERATE_CUSTOM_AUDIO",
|
|
173
|
-
"MAKE_CUSTOM_MUSIC",
|
|
174
|
-
"COMPOSE_CUSTOM_MUSIC",
|
|
175
|
-
"COMPOSE_MUSIC",
|
|
176
|
-
"CREATE_MUSIC",
|
|
177
|
-
"GENERATE_MUSIC"
|
|
178
187
|
],
|
|
179
|
-
validate: async (runtime,
|
|
180
|
-
|
|
188
|
+
validate: async (runtime, message) => {
|
|
189
|
+
var _a;
|
|
190
|
+
if (!runtime.getSetting("SUNO_API_KEY")) return false;
|
|
191
|
+
const text = (((_a = message.content) == null ? void 0 : _a.text) ?? "").toLowerCase();
|
|
192
|
+
return /\b(generate|create|make|compose|extend|music|song|audio|track)\b/.test(text);
|
|
181
193
|
},
|
|
182
|
-
handler: async (runtime, message, state,
|
|
194
|
+
handler: async (runtime, message, state, options, callback) => {
|
|
183
195
|
try {
|
|
196
|
+
const params = paramsFromMessageAndOptions(message, options);
|
|
197
|
+
const subaction = inferSubaction(message, params);
|
|
184
198
|
const provider = await SunoProvider.get(runtime, message, state);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
method: "POST",
|
|
191
|
-
body: JSON.stringify({
|
|
192
|
-
prompt: content.prompt,
|
|
193
|
-
duration: content.duration || 30,
|
|
194
|
-
temperature: content.temperature || 1,
|
|
195
|
-
top_k: content.topK || 250,
|
|
196
|
-
top_p: content.topP || 0.95,
|
|
197
|
-
classifier_free_guidance: content.classifier_free_guidance || 3,
|
|
198
|
-
reference_audio: content.reference_audio,
|
|
199
|
-
style: content.style,
|
|
200
|
-
bpm: content.bpm,
|
|
201
|
-
key: content.key,
|
|
202
|
-
mode: content.mode
|
|
203
|
-
})
|
|
204
|
-
});
|
|
205
|
-
if (callback) {
|
|
206
|
-
callback({
|
|
207
|
-
text: "Successfully generated custom music",
|
|
208
|
-
content: response
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
return true;
|
|
212
|
-
} catch (error) {
|
|
213
|
-
if (callback) {
|
|
214
|
-
callback({
|
|
215
|
-
text: `Failed to generate custom music: ${error.message}`,
|
|
216
|
-
error
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
examples: [
|
|
223
|
-
[
|
|
224
|
-
{
|
|
225
|
-
user: "{{user1}}",
|
|
226
|
-
content: {
|
|
227
|
-
text: "Create an upbeat electronic dance track with heavy bass",
|
|
228
|
-
prompt: "An upbeat electronic dance track with heavy bass and energetic synths",
|
|
229
|
-
duration: 60,
|
|
230
|
-
style: "electronic",
|
|
231
|
-
bpm: 128
|
|
232
|
-
}
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
user: "{{agent}}",
|
|
236
|
-
content: {
|
|
237
|
-
text: "I'll generate an energetic EDM track for you.",
|
|
238
|
-
action: "custom-generate-music"
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
user: "{{agent}}",
|
|
243
|
-
content: {
|
|
244
|
-
text: "Successfully generated your EDM track with heavy bass and synths."
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
],
|
|
248
|
-
[
|
|
249
|
-
{
|
|
250
|
-
user: "{{user1}}",
|
|
251
|
-
content: {
|
|
252
|
-
text: "Generate a calm piano melody in C major",
|
|
253
|
-
prompt: "A gentle, flowing piano melody with soft dynamics",
|
|
254
|
-
duration: 45,
|
|
255
|
-
style: "classical",
|
|
256
|
-
key: "C",
|
|
257
|
-
mode: "major",
|
|
258
|
-
temperature: 0.8
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
user: "{{agent}}",
|
|
263
|
-
content: {
|
|
264
|
-
text: "I'll create a calming piano piece in C major for you.",
|
|
265
|
-
action: "custom-generate-music"
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
user: "{{agent}}",
|
|
270
|
-
content: {
|
|
271
|
-
text: "Successfully generated your peaceful piano melody in C major."
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
],
|
|
275
|
-
[
|
|
276
|
-
{
|
|
277
|
-
user: "{{user1}}",
|
|
278
|
-
content: {
|
|
279
|
-
text: "Make a rock song with guitar solos",
|
|
280
|
-
prompt: "A rock song with powerful electric guitar solos and driving drums",
|
|
281
|
-
duration: 90,
|
|
282
|
-
style: "rock",
|
|
283
|
-
bpm: 120,
|
|
284
|
-
classifier_free_guidance: 4
|
|
199
|
+
let endpoint = "/generate";
|
|
200
|
+
let body;
|
|
201
|
+
if (subaction === "extend") {
|
|
202
|
+
if (!params.audio_id || !params.duration) {
|
|
203
|
+
throw new Error("Missing required parameters: audio_id and duration");
|
|
285
204
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
205
|
+
endpoint = "/extend";
|
|
206
|
+
body = {
|
|
207
|
+
audio_id: params.audio_id,
|
|
208
|
+
duration: params.duration
|
|
209
|
+
};
|
|
210
|
+
} else {
|
|
211
|
+
const prompt = promptFromParams(message, params);
|
|
212
|
+
if (!prompt) {
|
|
213
|
+
throw new Error("Missing required parameter: prompt");
|
|
292
214
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
215
|
+
body = generationBody(params, prompt);
|
|
216
|
+
if (subaction === "custom") {
|
|
217
|
+
endpoint = "/custom-generate";
|
|
218
|
+
body = {
|
|
219
|
+
...body,
|
|
220
|
+
reference_audio: params.reference_audio,
|
|
221
|
+
style: params.style,
|
|
222
|
+
bpm: params.bpm,
|
|
223
|
+
key: params.key,
|
|
224
|
+
mode: params.mode
|
|
225
|
+
};
|
|
298
226
|
}
|
|
299
227
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
var customGenerate_default = customGenerateMusic;
|
|
304
|
-
|
|
305
|
-
// src/actions/extend.ts
|
|
306
|
-
var extendAudio = {
|
|
307
|
-
name: "extend-audio",
|
|
308
|
-
description: "Extend the duration of an existing audio generation",
|
|
309
|
-
similes: [
|
|
310
|
-
"LENGTHEN_AUDIO",
|
|
311
|
-
"PROLONG_AUDIO",
|
|
312
|
-
"INCREASE_DURATION",
|
|
313
|
-
"MAKE_AUDIO_LONGER"
|
|
314
|
-
],
|
|
315
|
-
validate: async (runtime, _message) => {
|
|
316
|
-
return !!runtime.getSetting("SUNO_API_KEY");
|
|
317
|
-
},
|
|
318
|
-
handler: async (runtime, message, state, _options, callback) => {
|
|
319
|
-
try {
|
|
320
|
-
const provider = await SunoProvider.get(runtime, message, state);
|
|
321
|
-
const content = message.content;
|
|
322
|
-
if (!content.audio_id || !content.duration) {
|
|
323
|
-
throw new Error("Missing required parameters: audio_id and duration");
|
|
324
|
-
}
|
|
325
|
-
const response = await provider.request("/extend", {
|
|
228
|
+
const controller = new AbortController();
|
|
229
|
+
const timeout = setTimeout(() => controller.abort(), SUNO_ACTION_TIMEOUT_MS);
|
|
230
|
+
const response = await provider.request(runtime, endpoint, {
|
|
326
231
|
method: "POST",
|
|
327
|
-
body: JSON.stringify(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
return
|
|
232
|
+
body: JSON.stringify(body),
|
|
233
|
+
signal: controller.signal
|
|
234
|
+
}).finally(() => clearTimeout(timeout));
|
|
235
|
+
const cappedResponse = JSON.stringify(response).length > MAX_SUNO_RESPONSE_BYTES ? {
|
|
236
|
+
truncated: true,
|
|
237
|
+
preview: JSON.stringify(response).slice(0, MAX_SUNO_RESPONSE_BYTES)
|
|
238
|
+
} : response;
|
|
239
|
+
await (callback == null ? void 0 : callback({
|
|
240
|
+
text: subaction === "extend" ? `Successfully extended audio ${params.audio_id}` : `Successfully submitted ${subaction} music generation`,
|
|
241
|
+
content: cappedResponse
|
|
242
|
+
}));
|
|
243
|
+
return {
|
|
244
|
+
success: true,
|
|
245
|
+
text: subaction === "extend" ? `Successfully extended audio ${params.audio_id}` : `Successfully submitted ${subaction} music generation`,
|
|
246
|
+
data: { subaction, response: cappedResponse }
|
|
247
|
+
};
|
|
339
248
|
} catch (error) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
return false;
|
|
249
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
250
|
+
const text = `Music generation failed: ${errorMessage}`;
|
|
251
|
+
await (callback == null ? void 0 : callback({
|
|
252
|
+
text,
|
|
253
|
+
error
|
|
254
|
+
}));
|
|
255
|
+
return { success: false, text, error: errorMessage };
|
|
347
256
|
}
|
|
348
257
|
},
|
|
349
258
|
examples: [
|
|
350
259
|
[
|
|
351
260
|
{
|
|
352
|
-
|
|
353
|
-
content: {
|
|
354
|
-
text: "Make this song longer by 30 seconds",
|
|
355
|
-
audio_id: "abc123",
|
|
356
|
-
duration: 30
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
user: "{{agent}}",
|
|
361
|
-
content: {
|
|
362
|
-
text: "I'll extend your song by 30 seconds.",
|
|
363
|
-
action: "extend-audio"
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
user: "{{agent}}",
|
|
368
|
-
content: {
|
|
369
|
-
text: "Successfully extended your song by 30 seconds."
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
],
|
|
373
|
-
[
|
|
374
|
-
{
|
|
375
|
-
user: "{{user1}}",
|
|
376
|
-
content: {
|
|
377
|
-
text: "Double the length of this track",
|
|
378
|
-
audio_id: "xyz789",
|
|
379
|
-
duration: 60
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
user: "{{agent}}",
|
|
384
|
-
content: {
|
|
385
|
-
text: "I'll double the duration of your track.",
|
|
386
|
-
action: "extend-audio"
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
{
|
|
390
|
-
user: "{{agent}}",
|
|
391
|
-
content: {
|
|
392
|
-
text: "Successfully doubled the length of your track to 60 seconds."
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
],
|
|
396
|
-
[
|
|
397
|
-
{
|
|
398
|
-
user: "{{user1}}",
|
|
399
|
-
content: {
|
|
400
|
-
text: "Add 15 more seconds to this melody",
|
|
401
|
-
audio_id: "def456",
|
|
402
|
-
duration: 15
|
|
403
|
-
}
|
|
404
|
-
},
|
|
405
|
-
{
|
|
406
|
-
user: "{{agent}}",
|
|
261
|
+
name: "{{user1}}",
|
|
407
262
|
content: {
|
|
408
|
-
text: "
|
|
409
|
-
|
|
263
|
+
text: "Generate a relaxing ambient track",
|
|
264
|
+
prompt: "A peaceful ambient soundscape with gentle waves and soft pads",
|
|
265
|
+
duration: 45
|
|
410
266
|
}
|
|
411
267
|
},
|
|
412
268
|
{
|
|
413
|
-
|
|
269
|
+
name: "{{agent}}",
|
|
414
270
|
content: {
|
|
415
|
-
text: "
|
|
271
|
+
text: "I'll generate a calming ambient piece.",
|
|
272
|
+
action: "MUSIC_GENERATION"
|
|
416
273
|
}
|
|
417
274
|
}
|
|
418
275
|
]
|
|
419
276
|
]
|
|
420
277
|
};
|
|
421
|
-
var
|
|
278
|
+
var musicGeneration_default = musicGeneration;
|
|
422
279
|
|
|
423
280
|
// src/index.ts
|
|
424
281
|
var sunoPlugin = {
|
|
425
282
|
name: "suno",
|
|
426
283
|
description: "Suno AI Music Generation Plugin for Eliza",
|
|
427
|
-
actions: [
|
|
428
|
-
|
|
429
|
-
|
|
284
|
+
actions: [musicGeneration_default],
|
|
285
|
+
providers: [sunoStatusProvider],
|
|
286
|
+
// Self-declared auto-enable: activate when SUNO_API_KEY is set OR when
|
|
287
|
+
// media.audio is configured to use the suno provider with own-key mode.
|
|
288
|
+
autoEnable: {
|
|
289
|
+
shouldEnable: (env, config) => {
|
|
290
|
+
const key = env.SUNO_API_KEY;
|
|
291
|
+
if (typeof key === "string" && key.trim() !== "") return true;
|
|
292
|
+
const media = config == null ? void 0 : config.media;
|
|
293
|
+
const audio = media == null ? void 0 : media.audio;
|
|
294
|
+
return Boolean(
|
|
295
|
+
audio && audio.enabled !== false && audio.mode === "own-key" && audio.provider === "suno"
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
430
299
|
};
|
|
431
300
|
var index_default = sunoPlugin;
|
|
432
301
|
export {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
302
|
+
musicGeneration_default as CustomGenerateMusic,
|
|
303
|
+
musicGeneration_default as ExtendAudio,
|
|
304
|
+
musicGeneration_default as GenerateMusic,
|
|
305
|
+
musicGeneration_default as MusicGeneration,
|
|
436
306
|
SunoProvider,
|
|
437
307
|
index_default as default,
|
|
438
|
-
sunoPlugin
|
|
308
|
+
sunoPlugin,
|
|
309
|
+
sunoStatusProvider
|
|
439
310
|
};
|
|
440
311
|
//# sourceMappingURL=index.js.map
|