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.
@@ -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 > MAX_UPLOAD_BYTES) throw tooLarge(name, 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 > MAX_UPLOAD_BYTES) {
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 > MAX_UPLOAD_BYTES) {
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 (s\xEDncrono \u2014 retorna a URL na hora) usando o IA Lab da BePlus. 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
+ 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.default(DEFAULTS.voice).describe(VOICE_HELP_TOP),
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 = [args.voice, ms?.speaker1.voice, ms?.speaker2.voice].filter((v) => !!v);
24792
- if (isCustomVoice(args.voice)) {
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: args.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 ? ` \u2014 ${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.41.0") return "0.41.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";