beplus-mcp 0.19.0 → 0.20.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.
Files changed (2) hide show
  1. package/dist/index.js +62 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1120,7 +1120,7 @@ ${list}${flagsLine(status)}` }, ...blocks] };
1120
1120
  import { z as z2 } from "zod";
1121
1121
 
1122
1122
  // src/probe.ts
1123
- import { readFile as readFile2, open } from "fs/promises";
1123
+ import { open, stat } from "fs/promises";
1124
1124
  import { extname as extname2, isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
1125
1125
  import { homedir as homedir2 } from "os";
1126
1126
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -1144,6 +1144,49 @@ function kindFromExt(ref) {
1144
1144
  if (VIDEO_EXT.has(ext)) return "video";
1145
1145
  return null;
1146
1146
  }
1147
+ async function readAt(ref, offset, len) {
1148
+ if (!isRemote(ref)) {
1149
+ const fh = await open(toLocalPath2(ref), "r");
1150
+ try {
1151
+ const buf = Buffer.alloc(len);
1152
+ const { bytesRead } = await fh.read(buf, 0, len, offset);
1153
+ return buf.subarray(0, bytesRead);
1154
+ } finally {
1155
+ await fh.close();
1156
+ }
1157
+ }
1158
+ const ctrl = new AbortController();
1159
+ const timer = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
1160
+ try {
1161
+ const res = await fetch(ref, {
1162
+ headers: { Range: `bytes=${offset}-${offset + len - 1}` },
1163
+ signal: ctrl.signal
1164
+ });
1165
+ if (res.status !== 206) throw new Error("servidor n\xE3o aceita Range");
1166
+ return Buffer.from(await res.arrayBuffer());
1167
+ } finally {
1168
+ clearTimeout(timer);
1169
+ }
1170
+ }
1171
+ async function findMoov(ref, fileSize) {
1172
+ let offset = 0;
1173
+ for (let guard = 0; guard < 64 && offset + 8 <= fileSize; guard++) {
1174
+ const head = await readAt(ref, offset, 16);
1175
+ if (head.length < 8) return null;
1176
+ let size = head.readUInt32BE(0);
1177
+ const type = head.toString("ascii", 4, 8);
1178
+ if (size === 1) {
1179
+ if (head.length < 16) return null;
1180
+ size = Number(head.readBigUInt64BE(8));
1181
+ }
1182
+ if (size < 8) return null;
1183
+ if (type === "moov") {
1184
+ return readAt(ref, offset, Math.min(size, MAX_SCAN_BYTES));
1185
+ }
1186
+ offset += size;
1187
+ }
1188
+ return null;
1189
+ }
1147
1190
  async function readHead(ref, bytes) {
1148
1191
  if (!isRemote(ref)) {
1149
1192
  const fh = await open(toLocalPath2(ref), "r");
@@ -1297,6 +1340,11 @@ function probeMp4(b) {
1297
1340
  const fps = dur && frames ? Math.round(frames / dur * 100) / 100 : void 0;
1298
1341
  return { width, height, duration: dur, fps };
1299
1342
  }
1343
+ async function fileSizeOf(ref) {
1344
+ if (!isRemote(ref)) return (await stat(toLocalPath2(ref))).size;
1345
+ const res = await fetch(ref, { method: "HEAD" });
1346
+ return Number(res.headers.get("content-length") ?? 0);
1347
+ }
1300
1348
  var ProbeError = class extends Error {
1301
1349
  };
1302
1350
  async function probeMedia(ref) {
@@ -1319,10 +1367,13 @@ async function probeMedia(ref) {
1319
1367
  return { kind, width: dim.width, height: dim.height };
1320
1368
  }
1321
1369
  let info = probeMp4(head);
1322
- if (!info && !isRemote(ref)) {
1370
+ if (!info) {
1323
1371
  try {
1324
- const whole = await readFile2(toLocalPath2(ref));
1325
- info = probeMp4(whole.subarray(0, Math.min(whole.length, MAX_SCAN_BYTES))) ?? probeMp4(whole.subarray(Math.max(0, whole.length - MAX_SCAN_BYTES)));
1372
+ const size = await fileSizeOf(ref);
1373
+ if (size > 0) {
1374
+ const moov = await findMoov(ref, size);
1375
+ if (moov) info = probeMp4(moov);
1376
+ }
1326
1377
  } catch {
1327
1378
  }
1328
1379
  }
@@ -1337,7 +1388,7 @@ async function probeMedia(ref) {
1337
1388
  // src/tools/upscale.ts
1338
1389
  var IMAGE_MODEL = "topaz/upscale/image/generative";
1339
1390
  var VIDEO_MODEL = "topaz/upscale/video/generative";
1340
- var MAX_VIDEO_SECONDS = 30;
1391
+ var MAX_VIDEO_SECONDS = 300;
1341
1392
  var MAX_OUTPUT_HEIGHT = 1080;
1342
1393
  var IMAGE_BUDGET_MS2 = 9e4;
1343
1394
  var VIDEO_BUDGET_MS2 = 24e4;
@@ -1349,12 +1400,14 @@ function registerUpscaleTools(server, client, cfg) {
1349
1400
  "upscale",
1350
1401
  {
1351
1402
  title: "Melhorar resolu\xE7\xE3o (upscale Topaz)",
1352
- description: "Aumenta a resolu\xE7\xE3o de uma IMAGEM ou de um V\xCDDEO que j\xE1 existe, com o Topaz. Passe o arquivo em `file` (caminho local ou URL) \u2014 o tipo \xE9 detectado pela extens\xE3o e define o modelo e os ajustes v\xE1lidos. Imagem: at\xE9 4x, ~20s, a partir de 6\u{1F48E}. V\xEDdeo: no m\xE1ximo 30s de dura\xE7\xE3o e sa\xEDda at\xE9 1080p, custa por bloco de 10s (5s \u2248 87\u{1F48E}, o teto de 30s chega a 260\u{1F48E}), leva alguns minutos e o \xC1UDIO N\xC3O \xC9 MANTIDO. \u26A0\uFE0F Melhorar v\xEDdeo \xE9 restrito a quem tem a tag de budget admin. Use `estimate_cost` antes se quiser confirmar o pre\xE7o." + TEAM_GATING_NOTE,
1403
+ description: "Aumenta a resolu\xE7\xE3o de uma IMAGEM ou de um V\xCDDEO que j\xE1 existe, com o Topaz. Passe o arquivo em `file` (caminho local ou URL) \u2014 o tipo \xE9 detectado pela extens\xE3o e define o modelo e os ajustes v\xE1lidos. Imagem: at\xE9 4x, ~20s, a partir de 6\u{1F48E}. V\xEDdeo: at\xE9 5 minutos (o teto do provedor) e sa\xEDda at\xE9 1080p, custa por bloco de 10s (5s \u2248 87\u{1F48E}, 1 min \u2248 520\u{1F48E}, os 5 min chegam a ~2.600\u{1F48E}) e o \xC1UDIO N\xC3O \xC9 MANTIDO. \u23F1\uFE0F V\xEDdeo longo demora MUITO: o ritmo \xE9 ~1,7 megapixel-frame/s, ent\xE3o 1 min em 1080p passa de 25 minutos e 5 min passam de 2 horas \u2014 a tool devolve o id e voc\xEA acompanha com check_generation. \u26A0\uFE0F Melhorar v\xEDdeo \xE9 restrito a quem tem a tag de budget admin. Use `estimate_cost` antes se quiser confirmar o pre\xE7o." + TEAM_GATING_NOTE,
1353
1404
  inputSchema: {
1354
1405
  file: z2.string().min(1).describe(
1355
1406
  "Arquivo a melhorar: caminho local (/foto.png, ~/Desktop/clipe.mp4) OU URL p\xFAblica. Caminho local sobe pro R2 automaticamente. Imagem: png, jpg, jpeg, webp. V\xEDdeo: mp4, mov, m4v."
1356
1407
  ),
1357
- factor: z2.number().int().min(1).max(4).optional().describe("Quantas vezes aumentar (1 a 4). Padr\xE3o 2. Em 1x s\xF3 melhora a qualidade, sem ampliar."),
1408
+ factor: z2.number().min(1).max(4).optional().describe(
1409
+ "Quantas vezes aumentar, de 1 a 4 \u2014 aceita fracion\xE1rio (2.5 \xE9 v\xE1lido), como a API do Topaz. Padr\xE3o 2. Em 1x s\xF3 melhora a qualidade, sem ampliar."
1410
+ ),
1358
1411
  variant: z2.string().optional().describe(
1359
1412
  "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)."
1360
1413
  ),
@@ -1429,7 +1482,7 @@ function registerUpscaleTools(server, client, cfg) {
1429
1482
  if (isVideo) {
1430
1483
  if (duration && duration > MAX_VIDEO_SECONDS) {
1431
1484
  return errorResult(
1432
- `Este v\xEDdeo tem ${Math.round(duration)}s e o limite para melhorar \xE9 ${MAX_VIDEO_SECONDS}s. Corte um trecho menor e tente de novo.`
1485
+ `Este v\xEDdeo tem ${Math.round(duration)}s e o limite para melhorar \xE9 ${Math.round(MAX_VIDEO_SECONDS / 60)} minutos. Corte um trecho menor e tente de novo.`
1433
1486
  );
1434
1487
  }
1435
1488
  if (height && height * factor > MAX_OUTPUT_HEIGHT) {
@@ -1766,7 +1819,7 @@ Limites simult\xE2neos por usu\xE1rio: imagem=${m.limits.perUserMaxImage}, v\xED
1766
1819
  file: z5.string().optional().describe(
1767
1820
  "[upscale] Arquivo a medir (caminho local ou URL) \u2014 preenche sozinho as medidas abaixo. Use com model=topaz/upscale/image/generative ou .../video/generative."
1768
1821
  ),
1769
- upscale_factor: z5.number().int().min(1).max(4).optional().describe("[upscale] Fator de aumento (1 a 4). Padr\xE3o 2."),
1822
+ upscale_factor: z5.number().min(1).max(4).optional().describe("[upscale] Fator de aumento, de 1 a 4 (aceita fracion\xE1rio). Padr\xE3o 2."),
1770
1823
  model_variant: z5.string().optional().describe("[upscale] Variante do Topaz (ex.: Wonder 3, Starlight Fast 2) \u2014 muda o pre\xE7o."),
1771
1824
  source_width: z5.number().int().positive().optional().describe("[upscale] Largura do arquivo."),
1772
1825
  source_height: z5.number().int().positive().optional().describe("[upscale] Altura do arquivo."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beplus-mcp",
3
- "version": "0.19.0",
3
+ "version": "0.20.1",
4
4
  "description": "Conector MCP da equipe BePlus — gere imagens/vídeos/áudio e consulte calls, projetos e clientes pela sua conta BePlus (diamantes, limites e histórico aplicados pela plataforma).",
5
5
  "type": "module",
6
6
  "bin": {