@fangyb/ahchat-bridge 0.1.32 → 0.1.33

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.
@@ -31231,6 +31231,59 @@ var StdioServerTransport = class {
31231
31231
  }
31232
31232
  };
31233
31233
 
31234
+ // src/officialMcpQuota.ts
31235
+ init_cjs_shims();
31236
+ var OfficialMcpQuotaError = class extends Error {
31237
+ constructor(message) {
31238
+ super(message);
31239
+ this.name = "OfficialMcpQuotaError";
31240
+ }
31241
+ };
31242
+ async function consumeOfficialMcpDailyQuota(serverName, toolName) {
31243
+ const serverApiUrl = process.env.AHCHAT_SERVER_API_URL?.trim();
31244
+ const bridgeToken = process.env.AHCHAT_BRIDGE_TOKEN?.trim();
31245
+ if (!serverApiUrl || !bridgeToken) return;
31246
+ let response;
31247
+ try {
31248
+ response = await fetch(`${serverApiUrl.replace(/\/+$/, "")}/api/mcp/usage/consume`, {
31249
+ method: "POST",
31250
+ headers: {
31251
+ "Content-Type": "application/json",
31252
+ "X-AHChat-Bridge-Token": bridgeToken
31253
+ },
31254
+ body: JSON.stringify({ serverName, toolName })
31255
+ });
31256
+ } catch {
31257
+ throw new OfficialMcpQuotaError("\u6682\u65F6\u65E0\u6CD5\u6821\u9A8C\u5B98\u65B9\u5A92\u4F53 MCP \u6BCF\u65E5\u989D\u5EA6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002");
31258
+ }
31259
+ if (response.status === 404) return;
31260
+ const body = await readQuotaResponse(response);
31261
+ if (response.status === 429 || body.allowed === false) {
31262
+ throw new OfficialMcpQuotaError(formatQuotaExceededMessage(serverName, body));
31263
+ }
31264
+ if (!response.ok) {
31265
+ throw new OfficialMcpQuotaError(body.message || "\u5B98\u65B9\u5A92\u4F53 MCP \u6BCF\u65E5\u989D\u5EA6\u6821\u9A8C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002");
31266
+ }
31267
+ }
31268
+ async function readQuotaResponse(response) {
31269
+ try {
31270
+ const value = await response.json();
31271
+ if (value && typeof value === "object" && !Array.isArray(value)) {
31272
+ return value;
31273
+ }
31274
+ } catch {
31275
+ }
31276
+ return {};
31277
+ }
31278
+ function formatQuotaExceededMessage(serverName, body) {
31279
+ if (body.message) return body.message;
31280
+ const label = serverName === "seedance" ? "\u751F\u89C6\u9891" : serverName === "seedream" ? "\u751F\u56FE" : "\u5B98\u65B9\u5A92\u4F53";
31281
+ if (typeof body.used === "number" && typeof body.limit === "number") {
31282
+ return `\u4ECA\u5929\u7684${label}\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF08${body.used}/${body.limit}\uFF09\u3002\u8BF7\u660E\u5929\u518D\u8BD5\uFF0C\u6216\u8054\u7CFB\u8FD0\u8425\u8C03\u6574\u989D\u5EA6\u3002`;
31283
+ }
31284
+ return `\u4ECA\u5929\u7684${label}\u989D\u5EA6\u5DF2\u7528\u5B8C\u3002\u8BF7\u660E\u5929\u518D\u8BD5\uFF0C\u6216\u8054\u7CFB\u8FD0\u8425\u8C03\u6574\u989D\u5EA6\u3002`;
31285
+ }
31286
+
31234
31287
  // src/seedanceMcpCli.ts
31235
31288
  var SERVER_NAME = "ahchat-seedance-mcp";
31236
31289
  var SERVER_VERSION = "0.1.0";
