@sellable/mcp 0.1.521 → 0.1.523
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/tools/refill-executors.d.ts +10 -1
- package/dist/tools/refill-executors.js +2 -1
- package/dist/tools/refill-sends.js +18 -4
- package/dist/tools/refill-target-plan.js +91 -11
- package/dist/tools/registry.d.ts +98 -0
- package/dist/tools/senders.d.ts +67 -0
- package/dist/tools/senders.js +60 -1
- package/package.json +1 -1
|
@@ -5,6 +5,15 @@ export type PaidInmailRefreshAction = {
|
|
|
5
5
|
actionKey?: string | null;
|
|
6
6
|
action?: Record<string, unknown>;
|
|
7
7
|
};
|
|
8
|
+
export type PaidInmailCreditRefreshOptions = {
|
|
9
|
+
actionType?: string | null;
|
|
10
|
+
campaignId?: string | null;
|
|
11
|
+
tableId?: string | null;
|
|
12
|
+
columnId?: string | null;
|
|
13
|
+
threshold?: number | null;
|
|
14
|
+
maxStalenessSeconds?: number | null;
|
|
15
|
+
paidInmailCreditsMaxStalenessSeconds?: number | null;
|
|
16
|
+
};
|
|
8
17
|
export type YoloPrimitiveExecution = {
|
|
9
18
|
enabled: true;
|
|
10
19
|
status: "no_action" | "read_only_reread" | "executed_and_reread" | "refused" | "skipped_after_paid_refresh";
|
|
@@ -161,7 +170,7 @@ export declare function approveGeneratedMessagesBatch(action: Record<string, unk
|
|
|
161
170
|
refusalReason?: undefined;
|
|
162
171
|
}>;
|
|
163
172
|
export declare function continueSignalDiscoverySource(action: Record<string, unknown>, workspaceId?: string): Promise<YoloPrimitiveAttempt>;
|
|
164
|
-
export declare function refreshPaidInmailCreditsWithRetry(senderId: string, workspaceId: string): Promise<{
|
|
173
|
+
export declare function refreshPaidInmailCreditsWithRetry(senderId: string, workspaceId: string, options?: PaidInmailCreditRefreshOptions): Promise<{
|
|
165
174
|
receipt: import("./senders.js").RefreshPaidInmailCreditsResponse;
|
|
166
175
|
attempts: number;
|
|
167
176
|
errors: string[];
|
|
@@ -618,13 +618,14 @@ export async function continueSignalDiscoverySource(action, workspaceId) {
|
|
|
618
618
|
},
|
|
619
619
|
};
|
|
620
620
|
}
|
|
621
|
-
export async function refreshPaidInmailCreditsWithRetry(senderId, workspaceId) {
|
|
621
|
+
export async function refreshPaidInmailCreditsWithRetry(senderId, workspaceId, options = {}) {
|
|
622
622
|
const errors = [];
|
|
623
623
|
for (let attempt = 1; attempt <= PAID_INMAIL_REFRESH_MAX_ATTEMPTS; attempt += 1) {
|
|
624
624
|
try {
|
|
625
625
|
const receipt = await refreshPaidInmailCredits({
|
|
626
626
|
senderId,
|
|
627
627
|
workspaceId,
|
|
628
|
+
...options,
|
|
628
629
|
});
|
|
629
630
|
return { receipt, attempts: attempt, errors };
|
|
630
631
|
}
|
|
@@ -2,6 +2,7 @@ import { actionIds, collectPaidInmailRefreshActions, executeOneYoloPrimitive, fi
|
|
|
2
2
|
import { getRefillTargetPlan } from "./refill-target-plan.js";
|
|
3
3
|
import { createWorkspaceContext, normalizeExplicitWorkspaceId, } from "./workspace-context.js";
|
|
4
4
|
const DEFAULT_SCHEDULER_FORWARD_HOURS = 48;
|
|
5
|
+
const MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS = 4 * 60 * 60;
|
|
5
6
|
function normalizeHorizonSendDays(value) {
|
|
6
7
|
if (value === undefined || value === null)
|
|
7
8
|
return null;
|
|
@@ -329,6 +330,9 @@ function paidRefreshApprovalPacket(params) {
|
|
|
329
330
|
const action = params.action.action ?? {};
|
|
330
331
|
const ids = actionIds(action);
|
|
331
332
|
const threshold = numberValue(action.oldThreshold) ?? numberValue(action.threshold);
|
|
333
|
+
const maxStalenessSeconds = Math.max(numberValue(action.maxStalenessSeconds) ??
|
|
334
|
+
numberValue(action.paidInmailCreditsMaxStalenessSeconds) ??
|
|
335
|
+
MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS, MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS);
|
|
332
336
|
return {
|
|
333
337
|
approvalSource: "explicit_yolo_flag",
|
|
334
338
|
workspaceId: params.workspaceId ?? null,
|
|
@@ -339,12 +343,22 @@ function paidRefreshApprovalPacket(params) {
|
|
|
339
343
|
tableId: stringValue(ids.tableId) ?? stringValue(action.tableId) ?? null,
|
|
340
344
|
columnId: stringValue(ids.columnId) ?? stringValue(action.columnId) ?? null,
|
|
341
345
|
threshold: threshold ?? null,
|
|
342
|
-
maxStalenessSeconds
|
|
343
|
-
numberValue(action.paidInmailCreditsMaxStalenessSeconds) ??
|
|
344
|
-
null,
|
|
346
|
+
maxStalenessSeconds,
|
|
345
347
|
targetPlanFingerprint: targetPlanFingerprint(params.targetPlan),
|
|
346
348
|
};
|
|
347
349
|
}
|
|
350
|
+
function paidRefreshOptionsFromApprovalPacket(packet) {
|
|
351
|
+
return {
|
|
352
|
+
...(packet.actionType ? { actionType: packet.actionType } : {}),
|
|
353
|
+
...(packet.campaignId ? { campaignId: packet.campaignId } : {}),
|
|
354
|
+
...(packet.tableId ? { tableId: packet.tableId } : {}),
|
|
355
|
+
...(packet.columnId ? { columnId: packet.columnId } : {}),
|
|
356
|
+
...(typeof packet.threshold === "number"
|
|
357
|
+
? { threshold: packet.threshold }
|
|
358
|
+
: {}),
|
|
359
|
+
maxStalenessSeconds: packet.maxStalenessSeconds,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
348
362
|
export async function executeRefillSendsCommand(input = {}) {
|
|
349
363
|
const yolo = input.yolo === true;
|
|
350
364
|
const executionMode = input.executionMode ?? (yolo ? "yolo" : "manual");
|
|
@@ -407,7 +421,7 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
407
421
|
});
|
|
408
422
|
continue;
|
|
409
423
|
}
|
|
410
|
-
const refreshResult = await refreshPaidInmailCreditsWithRetry(action.senderId, workspaceId);
|
|
424
|
+
const refreshResult = await refreshPaidInmailCreditsWithRetry(action.senderId, workspaceId, paidRefreshOptionsFromApprovalPacket(approvalPacket));
|
|
411
425
|
if (refreshResult.receipt) {
|
|
412
426
|
refreshedPaidInmailSenderIds.push(action.senderId);
|
|
413
427
|
refreshReceipts.push({
|
|
@@ -36,6 +36,11 @@ const TERMINAL_NO_ACTION_BLOCKER_CODES = new Set([
|
|
|
36
36
|
"paid_inmail_credit_missing",
|
|
37
37
|
"paid_inmail_credit_stale",
|
|
38
38
|
]);
|
|
39
|
+
const MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS = 4 * 60 * 60;
|
|
40
|
+
const PAID_INMAIL_REFRESH_STATUSES = new Set([
|
|
41
|
+
"missing_credit_facts",
|
|
42
|
+
"stale_credit_facts",
|
|
43
|
+
]);
|
|
39
44
|
const SOURCE_PLAN_STATES = new Set([
|
|
40
45
|
"not_needed",
|
|
41
46
|
"use_existing_rows",
|
|
@@ -73,6 +78,9 @@ function actionTypesFrom(value) {
|
|
|
73
78
|
function numberValue(value) {
|
|
74
79
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
75
80
|
}
|
|
81
|
+
function optionalNumberValue(value) {
|
|
82
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
83
|
+
}
|
|
76
84
|
function stringValue(value) {
|
|
77
85
|
return typeof value === "string" ? value : undefined;
|
|
78
86
|
}
|
|
@@ -87,6 +95,20 @@ function numericRecord(value) {
|
|
|
87
95
|
function campaignClassificationValue(value) {
|
|
88
96
|
return value === "sales_nav_cascade" ? "sales_nav_cascade" : undefined;
|
|
89
97
|
}
|
|
98
|
+
function normalizePaidInmailMaxStalenessSeconds(value) {
|
|
99
|
+
const numeric = optionalNumberValue(value);
|
|
100
|
+
return numeric !== null && numeric > 0
|
|
101
|
+
? Math.max(Math.trunc(numeric), MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS)
|
|
102
|
+
: MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS;
|
|
103
|
+
}
|
|
104
|
+
function isFreshWithinMcpPaidInmailWindow(checkedAt, maxStalenessSeconds) {
|
|
105
|
+
if (!checkedAt)
|
|
106
|
+
return false;
|
|
107
|
+
const checkedAtMs = new Date(checkedAt).getTime();
|
|
108
|
+
if (!Number.isFinite(checkedAtMs))
|
|
109
|
+
return false;
|
|
110
|
+
return Date.now() - checkedAtMs <= maxStalenessSeconds * 1000;
|
|
111
|
+
}
|
|
90
112
|
function stringArray(value) {
|
|
91
113
|
if (!Array.isArray(value))
|
|
92
114
|
return [];
|
|
@@ -138,7 +160,7 @@ function sanitizeCounts(counts, selectedKeys) {
|
|
|
138
160
|
return Boolean(key && selectedKeys.has(key));
|
|
139
161
|
});
|
|
140
162
|
}
|
|
141
|
-
function sanitizeActionCandidates(candidates, selectedKeys, status, remainingReadyOrProjectedGap, remainingProjectedGap) {
|
|
163
|
+
function sanitizeActionCandidates(candidates, selectedKeys, paidRefreshNeededSenderIds, status, remainingReadyOrProjectedGap, remainingProjectedGap) {
|
|
142
164
|
const filtered = Array.isArray(candidates)
|
|
143
165
|
? candidates
|
|
144
166
|
.filter((item) => {
|
|
@@ -149,6 +171,13 @@ function sanitizeActionCandidates(candidates, selectedKeys, status, remainingRea
|
|
|
149
171
|
return false;
|
|
150
172
|
}
|
|
151
173
|
const actionType = item.actionType;
|
|
174
|
+
if (item.type === "refresh_paid_inmail_credits") {
|
|
175
|
+
const ids = isRecord(item.ids) ? item.ids : {};
|
|
176
|
+
const senderId = stringValue(item.senderId) ?? stringValue(ids.senderId);
|
|
177
|
+
return Boolean(senderId &&
|
|
178
|
+
paidRefreshNeededSenderIds.has(senderId) &&
|
|
179
|
+
selectedKeys.has(`${senderId}:send_inmail_closed`));
|
|
180
|
+
}
|
|
152
181
|
if (actionType === undefined)
|
|
153
182
|
return item.type === "wait_for_scheduler";
|
|
154
183
|
const allowed = allowedActionType(actionType);
|
|
@@ -375,6 +404,7 @@ function sanitizeToolInput(value) {
|
|
|
375
404
|
: undefined,
|
|
376
405
|
columnRole: stringValue(value.columnRole),
|
|
377
406
|
rowSelector: sanitizeRowSelector(value.rowSelector),
|
|
407
|
+
excludeRowIds: stringArray(value.excludeRowIds),
|
|
378
408
|
oldThreshold: typeof value.oldThreshold === "number" ? value.oldThreshold : undefined,
|
|
379
409
|
suggestedThreshold: typeof value.suggestedThreshold === "number"
|
|
380
410
|
? value.suggestedThreshold
|
|
@@ -532,20 +562,41 @@ function sanitizeSourcePlan(value) {
|
|
|
532
562
|
function sanitizePaidInmail(value) {
|
|
533
563
|
if (!isRecord(value))
|
|
534
564
|
return null;
|
|
565
|
+
const originalMaxStalenessSeconds = optionalNumberValue(value.maxStalenessSeconds);
|
|
566
|
+
const maxStalenessSeconds = normalizePaidInmailMaxStalenessSeconds(value.maxStalenessSeconds);
|
|
567
|
+
const checkedAt = stringValue(value.checkedAt) ?? null;
|
|
568
|
+
const availableCredits = numberValue(value.availableCredits);
|
|
569
|
+
const threshold = numberValue(value.threshold);
|
|
570
|
+
let status = stringValue(value.status) ?? "missing_credit_facts";
|
|
571
|
+
let reason = stringValue(value.reason) ?? "";
|
|
572
|
+
let freshnessPolicy;
|
|
573
|
+
if (status === "stale_credit_facts" &&
|
|
574
|
+
isFreshWithinMcpPaidInmailWindow(checkedAt, maxStalenessSeconds)) {
|
|
575
|
+
status = availableCredits < threshold ? "below_threshold" : "ok";
|
|
576
|
+
reason =
|
|
577
|
+
status === "below_threshold"
|
|
578
|
+
? "MCP normalized paid InMail freshness to 4h; cached credits are fresh enough but below threshold."
|
|
579
|
+
: "MCP normalized paid InMail freshness to 4h; cached credits are fresh enough.";
|
|
580
|
+
freshnessPolicy = {
|
|
581
|
+
normalizedBy: "mcp",
|
|
582
|
+
minMaxStalenessSeconds: MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS,
|
|
583
|
+
originalMaxStalenessSeconds,
|
|
584
|
+
};
|
|
585
|
+
}
|
|
535
586
|
return {
|
|
536
|
-
status
|
|
537
|
-
reason
|
|
538
|
-
checkedAt
|
|
587
|
+
status,
|
|
588
|
+
reason,
|
|
589
|
+
checkedAt,
|
|
539
590
|
balance: typeof value.balance === "number" ? value.balance : null,
|
|
540
591
|
sentSince: numberValue(value.sentSince),
|
|
541
|
-
availableCredits
|
|
542
|
-
threshold
|
|
592
|
+
availableCredits,
|
|
593
|
+
threshold,
|
|
543
594
|
campaignId: stringValue(value.campaignId) ?? null,
|
|
544
595
|
campaignName: stringValue(value.campaignName) ?? null,
|
|
545
596
|
tableId: stringValue(value.tableId) ?? null,
|
|
546
597
|
tableName: stringValue(value.tableName) ?? null,
|
|
547
598
|
columnId: stringValue(value.columnId) ?? null,
|
|
548
|
-
maxStalenessSeconds
|
|
599
|
+
maxStalenessSeconds,
|
|
549
600
|
campaignClassification: campaignClassificationValue(value.campaignClassification) ?? null,
|
|
550
601
|
connectionFallbackAvailable: booleanValue(value.connectionFallbackAvailable) ?? false,
|
|
551
602
|
connectionFallbackCampaignId: stringValue(value.connectionFallbackCampaignId) ?? null,
|
|
@@ -553,8 +604,19 @@ function sanitizePaidInmail(value) {
|
|
|
553
604
|
suggestedThreshold: typeof value.suggestedThreshold === "number"
|
|
554
605
|
? value.suggestedThreshold
|
|
555
606
|
: null,
|
|
607
|
+
...(freshnessPolicy ? { freshnessPolicy } : {}),
|
|
556
608
|
};
|
|
557
609
|
}
|
|
610
|
+
function paidInmailNeedsRefresh(value) {
|
|
611
|
+
if (!isRecord(value))
|
|
612
|
+
return false;
|
|
613
|
+
const status = stringValue(value.status);
|
|
614
|
+
return Boolean(status && PAID_INMAIL_REFRESH_STATUSES.has(status));
|
|
615
|
+
}
|
|
616
|
+
function filterFreshPaidInmailRefreshAction(action, paidInmail) {
|
|
617
|
+
return (action.type !== "refresh_paid_inmail_credits" ||
|
|
618
|
+
paidInmailNeedsRefresh(paidInmail));
|
|
619
|
+
}
|
|
558
620
|
function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
559
621
|
if (!Array.isArray(value))
|
|
560
622
|
return [];
|
|
@@ -566,10 +628,12 @@ function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
|
566
628
|
return Boolean(selectedLane && selectedBySender.get(plan.senderId) === selectedLane);
|
|
567
629
|
})
|
|
568
630
|
.map((plan) => {
|
|
631
|
+
const paidInmail = sanitizePaidInmail(plan.paidInmail);
|
|
569
632
|
const nextActions = Array.isArray(plan.nextActions)
|
|
570
633
|
? plan.nextActions
|
|
571
634
|
.map((action, index) => sanitizeStructuredAction(action, selectedBySender, "next", index + 1))
|
|
572
635
|
.filter((action) => Boolean(action))
|
|
636
|
+
.filter((action) => filterFreshPaidInmailRefreshAction(action, paidInmail))
|
|
573
637
|
: [];
|
|
574
638
|
const manualAlternates = Array.isArray(plan.manualAlternates)
|
|
575
639
|
? plan.manualAlternates
|
|
@@ -614,7 +678,7 @@ function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
|
614
678
|
: {},
|
|
615
679
|
coverageDisplay: stringArray(plan.coverageDisplay),
|
|
616
680
|
campaignRanking: sanitizeCampaignRanking(plan.campaignRanking),
|
|
617
|
-
paidInmail
|
|
681
|
+
paidInmail,
|
|
618
682
|
sourcePlan: sanitizeSourcePlan(plan.sourcePlan),
|
|
619
683
|
refillReceipt: sanitizeRefillReceipt(plan.refillReceipt),
|
|
620
684
|
nextActions,
|
|
@@ -640,6 +704,17 @@ function buildSanitizedGlobalActionQueue(senderRefillPlans) {
|
|
|
640
704
|
rank: index + 1,
|
|
641
705
|
}));
|
|
642
706
|
}
|
|
707
|
+
function paidRefreshNeededSenderIds(senderRefillPlans) {
|
|
708
|
+
const senderIds = new Set();
|
|
709
|
+
for (const plan of senderRefillPlans) {
|
|
710
|
+
if (!paidInmailNeedsRefresh(plan.paidInmail))
|
|
711
|
+
continue;
|
|
712
|
+
const senderId = stringValue(plan.senderId);
|
|
713
|
+
if (senderId)
|
|
714
|
+
senderIds.add(senderId);
|
|
715
|
+
}
|
|
716
|
+
return senderIds;
|
|
717
|
+
}
|
|
643
718
|
function emptyUnsupportedResult(result) {
|
|
644
719
|
if (!isRecord(result) || !isRecord(result.target))
|
|
645
720
|
return result;
|
|
@@ -682,7 +757,7 @@ function emptyUnsupportedResult(result) {
|
|
|
682
757
|
mcpSanitizedRefillLanes: true,
|
|
683
758
|
};
|
|
684
759
|
}
|
|
685
|
-
function sanitizeBlockers(blockers, selectedKeys) {
|
|
760
|
+
function sanitizeBlockers(blockers, selectedKeys, paidRefreshNeededSenderIds) {
|
|
686
761
|
if (!Array.isArray(blockers))
|
|
687
762
|
return [];
|
|
688
763
|
return blockers.filter((item) => {
|
|
@@ -694,6 +769,10 @@ function sanitizeBlockers(blockers, selectedKeys) {
|
|
|
694
769
|
return true;
|
|
695
770
|
const detailSenderId = detail.split(":")[0];
|
|
696
771
|
if (code.startsWith("paid_inmail_")) {
|
|
772
|
+
if (code === "paid_inmail_credit_stale" &&
|
|
773
|
+
!paidRefreshNeededSenderIds.has(detailSenderId)) {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
697
776
|
return selectedKeys.has(`${detailSenderId}:send_inmail_closed`);
|
|
698
777
|
}
|
|
699
778
|
if (detail.includes(":send_dm") || detail.includes(":send_inmail_open")) {
|
|
@@ -782,9 +861,10 @@ function sanitizeRefillTargetPlanResult(result) {
|
|
|
782
861
|
const remainingScheduledGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingScheduledGap), 0);
|
|
783
862
|
const remainingProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingProjectedGap), 0);
|
|
784
863
|
const remainingReadyOrProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingReadyOrProjectedGap), 0);
|
|
785
|
-
const blockers = sanitizeBlockers(result.blockers, selectedKeys);
|
|
786
864
|
const eligibleSenderLedger = sanitizeEligibleSenderLedger(target.eligibleSenderLedger, selectedBySender);
|
|
787
865
|
const senderRefillPlans = sanitizeStructuredSenderPlans(target.senderRefillPlans, selectedBySender);
|
|
866
|
+
const paidRefreshNeededSenderIdSet = paidRefreshNeededSenderIds(senderRefillPlans);
|
|
867
|
+
const blockers = sanitizeBlockers(result.blockers, selectedKeys, paidRefreshNeededSenderIdSet);
|
|
788
868
|
const globalActionQueue = buildSanitizedGlobalActionQueue(senderRefillPlans);
|
|
789
869
|
const hasTerminalNoActionBlocker = globalActionQueue.length === 0 &&
|
|
790
870
|
blockers.some((blocker) => TERMINAL_NO_ACTION_BLOCKER_CODES.has(String(blocker.code)));
|
|
@@ -831,7 +911,7 @@ function sanitizeRefillTargetPlanResult(result) {
|
|
|
831
911
|
readyCounts: sanitizeCounts(result.coverage.readyCounts, selectedKeys),
|
|
832
912
|
}
|
|
833
913
|
: result.coverage,
|
|
834
|
-
actionCandidates: sanitizeActionCandidates(result.actionCandidates, selectedKeys, status, remainingReadyOrProjectedGap, remainingProjectedGap),
|
|
914
|
+
actionCandidates: sanitizeActionCandidates(result.actionCandidates, selectedKeys, paidRefreshNeededSenderIdSet, status, remainingReadyOrProjectedGap, remainingProjectedGap),
|
|
835
915
|
blockers,
|
|
836
916
|
mcpSanitizedRefillLanes: true,
|
|
837
917
|
};
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -584,6 +584,97 @@ export declare const allTools: ({
|
|
|
584
584
|
required: string[];
|
|
585
585
|
additionalProperties: boolean;
|
|
586
586
|
};
|
|
587
|
+
} | {
|
|
588
|
+
name: string;
|
|
589
|
+
description: string;
|
|
590
|
+
inputSchema: {
|
|
591
|
+
type: string;
|
|
592
|
+
properties: {
|
|
593
|
+
campaignId: {
|
|
594
|
+
type: string;
|
|
595
|
+
description: string;
|
|
596
|
+
};
|
|
597
|
+
tableId: {
|
|
598
|
+
type: string;
|
|
599
|
+
};
|
|
600
|
+
targetPreparedMessages: {
|
|
601
|
+
type: string;
|
|
602
|
+
minimum: number;
|
|
603
|
+
maximum: number;
|
|
604
|
+
};
|
|
605
|
+
maxRowsToCheck: {
|
|
606
|
+
type: string;
|
|
607
|
+
minimum: number;
|
|
608
|
+
maximum: number;
|
|
609
|
+
description: string;
|
|
610
|
+
};
|
|
611
|
+
batchSize: {
|
|
612
|
+
type: string;
|
|
613
|
+
minimum: number;
|
|
614
|
+
maximum: number;
|
|
615
|
+
description: string;
|
|
616
|
+
};
|
|
617
|
+
maxBatchRows: {
|
|
618
|
+
type: string;
|
|
619
|
+
minimum: number;
|
|
620
|
+
maximum: number;
|
|
621
|
+
description: string;
|
|
622
|
+
};
|
|
623
|
+
approvalMode: {
|
|
624
|
+
type: string;
|
|
625
|
+
enum: string[];
|
|
626
|
+
description: string;
|
|
627
|
+
};
|
|
628
|
+
rowSelector: {
|
|
629
|
+
type: string;
|
|
630
|
+
description: string;
|
|
631
|
+
properties: {
|
|
632
|
+
type: {
|
|
633
|
+
type: string;
|
|
634
|
+
enum: string[];
|
|
635
|
+
};
|
|
636
|
+
limit: {
|
|
637
|
+
type: string;
|
|
638
|
+
minimum: number;
|
|
639
|
+
maximum: number;
|
|
640
|
+
};
|
|
641
|
+
};
|
|
642
|
+
required: string[];
|
|
643
|
+
additionalProperties: boolean;
|
|
644
|
+
};
|
|
645
|
+
excludeRowIds: {
|
|
646
|
+
type: string;
|
|
647
|
+
items: {
|
|
648
|
+
type: string;
|
|
649
|
+
};
|
|
650
|
+
maxItems: number;
|
|
651
|
+
description: string;
|
|
652
|
+
};
|
|
653
|
+
autoContinue: {
|
|
654
|
+
type: string;
|
|
655
|
+
};
|
|
656
|
+
senderId: {
|
|
657
|
+
type: string;
|
|
658
|
+
description: string;
|
|
659
|
+
};
|
|
660
|
+
actionType: {
|
|
661
|
+
type: string;
|
|
662
|
+
enum: string[];
|
|
663
|
+
description: string;
|
|
664
|
+
};
|
|
665
|
+
disableLowPassRateStop: {
|
|
666
|
+
type: string;
|
|
667
|
+
description: string;
|
|
668
|
+
};
|
|
669
|
+
workspaceId: {
|
|
670
|
+
type: string;
|
|
671
|
+
description: string;
|
|
672
|
+
};
|
|
673
|
+
jobId?: undefined;
|
|
674
|
+
};
|
|
675
|
+
required: string[];
|
|
676
|
+
additionalProperties: boolean;
|
|
677
|
+
};
|
|
587
678
|
} | {
|
|
588
679
|
name: string;
|
|
589
680
|
description: string;
|
|
@@ -2343,6 +2434,13 @@ export declare const allTools: ({
|
|
|
2343
2434
|
type: string;
|
|
2344
2435
|
description: string;
|
|
2345
2436
|
};
|
|
2437
|
+
actionType?: undefined;
|
|
2438
|
+
campaignId?: undefined;
|
|
2439
|
+
tableId?: undefined;
|
|
2440
|
+
columnId?: undefined;
|
|
2441
|
+
threshold?: undefined;
|
|
2442
|
+
maxStalenessSeconds?: undefined;
|
|
2443
|
+
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
2346
2444
|
};
|
|
2347
2445
|
required: string[];
|
|
2348
2446
|
additionalProperties: boolean;
|
package/dist/tools/senders.d.ts
CHANGED
|
@@ -35,6 +35,13 @@ export type SenderDetailResponse = {
|
|
|
35
35
|
export type RefreshPaidInmailCreditsInput = {
|
|
36
36
|
senderId: string;
|
|
37
37
|
workspaceId: string;
|
|
38
|
+
actionType?: string | null;
|
|
39
|
+
campaignId?: string | null;
|
|
40
|
+
tableId?: string | null;
|
|
41
|
+
columnId?: string | null;
|
|
42
|
+
threshold?: number | null;
|
|
43
|
+
maxStalenessSeconds?: number | null;
|
|
44
|
+
paidInmailCreditsMaxStalenessSeconds?: number | null;
|
|
38
45
|
};
|
|
39
46
|
export type PaidInmailCreditStatus = {
|
|
40
47
|
available: number;
|
|
@@ -68,6 +75,13 @@ export declare const senderToolDefinitions: ({
|
|
|
68
75
|
description: string;
|
|
69
76
|
};
|
|
70
77
|
senderId?: undefined;
|
|
78
|
+
actionType?: undefined;
|
|
79
|
+
campaignId?: undefined;
|
|
80
|
+
tableId?: undefined;
|
|
81
|
+
columnId?: undefined;
|
|
82
|
+
threshold?: undefined;
|
|
83
|
+
maxStalenessSeconds?: undefined;
|
|
84
|
+
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
71
85
|
};
|
|
72
86
|
required: never[];
|
|
73
87
|
additionalProperties: boolean;
|
|
@@ -86,6 +100,59 @@ export declare const senderToolDefinitions: ({
|
|
|
86
100
|
type: string;
|
|
87
101
|
description: string;
|
|
88
102
|
};
|
|
103
|
+
actionType?: undefined;
|
|
104
|
+
campaignId?: undefined;
|
|
105
|
+
tableId?: undefined;
|
|
106
|
+
columnId?: undefined;
|
|
107
|
+
threshold?: undefined;
|
|
108
|
+
maxStalenessSeconds?: undefined;
|
|
109
|
+
paidInmailCreditsMaxStalenessSeconds?: undefined;
|
|
110
|
+
};
|
|
111
|
+
required: string[];
|
|
112
|
+
additionalProperties: boolean;
|
|
113
|
+
};
|
|
114
|
+
} | {
|
|
115
|
+
name: string;
|
|
116
|
+
description: string;
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: string;
|
|
119
|
+
properties: {
|
|
120
|
+
senderId: {
|
|
121
|
+
type: string;
|
|
122
|
+
description: string;
|
|
123
|
+
};
|
|
124
|
+
workspaceId: {
|
|
125
|
+
type: string;
|
|
126
|
+
description: string;
|
|
127
|
+
};
|
|
128
|
+
actionType: {
|
|
129
|
+
type: string;
|
|
130
|
+
description: string;
|
|
131
|
+
};
|
|
132
|
+
campaignId: {
|
|
133
|
+
type: string;
|
|
134
|
+
description: string;
|
|
135
|
+
};
|
|
136
|
+
tableId: {
|
|
137
|
+
type: string;
|
|
138
|
+
description: string;
|
|
139
|
+
};
|
|
140
|
+
columnId: {
|
|
141
|
+
type: string;
|
|
142
|
+
description: string;
|
|
143
|
+
};
|
|
144
|
+
threshold: {
|
|
145
|
+
type: string;
|
|
146
|
+
description: string;
|
|
147
|
+
};
|
|
148
|
+
maxStalenessSeconds: {
|
|
149
|
+
type: string;
|
|
150
|
+
description: string;
|
|
151
|
+
};
|
|
152
|
+
paidInmailCreditsMaxStalenessSeconds: {
|
|
153
|
+
type: string;
|
|
154
|
+
description: string;
|
|
155
|
+
};
|
|
89
156
|
};
|
|
90
157
|
required: string[];
|
|
91
158
|
additionalProperties: boolean;
|
package/dist/tools/senders.js
CHANGED
|
@@ -11,6 +11,19 @@ function pickString(...values) {
|
|
|
11
11
|
}
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
|
+
const DEFAULT_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS = 4 * 60 * 60;
|
|
15
|
+
function numberOrNull(value) {
|
|
16
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
17
|
+
}
|
|
18
|
+
function normalizePaidInmailCreditsMaxStalenessSeconds(...values) {
|
|
19
|
+
for (const value of values) {
|
|
20
|
+
const numeric = numberOrNull(value);
|
|
21
|
+
if (numeric === null || numeric <= 0)
|
|
22
|
+
continue;
|
|
23
|
+
return Math.max(Math.trunc(numeric), DEFAULT_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS);
|
|
24
|
+
}
|
|
25
|
+
return DEFAULT_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS;
|
|
26
|
+
}
|
|
14
27
|
function computeDisplayName(sender) {
|
|
15
28
|
const profile = sender?.unipileAccount?.profileData;
|
|
16
29
|
const name = pickString(profile?.name);
|
|
@@ -148,6 +161,34 @@ export const senderToolDefinitions = [
|
|
|
148
161
|
type: "string",
|
|
149
162
|
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
150
163
|
},
|
|
164
|
+
actionType: {
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "Optional action type context for the credit freshness check. Defaults to send_inmail_closed.",
|
|
167
|
+
},
|
|
168
|
+
campaignId: {
|
|
169
|
+
type: "string",
|
|
170
|
+
description: "Optional campaign context for the refresh receipt.",
|
|
171
|
+
},
|
|
172
|
+
tableId: {
|
|
173
|
+
type: "string",
|
|
174
|
+
description: "Optional workflow table context for the refresh receipt.",
|
|
175
|
+
},
|
|
176
|
+
columnId: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: "Optional workflow column context for the refresh receipt.",
|
|
179
|
+
},
|
|
180
|
+
threshold: {
|
|
181
|
+
type: "number",
|
|
182
|
+
description: "Optional paid InMail threshold used by the planner for this sender.",
|
|
183
|
+
},
|
|
184
|
+
maxStalenessSeconds: {
|
|
185
|
+
type: "number",
|
|
186
|
+
description: "Optional cache freshness window in seconds. Values below 4h are clamped to 4h.",
|
|
187
|
+
},
|
|
188
|
+
paidInmailCreditsMaxStalenessSeconds: {
|
|
189
|
+
type: "number",
|
|
190
|
+
description: "Optional legacy alias for maxStalenessSeconds. Values below 4h are clamped to 4h.",
|
|
191
|
+
},
|
|
151
192
|
},
|
|
152
193
|
required: ["senderId", "workspaceId"],
|
|
153
194
|
additionalProperties: false,
|
|
@@ -213,7 +254,25 @@ export async function refreshPaidInmailCredits(input) {
|
|
|
213
254
|
throw new Error("workspaceId is required.");
|
|
214
255
|
}
|
|
215
256
|
const requestOptions = workspaceRequestOptions(workspaceId);
|
|
216
|
-
const
|
|
257
|
+
const threshold = numberOrNull(input.threshold);
|
|
258
|
+
const body = {
|
|
259
|
+
workspaceId,
|
|
260
|
+
maxStalenessSeconds: normalizePaidInmailCreditsMaxStalenessSeconds(input.maxStalenessSeconds, input.paidInmailCreditsMaxStalenessSeconds),
|
|
261
|
+
};
|
|
262
|
+
const actionType = pickString(input.actionType);
|
|
263
|
+
const campaignId = pickString(input.campaignId);
|
|
264
|
+
const tableId = pickString(input.tableId);
|
|
265
|
+
const columnId = pickString(input.columnId);
|
|
266
|
+
if (actionType)
|
|
267
|
+
body.actionType = actionType;
|
|
268
|
+
if (campaignId)
|
|
269
|
+
body.campaignId = campaignId;
|
|
270
|
+
if (tableId)
|
|
271
|
+
body.tableId = tableId;
|
|
272
|
+
if (columnId)
|
|
273
|
+
body.columnId = columnId;
|
|
274
|
+
if (threshold !== null)
|
|
275
|
+
body.threshold = threshold;
|
|
217
276
|
const result = await api.post(`/api/v3/mcp/senders/${encodeURIComponent(senderId)}/refresh-inmail-credits`, body, requestOptions);
|
|
218
277
|
return {
|
|
219
278
|
senderId,
|