@sellable/mcp 0.1.521 → 0.1.522
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 +90 -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);
|
|
@@ -532,20 +561,41 @@ function sanitizeSourcePlan(value) {
|
|
|
532
561
|
function sanitizePaidInmail(value) {
|
|
533
562
|
if (!isRecord(value))
|
|
534
563
|
return null;
|
|
564
|
+
const originalMaxStalenessSeconds = optionalNumberValue(value.maxStalenessSeconds);
|
|
565
|
+
const maxStalenessSeconds = normalizePaidInmailMaxStalenessSeconds(value.maxStalenessSeconds);
|
|
566
|
+
const checkedAt = stringValue(value.checkedAt) ?? null;
|
|
567
|
+
const availableCredits = numberValue(value.availableCredits);
|
|
568
|
+
const threshold = numberValue(value.threshold);
|
|
569
|
+
let status = stringValue(value.status) ?? "missing_credit_facts";
|
|
570
|
+
let reason = stringValue(value.reason) ?? "";
|
|
571
|
+
let freshnessPolicy;
|
|
572
|
+
if (status === "stale_credit_facts" &&
|
|
573
|
+
isFreshWithinMcpPaidInmailWindow(checkedAt, maxStalenessSeconds)) {
|
|
574
|
+
status = availableCredits < threshold ? "below_threshold" : "ok";
|
|
575
|
+
reason =
|
|
576
|
+
status === "below_threshold"
|
|
577
|
+
? "MCP normalized paid InMail freshness to 4h; cached credits are fresh enough but below threshold."
|
|
578
|
+
: "MCP normalized paid InMail freshness to 4h; cached credits are fresh enough.";
|
|
579
|
+
freshnessPolicy = {
|
|
580
|
+
normalizedBy: "mcp",
|
|
581
|
+
minMaxStalenessSeconds: MCP_PAID_INMAIL_CREDITS_MAX_STALENESS_SECONDS,
|
|
582
|
+
originalMaxStalenessSeconds,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
535
585
|
return {
|
|
536
|
-
status
|
|
537
|
-
reason
|
|
538
|
-
checkedAt
|
|
586
|
+
status,
|
|
587
|
+
reason,
|
|
588
|
+
checkedAt,
|
|
539
589
|
balance: typeof value.balance === "number" ? value.balance : null,
|
|
540
590
|
sentSince: numberValue(value.sentSince),
|
|
541
|
-
availableCredits
|
|
542
|
-
threshold
|
|
591
|
+
availableCredits,
|
|
592
|
+
threshold,
|
|
543
593
|
campaignId: stringValue(value.campaignId) ?? null,
|
|
544
594
|
campaignName: stringValue(value.campaignName) ?? null,
|
|
545
595
|
tableId: stringValue(value.tableId) ?? null,
|
|
546
596
|
tableName: stringValue(value.tableName) ?? null,
|
|
547
597
|
columnId: stringValue(value.columnId) ?? null,
|
|
548
|
-
maxStalenessSeconds
|
|
598
|
+
maxStalenessSeconds,
|
|
549
599
|
campaignClassification: campaignClassificationValue(value.campaignClassification) ?? null,
|
|
550
600
|
connectionFallbackAvailable: booleanValue(value.connectionFallbackAvailable) ?? false,
|
|
551
601
|
connectionFallbackCampaignId: stringValue(value.connectionFallbackCampaignId) ?? null,
|
|
@@ -553,8 +603,19 @@ function sanitizePaidInmail(value) {
|
|
|
553
603
|
suggestedThreshold: typeof value.suggestedThreshold === "number"
|
|
554
604
|
? value.suggestedThreshold
|
|
555
605
|
: null,
|
|
606
|
+
...(freshnessPolicy ? { freshnessPolicy } : {}),
|
|
556
607
|
};
|
|
557
608
|
}
|
|
609
|
+
function paidInmailNeedsRefresh(value) {
|
|
610
|
+
if (!isRecord(value))
|
|
611
|
+
return false;
|
|
612
|
+
const status = stringValue(value.status);
|
|
613
|
+
return Boolean(status && PAID_INMAIL_REFRESH_STATUSES.has(status));
|
|
614
|
+
}
|
|
615
|
+
function filterFreshPaidInmailRefreshAction(action, paidInmail) {
|
|
616
|
+
return (action.type !== "refresh_paid_inmail_credits" ||
|
|
617
|
+
paidInmailNeedsRefresh(paidInmail));
|
|
618
|
+
}
|
|
558
619
|
function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
559
620
|
if (!Array.isArray(value))
|
|
560
621
|
return [];
|
|
@@ -566,10 +627,12 @@ function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
|
566
627
|
return Boolean(selectedLane && selectedBySender.get(plan.senderId) === selectedLane);
|
|
567
628
|
})
|
|
568
629
|
.map((plan) => {
|
|
630
|
+
const paidInmail = sanitizePaidInmail(plan.paidInmail);
|
|
569
631
|
const nextActions = Array.isArray(plan.nextActions)
|
|
570
632
|
? plan.nextActions
|
|
571
633
|
.map((action, index) => sanitizeStructuredAction(action, selectedBySender, "next", index + 1))
|
|
572
634
|
.filter((action) => Boolean(action))
|
|
635
|
+
.filter((action) => filterFreshPaidInmailRefreshAction(action, paidInmail))
|
|
573
636
|
: [];
|
|
574
637
|
const manualAlternates = Array.isArray(plan.manualAlternates)
|
|
575
638
|
? plan.manualAlternates
|
|
@@ -614,7 +677,7 @@ function sanitizeStructuredSenderPlans(value, selectedBySender) {
|
|
|
614
677
|
: {},
|
|
615
678
|
coverageDisplay: stringArray(plan.coverageDisplay),
|
|
616
679
|
campaignRanking: sanitizeCampaignRanking(plan.campaignRanking),
|
|
617
|
-
paidInmail
|
|
680
|
+
paidInmail,
|
|
618
681
|
sourcePlan: sanitizeSourcePlan(plan.sourcePlan),
|
|
619
682
|
refillReceipt: sanitizeRefillReceipt(plan.refillReceipt),
|
|
620
683
|
nextActions,
|
|
@@ -640,6 +703,17 @@ function buildSanitizedGlobalActionQueue(senderRefillPlans) {
|
|
|
640
703
|
rank: index + 1,
|
|
641
704
|
}));
|
|
642
705
|
}
|
|
706
|
+
function paidRefreshNeededSenderIds(senderRefillPlans) {
|
|
707
|
+
const senderIds = new Set();
|
|
708
|
+
for (const plan of senderRefillPlans) {
|
|
709
|
+
if (!paidInmailNeedsRefresh(plan.paidInmail))
|
|
710
|
+
continue;
|
|
711
|
+
const senderId = stringValue(plan.senderId);
|
|
712
|
+
if (senderId)
|
|
713
|
+
senderIds.add(senderId);
|
|
714
|
+
}
|
|
715
|
+
return senderIds;
|
|
716
|
+
}
|
|
643
717
|
function emptyUnsupportedResult(result) {
|
|
644
718
|
if (!isRecord(result) || !isRecord(result.target))
|
|
645
719
|
return result;
|
|
@@ -682,7 +756,7 @@ function emptyUnsupportedResult(result) {
|
|
|
682
756
|
mcpSanitizedRefillLanes: true,
|
|
683
757
|
};
|
|
684
758
|
}
|
|
685
|
-
function sanitizeBlockers(blockers, selectedKeys) {
|
|
759
|
+
function sanitizeBlockers(blockers, selectedKeys, paidRefreshNeededSenderIds) {
|
|
686
760
|
if (!Array.isArray(blockers))
|
|
687
761
|
return [];
|
|
688
762
|
return blockers.filter((item) => {
|
|
@@ -694,6 +768,10 @@ function sanitizeBlockers(blockers, selectedKeys) {
|
|
|
694
768
|
return true;
|
|
695
769
|
const detailSenderId = detail.split(":")[0];
|
|
696
770
|
if (code.startsWith("paid_inmail_")) {
|
|
771
|
+
if (code === "paid_inmail_credit_stale" &&
|
|
772
|
+
!paidRefreshNeededSenderIds.has(detailSenderId)) {
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
697
775
|
return selectedKeys.has(`${detailSenderId}:send_inmail_closed`);
|
|
698
776
|
}
|
|
699
777
|
if (detail.includes(":send_dm") || detail.includes(":send_inmail_open")) {
|
|
@@ -782,9 +860,10 @@ function sanitizeRefillTargetPlanResult(result) {
|
|
|
782
860
|
const remainingScheduledGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingScheduledGap), 0);
|
|
783
861
|
const remainingProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingProjectedGap), 0);
|
|
784
862
|
const remainingReadyOrProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingReadyOrProjectedGap), 0);
|
|
785
|
-
const blockers = sanitizeBlockers(result.blockers, selectedKeys);
|
|
786
863
|
const eligibleSenderLedger = sanitizeEligibleSenderLedger(target.eligibleSenderLedger, selectedBySender);
|
|
787
864
|
const senderRefillPlans = sanitizeStructuredSenderPlans(target.senderRefillPlans, selectedBySender);
|
|
865
|
+
const paidRefreshNeededSenderIdSet = paidRefreshNeededSenderIds(senderRefillPlans);
|
|
866
|
+
const blockers = sanitizeBlockers(result.blockers, selectedKeys, paidRefreshNeededSenderIdSet);
|
|
788
867
|
const globalActionQueue = buildSanitizedGlobalActionQueue(senderRefillPlans);
|
|
789
868
|
const hasTerminalNoActionBlocker = globalActionQueue.length === 0 &&
|
|
790
869
|
blockers.some((blocker) => TERMINAL_NO_ACTION_BLOCKER_CODES.has(String(blocker.code)));
|
|
@@ -831,7 +910,7 @@ function sanitizeRefillTargetPlanResult(result) {
|
|
|
831
910
|
readyCounts: sanitizeCounts(result.coverage.readyCounts, selectedKeys),
|
|
832
911
|
}
|
|
833
912
|
: result.coverage,
|
|
834
|
-
actionCandidates: sanitizeActionCandidates(result.actionCandidates, selectedKeys, status, remainingReadyOrProjectedGap, remainingProjectedGap),
|
|
913
|
+
actionCandidates: sanitizeActionCandidates(result.actionCandidates, selectedKeys, paidRefreshNeededSenderIdSet, status, remainingReadyOrProjectedGap, remainingProjectedGap),
|
|
835
914
|
blockers,
|
|
836
915
|
mcpSanitizedRefillLanes: true,
|
|
837
916
|
};
|
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,
|