@sellable/mcp 0.1.634 → 0.1.635
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/refill-run-loop.js +38 -6
- package/dist/tools/refill-sends.js +26 -4
- package/package.json +1 -1
package/dist/refill-run-loop.js
CHANGED
|
@@ -480,7 +480,16 @@ function doneReasonFromPlan(plan) {
|
|
|
480
480
|
const action = firstAction(plan);
|
|
481
481
|
return (stringValue(action?.doneReason) ??
|
|
482
482
|
stringValue(recordValue(plan.packet)?.doneReason) ??
|
|
483
|
-
stringValue(plan.doneReason)
|
|
483
|
+
stringValue(plan.doneReason) ??
|
|
484
|
+
(canonicalReportingCoverageComplete(plan) ? "complete" : null));
|
|
485
|
+
}
|
|
486
|
+
function canonicalReportingCoverageComplete(value) {
|
|
487
|
+
const reporting = reportingFrom(value);
|
|
488
|
+
const terminal = recordValue(reporting?.terminal);
|
|
489
|
+
return (reporting?.schemaVersion === "refill_reporting.v2" &&
|
|
490
|
+
terminal?.status === "complete" &&
|
|
491
|
+
terminal.complete === true &&
|
|
492
|
+
terminal.reason === "coverage_complete");
|
|
484
493
|
}
|
|
485
494
|
function selectedLaneAuthority(plan, action) {
|
|
486
495
|
const senderId = actionSenderId(action);
|
|
@@ -538,8 +547,7 @@ function isSelectedSenderOwnedPostEngagersLane(plan, action) {
|
|
|
538
547
|
const selections = arrayValue(evergreen.senderLaneSelections).filter(isRecord);
|
|
539
548
|
const selection = selections.find((entry) => stringValue(entry.senderId) === senderId);
|
|
540
549
|
const selectedLane = recordValue(selection?.selectedLane);
|
|
541
|
-
if (!selectedLane ||
|
|
542
|
-
stringValue(selectedLane.campaignId) !== campaignId) {
|
|
550
|
+
if (!selectedLane || stringValue(selectedLane.campaignId) !== campaignId) {
|
|
543
551
|
return false;
|
|
544
552
|
}
|
|
545
553
|
const laneKey = stringValue(selectedLane.laneKey);
|
|
@@ -1988,6 +1996,13 @@ async function gatePlan(input, deps, ctx) {
|
|
|
1988
1996
|
report: plan,
|
|
1989
1997
|
};
|
|
1990
1998
|
}
|
|
1999
|
+
// Canonical reporting completion wins over a stale queue head. Check it
|
|
2000
|
+
// before packet coherence so `terminal_with_action_queue` cannot turn a
|
|
2001
|
+
// completed fenced run into a permanent blocker/continuation loop.
|
|
2002
|
+
if (canonicalReportingCoverageComplete(plan)) {
|
|
2003
|
+
ctx.plan = plan;
|
|
2004
|
+
return completeTerminal(input, deps, ctx, "complete", { plan });
|
|
2005
|
+
}
|
|
1991
2006
|
const coherenceFailure = packetCoherenceFailure(plan);
|
|
1992
2007
|
if (coherenceFailure) {
|
|
1993
2008
|
await safeJournalAppend(ctx, deps, deps.journal.renderPlanSection({
|
|
@@ -3518,8 +3533,7 @@ async function gateVerify(input, deps, ctx, budgets) {
|
|
|
3518
3533
|
// outer workspace coordinator can skip this target and preflight the next
|
|
3519
3534
|
// ranked campaign behind a new fence. Trying to replan across campaigns
|
|
3520
3535
|
// inside this fence would correctly fail target_config_mismatch.
|
|
3521
|
-
if (exhaustionReason === "sender_owned_post_required" &&
|
|
3522
|
-
ctx.targetConfig) {
|
|
3536
|
+
if (exhaustionReason === "sender_owned_post_required" && ctx.targetConfig) {
|
|
3523
3537
|
ctx.runState = nextRunState;
|
|
3524
3538
|
return completeTerminal(input, deps, ctx, "lanes_exhausted", {
|
|
3525
3539
|
laneExhaustion: {
|
|
@@ -3758,7 +3772,25 @@ async function finalizeVerifyOrHeartbeat(input, deps, ctx, budgets) {
|
|
|
3758
3772
|
if (verified)
|
|
3759
3773
|
return verified;
|
|
3760
3774
|
// gateVerify advanced the gate off g3_verify (typically to g1_plan); fall
|
|
3761
|
-
// through and heartbeat at the clean, resumable re-entry point.
|
|
3775
|
+
// through and heartbeat at the clean, resumable re-entry point. Before
|
|
3776
|
+
// yielding, perform one read-only completion check: the verified primitive
|
|
3777
|
+
// may have filled the final slots, and emitting an active continuation in
|
|
3778
|
+
// that state was the Nick Bird coverage_complete loop.
|
|
3779
|
+
if (ctx.gate === "g1_plan") {
|
|
3780
|
+
try {
|
|
3781
|
+
const fresh = await deps.readPlan(refillPlanReadInput(input, { ctx, journal: false }));
|
|
3782
|
+
ctx.plan = fresh;
|
|
3783
|
+
if (canonicalReportingCoverageComplete(fresh)) {
|
|
3784
|
+
return completeTerminal(input, deps, ctx, "complete", {
|
|
3785
|
+
plan: fresh,
|
|
3786
|
+
});
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3789
|
+
catch {
|
|
3790
|
+
// The ordinary heartbeat remains the safe fallback when the optional
|
|
3791
|
+
// terminal reread is temporarily unavailable.
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3762
3794
|
}
|
|
3763
3795
|
return heartbeatAndContinue(input, deps, ctx);
|
|
3764
3796
|
}
|
|
@@ -599,8 +599,17 @@ function evergreenExactTargetCandidates(workspacePlan, options) {
|
|
|
599
599
|
}
|
|
600
600
|
async function selectWorkspaceExactTarget(input, workspacePlanOverride, options = {}) {
|
|
601
601
|
const workspaceInput = workspaceCoordinatorInput(input);
|
|
602
|
-
|
|
602
|
+
let workspacePlan = workspacePlanOverride ??
|
|
603
603
|
(await getRefillTargetPlan(targetPlanInputFor(workspaceInput)));
|
|
604
|
+
// A workspace-wide inference read can briefly observe every enrolled sender
|
|
605
|
+
// as disconnected while the authoritative account status is converging. Do
|
|
606
|
+
// one fresh, read-only planner pass before turning that transient snapshot
|
|
607
|
+
// into a terminal blocker. A stable disconnection still blocks on the second
|
|
608
|
+
// receipt and no mutation is attempted.
|
|
609
|
+
if (workspaceConnectivityEmptyState(workspacePlan) &&
|
|
610
|
+
workspacePlanOverride === undefined) {
|
|
611
|
+
workspacePlan = await getRefillTargetPlan(targetPlanInputFor(workspaceInput));
|
|
612
|
+
}
|
|
604
613
|
if (yoloPlanIsComplete(workspacePlan)) {
|
|
605
614
|
return { status: "complete", workspacePlan };
|
|
606
615
|
}
|
|
@@ -628,8 +637,7 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
|
|
|
628
637
|
preferredSenderId: options.preferredSenderId,
|
|
629
638
|
actionTypes: input.actionTypes,
|
|
630
639
|
}),
|
|
631
|
-
]
|
|
632
|
-
.find((candidate) => Boolean(candidate) &&
|
|
640
|
+
].find((candidate) => Boolean(candidate) &&
|
|
633
641
|
!excludedTargets.some((excluded) => excluded.campaignId === candidate?.campaignId &&
|
|
634
642
|
excluded.tableId === candidate?.tableId));
|
|
635
643
|
if (!selectedTarget) {
|
|
@@ -714,7 +722,21 @@ function yoloCoverage(plan) {
|
|
|
714
722
|
}
|
|
715
723
|
function yoloPlanIsComplete(plan) {
|
|
716
724
|
const coverage = yoloCoverage(plan);
|
|
717
|
-
return coverage.status === "complete" ||
|
|
725
|
+
return (coverage.status === "complete" ||
|
|
726
|
+
(coverage.status !== "blocked" &&
|
|
727
|
+
typeof coverage.grossTarget === "number" &&
|
|
728
|
+
coverage.grossTarget > 0 &&
|
|
729
|
+
coverage.remainingProjectedGap === 0));
|
|
730
|
+
}
|
|
731
|
+
function workspaceConnectivityEmptyState(plan) {
|
|
732
|
+
const target = yoloTarget(plan);
|
|
733
|
+
const emptyState = recordValue(target?.emptyState);
|
|
734
|
+
const blockerCodes = Array.isArray(emptyState?.blockerCodes)
|
|
735
|
+
? normalizeStrings(emptyState.blockerCodes)
|
|
736
|
+
: [];
|
|
737
|
+
return (stringValue(recordValue(plan)?.status) === "blocked" &&
|
|
738
|
+
emptyState?.code === "no_connected_eligible_senders" &&
|
|
739
|
+
blockerCodes.includes("sender_disconnected"));
|
|
718
740
|
}
|
|
719
741
|
function yoloActionIdentity(action) {
|
|
720
742
|
if (!action)
|