@sellable/mcp 0.1.497 → 0.1.498
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-sends.js +90 -12
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { refreshPaidInmailCredits } from "./senders.js";
|
|
1
|
+
import { getApi, SellableApiError } from "../api.js";
|
|
3
2
|
import { startPrepareCampaignMessages } from "./campaign-message-preparation.js";
|
|
4
3
|
import { confirmLeadList, importLeads, searchSignals, selectPromisingPosts, } from "./leads.js";
|
|
5
4
|
import { markProviderPromptLoaded } from "./provider-preflight.js";
|
|
6
|
-
import {
|
|
5
|
+
import { getRefillTargetPlan } from "./refill-target-plan.js";
|
|
6
|
+
import { refreshPaidInmailCredits } from "./senders.js";
|
|
7
7
|
const DEFAULT_SCHEDULER_FORWARD_HOURS = 48;
|
|
8
8
|
const PAID_INMAIL_REFRESH_MAX_ATTEMPTS = 3;
|
|
9
9
|
const PAID_INMAIL_REFRESH_RETRY_DELAY_MS = Number(process.env.SELLABLE_MCP_PAID_REFRESH_RETRY_DELAY_MS ?? "1000");
|
|
@@ -66,6 +66,20 @@ function normalizeTargetDate(value) {
|
|
|
66
66
|
}
|
|
67
67
|
return trimmed;
|
|
68
68
|
}
|
|
69
|
+
function userAddedRowsLimitPayloadFromError(error) {
|
|
70
|
+
if (!(error instanceof SellableApiError) || error.status !== 400) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(error.body);
|
|
75
|
+
if (parsed?.code !== "USER_ADDED_ROWS_LIMIT_EXCEEDED")
|
|
76
|
+
return null;
|
|
77
|
+
return parsed;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
69
83
|
export const refillSendsToolDefinitions = [
|
|
70
84
|
{
|
|
71
85
|
name: "refill_sends",
|
|
@@ -194,9 +208,7 @@ export function refillSendsCommand(input = {}) {
|
|
|
194
208
|
firstOperationalSteps: [
|
|
195
209
|
'Load get_subskill_prompt({ subskillName: "refill-sends-workflow" }) before any product operation.',
|
|
196
210
|
"A skill cannot create or invoke /goal by itself. If this refill is already running inside an active Codex goal, keep that goal open until every selected sender lane is horizon-filled by projected coverage (sent + scheduled), Christian explicitly stops/statuses the run, or a concrete non-scheduler blocker appears.",
|
|
197
|
-
`Call get_refill_target_plan({ intent: "${intent}"${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""}${senderIds.length > 0
|
|
198
|
-
? `, senderIds: ${JSON.stringify(senderIds)}`
|
|
199
|
-
: ""}${senderNames.length > 0
|
|
211
|
+
`Call get_refill_target_plan({ intent: "${intent}"${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""}${senderIds.length > 0 ? `, senderIds: ${JSON.stringify(senderIds)}` : ""}${senderNames.length > 0
|
|
200
212
|
? `, senderNames: ${JSON.stringify(senderNames)}`
|
|
201
213
|
: ""}${senders.length > 0 ? `, senders: ${JSON.stringify(senders)}` : ""}${targetDate
|
|
202
214
|
? `, targetDate: "${targetDate}"`
|
|
@@ -707,7 +719,9 @@ async function executeOneYoloPrimitive(action) {
|
|
|
707
719
|
const toolInput = actionToolInput(action);
|
|
708
720
|
const targetPreparedMessages = numberValue(toolInput.targetPreparedMessages);
|
|
709
721
|
const approvalMode = toolInput.approvalMode === "approve" ? "approve" : "mark_ready";
|
|
710
|
-
if (!campaignId ||
|
|
722
|
+
if (!campaignId ||
|
|
723
|
+
!targetPreparedMessages ||
|
|
724
|
+
targetPreparedMessages <= 0) {
|
|
711
725
|
return {
|
|
712
726
|
status: "refused",
|
|
713
727
|
refusalReason: "prepare_messages action is missing campaignId or bounded targetPreparedMessages",
|
|
@@ -747,21 +761,85 @@ async function executeOneYoloPrimitive(action) {
|
|
|
747
761
|
refusalReason: "copy_selected_source_rows action is missing campaignOfferId, sourceLeadListId, or sourceFingerprint",
|
|
748
762
|
};
|
|
749
763
|
}
|
|
750
|
-
if (sourceRowIds.length === 0 &&
|
|
764
|
+
if (sourceRowIds.length === 0 &&
|
|
765
|
+
(!sourceRowLimit || sourceRowLimit <= 0)) {
|
|
751
766
|
return {
|
|
752
767
|
status: "refused",
|
|
753
768
|
refusalReason: "copy_selected_source_rows action is missing exact sourceRowIds or a bounded sourceRowLimit",
|
|
754
769
|
};
|
|
755
770
|
}
|
|
756
|
-
const
|
|
771
|
+
const copyInput = {
|
|
757
772
|
campaignOfferId,
|
|
758
773
|
sourceLeadListId,
|
|
759
774
|
currentStep: null,
|
|
760
775
|
confirmed: true,
|
|
761
776
|
sourceRowIds: sourceRowIds.length > 0 ? sourceRowIds : undefined,
|
|
762
|
-
sourceRowLimit: sourceRowIds.length > 0 ? undefined : sourceRowLimit ?? undefined,
|
|
763
|
-
reviewBatchLimit: sourceRowIds.length > 0
|
|
764
|
-
|
|
777
|
+
sourceRowLimit: sourceRowIds.length > 0 ? undefined : (sourceRowLimit ?? undefined),
|
|
778
|
+
reviewBatchLimit: sourceRowIds.length > 0
|
|
779
|
+
? sourceRowIds.length
|
|
780
|
+
: (sourceRowLimit ?? undefined),
|
|
781
|
+
};
|
|
782
|
+
let result;
|
|
783
|
+
try {
|
|
784
|
+
result = await confirmLeadList(copyInput);
|
|
785
|
+
}
|
|
786
|
+
catch (error) {
|
|
787
|
+
const rowLimitPayload = userAddedRowsLimitPayloadFromError(error);
|
|
788
|
+
if (!rowLimitPayload)
|
|
789
|
+
throw error;
|
|
790
|
+
const remainingRows = typeof rowLimitPayload.remainingRows === "number" &&
|
|
791
|
+
Number.isFinite(rowLimitPayload.remainingRows)
|
|
792
|
+
? Math.floor(rowLimitPayload.remainingRows)
|
|
793
|
+
: 0;
|
|
794
|
+
if (remainingRows <= 0) {
|
|
795
|
+
return {
|
|
796
|
+
status: "refused",
|
|
797
|
+
refusalReason: rowLimitPayload.error ??
|
|
798
|
+
"selected campaign table is at the workflow row limit",
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
const retrySourceRowIds = sourceRowIds.length > 0 ? sourceRowIds.slice(0, remainingRows) : [];
|
|
802
|
+
const retrySourceRowLimit = retrySourceRowIds.length > 0
|
|
803
|
+
? undefined
|
|
804
|
+
: Math.min(sourceRowLimit ?? remainingRows, remainingRows);
|
|
805
|
+
const retryReviewBatchLimit = retrySourceRowIds.length > 0
|
|
806
|
+
? retrySourceRowIds.length
|
|
807
|
+
: retrySourceRowLimit;
|
|
808
|
+
if (!retryReviewBatchLimit || retryReviewBatchLimit <= 0) {
|
|
809
|
+
return {
|
|
810
|
+
status: "refused",
|
|
811
|
+
refusalReason: rowLimitPayload.error ??
|
|
812
|
+
"selected campaign table cannot accept more workflow rows",
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
const retryResult = await confirmLeadList({
|
|
816
|
+
...copyInput,
|
|
817
|
+
sourceRowIds: retrySourceRowIds.length > 0 ? retrySourceRowIds : undefined,
|
|
818
|
+
sourceRowLimit: retrySourceRowIds.length > 0 ? undefined : retrySourceRowLimit,
|
|
819
|
+
reviewBatchLimit: retryReviewBatchLimit,
|
|
820
|
+
});
|
|
821
|
+
result =
|
|
822
|
+
retryResult && typeof retryResult === "object"
|
|
823
|
+
? {
|
|
824
|
+
...retryResult,
|
|
825
|
+
rowLimitRetry: {
|
|
826
|
+
code: rowLimitPayload.code,
|
|
827
|
+
maxRows: rowLimitPayload.maxRows,
|
|
828
|
+
currentRows: rowLimitPayload.currentRows,
|
|
829
|
+
requestedRows: rowLimitPayload.requestedRows,
|
|
830
|
+
remainingRows,
|
|
831
|
+
retriedRows: retryReviewBatchLimit,
|
|
832
|
+
},
|
|
833
|
+
}
|
|
834
|
+
: {
|
|
835
|
+
result: retryResult,
|
|
836
|
+
rowLimitRetry: {
|
|
837
|
+
code: rowLimitPayload.code,
|
|
838
|
+
remainingRows,
|
|
839
|
+
retriedRows: retryReviewBatchLimit,
|
|
840
|
+
},
|
|
841
|
+
};
|
|
842
|
+
}
|
|
765
843
|
return { status: "executed_and_reread", result };
|
|
766
844
|
}
|
|
767
845
|
case "continue_signal_discovery_source":
|