@sellable/mcp 0.1.479 → 0.1.480

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.
@@ -241,11 +241,15 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
241
241
  refreshedPaidInmailSenderIds: string[];
242
242
  failedPaidInmailRefreshes: {
243
243
  senderId: string;
244
+ attempts?: number;
244
245
  error: string;
246
+ errors?: string[];
245
247
  }[];
246
248
  refreshReceipts: {
247
249
  senderId: string;
248
250
  actionKey: string | null;
251
+ attempts: number;
252
+ retryErrors: string[];
249
253
  receipt: import("./senders.js").RefreshPaidInmailCreditsResponse;
250
254
  }[];
251
255
  attemptedSenderIds: string[];
@@ -4,6 +4,8 @@ import { startPrepareCampaignMessages } from "./campaign-message-preparation.js"
4
4
  import { confirmLeadList } from "./leads.js";
5
5
  import { getApi } from "../api.js";
6
6
  const DEFAULT_SCHEDULER_FORWARD_HOURS = 48;
7
+ const PAID_INMAIL_REFRESH_MAX_ATTEMPTS = 3;
8
+ const PAID_INMAIL_REFRESH_RETRY_DELAY_MS = Number(process.env.SELLABLE_MCP_PAID_REFRESH_RETRY_DELAY_MS ?? "1000");
7
9
  function normalizeStrings(values) {
8
10
  if (!Array.isArray(values))
9
11
  return [];
@@ -13,6 +15,11 @@ function normalizeStrings(values) {
13
15
  .filter(Boolean)),
14
16
  ];
15
17
  }
18
+ function sleep(ms) {
19
+ if (!Number.isFinite(ms) || ms <= 0)
20
+ return Promise.resolve();
21
+ return new Promise((resolve) => setTimeout(resolve, ms));
22
+ }
16
23
  function normalizeHorizonSendDays(value) {
17
24
  if (value === undefined || value === null)
18
25
  return null;
@@ -427,6 +434,26 @@ async function approveGeneratedMessagesBatch(action) {
427
434
  });
428
435
  return { status: "executed_and_reread", result };
429
436
  }
437
+ async function refreshPaidInmailCreditsWithRetry(senderId) {
438
+ const errors = [];
439
+ for (let attempt = 1; attempt <= PAID_INMAIL_REFRESH_MAX_ATTEMPTS; attempt += 1) {
440
+ try {
441
+ const receipt = await refreshPaidInmailCredits({ senderId });
442
+ return { receipt, attempts: attempt, errors };
443
+ }
444
+ catch (error) {
445
+ errors.push(error instanceof Error ? error.message : String(error));
446
+ if (attempt < PAID_INMAIL_REFRESH_MAX_ATTEMPTS) {
447
+ await sleep(PAID_INMAIL_REFRESH_RETRY_DELAY_MS);
448
+ }
449
+ }
450
+ }
451
+ return {
452
+ receipt: null,
453
+ attempts: PAID_INMAIL_REFRESH_MAX_ATTEMPTS,
454
+ errors,
455
+ };
456
+ }
430
457
  async function executeOneYoloPrimitive(action) {
431
458
  if (!action)
432
459
  return { status: "no_action" };
@@ -529,21 +556,24 @@ export async function executeRefillSendsCommand(input = {}) {
529
556
  const failedPaidInmailRefreshes = [];
530
557
  const refreshReceipts = [];
531
558
  for (const action of refreshActions) {
532
- try {
533
- const receipt = await refreshPaidInmailCredits({
534
- senderId: action.senderId,
535
- });
559
+ const refreshResult = await refreshPaidInmailCreditsWithRetry(action.senderId);
560
+ if (refreshResult.receipt) {
536
561
  refreshedPaidInmailSenderIds.push(action.senderId);
537
562
  refreshReceipts.push({
538
563
  senderId: action.senderId,
539
564
  actionKey: action.actionKey ?? null,
540
- receipt,
565
+ attempts: refreshResult.attempts,
566
+ retryErrors: refreshResult.errors,
567
+ receipt: refreshResult.receipt,
541
568
  });
542
569
  }
543
- catch (error) {
570
+ else {
544
571
  failedPaidInmailRefreshes.push({
545
572
  senderId: action.senderId,
546
- error: error instanceof Error ? error.message : String(error),
573
+ attempts: refreshResult.attempts,
574
+ error: refreshResult.errors[refreshResult.errors.length - 1] ??
575
+ "paid InMail credit refresh failed",
576
+ errors: refreshResult.errors,
547
577
  });
548
578
  }
549
579
  }
@@ -578,7 +608,7 @@ export async function executeRefillSendsCommand(input = {}) {
578
608
  attemptedSenderIds: refreshActions.map((action) => action.senderId),
579
609
  targetPlanReread: refreshActions.length > 0,
580
610
  note: refreshActions.length > 0
581
- ? "refill_sends refreshed stale paid InMail credit facts internally, once per sender, then returned the post-refresh targetPlan."
611
+ ? "refill_sends refreshed stale paid InMail credit facts internally with bounded retries, once per sender, then returned the post-refresh targetPlan."
582
612
  : "No stale or missing paid InMail credit refresh candidates were present in the initial target plan.",
583
613
  },
584
614
  yoloExecution: refreshActions.length > 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.479",
3
+ "version": "0.1.480",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",