@@ -31292,7 +31345,7 @@ function createServer() {
31292
31345
  const server = new McpServer(
31293
31346
  { name: SERVER_NAME, version: SERVER_VERSION },
31294
31347
  {
31295
- instructions: "AHChat official Seedance video generation MCP. Call seedance_create_task to submit a job, then seedance_check_task to poll the task_id. Generated URLs can expire; show or download them promptly."
31348
+ instructions: "AHChat official Seedance video generation MCP. Each user request should create exactly one video task. Call seedance_create_task once to submit a job, then seedance_check_task only when progress is requested. Generated URLs can expire; show or download them promptly."
31296
31349
  }
31297
31350
  );
31298
31351
  server.registerTool(
@@ -31315,7 +31368,7 @@ function createServer() {
31315
31368
  "seedance_create_task",
31316
31369
  {
31317
31370
  title: "Create Seedance video generation task",
31318
- description: "Submit a Seedance video generation task to the Volcengine Ark API and return the task_id immediately. Poll seedance_check_task afterwards.",
31371
+ description: "Submit exactly one Seedance video generation task to the Volcengine Ark API and return the task_id immediately. In AHChat, do not submit alternate tasks, loop, or sleep afterwards; the media task card tracks status.",
31319
31372
  inputSchema: createTaskInputShape,
31320
31373
  annotations: {
31321
31374
  readOnlyHint: false,
@@ -31328,6 +31381,7 @@ function createServer() {
31328
31381
  if (validationError) return errorResult(validationError);
31329
31382
  try {
31330
31383
  const normalized = normalizeCreateTaskInput(input);
31384
+ await consumeOfficialMcpDailyQuota("seedance", "seedance_create_task");
31331
31385
  const result = await createSeedanceTask(normalized);
31332
31386
  const payload = {
31333
31387
  state: "submitted",
@@ -31500,7 +31554,10 @@ async function parseJsonSafe(response) {
31500
31554
  if (!text) return void 0;
31501
31555
  try {
31502
31556
  return JSON.parse(text);
31503
- } catch {
31557
+ } catch (error51) {
31558
+ writeStderr(
31559
+ `[${SERVER_NAME}] ARK API returned a non-JSON response body: ${error51 instanceof Error ? error51.message : String(error51)}`
31560
+ );
31504
31561
  return text;
31505
31562
  }
31506
31563
  }
@@ -31579,22 +31636,27 @@ function errorResult(message) {
31579
31636
  function usageGuide() {
31580
31637
  return [
31581
31638
  "AHChat Seedance workflow:",
31582
- "1. Call seedance_create_task with prompt and optional reference media URLs.",
31583
- "2. Wait 30-90 seconds, then call seedance_check_task with the returned task_id.",
31584
- "3. When status is succeeded, use video_url in the chat result. Signed URLs may expire.",
31639
+ "1. Call seedance_create_task with prompt and optional reference media URLs. Each user request creates exactly one video task.",
31640
+ "2. After submission, stop manual waiting. AHChat will track the task in the visible media card.",
31641
+ "3. Only call seedance_check_task once when the user explicitly asks for progress or when diagnostics are needed.",
31642
+ "4. When status is succeeded, keep the text reply short and let the media card show preview, download, copy, and regenerate actions. Signed URLs may expire.",
31585
31643
  "",
31586
31644
  "Common defaults: model=doubao-seedance-2-0-260128, duration=5, ratio=16:9, resolution=720p, generate_audio=true.",
31587
31645
  "For vertical short video, set ratio=9:16. Reference media URLs must be reachable by Volcengine Ark."
31588
31646
  ].join("\n");
31589
31647
  }
31648
+ function writeStderr(message) {
31649
+ process.stderr.write(`${message}
31650
+ `);
31651
+ }
31590
31652
  async function main() {
31591
31653
  const server = createServer();
31592
31654
  const transport = new StdioServerTransport();
31593
31655
  await server.connect(transport);
31594
- console.error(`${SERVER_NAME} v${SERVER_VERSION} running on stdio`);
31656
+ writeStderr(`${SERVER_NAME} v${SERVER_VERSION} running on stdio`);
31595
31657
  }
31596
31658
  main().catch((error51) => {
31597
31659
  const message = error51 instanceof Error ? error51.stack ?? error51.message : String(error51);
31598
- console.error(`Fatal error in ${SERVER_NAME}: ${message}`);
31660
+ writeStderr(`Fatal error in ${SERVER_NAME}: ${message}`);
31599
31661
  process.exit(1);
31600
31662
  });