beplus-mcp 0.23.0 → 0.25.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/dist/index.js CHANGED
@@ -21293,11 +21293,12 @@ var BeplusClient = class {
21293
21293
  calculateCost(query) {
21294
21294
  return this.request("GET", "/calculate-cost", { query });
21295
21295
  }
21296
- balance() {
21297
- return this.request("GET", "/balance");
21296
+ /** `billing: 'personal'` pula o budget do projeto ativo no preview do saldo. */
21297
+ balance(billing) {
21298
+ return this.request("GET", "/balance", { query: { billing } });
21298
21299
  }
21299
- me() {
21300
- return this.request("GET", "/me");
21300
+ me(billing) {
21301
+ return this.request("GET", "/me", { query: { billing } });
21301
21302
  }
21302
21303
  readProvenance(body) {
21303
21304
  return this.request("POST", "/read-provenance", { body, timeoutMs: 3e4 });
@@ -21599,6 +21600,10 @@ function compact(obj) {
21599
21600
  }
21600
21601
  return out;
21601
21602
  }
21603
+ function resolveProjectArg(project, billing, activeProject) {
21604
+ if (billing === "personal") return void 0;
21605
+ return project ?? activeProject ?? void 0;
21606
+ }
21602
21607
  var CHARGED_FROM_LABEL = {
21603
21608
  budget: "do budget do projeto",
21604
21609
  weekly_allowance: "do cr\xE9dito semanal da equipe",
@@ -21765,6 +21770,9 @@ var DEFAULTS = {
21765
21770
  // src/tools/generation.ts
21766
21771
  var IMAGE_BUDGET_MS = 9e4;
21767
21772
  var VIDEO_BUDGET_MS = 12e4;
21773
+ var BILLING_FIELD = external_exports.enum(["personal"]).optional().describe(
21774
+ '"personal" = cobra do seu diamante pessoal, IGNORANDO o projeto ativo (mesmo se houver um). Use quando quiser garantir que isto N\xC3O sai do budget de nenhum projeto. Incompat\xEDvel com `project`.'
21775
+ );
21768
21776
  function flagsLine(g) {
21769
21777
  const parts = [
21770
21778
  g.is_favorite ? "\u2B50 like" : null,
@@ -21831,7 +21839,8 @@ function registerGenerationTools(server, client, cfg) {
21831
21839
  character_reference: external_exports.string().optional().describe("Midjourney: refer\xEAncia de PERSONAGEM (URL/arquivo). v7 usa --oref, v6 usa --cref (autom\xE1tico)."),
21832
21840
  character_weight: external_exports.number().int().min(0).max(1e3).optional().describe("Midjourney: peso do character ref (--ow v7 / --cw v6)."),
21833
21841
  image_weight: external_exports.number().min(0).max(3).optional().describe("Midjourney: --iw peso das reference_images (image-prompts) 0-3. Padr\xE3o 1."),
21834
- project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.')
21842
+ project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.'),
21843
+ billing: BILLING_FIELD
21835
21844
  }
21836
21845
  },
21837
21846
  async (args) => {
@@ -21916,7 +21925,12 @@ function registerGenerationTools(server, client, cfg) {
21916
21925
  image_weight: args.image_weight
21917
21926
  });
21918
21927
  const start = await client.startGeneration(
21919
- compact({ model: args.model, input, project: args.project ?? cfg.activeProject ?? void 0 })
21928
+ compact({
21929
+ model: args.model,
21930
+ input,
21931
+ project: resolveProjectArg(args.project, args.billing, cfg.activeProject),
21932
+ billing: args.billing
21933
+ })
21920
21934
  );
21921
21935
  if (!start.success || !start.generation_id) {
21922
21936
  if (isTeamGatingError(start.message)) return errorResult(await buildPickProjectMessage(client));
@@ -21966,7 +21980,8 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
21966
21980
  zoom_ratio: external_exports.enum(["1.5", "2"]).optional().describe("Zoom out (outpaint)."),
21967
21981
  mask: external_exports.string().optional().describe("M\xE1scara base64 B/W PNG (inpaint) \u2014 \xE1rea branca = repintar."),
21968
21982
  prompt: external_exports.string().max(2e3).optional().describe("Prompt opcional (inpaint)."),
21969
- project: external_exports.string().max(64).optional().describe("Projeto (uuid OU code curto).")
21983
+ project: external_exports.string().max(64).optional().describe("Projeto (uuid OU code curto)."),
21984
+ billing: BILLING_FIELD
21970
21985
  }
21971
21986
  },
21972
21987
  async (args) => {
@@ -21981,7 +21996,12 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
21981
21996
  prompt: args.prompt
21982
21997
  });
21983
21998
  const start = await client.startGeneration(
21984
- compact({ model: "midjourney", input, project: args.project ?? cfg.activeProject ?? void 0 })
21999
+ compact({
22000
+ model: "midjourney",
22001
+ input,
22002
+ project: resolveProjectArg(args.project, args.billing, cfg.activeProject),
22003
+ billing: args.billing
22004
+ })
21985
22005
  );
21986
22006
  if (!start.success || !start.generation_id) {
21987
22007
  if (isTeamGatingError(start.message)) return errorResult(await buildPickProjectMessage(client));
@@ -22018,11 +22038,13 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22018
22038
  "generate_video",
22019
22039
  {
22020
22040
  title: "Gerar v\xEDdeo",
22021
- description: "Gera um v\xEDdeo curto usando o IA Lab da BePlus. LENTO (geralmente 1-5+ min). Aguarda at\xE9 ~2 min; se n\xE3o terminar, retorna o generation_id e o status \u2014 ent\xE3o use check_generation. Consome diamantes (mais caro para dura\xE7\xF5es/resolu\xE7\xF5es maiores). Suporta image-to-video (`first_frame_image`), \xFAltimo frame (`last_frame_image`), refer\xEAncias de imagem/v\xEDdeo/\xE1udio, prompt negativo, \xE1udio gerado e mais \u2014 os campos aceitos variam por modelo (consulte list_models). `kling-v2.6-motion-control` usa `first_frame_image` + `motion_video`. Imagens com rosto de pessoa REAL s\xE3o bloqueadas pela modera\xE7\xE3o do provedor (use ilustra\xE7\xF5es/personagens)." + TEAM_GATING_NOTE,
22041
+ description: "Gera um v\xEDdeo curto usando o IA Lab da BePlus. LENTO (geralmente 1-5+ min). Aguarda at\xE9 ~2 min; se n\xE3o terminar, retorna o generation_id e o status \u2014 ent\xE3o use check_generation. Consome diamantes (mais caro para dura\xE7\xF5es/resolu\xE7\xF5es maiores). Suporta image-to-video (`first_frame_image`), \xFAltimo frame (`last_frame_image`), refer\xEAncias de imagem/v\xEDdeo/\xE1udio, prompt negativo, \xE1udio gerado e mais \u2014 os campos aceitos variam por modelo (consulte list_models). `kling-v2.6-motion-control` usa `first_frame_image` + `motion_video`. Nos modelos Seedance, refer\xEAncia com rosto de pessoa REAL \xE9 bloqueada pelo provedor padr\xE3o (BytePlus) \u2014 use `real_people_references: true` para rotear pra fal.ai, que aceita (custa mais caro). Kling e outros provedores n\xE3o t\xEAm essa op\xE7\xE3o." + TEAM_GATING_NOTE,
22022
22042
  inputSchema: {
22023
22043
  // Sem teto local — ver nota em generate_image. O Seedance não publica
22024
22044
  // limite; o Kling publica 2500 e o backend recusa dizendo quanto cortar.
22025
- prompt: external_exports.string().min(1).describe("Descri\xE7\xE3o do v\xEDdeo desejado."),
22045
+ // Opcional só por causa de `draft_task_id` (upscale de um draft não
22046
+ // manda prompt — é herdado do draft original); validado no handler.
22047
+ prompt: external_exports.string().optional().describe("Descri\xE7\xE3o do v\xEDdeo desejado. Omita s\xF3 ao usar `draft_task_id`."),
22026
22048
  model: external_exports.enum(VIDEO_MODELS).default(DEFAULTS.videoModel).describe(
22027
22049
  "seedance-2.0-fast = barato/r\xE1pido; seedance-2.5 = at\xE9 30s num take, 50 refs e at\xE9 1080p; seedance-2.0 = \xFAnico com 4K; kling-v3-video = alternativa."
22028
22050
  ),
@@ -22052,7 +22074,17 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22052
22074
  video_task_type: external_exports.enum(["auto", "reference", "edit", "extend"]).optional().describe(
22053
22075
  "O que fazer com os v\xEDdeos de refer\xEAncia (s\xF3 seedance-2.5): `reference` gera um v\xEDdeo novo; `edit` edita o original (exige 1 v\xEDdeo de 4-30s, a dura\xE7\xE3o vira a dele); `extend` estende o original. Sem isto o modelo adivinha e um par\xE2metro incompat\xEDvel s\xF3 falha DEPOIS da fila."
22054
22076
  ),
22055
- project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.')
22077
+ real_people_references: external_exports.boolean().optional().describe(
22078
+ 'S\xF3 Seedance (2.0/2.0-fast/2.0-mini/2.5): quando true, roteia pra fal.ai em vez da BytePlus \u2014 a BytePlus recusa refer\xEAncia com pessoa real, a fal aceita (mais caro). `first_frame_image` + `last_frame_image` continuam funcionando (viram image-to-video da fal, com end frame). Com isto ligado, `output_format` e `video_task_type` (edit/extend) n\xE3o t\xEAm equivalente na fal e s\xE3o recusados antes de cobrar \u2014 e `seedance-2.0-fast` com `resolution: "480p"` tamb\xE9m, porque a fal n\xE3o publica pre\xE7o para essa combina\xE7\xE3o.'
22079
+ ),
22080
+ project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.'),
22081
+ billing: BILLING_FIELD,
22082
+ draft: external_exports.boolean().optional().describe(
22083
+ 'Draft Mode (s\xF3 seedance-2.5, lan\xE7ado pela BytePlus em 22/set/2026): gera um preview 480p barato para validar composi\xE7\xE3o/movimento antes de pagar o 1080p. Depois de check_generation mostrar "completed", o `draft_task_id` vem no retorno \u2014 \xE9 o que voc\xEA passa no pr\xF3ximo generate_video para render a vers\xE3o final, a mesma tomada, sem regenerar do zero.'
22084
+ ),
22085
+ draft_task_id: external_exports.string().min(1).optional().describe(
22086
+ "Gera a vers\xE3o 1080p de um draft j\xE1 pronto (feito com `draft: true`). Passe aqui o `draft_task_id` que check_generation devolveu para aquele draft \u2014 N\xC3O o generation_id. Prompt/refs/seed/ratio/\xE1udio s\xE3o HERDADOS do draft, n\xE3o os reenvie. `duration` \xE9 OBRIGAT\xD3RIO e tem que ser exatamente a dura\xE7\xE3o do draft original (\xE9 o que precifica certo); `resolution` \xE9 sempre 1080p. Drafts expiram em 7 dias."
22087
+ )
22056
22088
  }
22057
22089
  },
22058
22090
  async (args) => {
@@ -22072,9 +22104,41 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22072
22104
  if (!isSeedance25 && args.output_format && args.output_format !== "mp4") {
22073
22105
  return errorResult(`output_format ${args.output_format} s\xF3 existe no seedance-2.5 (voc\xEA pediu ${args.model}).`);
22074
22106
  }
22107
+ if ((args.draft || args.draft_task_id) && !isSeedance25) {
22108
+ return errorResult(`Draft Mode s\xF3 existe no seedance-2.5 (voc\xEA pediu ${args.model}).`);
22109
+ }
22110
+ if (!args.draft_task_id && !args.prompt) {
22111
+ return errorResult("`prompt` \xE9 obrigat\xF3rio (s\xF3 pode faltar ao usar `draft_task_id`).");
22112
+ }
22113
+ if (args.draft_task_id) {
22114
+ if (args.duration == null) {
22115
+ return errorResult("Ao usar `draft_task_id`, `duration` \xE9 obrigat\xF3rio \u2014 a mesma dura\xE7\xE3o do draft original.");
22116
+ }
22117
+ if (args.resolution && args.resolution !== "1080p") {
22118
+ return errorResult('O upscale de um draft s\xF3 gera em 1080p \u2014 omita `resolution` ou use "1080p".');
22119
+ }
22120
+ }
22075
22121
  if (!isSeedance25 && args.video_task_type && args.video_task_type !== "auto") {
22076
22122
  return errorResult(`Editar e estender v\xEDdeo s\xF3 existe no seedance-2.5 (voc\xEA pediu ${args.model}).`);
22077
22123
  }
22124
+ if (args.real_people_references && !args.model?.startsWith("bytedance/seedance-")) {
22125
+ return errorResult(`real_people_references s\xF3 existe nos modelos Seedance (voc\xEA pediu ${args.model}).`);
22126
+ }
22127
+ if (args.real_people_references) {
22128
+ const unsupported = [];
22129
+ if (args.output_format && args.output_format !== "mp4") unsupported.push("output_format");
22130
+ if (args.video_task_type && args.video_task_type !== "auto") unsupported.push("video_task_type (edit/extend)");
22131
+ if (args.model === "bytedance/seedance-2.0-fast" && args.resolution === "480p") {
22132
+ unsupported.push("resolution 480p (a fal n\xE3o publica pre\xE7o para seedance-2.0-fast nesta resolu\xE7\xE3o)");
22133
+ }
22134
+ if (args.draft) unsupported.push("draft (Modo Rascunho \u2014 s\xF3 existe na BytePlus)");
22135
+ if (args.draft_task_id) unsupported.push("draft_task_id (upscale de rascunho \u2014 s\xF3 existe na BytePlus)");
22136
+ if (unsupported.length > 0) {
22137
+ return errorResult(
22138
+ `Com real_people_references, a fal.ai n\xE3o suporta: ${unsupported.join(", ")}. Remova essas op\xE7\xF5es.`
22139
+ );
22140
+ }
22141
+ }
22078
22142
  if ((args.video_task_type === "edit" || args.video_task_type === "extend") && !(args.reference_videos && args.reference_videos.length > 0)) {
22079
22143
  return errorResult(`video_task_type "${args.video_task_type}" exige o v\xEDdeo original em reference_videos.`);
22080
22144
  }
@@ -22105,7 +22169,12 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22105
22169
  const referenceAudios = await resolveRefs(cfg, args.reference_audios);
22106
22170
  const motionVideo = await resolveRef(cfg, args.motion_video);
22107
22171
  const refVideos = await resolveRefs(cfg, args.reference_videos);
22108
- const input = compact({
22172
+ const input = args.draft_task_id ? compact({
22173
+ draft_task_id: args.draft_task_id,
22174
+ resolution: "1080p",
22175
+ duration: args.duration,
22176
+ output_format: args.output_format
22177
+ }) : compact({
22109
22178
  prompt: args.prompt,
22110
22179
  aspect_ratio: args.aspect_ratio ?? DEFAULTS.videoAspect,
22111
22180
  resolution: args.resolution ?? DEFAULTS.videoResolution,
@@ -22124,10 +22193,17 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22124
22193
  keep_original_sound: args.keep_original_sound,
22125
22194
  seed: args.seed,
22126
22195
  output_format: args.output_format,
22127
- omni_reference_task_type: args.video_task_type
22196
+ omni_reference_task_type: args.video_task_type,
22197
+ draft: args.draft,
22198
+ realPeopleReferences: args.real_people_references
22128
22199
  });
22129
22200
  const start = await client.startGeneration(
22130
- compact({ model: args.model, input, project: args.project ?? cfg.activeProject ?? void 0 })
22201
+ compact({
22202
+ model: args.model,
22203
+ input,
22204
+ project: resolveProjectArg(args.project, args.billing, cfg.activeProject),
22205
+ billing: args.billing
22206
+ })
22131
22207
  );
22132
22208
  if (!start.success || !start.generation_id) {
22133
22209
  if (isTeamGatingError(start.message)) return errorResult(await buildPickProjectMessage(client));
@@ -22177,8 +22253,11 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
22177
22253
  const urls = outputUrls(status);
22178
22254
  const blocks = await buildImageBlocks(urls, cfg);
22179
22255
  const list = urls.map((u, i) => `${i + 1}. ${u}`).join("\n") || "(sem URLs)";
22256
+ const draftHint = status.draft_task_id ? `
22257
+
22258
+ \u{1F3AC} Draft pronto \u2014 pra gerar em 1080p, chame generate_video de novo com draft_task_id: "${status.draft_task_id}" (mesma duration deste draft).` : "";
22180
22259
  return { content: [{ type: "text", text: `\u2705 Pronto.
22181
- ${list}${flagsLine(status)}` }, ...blocks] };
22260
+ ${list}${flagsLine(status)}${draftHint}` }, ...blocks] };
22182
22261
  }
22183
22262
  if (status.status === "failed") {
22184
22263
  return errorResult(`Gera\xE7\xE3o falhou: ${status.error_message || "erro desconhecido"}.`);
@@ -22606,6 +22685,9 @@ function registerUpscaleTools(server, client, cfg) {
22606
22685
  "Modelo do Topaz. Imagem: Wonder 3 (padr\xE3o, serve para quase tudo), Wonder 3.5 (detalhe fino), Wonder 2, Wonder, Recover 3 (imagem muito danificada), Standard MAX (fiel ao original), Redefine (usa a descri\xE7\xE3o), Recovery V2, Recovery. V\xEDdeo: Starlight Precise 2.6 (padr\xE3o), Starlight HQ, Starlight Mini, Starlight Sharp, Starlight Fast 2 (mais r\xE1pido e custa metade)."
22607
22686
  ),
22608
22687
  project: external_exports.string().max(64).optional().describe('Projeto de destino (uuid OU code curto, ex.: "VRAO-26"). Ausente \u2192 projeto ativo.'),
22688
+ billing: external_exports.enum(["personal"]).optional().describe(
22689
+ '"personal" = cobra do seu diamante pessoal, IGNORANDO o projeto ativo (mesmo se houver um). Use quando quiser garantir que isto N\xC3O sai do budget de nenhum projeto. Incompat\xEDvel com `project`.'
22690
+ ),
22609
22691
  // ── só imagem ────────────────────────────────────────────────────────
22610
22692
  output_format: external_exports.enum(["jpeg", "png"]).optional().describe("[imagem] Formato da sa\xEDda. Padr\xE3o png."),
22611
22693
  subject_detection: external_exports.enum(["All", "Foreground", "Background"]).optional().describe("[imagem] Onde aplicar: imagem toda, s\xF3 o primeiro plano ou s\xF3 o fundo. Padr\xE3o All."),
@@ -22723,7 +22805,8 @@ function registerUpscaleTools(server, client, cfg) {
22723
22805
  compact({
22724
22806
  model: isVideo ? VIDEO_MODEL : IMAGE_MODEL,
22725
22807
  input,
22726
- project: args.project ?? cfg.activeProject ?? void 0
22808
+ project: resolveProjectArg(args.project, args.billing, cfg.activeProject),
22809
+ billing: args.billing
22727
22810
  })
22728
22811
  );
22729
22812
  if (!start.success || !start.generation_id) {
@@ -22844,7 +22927,10 @@ function registerMusicTools(server, client, cfg) {
22844
22927
  negative_tags: external_exports.string().max(1e3).optional().describe("Estilos/elementos a evitar."),
22845
22928
  style_weight: external_exports.number().min(0).max(1).optional().describe("Peso do estilo (0\u20131). Maior = segue mais as tags. Omita para o modelo decidir."),
22846
22929
  weirdness_constraint: external_exports.number().min(0).max(1).optional().describe("Criatividade/imprevisibilidade (0\u20131). Omita para o modelo decidir."),
22847
- project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.')
22930
+ project: external_exports.string().max(64).optional().describe('Projeto (uuid OU code curto, ex.: "VRAO-26"). S\xF3 omita se o usu\xE1rio J\xC1 confirmou o projeto ativo nesta sess\xE3o.'),
22931
+ billing: external_exports.enum(["personal"]).optional().describe(
22932
+ '"personal" = cobra do seu diamante pessoal, IGNORANDO o projeto ativo (mesmo se houver um). Use quando quiser garantir que isto N\xC3O sai do budget de nenhum projeto. Incompat\xEDvel com `project`.'
22933
+ )
22848
22934
  }
22849
22935
  },
22850
22936
  async (args) => {
@@ -22874,7 +22960,12 @@ function registerMusicTools(server, client, cfg) {
22874
22960
  input.prompt = desc;
22875
22961
  }
22876
22962
  const start = await client.startGeneration(
22877
- compact({ model: args.model, input, project: args.project ?? cfg.activeProject ?? void 0 })
22963
+ compact({
22964
+ model: args.model,
22965
+ input,
22966
+ project: resolveProjectArg(args.project, args.billing, cfg.activeProject),
22967
+ billing: args.billing
22968
+ })
22878
22969
  );
22879
22970
  if (!start.success || !start.generation_id) {
22880
22971
  if (isTeamGatingError(start.message)) return errorResult(await buildPickProjectMessage(client));
@@ -23074,6 +23165,9 @@ function registerAnalyzeTools(server, client, cfg) {
23074
23165
  ),
23075
23166
  project: external_exports.string().optional().describe(
23076
23167
  'Projeto (uuid ou code curto, ex.: "ICONS") de cujo budget cobrar. Omitido \u2192 usa o projeto ativo da conta.'
23168
+ ),
23169
+ billing: external_exports.enum(["personal"]).optional().describe(
23170
+ '"personal" = cobra do seu diamante pessoal, IGNORANDO o projeto ativo (mesmo se houver um). Use quando quiser garantir que isto N\xC3O sai do budget de nenhum projeto. Incompat\xEDvel com `project`.'
23077
23171
  )
23078
23172
  }
23079
23173
  },
@@ -23085,7 +23179,8 @@ function registerAnalyzeTools(server, client, cfg) {
23085
23179
  prompt: args.prompt,
23086
23180
  media_urls,
23087
23181
  model: args.model,
23088
- project: args.project
23182
+ project: args.project,
23183
+ billing: args.billing
23089
23184
  })
23090
23185
  );
23091
23186
  const origem = res.chargedFrom === "budget" ? "restam no budget do projeto" : res.chargedFrom === "weekly_allowance" ? "restam no cr\xE9dito semanal" : res.chargedFrom === "unlimited" ? "limite livre" : "saldo pessoal";
@@ -23375,7 +23470,7 @@ ${calls.map(callLine).join("\n\n")}`);
23375
23470
  import { createRequire } from "module";
23376
23471
  var require2 = createRequire(import.meta.url);
23377
23472
  function readVersion() {
23378
- if ("0.23.0") return "0.23.0";
23473
+ if ("0.25.0") return "0.25.0";
23379
23474
  try {
23380
23475
  const pkg = require2("../package.json");
23381
23476
  return pkg.version ?? "0.0.0-unknown";