beplus-mcp 0.21.1 → 0.23.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 +1 -1
- package/dist/index.js +101 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Reinicie o cliente. Rode a tool **`whoami`** para confirmar o vínculo.
|
|
|
88
88
|
| `check_generation` | Status de uma geração async por id. |
|
|
89
89
|
| `cancel_generation` | Cancela uma geração em fila/processamento (estorna diamantes). |
|
|
90
90
|
| `estimate_cost` | Custo em diamantes antes de gerar. |
|
|
91
|
-
| `read_image_metadata` / `analyze_media` | Lê a proveniência embutida numa imagem / analisa mídia (imagem/vídeo/áudio/PDF) com prompt. |
|
|
91
|
+
| `read_image_metadata` / `analyze_media` | Lê a proveniência embutida numa imagem / analisa mídia (imagem/vídeo/áudio/PDF) com prompt, em Gemini, Claude ou GPT. O apelido do modelo vai em `model` e o catálogo por faixa de preço (econômico, médio, top) sai no `list_models`. Vídeo e áudio só nos `gemini-*`. |
|
|
92
92
|
|
|
93
93
|
> **Referências de arquivo local (desde 0.8.1):** os campos de mídia — `reference_images`,
|
|
94
94
|
> `first_frame_image`, `last_frame_image`, `reference_videos`, `reference_audios`, `motion_video`
|
package/dist/index.js
CHANGED
|
@@ -21529,6 +21529,63 @@ function budgetLine(b) {
|
|
|
21529
21529
|
if (exhausted) line += " \u2014 pe\xE7a a um admin para recarregar";
|
|
21530
21530
|
return line;
|
|
21531
21531
|
}
|
|
21532
|
+
var TIER_ORDER = ["economy", "mid", "top"];
|
|
21533
|
+
var TIER_LABEL = {
|
|
21534
|
+
economy: "\u{1F49A} Econ\xF4mico (r\xE1pido e barato)",
|
|
21535
|
+
mid: "\u{1F49B} M\xE9dio (equil\xEDbrio)",
|
|
21536
|
+
top: "\u2764\uFE0F Top (mais capaz, mais caro)"
|
|
21537
|
+
};
|
|
21538
|
+
var TIER_ALIAS = {
|
|
21539
|
+
economico: "economy",
|
|
21540
|
+
medio: "mid"
|
|
21541
|
+
};
|
|
21542
|
+
function normalizeTier(tier) {
|
|
21543
|
+
if (!tier) return "";
|
|
21544
|
+
const normalized = tier.normalize("NFD").replace(/[̀-ͯ]/g, "").trim().toLowerCase();
|
|
21545
|
+
return TIER_ALIAS[normalized] ?? normalized;
|
|
21546
|
+
}
|
|
21547
|
+
function usd(value) {
|
|
21548
|
+
return `$${value.toFixed(2)}`;
|
|
21549
|
+
}
|
|
21550
|
+
function acceptsLine(accepts) {
|
|
21551
|
+
const parts = [];
|
|
21552
|
+
if (accepts.images > 0) parts.push(`imagem (at\xE9 ${accepts.images})`);
|
|
21553
|
+
if (accepts.videos > 0) parts.push(`v\xEDdeo (at\xE9 ${accepts.videos})`);
|
|
21554
|
+
if (accepts.audios > 0) parts.push(`\xE1udio (at\xE9 ${accepts.audios})`);
|
|
21555
|
+
if (accepts.pdfs > 0) parts.push(`PDF (at\xE9 ${accepts.pdfs})`);
|
|
21556
|
+
return parts.length ? parts.join(", ") : "s\xF3 texto";
|
|
21557
|
+
}
|
|
21558
|
+
function analyzeModelLine(m) {
|
|
21559
|
+
const provider = m.provider ? ` \xB7 ${m.provider}` : "";
|
|
21560
|
+
return ` \u2022 ${m.model} \xB7 ${m.label}${provider}
|
|
21561
|
+
${usd(m.inputCostPerMillion)} entrada / ${usd(m.outputCostPerMillion)} sa\xEDda por 1M tokens \xB7 aceita ${acceptsLine(m.accepts)}`;
|
|
21562
|
+
}
|
|
21563
|
+
function analyzeCatalogBlock(models) {
|
|
21564
|
+
if (!models?.length) return "";
|
|
21565
|
+
const groups = /* @__PURE__ */ new Map();
|
|
21566
|
+
for (const m of models) {
|
|
21567
|
+
const key = normalizeTier(typeof m.tier === "string" ? m.tier : void 0);
|
|
21568
|
+
const bucket = groups.get(key);
|
|
21569
|
+
if (bucket) bucket.push(m);
|
|
21570
|
+
else groups.set(key, [m]);
|
|
21571
|
+
}
|
|
21572
|
+
const known = TIER_ORDER.filter((t) => groups.has(t));
|
|
21573
|
+
const unknown2 = [...groups.keys()].filter((k) => !TIER_ORDER.includes(k));
|
|
21574
|
+
const untiered = groups.size === 1 && groups.has("");
|
|
21575
|
+
const sections = [...known, ...unknown2].map((key) => {
|
|
21576
|
+
const bucket = groups.get(key);
|
|
21577
|
+
const lines = bucket.map(analyzeModelLine).join("\n");
|
|
21578
|
+
if (untiered) return lines;
|
|
21579
|
+
const fallback = bucket[0]?.tierLabel?.trim();
|
|
21580
|
+
const heading = TIER_LABEL[key] ?? (fallback || (key ? `Faixa ${key}` : "Sem faixa definida"));
|
|
21581
|
+
return `${heading}:
|
|
21582
|
+
${lines}`;
|
|
21583
|
+
});
|
|
21584
|
+
const videoAliases = models.filter((m) => m.accepts.videos > 0).map((m) => m.model);
|
|
21585
|
+
const videoHint = videoAliases.length && videoAliases.length < models.length ? `
|
|
21586
|
+
V\xEDdeo e \xE1udio s\xF3 em: ${videoAliases.join(", ")}.` : "";
|
|
21587
|
+
return "\n\nAn\xE1lise multimodal (tool analyze_media \xB7 prompt + m\xEDdia \u2192 texto):\n" + sections.join("\n") + "\nPasse o apelido em `model`." + videoHint;
|
|
21588
|
+
}
|
|
21532
21589
|
function textResult(s) {
|
|
21533
21590
|
return { content: [{ type: "text", text: s }] };
|
|
21534
21591
|
}
|
|
@@ -21967,10 +22024,10 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
|
|
|
21967
22024
|
// limite; o Kling publica 2500 e o backend recusa dizendo quanto cortar.
|
|
21968
22025
|
prompt: external_exports.string().min(1).describe("Descri\xE7\xE3o do v\xEDdeo desejado."),
|
|
21969
22026
|
model: external_exports.enum(VIDEO_MODELS).default(DEFAULTS.videoModel).describe(
|
|
21970
|
-
"seedance-2.0-fast = barato/r\xE1pido; seedance-2.5 = at\xE9 30s num take
|
|
22027
|
+
"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."
|
|
21971
22028
|
),
|
|
21972
22029
|
aspect_ratio: external_exports.enum(VIDEO_ASPECT_RATIOS).optional().describe("Propor\xE7\xE3o. Padr\xE3o 16:9. `adaptive` (herda dos inputs) s\xF3 no seedance-2.5."),
|
|
21973
|
-
resolution: external_exports.enum(VIDEO_RESOLUTIONS).optional().describe("480p/720p/1080p/4K (
|
|
22030
|
+
resolution: external_exports.enum(VIDEO_RESOLUTIONS).optional().describe("480p/720p/1080p/4K (4K S\xD3 no seedance-2.0 standard; o 2.5 vai at\xE9 1080p; fast e mini param em 720p). Padr\xE3o 720p."),
|
|
21974
22031
|
duration: external_exports.number().int().min(3).max(60).optional().describe(
|
|
21975
22032
|
"Dura\xE7\xE3o em segundos. Seedance 2.5: 4\u201330 (granular). Seedance 2.0/2.0-fast: 4\u201315. Kling: 5 ou 10. O backend valida por modelo \u2014 consulte list_models p/ os valores aceitos. Padr\xE3o 5."
|
|
21976
22033
|
),
|
|
@@ -21979,24 +22036,48 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
|
|
|
21979
22036
|
generate_audio: external_exports.boolean().optional().describe("Gerar trilha de \xE1udio junto com o v\xEDdeo (Seedance/Kling). Na web fica ligado por padr\xE3o."),
|
|
21980
22037
|
first_frame_image: external_exports.string().min(1).optional().describe("Imagem inicial (image-to-video / primeiro frame): URL p\xFAblica OU caminho local (sobe pro R2)."),
|
|
21981
22038
|
last_frame_image: external_exports.string().min(1).optional().describe("Imagem do \xFAltimo frame (Seedance/Kling): URL p\xFAblica OU caminho local (sobe pro R2)."),
|
|
21982
|
-
|
|
21983
|
-
|
|
21984
|
-
|
|
22039
|
+
// Os tetos aqui são os do MODELO MAIS PERMISSIVO (seedance-2.5:
|
|
22040
|
+
// 30 imagens / 10 vídeos / 10 áudios). Quem for além do que o modelo
|
|
22041
|
+
// escolhido aceita leva a mensagem do backend, que conhece o limite
|
|
22042
|
+
// por modelo — cortar em 9/3/3 aqui só escondia metade do 2.5.
|
|
22043
|
+
reference_images: external_exports.array(external_exports.string().min(1)).max(30).optional().describe("Imagens de refer\xEAncia (personagem/estilo) \u2014 omni/Seedance. URL p\xFAblica OU caminho local. At\xE9 30 no 2.5, 9 no 2.0."),
|
|
22044
|
+
reference_videos: external_exports.array(external_exports.string().min(1)).max(10).optional().describe("V\xEDdeos de refer\xEAncia (Seedance reference_videos / Kling reference_video): URL OU caminho local. At\xE9 10 no 2.5 (cada um de 1,8s a 30s), 3 no 2.0."),
|
|
22045
|
+
reference_audios: external_exports.array(external_exports.string().min(1)).max(10).optional().describe("\xC1udios de refer\xEAncia: URL p\xFAblica OU caminho local. At\xE9 10 no 2.5 (onde o \xE1udio pode vir sozinho), 3 no 2.0."),
|
|
21985
22046
|
motion_video: external_exports.string().min(1).optional().describe("V\xEDdeo de movimento/m\xE1scara din\xE2mica (kling-v2.6-motion-control): URL OU caminho local."),
|
|
21986
22047
|
character_orientation: external_exports.string().optional().describe("Orienta\xE7\xE3o do personagem (alguns modelos Kling via Replicate)."),
|
|
21987
22048
|
keep_original_sound: external_exports.boolean().optional().describe("Manter o som original do v\xEDdeo de refer\xEAncia (alguns modelos Kling)."),
|
|
21988
22049
|
reference_image: external_exports.string().min(1).optional().describe("[Obsoleto \u2014 use first_frame_image] Imagem de refer\xEAncia: URL p\xFAblica OU caminho local."),
|
|
21989
22050
|
seed: external_exports.number().int().optional(),
|
|
22051
|
+
output_format: external_exports.enum(["mp4", "mov"]).optional().describe("Formato do arquivo (s\xF3 seedance-2.5). Padr\xE3o mp4; `mov` \xE9 H.264 4:4:4 + PCM, para p\xF3s-produ\xE7\xE3o \u2014 nem todo player abre."),
|
|
22052
|
+
video_task_type: external_exports.enum(["auto", "reference", "edit", "extend"]).optional().describe(
|
|
22053
|
+
"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
|
+
),
|
|
21990
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.')
|
|
21991
22056
|
}
|
|
21992
22057
|
},
|
|
21993
22058
|
async (args) => {
|
|
21994
22059
|
try {
|
|
21995
|
-
|
|
22060
|
+
const MAX_RESOLUTION = {
|
|
22061
|
+
"bytedance/seedance-2.0-mini": ["480p", "720p"],
|
|
22062
|
+
"bytedance/seedance-2.0-fast": ["480p", "720p"],
|
|
22063
|
+
"bytedance/seedance-2.5": ["480p", "720p", "1080p"]
|
|
22064
|
+
};
|
|
22065
|
+
const allowedResolutions = args.model ? MAX_RESOLUTION[args.model] : void 0;
|
|
22066
|
+
if (allowedResolutions && args.resolution && !allowedResolutions.includes(args.resolution)) {
|
|
21996
22067
|
return errorResult(
|
|
21997
|
-
`${args.model} s\xF3 suporta
|
|
22068
|
+
`${args.model} s\xF3 suporta ${allowedResolutions.join(" ou ")} (voc\xEA pediu ${args.resolution}). Use seedance-2.0 (standard) para 4K.`
|
|
21998
22069
|
);
|
|
21999
22070
|
}
|
|
22071
|
+
const isSeedance25 = args.model === "bytedance/seedance-2.5";
|
|
22072
|
+
if (!isSeedance25 && args.output_format && args.output_format !== "mp4") {
|
|
22073
|
+
return errorResult(`output_format ${args.output_format} s\xF3 existe no seedance-2.5 (voc\xEA pediu ${args.model}).`);
|
|
22074
|
+
}
|
|
22075
|
+
if (!isSeedance25 && args.video_task_type && args.video_task_type !== "auto") {
|
|
22076
|
+
return errorResult(`Editar e estender v\xEDdeo s\xF3 existe no seedance-2.5 (voc\xEA pediu ${args.model}).`);
|
|
22077
|
+
}
|
|
22078
|
+
if ((args.video_task_type === "edit" || args.video_task_type === "extend") && !(args.reference_videos && args.reference_videos.length > 0)) {
|
|
22079
|
+
return errorResult(`video_task_type "${args.video_task_type}" exige o v\xEDdeo original em reference_videos.`);
|
|
22080
|
+
}
|
|
22000
22081
|
if (args.model?.startsWith("bytedance/seedance-") && args.aspect_ratio) {
|
|
22001
22082
|
const SEEDANCE_RATIOS = ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "adaptive"];
|
|
22002
22083
|
if (!SEEDANCE_RATIOS.includes(args.aspect_ratio)) {
|
|
@@ -22041,7 +22122,9 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
|
|
|
22041
22122
|
motion_video: motionVideo,
|
|
22042
22123
|
character_orientation: args.character_orientation,
|
|
22043
22124
|
keep_original_sound: args.keep_original_sound,
|
|
22044
|
-
seed: args.seed
|
|
22125
|
+
seed: args.seed,
|
|
22126
|
+
output_format: args.output_format,
|
|
22127
|
+
omni_reference_task_type: args.video_task_type
|
|
22045
22128
|
});
|
|
22046
22129
|
const start = await client.startGeneration(
|
|
22047
22130
|
compact({ model: args.model, input, project: args.project ?? cfg.activeProject ?? void 0 })
|
|
@@ -22878,7 +22961,7 @@ ${budget}` : "")
|
|
|
22878
22961
|
"list_models",
|
|
22879
22962
|
{
|
|
22880
22963
|
title: "Listar modelos",
|
|
22881
|
-
description: "Lista os modelos dispon\xEDveis com pre\xE7o-base e limites por usu\xE1rio. Use quando estiver em d\xFAvida sobre qual modelo/params usar ou quanto custa. \xC9 a fonte de verdade em runtime.",
|
|
22964
|
+
description: "Lista os modelos dispon\xEDveis com pre\xE7o-base e limites por usu\xE1rio, e o cat\xE1logo de an\xE1lise multimodal (Gemini, Claude e GPT) agrupado por faixa de pre\xE7o. Use quando estiver em d\xFAvida sobre qual modelo/params usar ou quanto custa. \xC9 a fonte de verdade em runtime.",
|
|
22882
22965
|
inputSchema: {
|
|
22883
22966
|
kind: external_exports.enum(["image", "video", "audio", "all"]).default("all").optional().describe("Filtrar por tipo.")
|
|
22884
22967
|
}
|
|
@@ -22890,13 +22973,7 @@ ${budget}` : "")
|
|
|
22890
22973
|
const price = typeof x.pricing === "number" ? `$${x.pricing}` : JSON.stringify(x.pricing);
|
|
22891
22974
|
return `\u2022 ${x.model} \u2014 ${price} (base USD)`;
|
|
22892
22975
|
});
|
|
22893
|
-
const
|
|
22894
|
-
(a) => `\u2022 ${a.model} (${a.label}) \u2014 $${a.inputCostPerMillion}/$${a.outputCostPerMillion} por 1M tok in/out \xB7 aceita img=${a.accepts.images} vid=${a.accepts.videos} \xE1udio=${a.accepts.audios} pdf=${a.accepts.pdfs}`
|
|
22895
|
-
);
|
|
22896
|
-
const analyzeBlock = analyzeLines.length ? `
|
|
22897
|
-
|
|
22898
|
-
Modelos de an\xE1lise multimodal (tool analyze_media \u2014 prompt + m\xEDdia \u2192 texto):
|
|
22899
|
-
${analyzeLines.join("\n")}` : "";
|
|
22976
|
+
const analyzeBlock = analyzeCatalogBlock(m.analyze);
|
|
22900
22977
|
const txt = `Modelos de gera\xE7\xE3o:
|
|
22901
22978
|
${lines.join("\n") || "(nenhum)"}` + analyzeBlock + `
|
|
22902
22979
|
|
|
@@ -22983,14 +23060,18 @@ function registerAnalyzeTools(server, client, cfg) {
|
|
|
22983
23060
|
server.registerTool(
|
|
22984
23061
|
"analyze_media",
|
|
22985
23062
|
{
|
|
22986
|
-
title: "Analisar m\xEDdia (Gemini)",
|
|
22987
|
-
description: "Envia um prompt + m\xEDdia (imagem, v\xEDdeo, \xE1udio ou PDF) para
|
|
23063
|
+
title: "Analisar m\xEDdia (Gemini, Claude e GPT)",
|
|
23064
|
+
description: "Envia um prompt + m\xEDdia (imagem, v\xEDdeo, \xE1udio ou PDF) para um modelo de texto e devolve a resposta. Use para descrever/analisar/transcrever/resumir/extrair informa\xE7\xE3o de m\xEDdia, ou perguntar algo sobre ela. Tamb\xE9m funciona s\xF3 com texto, sem m\xEDdia. Tr\xEAs faixas de pre\xE7o: econ\xF4mica, m\xE9dia e top. A m\xEDdia entra como `media_urls` (URLs p\xFAblicas ou caminhos locais). V\xEDdeo e \xE1udio s\xF3 nos modelos Gemini, que leem arquivos grandes pela Files API do Google. Consome diamantes (reembolsados se falhar). O cat\xE1logo vivo, com pre\xE7o por 1M de tokens e m\xEDdia aceita por modelo, sai no list_models.",
|
|
22988
23065
|
inputSchema: {
|
|
22989
23066
|
prompt: external_exports.string().min(1).max(5e4).describe('O que voc\xEA quer do modelo sobre a m\xEDdia (ex.: "descreva este v\xEDdeo", "transcreva este \xE1udio").'),
|
|
22990
23067
|
media_urls: external_exports.array(external_exports.string().min(1)).max(50).optional().describe(
|
|
22991
23068
|
"M\xEDdia (imagem/v\xEDdeo/\xE1udio/PDF): URLs p\xFAblicas OU caminhos de arquivo local (o MCP sobe pro R2 automaticamente). Pode misturar tipos. Opcional (prompt s\xF3-texto tamb\xE9m funciona)."
|
|
22992
23069
|
),
|
|
22993
|
-
|
|
23070
|
+
// String livre, não z.enum: quem valida o apelido é o backend, então um
|
|
23071
|
+
// modelo novo no catálogo passa a valer sem republicar o pacote.
|
|
23072
|
+
model: external_exports.string().min(1).default("gemini-flash").optional().describe(
|
|
23073
|
+
"Apelido do modelo. Econ\xF4micos: gemini-lite, gpt-mini, claude-haiku. M\xE9dios: gemini-flash (padr\xE3o), gpt, claude-sonnet. Top: gemini-pro, claude-opus, gpt-pro, claude-fable. V\xEDdeo e \xE1udio s\xF3 nos gemini-*; PDF nos gemini-* e claude-*; os gpt-* leem s\xF3 imagem. Lista autoritativa, com pre\xE7os: list_models."
|
|
23074
|
+
),
|
|
22994
23075
|
project: external_exports.string().optional().describe(
|
|
22995
23076
|
'Projeto (uuid ou code curto, ex.: "ICONS") de cujo budget cobrar. Omitido \u2192 usa o projeto ativo da conta.'
|
|
22996
23077
|
)
|
|
@@ -23294,7 +23375,7 @@ ${calls.map(callLine).join("\n\n")}`);
|
|
|
23294
23375
|
import { createRequire } from "module";
|
|
23295
23376
|
var require2 = createRequire(import.meta.url);
|
|
23296
23377
|
function readVersion() {
|
|
23297
|
-
if ("0.
|
|
23378
|
+
if ("0.23.0") return "0.23.0";
|
|
23298
23379
|
try {
|
|
23299
23380
|
const pkg = require2("../package.json");
|
|
23300
23381
|
return pkg.version ?? "0.0.0-unknown";
|