@sellable/mcp 0.1.147 → 0.1.149
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/leads.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ export declare function selectSignalPostsForImport<T extends SignalPostForImport
|
|
|
9
9
|
}): {
|
|
10
10
|
posts: T[];
|
|
11
11
|
estimatedEngagers: number;
|
|
12
|
+
availableEngagers: number;
|
|
13
|
+
targetEngagerCount: number | null;
|
|
14
|
+
targetReached: boolean;
|
|
12
15
|
limited: boolean;
|
|
13
16
|
};
|
|
14
17
|
export type GetProviderPromptInput = {
|
package/dist/tools/leads.js
CHANGED
|
@@ -343,13 +343,18 @@ export function selectSignalPostsForImport(posts, options) {
|
|
|
343
343
|
const normalizedTargetEngagers = normalizePositiveInteger(options.targetEngagerCount);
|
|
344
344
|
const normalizedMaxPosts = normalizePositiveInteger(options.maxPostsToScrape);
|
|
345
345
|
if (!normalizedTargetEngagers && !normalizedMaxPosts) {
|
|
346
|
+
const availableEngagers = posts.reduce((sum, post) => sum + post.likes + post.comments, 0);
|
|
346
347
|
return {
|
|
347
348
|
posts,
|
|
348
|
-
estimatedEngagers:
|
|
349
|
+
estimatedEngagers: availableEngagers,
|
|
350
|
+
availableEngagers,
|
|
351
|
+
targetEngagerCount: null,
|
|
352
|
+
targetReached: true,
|
|
349
353
|
limited: false,
|
|
350
354
|
};
|
|
351
355
|
}
|
|
352
356
|
const ranked = [...posts].sort((a, b) => b.likes + b.comments - (a.likes + a.comments));
|
|
357
|
+
const availableEngagers = ranked.reduce((sum, post) => sum + post.likes + post.comments, 0);
|
|
353
358
|
const selected = [];
|
|
354
359
|
let estimatedEngagers = 0;
|
|
355
360
|
for (const post of ranked) {
|
|
@@ -366,6 +371,10 @@ export function selectSignalPostsForImport(posts, options) {
|
|
|
366
371
|
return {
|
|
367
372
|
posts: selected.length > 0 ? selected : ranked,
|
|
368
373
|
estimatedEngagers,
|
|
374
|
+
availableEngagers,
|
|
375
|
+
targetEngagerCount: normalizedTargetEngagers ?? null,
|
|
376
|
+
targetReached: !normalizedTargetEngagers ||
|
|
377
|
+
estimatedEngagers >= normalizedTargetEngagers,
|
|
369
378
|
limited: selected.length > 0 && selected.length < posts.length,
|
|
370
379
|
};
|
|
371
380
|
}
|
|
@@ -2312,12 +2321,19 @@ export async function importLeads(input) {
|
|
|
2312
2321
|
maxPostsToScrape,
|
|
2313
2322
|
});
|
|
2314
2323
|
const postsToScrape = importSelection.posts;
|
|
2324
|
+
if (!importSelection.targetReached && importSelection.targetEngagerCount) {
|
|
2325
|
+
const capClause = importSelection.availableEngagers >= importSelection.targetEngagerCount
|
|
2326
|
+
? ` The selected posts can cover the target, but maxPostsToScrape=${normalizePositiveInteger(maxPostsToScrape)} prevents reaching it. Increase maxPostsToScrape or remove that cap.`
|
|
2327
|
+
: " Select/promote more right-content posts, run another narrow Signal Discovery search, or switch to Sales Nav recent activity if the lane cannot produce enough source candidates.";
|
|
2328
|
+
throw new Error(`Signal Discovery selected posts only cover about ${importSelection.estimatedEngagers.toLocaleString("en-US")} visible engagers, below the approved ${importSelection.targetEngagerCount.toLocaleString("en-US")} source-candidate target. Do not scrape this under-capacity post set.${capClause}`);
|
|
2329
|
+
}
|
|
2315
2330
|
const effectiveHeadlineICPCriteria = headlineICPCriteria && headlineICPCriteria.length > 0
|
|
2316
2331
|
? headlineICPCriteria
|
|
2317
2332
|
: rubricGuidelines;
|
|
2318
2333
|
// Start the scrape job
|
|
2319
2334
|
const result = await api.post(`/api/v3/campaigns/${campaignOfferId}/signal-leads/create`, {
|
|
2320
2335
|
posts: postsToScrape,
|
|
2336
|
+
targetEngagerCount: importSelection.targetEngagerCount ?? undefined,
|
|
2321
2337
|
...(effectiveHeadlineICPCriteria &&
|
|
2322
2338
|
effectiveHeadlineICPCriteria.length > 0
|
|
2323
2339
|
? {
|
|
@@ -2577,6 +2593,19 @@ export async function confirmLeadList(input) {
|
|
|
2577
2593
|
const leadListConfig = leadListMeta.table?.config ?? null;
|
|
2578
2594
|
const leadListRowCount = leadListMeta.rowCount ?? 0;
|
|
2579
2595
|
const importProgress = leadListConfig?.importProgress ?? null;
|
|
2596
|
+
const signalSourceTargetLeadCount = resolvedProvider === "signal-discovery" &&
|
|
2597
|
+
typeof leadListConfig?.targetLeadCount === "number" &&
|
|
2598
|
+
Number.isFinite(leadListConfig.targetLeadCount) &&
|
|
2599
|
+
leadListConfig.targetLeadCount > 0
|
|
2600
|
+
? leadListConfig.targetLeadCount
|
|
2601
|
+
: null;
|
|
2602
|
+
if (resolvedProvider === "signal-discovery" &&
|
|
2603
|
+
signalSourceTargetLeadCount !== null &&
|
|
2604
|
+
leadListConfig?.importStatus === "complete" &&
|
|
2605
|
+
leadListRowCount > 0 &&
|
|
2606
|
+
leadListRowCount < signalSourceTargetLeadCount) {
|
|
2607
|
+
throw new Error(`Signal Discovery source list is under capacity: it completed with ${leadListRowCount.toLocaleString("en-US")} source candidates, below the approved ${signalSourceTargetLeadCount.toLocaleString("en-US")} source-candidate target. Do not import the bounded review batch from this source. Select more posts, rerun Signal Discovery, or move to Sales Nav/Prospeo.`);
|
|
2608
|
+
}
|
|
2580
2609
|
const progressProcessed = typeof importProgress?.processed === "number"
|
|
2581
2610
|
? importProgress.processed
|
|
2582
2611
|
: null;
|
package/dist/tools/readiness.js
CHANGED
|
@@ -101,7 +101,7 @@ export const readinessToolDefinitions = [
|
|
|
101
101
|
},
|
|
102
102
|
targetLeadCount: {
|
|
103
103
|
type: "number",
|
|
104
|
-
description: "Target number of leads requested. Used as a fallback completion check when status is unavailable.",
|
|
104
|
+
description: "Target number of leads requested. Used as a fallback completion check when status is unavailable. For Signal Discovery, pass the approved source-candidate target; if the completed source list lands below it, the tool returns source_under_capacity instead of ready.",
|
|
105
105
|
},
|
|
106
106
|
timeoutMs: {
|
|
107
107
|
type: "number",
|
|
@@ -472,6 +472,23 @@ export async function waitForLeadListReady(input) {
|
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
474
|
if ((!requireRows || rowCount > 0) && importComplete) {
|
|
475
|
+
if (provider === "signal-discovery" &&
|
|
476
|
+
typeof targetLeadCount === "number" &&
|
|
477
|
+
rowCount > 0 &&
|
|
478
|
+
rowCount < targetLeadCount) {
|
|
479
|
+
return {
|
|
480
|
+
ready: false,
|
|
481
|
+
reason: "source_under_capacity",
|
|
482
|
+
leadListId,
|
|
483
|
+
provider: provider ?? null,
|
|
484
|
+
attempts,
|
|
485
|
+
elapsedMs: Date.now() - start,
|
|
486
|
+
rowCount,
|
|
487
|
+
status: lastStatus,
|
|
488
|
+
targetLeadCount,
|
|
489
|
+
error: `Signal Discovery completed with ${rowCount.toLocaleString("en-US")} source candidates, below the approved ${targetLeadCount.toLocaleString("en-US")} source-candidate target. Do not confirm this lead list; select more posts, rerun source discovery, or move to Sales Nav/Prospeo.`,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
475
492
|
return {
|
|
476
493
|
ready: true,
|
|
477
494
|
leadListId,
|
package/package.json
CHANGED
|
@@ -127,9 +127,11 @@ rate with a conservative cleanup factor, cap the source candidates at the
|
|
|
127
127
|
approved provider limit, and select only enough posts to reach that engager
|
|
128
128
|
count. The planning floor is 10% projected fit after cleanup; if Signal
|
|
129
129
|
Discovery falls below that floor, do not import the source list. Route back to
|
|
130
|
-
find-leads and move to Sales Nav recent activity instead.
|
|
131
|
-
`
|
|
132
|
-
|
|
130
|
+
find-leads and move to Sales Nav recent activity instead. After the scrape,
|
|
131
|
+
`wait_for_lead_list_ready` must clear the approved source-candidate target; if
|
|
132
|
+
it reports `source_under_capacity`, do not call `confirm_lead_list`. The
|
|
133
|
+
subsequent `confirm_lead_list` call still uses `targetLeadCount: <importLimit>`
|
|
134
|
+
so only the bounded review batch enters the campaign table.
|
|
133
135
|
|
|
134
136
|
For supplied direct lists, `confirm_lead_list` must receive
|
|
135
137
|
`targetLeadCount: <importLimit>` or explicit `sourceRowIds` so a 100-row source
|
|
@@ -459,6 +459,9 @@ targetLeadCount, targetEngagerCount, maxPostsToScrape })` for the approved
|
|
|
459
459
|
source-capacity plan without asking for another yes/no gate. Then
|
|
460
460
|
`confirm_lead_list` imports only the bounded review batch into the campaign
|
|
461
461
|
table. Do not confuse the source-candidate target with the review-batch size.
|
|
462
|
+
If the completed source scrape comes back below the approved source-candidate
|
|
463
|
+
target, do not call `confirm_lead_list`; select more posts, rerun source
|
|
464
|
+
discovery, or move to Sales Nav.
|
|
462
465
|
|
|
463
466
|
The promotion/select step is required campaign state. Use post IDs from the
|
|
464
467
|
current campaign-scoped search result, not stale IDs copied from a source review
|