beplus-mcp 0.41.0 → 0.42.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 +11 -1
- package/dist/index.js +41 -19
- package/dist/index.js.map +1 -1
- package/dist/remote-server.js +41 -19
- package/dist/remote-server.js.map +1 -1
- package/package.json +1 -1
package/dist/remote-server.js
CHANGED
|
@@ -22517,7 +22517,7 @@ var BeplusClient = class {
|
|
|
22517
22517
|
});
|
|
22518
22518
|
}
|
|
22519
22519
|
tts(body2) {
|
|
22520
|
-
return this.request("POST", "/tts", { body: body2, timeoutMs: 9e4 });
|
|
22520
|
+
return this.request("POST", "/tts", { body: body2, timeoutMs: body2.model === "seed-audio-1.0" ? 18e4 : 9e4 });
|
|
22521
22521
|
}
|
|
22522
22522
|
ttsVoices(query) {
|
|
22523
22523
|
return this.request("GET", "/tts/voices", { query, timeoutMs: 2e4 });
|
|
@@ -22820,7 +22820,7 @@ function tooLarge(name, bytes) {
|
|
|
22820
22820
|
`"${name}" ${size} acima do teto de 95 MB para subir pela API (o proxy da Cloudflare corta corpo acima de 100 MB antes de chegar no servidor). Comprima ou corte o arquivo (ex.: ffmpeg -i entrada.mp4 -crf 26 saida.mp4) e tente de novo.`
|
|
22821
22821
|
);
|
|
22822
22822
|
}
|
|
22823
|
-
async function loadLocal(ref) {
|
|
22823
|
+
async function loadLocal(ref, maxBytes = MAX_UPLOAD_BYTES) {
|
|
22824
22824
|
const abs = toLocalPath(ref);
|
|
22825
22825
|
const name = basename(abs);
|
|
22826
22826
|
let size;
|
|
@@ -22832,10 +22832,10 @@ async function loadLocal(ref) {
|
|
|
22832
22832
|
`Arquivo local n\xE3o encontrado: "${ref}". Passe um caminho v\xE1lido ou uma URL p\xFAblica (http/https).`
|
|
22833
22833
|
);
|
|
22834
22834
|
}
|
|
22835
|
-
if (size >
|
|
22835
|
+
if (size > maxBytes) throw maxBytes === MAX_UPLOAD_BYTES ? tooLarge(name, size) : new ApiError(413, `O arquivo deve ter at\xE9 ${mb(maxBytes)} MB.`);
|
|
22836
22836
|
return { buf: await readFile2(abs), name, mime: mimeForName(abs), localPath: abs };
|
|
22837
22837
|
}
|
|
22838
|
-
async function loadRemote(url) {
|
|
22838
|
+
async function loadRemote(url, maxBytes = MAX_UPLOAD_BYTES) {
|
|
22839
22839
|
const u = new URL(url);
|
|
22840
22840
|
let name = decodeURIComponent(basename(u.pathname)) || "arquivo";
|
|
22841
22841
|
let res;
|
|
@@ -22851,10 +22851,10 @@ async function loadRemote(url) {
|
|
|
22851
22851
|
throw new ApiError(res.status, `N\xE3o consegui baixar ${url}: a origem respondeu HTTP ${res.status}.`);
|
|
22852
22852
|
}
|
|
22853
22853
|
const declared = Number(res.headers.get("content-length") ?? NaN);
|
|
22854
|
-
if (Number.isFinite(declared) && declared >
|
|
22854
|
+
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
22855
22855
|
await res.body?.cancel().catch(() => {
|
|
22856
22856
|
});
|
|
22857
|
-
throw tooLarge(name, declared);
|
|
22857
|
+
throw maxBytes === MAX_UPLOAD_BYTES ? tooLarge(name, declared) : new ApiError(413, `O arquivo deve ter at\xE9 ${mb(maxBytes)} MB.`);
|
|
22858
22858
|
}
|
|
22859
22859
|
const chunks = [];
|
|
22860
22860
|
let total = 0;
|
|
@@ -22865,10 +22865,10 @@ async function loadRemote(url) {
|
|
|
22865
22865
|
const { done, value } = await reader.read();
|
|
22866
22866
|
if (done) break;
|
|
22867
22867
|
total += value.byteLength;
|
|
22868
|
-
if (total >
|
|
22868
|
+
if (total > maxBytes) {
|
|
22869
22869
|
await reader.cancel().catch(() => {
|
|
22870
22870
|
});
|
|
22871
|
-
throw tooLarge(name, null);
|
|
22871
|
+
throw maxBytes === MAX_UPLOAD_BYTES ? tooLarge(name, null) : new ApiError(413, `O arquivo deve ter at\xE9 ${mb(maxBytes)} MB.`);
|
|
22872
22872
|
}
|
|
22873
22873
|
chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
|
|
22874
22874
|
}
|
|
@@ -23179,6 +23179,7 @@ var MUSIC_TASK_TYPES = ["create", "extend", "cover", "upload_extend", "upload_co
|
|
|
23179
23179
|
var MUSIC_TOOLS = ["wav", "midi", "stems-basic", "stems-full", "bpm", "lyrics-timeline"];
|
|
23180
23180
|
var VOCAL_GENDERS = ["f", "m"];
|
|
23181
23181
|
var TTS_MODELS = [
|
|
23182
|
+
"seed-audio-1.0",
|
|
23182
23183
|
"gemini-3.8-flash-lite-tts",
|
|
23183
23184
|
"gemini-3.8-flash-tts",
|
|
23184
23185
|
"gemini-3.1-flash-tts-preview",
|
|
@@ -24753,7 +24754,7 @@ var VOICE_HELP_TOP = `${VOICE_HELP} Ou o id de uma voz pr\xF3pria (voice_xxx, de
|
|
|
24753
24754
|
var voiceSchema = external_exports.string().refine((v) => VOICES.includes(v) || LIBRARY_VOICE_ID.test(v), {
|
|
24754
24755
|
message: "Voz inv\xE1lida: use uma das 30 vozes cl\xE1ssicas (ex.: Kore) ou um id da biblioteca (ex.: pt-br-advisor-10)."
|
|
24755
24756
|
});
|
|
24756
|
-
var topVoiceSchema = external_exports.string().refine((v) => VOICES.includes(v) || LIBRARY_VOICE_ID.test(v) || CUSTOM_VOICE_ID.test(v), {
|
|
24757
|
+
var topVoiceSchema = external_exports.string().refine((v) => v === "seed-auto" || VOICES.includes(v) || LIBRARY_VOICE_ID.test(v) || CUSTOM_VOICE_ID.test(v), {
|
|
24757
24758
|
message: "Voz inv\xE1lida: use uma das 30 vozes cl\xE1ssicas (ex.: Kore), um id da biblioteca (ex.: pt-br-advisor-10) ou uma voz pr\xF3pria (voice_xxx)."
|
|
24758
24759
|
});
|
|
24759
24760
|
function isCustomVoice(v) {
|
|
@@ -24772,10 +24773,13 @@ function registerAudioTools(server, client, cfg) {
|
|
|
24772
24773
|
"generate_audio",
|
|
24773
24774
|
{
|
|
24774
24775
|
title: "Gerar \xE1udio (TTS)",
|
|
24775
|
-
description: 'Sintetiza fala a partir de texto
|
|
24776
|
+
description: 'Sintetiza fala a partir de texto e retorna a URL usando o IA Lab da BePlus. SeedAudio 1.0 (seed-audio-1.0) aceita dire\xE7\xE3o e uma refer\xEAncia de voz opcional via seed_reference ou seed_reference_generation_id, com seed_consent. Texto e dire\xE7\xE3o somados at\xE9 2700 caracteres. N\xE3o aceita di\xE1logo nem vozes Gemini. Modelos Gemini 3.8 (`gemini-3.8-flash-lite-tts`, padr\xE3o, r\xE1pido e barato; `gemini-3.8-flash-tts`, qualidade de est\xFAdio, melhor para di\xE1logo e narra\xE7\xE3o longa) aceitam: vozes da biblioteca (milhares, por idioma; liste com `list_tts_voices` e passe o id em `voice`), tags vocais no texto como <laugh> <chuckle> <sigh> <breath> <gasp> <cough> <sneeze> <throat-clearing> <yawn> <groan> <scream> <whimper> <argh> <short pause> <long pause> (viram som de verdade), e estilo por locutor (`style` em cada speaker). No 3.8, `style_instruction` \xE9 dire\xE7\xE3o e N\xC3O \xE9 lida em voz alta. Os modelos legados (`gemini-3.1-flash-tts-preview`, `gemini-2.5-pro-preview-tts`) s\xF3 aceitam as 30 vozes cl\xE1ssicas (Kore, Puck, Charon...) e n\xE3o t\xEAm voz da biblioteca. Vozes pr\xF3prias (voice_xxx; liste com `list_custom_voices`, crie com `design_voice`) s\xF3 no 3.8 e sem `multi_speaker`. No 3.8, dire\xE7\xE3o por linha: `(sussurrando) texto` no in\xEDcio da linha vale at\xE9 a pr\xF3xima dire\xE7\xE3o; no di\xE1logo, `Ana (rindo): fala`; rea\xE7\xF5es `|hmm|` `|aham|` no meio da fala (s\xF3 di\xE1logo). Opcional `style_instruction` (ex.: "fale animado e pausado") e di\xE1logo com 2 locutores via `multi_speaker`. Consome diamantes por segundo de \xE1udio.' + TEAM_GATING_NOTE,
|
|
24776
24777
|
inputSchema: {
|
|
24777
24778
|
text: external_exports.string().min(1).max(1e4).describe("Texto a ser falado."),
|
|
24778
|
-
voice: topVoiceSchema.
|
|
24779
|
+
voice: topVoiceSchema.optional().describe(VOICE_HELP_TOP + " No SeedAudio, omita ou use seed-auto."),
|
|
24780
|
+
seed_reference: external_exports.string().min(1).optional().describe("SeedAudio: arquivo local (stdio) ou URL p\xFAblica de uma voz autorizada, de 1 a 30 s e at\xE9 3 MiB. N\xE3o \xE9 publicado pelo MCP."),
|
|
24781
|
+
seed_reference_generation_id: external_exports.string().uuid().optional().describe("Reutiliza a refer\xEAncia de uma gera\xE7\xE3o SeedAudio sua. Alternativa a seed_reference."),
|
|
24782
|
+
seed_consent: external_exports.literal(true).optional().describe("Confirme apenas ap\xF3s autoriza\xE7\xE3o expl\xEDcita da pessoa para usar sua voz. Obrigat\xF3rio com refer\xEAncia."),
|
|
24779
24783
|
model: external_exports.enum(TTS_MODELS).default(DEFAULTS.ttsModel).describe("Modelo TTS."),
|
|
24780
24784
|
style_instruction: external_exports.string().max(2e3).optional().describe("Instru\xE7\xE3o de estilo/tom aplicada \xE0 fala."),
|
|
24781
24785
|
multi_speaker: external_exports.object({
|
|
@@ -24787,9 +24791,17 @@ function registerAudioTools(server, client, cfg) {
|
|
|
24787
24791
|
},
|
|
24788
24792
|
async (args) => {
|
|
24789
24793
|
try {
|
|
24794
|
+
const seed = args.model === "seed-audio-1.0";
|
|
24795
|
+
const voice = args.voice ?? (seed ? "seed-auto" : DEFAULTS.voice);
|
|
24796
|
+
const hasReference = !!(args.seed_reference || args.seed_reference_generation_id);
|
|
24797
|
+
if (!seed && (hasReference || args.seed_consent || voice === "seed-auto")) return errorResult("Os controles SeedAudio exigem seed-audio-1.0.");
|
|
24798
|
+
if (seed && (voice !== "seed-auto" || args.multi_speaker)) return errorResult("SeedAudio usa seed-auto e n\xE3o aceita di\xE1logo.");
|
|
24799
|
+
if (args.seed_reference && args.seed_reference_generation_id) return errorResult("Use apenas uma origem de refer\xEAncia.");
|
|
24800
|
+
if (hasReference && !args.seed_consent) return errorResult("Confirme a autoriza\xE7\xE3o da voz em seed_consent.");
|
|
24801
|
+
if (seed && args.text.trim().length + (args.style_instruction?.trim().length ?? 0) > 2700) return errorResult("SeedAudio: texto e dire\xE7\xE3o devem somar at\xE9 2700 caracteres.");
|
|
24790
24802
|
const ms = args.multi_speaker;
|
|
24791
|
-
const voices = [
|
|
24792
|
-
if (isCustomVoice(
|
|
24803
|
+
const voices = [voice, ms?.speaker1.voice, ms?.speaker2.voice].filter((v) => !!v);
|
|
24804
|
+
if (isCustomVoice(voice)) {
|
|
24793
24805
|
if (!TTS_MODELS_38.includes(args.model)) {
|
|
24794
24806
|
return errorResult("Vozes pr\xF3prias s\xF3 funcionam nos modelos Gemini 3.8 (gemini-3.8-flash-lite-tts, gemini-3.8-flash-tts).");
|
|
24795
24807
|
}
|
|
@@ -24797,7 +24809,7 @@ function registerAudioTools(server, client, cfg) {
|
|
|
24797
24809
|
return errorResult("Vozes pr\xF3prias n\xE3o funcionam no modo di\xE1logo (multi_speaker). Use uma voz da biblioteca ou cl\xE1ssica.");
|
|
24798
24810
|
}
|
|
24799
24811
|
}
|
|
24800
|
-
if (!TTS_MODELS_38.includes(args.model)) {
|
|
24812
|
+
if (!seed && !TTS_MODELS_38.includes(args.model)) {
|
|
24801
24813
|
if (voices.some(isLibraryVoice)) {
|
|
24802
24814
|
return errorResult(
|
|
24803
24815
|
`Vozes da biblioteca s\xF3 funcionam nos modelos Gemini 3.8 (gemini-3.8-flash-lite-tts, gemini-3.8-flash-tts). O modelo ${args.model} s\xF3 aceita as 30 vozes cl\xE1ssicas (Kore, Puck, Charon...).`
|
|
@@ -24807,9 +24819,18 @@ function registerAudioTools(server, client, cfg) {
|
|
|
24807
24819
|
return errorResult("O estilo por locutor (`style`) s\xF3 funciona nos modelos Gemini 3.8.");
|
|
24808
24820
|
}
|
|
24809
24821
|
}
|
|
24822
|
+
let seedReference;
|
|
24823
|
+
if (args.seed_reference) {
|
|
24824
|
+
const file = await (isRemoteRef(args.seed_reference) ? loadRemote(args.seed_reference, 3 * 1024 * 1024) : loadLocal(args.seed_reference, 3 * 1024 * 1024));
|
|
24825
|
+
if (!file.buf.length || file.buf.length > 3 * 1024 * 1024) return errorResult("A refer\xEAncia deve ter at\xE9 3 MiB.");
|
|
24826
|
+
seedReference = { audio: file.buf.toString("base64"), mime: file.mime };
|
|
24827
|
+
}
|
|
24810
24828
|
const body2 = compact({
|
|
24829
|
+
seedReference,
|
|
24830
|
+
seedReferenceGenerationId: args.seed_reference_generation_id,
|
|
24831
|
+
seedConsent: args.seed_consent,
|
|
24811
24832
|
text: args.text,
|
|
24812
|
-
voice
|
|
24833
|
+
voice,
|
|
24813
24834
|
model: args.model,
|
|
24814
24835
|
styleInstruction: args.style_instruction,
|
|
24815
24836
|
multiSpeaker: args.multi_speaker,
|
|
@@ -24819,12 +24840,13 @@ function registerAudioTools(server, client, cfg) {
|
|
|
24819
24840
|
const parts = [`Custo: ${res.diamond_cost} \u{1F48E}`];
|
|
24820
24841
|
if (res.diamonds_refunded) parts.push(`Estorno: ${res.diamonds_refunded} \u{1F48E}`);
|
|
24821
24842
|
const projLine = res.project_code ? `
|
|
24822
|
-
\u{1F4C1} Projeto: ${res.project_code}${res.project_name ?
|
|
24843
|
+
\u{1F4C1} Projeto: ${res.project_code}${res.project_name ? `: ${res.project_name}` : ""}` : "";
|
|
24823
24844
|
const wa = weeklyAllowanceLine(res.weekly_allowance);
|
|
24824
24845
|
const budget = budgetLine(res.budget);
|
|
24825
24846
|
return textResult(
|
|
24826
|
-
`\u2705 \xC1udio gerado (${res.model}, voz ${res.voice}, ${res.duration_sec.toFixed(1)}s).
|
|
24847
|
+
`\u2705 \xC1udio gerado (${res.model}, voz ${seed ? "por refer\xEAncia ou descri\xE7\xE3o" : res.voice}, ${res.duration_sec.toFixed(1)}s).
|
|
24827
24848
|
${res.url}
|
|
24849
|
+
Gera\xE7\xE3o: ${res.generation_id}
|
|
24828
24850
|
${parts.join(" \xB7 ")}${projLine}` + (budget ? `
|
|
24829
24851
|
${budget}` : "") + (wa ? `
|
|
24830
24852
|
${wa}` : "")
|
|
@@ -25670,7 +25692,7 @@ var KINDS = {
|
|
|
25670
25692
|
data: { model: "gemini-3.8-flash-lite-tts", voice: "Algieba", speed: "normal" },
|
|
25671
25693
|
inputs: ["text"],
|
|
25672
25694
|
outputs: ["audio", "approved"],
|
|
25673
|
-
dynamic: "style conforme o modelo"
|
|
25695
|
+
dynamic: "style conforme o modelo; SeedAudio 1.0 tem reference (audio), usa voice: seed-auto e seedConsent: true com refer\xEAncia; alternativa seedReferenceGenerationId de gera\xE7\xE3o pr\xF3pria"
|
|
25674
25696
|
},
|
|
25675
25697
|
music: {
|
|
25676
25698
|
title: "Trilha",
|
|
@@ -28720,7 +28742,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
|
|
|
28720
28742
|
import { createRequire } from "module";
|
|
28721
28743
|
var require2 = createRequire(import.meta.url);
|
|
28722
28744
|
function readVersion() {
|
|
28723
|
-
if ("0.
|
|
28745
|
+
if ("0.42.0") return "0.42.0";
|
|
28724
28746
|
try {
|
|
28725
28747
|
const pkg = require2("../package.json");
|
|
28726
28748
|
return pkg.version ?? "0.0.0-unknown";
|