@sellable/mcp 0.1.555 → 0.1.557
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/README.md +13 -2
- package/agents/registry.json +2 -2
- package/dist/api.js +3 -6
- package/dist/auth.d.ts +0 -6
- package/dist/auth.js +2 -44
- package/dist/refill-run-client.d.ts +0 -5
- package/dist/refill-run-client.js +0 -15
- package/dist/refill-run-loop.d.ts +1 -12
- package/dist/refill-run-loop.js +13 -158
- package/dist/server.js +23 -0
- package/dist/tools/auth.d.ts +0 -5
- package/dist/tools/auth.js +12 -49
- package/dist/tools/campaign-message-preparation.d.ts +0 -62
- package/dist/tools/campaign-message-preparation.js +0 -41
- package/dist/tools/campaigns.js +2 -2
- package/dist/tools/csv-dnc.js +2 -2
- package/dist/tools/evergreen-refill-plan.d.ts +0 -3
- package/dist/tools/evergreen-refill-plan.js +7 -29
- package/dist/tools/find-leads-runs.d.ts +151 -0
- package/dist/tools/find-leads-runs.js +98 -0
- package/dist/tools/leads.d.ts +317 -32
- package/dist/tools/leads.js +171 -10
- package/dist/tools/model-quality.js +4 -6
- package/dist/tools/prompts.d.ts +3 -3
- package/dist/tools/prompts.js +7 -15
- package/dist/tools/provider-preflight.d.ts +65 -2
- package/dist/tools/provider-preflight.js +97 -10
- package/dist/tools/readiness.d.ts +89 -5
- package/dist/tools/readiness.js +66 -0
- package/dist/tools/refill-executors.d.ts +0 -38
- package/dist/tools/refill-executors.js +3 -222
- package/dist/tools/refill-sends-v2.d.ts +1 -112
- package/dist/tools/refill-sends-v2.js +2 -302
- package/dist/tools/refill-sends.d.ts +32 -678
- package/dist/tools/refill-sends.js +13 -274
- package/dist/tools/refill-target-plan.js +14 -486
- package/dist/tools/registry.d.ts +330 -115
- package/dist/tools/registry.js +7 -1
- package/dist/tools/scheduler-fill-capacity.js +1 -1
- package/dist/tools/scheduler-run.d.ts +0 -71
- package/dist/tools/scheduler-run.js +1 -203
- package/dist/tools/setup-evergreen-campaigns.js +1 -1
- package/dist/tools/workspace-context.d.ts +1 -1
- package/dist/tools/workspace-context.js +3 -8
- package/dist/tools/workspace-export.js +2 -2
- package/dist/tools/workspaces.d.ts +2 -48
- package/dist/tools/workspaces.js +5 -48
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +3 -3
- package/skills/create-campaign-v2/SKILL.md +1 -1
- package/skills/create-evergreen-campaigns/SKILL.md +16 -16
- package/skills/find-leads/SKILL.md +48 -630
- package/skills/find-leads-v2/SKILL.md +70 -0
- package/skills/find-leads-v2/core/flow.v1.json +31 -0
- package/skills/refill-sends/SKILL.md +353 -91
- package/skills/refill-sends-v2/SKILL.md +6 -6
- package/skills/refill-sends-v2-workflow/SKILL.md +5 -5
- package/skills/refill-sends-v2-workflow/core/flow.v1.json +8 -8
- package/skills/refill-sends-workflow/SKILL.md +743 -100
- package/skills/refill-sends-workflow/core/flow.v1.json +1 -185
- package/dist/refill-contract.d.ts +0 -157
- package/dist/refill-contract.js +0 -487
- package/skills/refill-sends-workflow/core/contract.v2.json +0 -543
|
@@ -1,10 +1,84 @@
|
|
|
1
|
+
import { getApi } from "../api.js";
|
|
2
|
+
import { getConfig } from "../auth.js";
|
|
3
|
+
export const FIND_LEADS_WORKFLOW_VERSION = "find-leads-v1";
|
|
4
|
+
function diagnostic(code, message, nextAction) {
|
|
5
|
+
return { ok: false, code, message, nextAction, resumable: true };
|
|
6
|
+
}
|
|
7
|
+
export async function preflightFindLeadsProvider(input) {
|
|
8
|
+
if (input.workflowVersion !== FIND_LEADS_WORKFLOW_VERSION) {
|
|
9
|
+
return diagnostic("find_leads_mcp_runtime_outdated", `Find Leads requires ${FIND_LEADS_WORKFLOW_VERSION}; received ${input.workflowVersion}.`, "update the Sellable MCP/plugin, restart the MCP server, and retry Find Leads.");
|
|
10
|
+
}
|
|
11
|
+
let workspaceId = null;
|
|
12
|
+
try {
|
|
13
|
+
const config = getConfig();
|
|
14
|
+
workspaceId = config.activeWorkspaceId || config.workspaceId || null;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return diagnostic("find_leads_auth_required", "Sellable authentication is required before Find Leads can start.", "Run the Sellable first-run login flow, then retry bootstrap_find_leads.");
|
|
18
|
+
}
|
|
19
|
+
if (!workspaceId) {
|
|
20
|
+
return diagnostic("find_leads_workspace_required", "Find Leads needs an active request-scoped workspace.", "Run list_workspaces, set_active_workspace, and retry.");
|
|
21
|
+
}
|
|
22
|
+
if (input.providerFacts && !input.providerFacts.configured) {
|
|
23
|
+
const code = input.provider === "sales-nav"
|
|
24
|
+
? "find_leads_sales_nav_unavailable"
|
|
25
|
+
: input.provider === "prospeo"
|
|
26
|
+
? "find_leads_prospeo_unavailable"
|
|
27
|
+
: "find_leads_signal_capacity_unavailable";
|
|
28
|
+
const nextAction = input.provider === "sales-nav"
|
|
29
|
+
? "Connect a LinkedIn account with an active Sales Navigator search session, then retry preflight."
|
|
30
|
+
: input.provider === "prospeo"
|
|
31
|
+
? "Configure Prospeo and ensure enough credits are available, then retry preflight."
|
|
32
|
+
: "Wait for Signal Discovery capacity or choose another provider, then retry preflight.";
|
|
33
|
+
return diagnostic(code, input.providerFacts.reason || `${input.provider} is not ready`, nextAction);
|
|
34
|
+
}
|
|
35
|
+
if (!Number.isInteger(input.runVersion) || (input.runVersion ?? -1) < 0) {
|
|
36
|
+
return diagnostic("find_leads_run_version_required", "A current durable run version is required to persist provider preflight.", "Call get_find_leads_run, then retry preflight with the returned version.");
|
|
37
|
+
}
|
|
38
|
+
const receipt = {
|
|
39
|
+
workflowVersion: FIND_LEADS_WORKFLOW_VERSION,
|
|
40
|
+
promptHash: input.promptHash || `builtin:${FIND_LEADS_WORKFLOW_VERSION}:${input.provider}`,
|
|
41
|
+
provider: input.provider,
|
|
42
|
+
checkedAt: new Date().toISOString(),
|
|
43
|
+
};
|
|
44
|
+
const response = await getApi().patch(`/api/v3/find-leads/runs/${encodeURIComponent(input.runId)}`, {
|
|
45
|
+
action: "record_receipt",
|
|
46
|
+
version: input.runVersion,
|
|
47
|
+
kind: "provider_prompt",
|
|
48
|
+
provider: input.provider.replace(/-/g, "_"),
|
|
49
|
+
receipt,
|
|
50
|
+
}, { workspaceId });
|
|
51
|
+
markProviderPromptLoaded({
|
|
52
|
+
provider: input.provider,
|
|
53
|
+
findLeadsRunId: input.runId,
|
|
54
|
+
});
|
|
55
|
+
return { ok: true, provider: input.provider, receipt, run: response };
|
|
56
|
+
}
|
|
57
|
+
export const findLeadsProviderPreflightToolDefinitions = [
|
|
58
|
+
{
|
|
59
|
+
name: "preflight_find_leads_provider",
|
|
60
|
+
description: "Persist the selected provider prompt/version receipt and return actionable setup diagnostics before any provider call.",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
runId: { type: "string" },
|
|
65
|
+
runVersion: { type: "number" },
|
|
66
|
+
provider: { type: "string", enum: ["sales-nav", "prospeo", "signal-discovery"] },
|
|
67
|
+
workflowVersion: { type: "string" },
|
|
68
|
+
promptHash: { type: "string" },
|
|
69
|
+
},
|
|
70
|
+
required: ["runId", "runVersion", "provider", "workflowVersion"],
|
|
71
|
+
additionalProperties: false,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
];
|
|
1
75
|
const providerPromptLoadedState = new Map();
|
|
2
|
-
function scopedKey(provider, campaignOfferId) {
|
|
3
|
-
return `${campaignOfferId
|
|
76
|
+
function scopedKey(provider, campaignOfferId, findLeadsRunId) {
|
|
77
|
+
return `${campaignOfferId ? `campaign:${campaignOfferId}` : findLeadsRunId ? `run:${findLeadsRunId}` : "provider:*"}::${provider}`;
|
|
4
78
|
}
|
|
5
|
-
function resolveLoadedState(provider, campaignOfferId) {
|
|
6
|
-
if (campaignOfferId) {
|
|
7
|
-
return (providerPromptLoadedState.get(scopedKey(provider, campaignOfferId)) ??
|
|
79
|
+
function resolveLoadedState(provider, campaignOfferId, findLeadsRunId) {
|
|
80
|
+
if (campaignOfferId || findLeadsRunId) {
|
|
81
|
+
return (providerPromptLoadedState.get(scopedKey(provider, campaignOfferId, findLeadsRunId)) ??
|
|
8
82
|
null);
|
|
9
83
|
}
|
|
10
84
|
const providerScoped = providerPromptLoadedState.get(scopedKey(provider));
|
|
@@ -14,32 +88,45 @@ export function markProviderPromptLoaded(params) {
|
|
|
14
88
|
const entry = {
|
|
15
89
|
provider: params.provider,
|
|
16
90
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
91
|
+
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
17
92
|
loadedAt: new Date().toISOString(),
|
|
18
93
|
};
|
|
19
|
-
providerPromptLoadedState.set(scopedKey(params.provider, params.campaignOfferId), entry);
|
|
94
|
+
providerPromptLoadedState.set(scopedKey(params.provider, params.campaignOfferId, params.findLeadsRunId), entry);
|
|
20
95
|
return {
|
|
21
96
|
...entry,
|
|
22
|
-
scope: entry.campaignOfferId
|
|
97
|
+
scope: entry.campaignOfferId
|
|
98
|
+
? "campaign"
|
|
99
|
+
: entry.findLeadsRunId
|
|
100
|
+
? "find-leads-run"
|
|
101
|
+
: "provider",
|
|
23
102
|
};
|
|
24
103
|
}
|
|
25
104
|
export function assertProviderPromptLoaded(params) {
|
|
26
|
-
const loadedState = resolveLoadedState(params.provider, params.campaignOfferId);
|
|
105
|
+
const loadedState = resolveLoadedState(params.provider, params.campaignOfferId, params.findLeadsRunId);
|
|
27
106
|
if (loadedState) {
|
|
28
107
|
return {
|
|
29
108
|
ok: true,
|
|
30
109
|
provider: params.provider,
|
|
31
110
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
111
|
+
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
32
112
|
loadedAt: loadedState.loadedAt,
|
|
33
|
-
scope: loadedState.campaignOfferId
|
|
113
|
+
scope: loadedState.campaignOfferId
|
|
114
|
+
? "campaign"
|
|
115
|
+
: loadedState.findLeadsRunId
|
|
116
|
+
? "find-leads-run"
|
|
117
|
+
: "provider",
|
|
34
118
|
};
|
|
35
119
|
}
|
|
36
120
|
const scopeText = params.campaignOfferId
|
|
37
121
|
? `campaign ${params.campaignOfferId}`
|
|
38
|
-
:
|
|
122
|
+
: params.findLeadsRunId
|
|
123
|
+
? `Find Leads run ${params.findLeadsRunId}`
|
|
124
|
+
: "this provider session";
|
|
39
125
|
const blockingMessage = `Provider prompt preflight missing for ${params.provider} (${scopeText}).`;
|
|
40
126
|
const diagnostics = {
|
|
41
127
|
provider: params.provider,
|
|
42
128
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
129
|
+
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
43
130
|
safeToProceed: false,
|
|
44
131
|
blockingErrors: [
|
|
45
132
|
`${blockingMessage} Call get_provider_prompt({ provider: "${params.provider}"${params.campaignOfferId
|
|
@@ -8,6 +8,7 @@ type WaitForCampaignTableReadyInput = {
|
|
|
8
8
|
type WaitForLeadListReadyInput = {
|
|
9
9
|
leadListId?: string;
|
|
10
10
|
campaignOfferId?: string;
|
|
11
|
+
findLeadsRunId?: string;
|
|
11
12
|
workspaceId?: string;
|
|
12
13
|
provider?: "apollo" | "sales-nav" | "prospeo" | "signal-discovery" | "csv-linkedin";
|
|
13
14
|
jobId?: string;
|
|
@@ -52,6 +53,7 @@ export declare const readinessToolDefinitions: ({
|
|
|
52
53
|
};
|
|
53
54
|
leadListId?: undefined;
|
|
54
55
|
campaignOfferId?: undefined;
|
|
56
|
+
findLeadsRunId?: undefined;
|
|
55
57
|
workspaceId?: undefined;
|
|
56
58
|
provider?: undefined;
|
|
57
59
|
jobId?: undefined;
|
|
@@ -75,6 +77,10 @@ export declare const readinessToolDefinitions: ({
|
|
|
75
77
|
type: string;
|
|
76
78
|
description: string;
|
|
77
79
|
};
|
|
80
|
+
findLeadsRunId: {
|
|
81
|
+
type: string;
|
|
82
|
+
description: string;
|
|
83
|
+
};
|
|
78
84
|
workspaceId: {
|
|
79
85
|
type: string;
|
|
80
86
|
description: string;
|
|
@@ -280,16 +286,74 @@ export declare function waitForCampaignTableReady(input: WaitForCampaignTableRea
|
|
|
280
286
|
export declare function waitForLeadListReady(input: WaitForLeadListReadyInput): Promise<{
|
|
281
287
|
ready: boolean;
|
|
282
288
|
reason: string;
|
|
289
|
+
runId: string;
|
|
290
|
+
leadListId: string;
|
|
283
291
|
attempts: number;
|
|
284
292
|
elapsedMs: number;
|
|
285
|
-
leadListId: null;
|
|
286
293
|
provider?: undefined;
|
|
287
|
-
|
|
294
|
+
jobId?: undefined;
|
|
288
295
|
status?: undefined;
|
|
296
|
+
rowCount?: undefined;
|
|
297
|
+
counts?: undefined;
|
|
298
|
+
retryable?: undefined;
|
|
299
|
+
warning?: undefined;
|
|
300
|
+
targetLeadCount?: undefined;
|
|
301
|
+
error?: undefined;
|
|
302
|
+
sourceShortfall?: undefined;
|
|
303
|
+
materializing?: undefined;
|
|
304
|
+
} | {
|
|
305
|
+
ready: boolean;
|
|
306
|
+
reason: string | undefined;
|
|
307
|
+
runId: any;
|
|
308
|
+
leadListId: any;
|
|
309
|
+
provider: string | null;
|
|
310
|
+
jobId: any;
|
|
311
|
+
status: any;
|
|
312
|
+
rowCount: number;
|
|
313
|
+
counts: any;
|
|
314
|
+
retryable: any;
|
|
315
|
+
attempts: number;
|
|
316
|
+
elapsedMs: number;
|
|
317
|
+
warning?: undefined;
|
|
318
|
+
targetLeadCount?: undefined;
|
|
319
|
+
error?: undefined;
|
|
320
|
+
sourceShortfall?: undefined;
|
|
321
|
+
materializing?: undefined;
|
|
322
|
+
} | {
|
|
323
|
+
ready: boolean;
|
|
324
|
+
reason: string;
|
|
325
|
+
runId: string;
|
|
326
|
+
leadListId: any;
|
|
327
|
+
provider: string | null;
|
|
328
|
+
jobId: any;
|
|
329
|
+
status: any;
|
|
330
|
+
rowCount: number;
|
|
331
|
+
retryable: boolean;
|
|
332
|
+
attempts: number;
|
|
333
|
+
elapsedMs: number;
|
|
334
|
+
warning: string | undefined;
|
|
335
|
+
counts?: undefined;
|
|
289
336
|
targetLeadCount?: undefined;
|
|
290
337
|
error?: undefined;
|
|
291
338
|
sourceShortfall?: undefined;
|
|
339
|
+
materializing?: undefined;
|
|
340
|
+
} | {
|
|
341
|
+
ready: boolean;
|
|
342
|
+
reason: string;
|
|
343
|
+
attempts: number;
|
|
344
|
+
elapsedMs: number;
|
|
345
|
+
leadListId: null;
|
|
346
|
+
runId?: undefined;
|
|
347
|
+
provider?: undefined;
|
|
348
|
+
jobId?: undefined;
|
|
349
|
+
status?: undefined;
|
|
350
|
+
rowCount?: undefined;
|
|
351
|
+
counts?: undefined;
|
|
352
|
+
retryable?: undefined;
|
|
292
353
|
warning?: undefined;
|
|
354
|
+
targetLeadCount?: undefined;
|
|
355
|
+
error?: undefined;
|
|
356
|
+
sourceShortfall?: undefined;
|
|
293
357
|
materializing?: undefined;
|
|
294
358
|
} | {
|
|
295
359
|
ready: boolean;
|
|
@@ -301,9 +365,13 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
301
365
|
rowCount: number;
|
|
302
366
|
status: string;
|
|
303
367
|
targetLeadCount: number | undefined;
|
|
368
|
+
runId?: undefined;
|
|
369
|
+
jobId?: undefined;
|
|
370
|
+
counts?: undefined;
|
|
371
|
+
retryable?: undefined;
|
|
372
|
+
warning?: undefined;
|
|
304
373
|
error?: undefined;
|
|
305
374
|
sourceShortfall?: undefined;
|
|
306
|
-
warning?: undefined;
|
|
307
375
|
materializing?: undefined;
|
|
308
376
|
} | {
|
|
309
377
|
ready: boolean;
|
|
@@ -316,8 +384,12 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
316
384
|
status: string | null;
|
|
317
385
|
targetLeadCount: number | undefined;
|
|
318
386
|
error: string;
|
|
319
|
-
|
|
387
|
+
runId?: undefined;
|
|
388
|
+
jobId?: undefined;
|
|
389
|
+
counts?: undefined;
|
|
390
|
+
retryable?: undefined;
|
|
320
391
|
warning?: undefined;
|
|
392
|
+
sourceShortfall?: undefined;
|
|
321
393
|
materializing?: undefined;
|
|
322
394
|
} | {
|
|
323
395
|
ready: boolean;
|
|
@@ -330,8 +402,12 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
330
402
|
status: string;
|
|
331
403
|
targetLeadCount: number | undefined;
|
|
332
404
|
error: string | null;
|
|
333
|
-
|
|
405
|
+
runId?: undefined;
|
|
406
|
+
jobId?: undefined;
|
|
407
|
+
counts?: undefined;
|
|
408
|
+
retryable?: undefined;
|
|
334
409
|
warning?: undefined;
|
|
410
|
+
sourceShortfall?: undefined;
|
|
335
411
|
materializing?: undefined;
|
|
336
412
|
} | {
|
|
337
413
|
ready: boolean;
|
|
@@ -345,6 +421,10 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
345
421
|
sourceShortfall: boolean;
|
|
346
422
|
warning: string | undefined;
|
|
347
423
|
reason?: undefined;
|
|
424
|
+
runId?: undefined;
|
|
425
|
+
jobId?: undefined;
|
|
426
|
+
counts?: undefined;
|
|
427
|
+
retryable?: undefined;
|
|
348
428
|
error?: undefined;
|
|
349
429
|
materializing?: undefined;
|
|
350
430
|
} | {
|
|
@@ -360,6 +440,10 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
360
440
|
materializing: boolean | undefined;
|
|
361
441
|
warning: string | undefined;
|
|
362
442
|
error: string | undefined;
|
|
443
|
+
runId?: undefined;
|
|
444
|
+
jobId?: undefined;
|
|
445
|
+
counts?: undefined;
|
|
446
|
+
retryable?: undefined;
|
|
363
447
|
sourceShortfall?: undefined;
|
|
364
448
|
}>;
|
|
365
449
|
export {};
|
package/dist/tools/readiness.js
CHANGED
|
@@ -109,6 +109,10 @@ export const readinessToolDefinitions = [
|
|
|
109
109
|
type: "string",
|
|
110
110
|
description: "Campaign offer ID (used to resolve selectedLeadListId if leadListId is missing).",
|
|
111
111
|
},
|
|
112
|
+
findLeadsRunId: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "Durable campaignless run/list ID. When present, poll the authoritative run snapshot instead of campaign/table config.",
|
|
115
|
+
},
|
|
112
116
|
workspaceId: {
|
|
113
117
|
type: "string",
|
|
114
118
|
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation.",
|
|
@@ -204,6 +208,68 @@ export async function waitForLeadListReady(input) {
|
|
|
204
208
|
const intervalMs = Math.max(500, input.intervalMs ?? DEFAULT_INTERVAL_MS);
|
|
205
209
|
const requireRows = input.requireRows !== false;
|
|
206
210
|
const requireComplete = input.requireComplete !== false;
|
|
211
|
+
if (input.findLeadsRunId) {
|
|
212
|
+
if (input.campaignOfferId || (input.leadListId && input.leadListId !== input.findLeadsRunId)) {
|
|
213
|
+
return {
|
|
214
|
+
ready: false,
|
|
215
|
+
reason: "find_leads_target_mismatch",
|
|
216
|
+
runId: input.findLeadsRunId,
|
|
217
|
+
leadListId: input.leadListId ?? input.findLeadsRunId,
|
|
218
|
+
attempts: 0,
|
|
219
|
+
elapsedMs: 0,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const startedAt = Date.now();
|
|
223
|
+
let attempts = 0;
|
|
224
|
+
let snapshot = null;
|
|
225
|
+
while (Date.now() - startedAt <= effectiveTimeoutMs) {
|
|
226
|
+
attempts += 1;
|
|
227
|
+
snapshot = await apiGet(`/api/v3/find-leads/runs/${encodeURIComponent(input.findLeadsRunId)}`);
|
|
228
|
+
const status = String(snapshot.status ?? "").toLowerCase();
|
|
229
|
+
const terminal = snapshot.terminal === true ||
|
|
230
|
+
["ready", "completed", "empty", "failed", "cancelled"].includes(status);
|
|
231
|
+
if (terminal) {
|
|
232
|
+
const rowCount = Number(snapshot.counts?.rows ?? snapshot.rowCount ?? snapshot.counts?.materialized ?? 0);
|
|
233
|
+
const failed = status === "failed";
|
|
234
|
+
const cancelled = status === "cancelled" || snapshot.cancelled === true;
|
|
235
|
+
return {
|
|
236
|
+
ready: !failed && !cancelled,
|
|
237
|
+
reason: failed ? "import_failed" : cancelled ? "cancelled" : undefined,
|
|
238
|
+
runId: snapshot.runId ?? input.findLeadsRunId,
|
|
239
|
+
leadListId: snapshot.leadListId ?? input.findLeadsRunId,
|
|
240
|
+
provider: String(snapshot.provider ?? "").replaceAll("_", "-") || null,
|
|
241
|
+
jobId: snapshot.importJobId ?? null,
|
|
242
|
+
status: snapshot.status,
|
|
243
|
+
rowCount,
|
|
244
|
+
counts: snapshot.counts ?? { rows: rowCount },
|
|
245
|
+
retryable: snapshot.retryable ?? false,
|
|
246
|
+
attempts,
|
|
247
|
+
elapsedMs: Date.now() - startedAt,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (Date.now() - startedAt >= effectiveTimeoutMs)
|
|
251
|
+
break;
|
|
252
|
+
await sleep(intervalMs);
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
ready: false,
|
|
256
|
+
reason: guardApplied ? "tool_timeout_guard" : "timeout",
|
|
257
|
+
runId: input.findLeadsRunId,
|
|
258
|
+
leadListId: snapshot?.leadListId ?? input.findLeadsRunId,
|
|
259
|
+
provider: snapshot?.provider
|
|
260
|
+
? String(snapshot.provider).replaceAll("_", "-")
|
|
261
|
+
: null,
|
|
262
|
+
jobId: snapshot?.importJobId ?? null,
|
|
263
|
+
status: snapshot?.status,
|
|
264
|
+
rowCount: Number(snapshot?.counts?.rows ?? snapshot?.rowCount ?? 0),
|
|
265
|
+
retryable: true,
|
|
266
|
+
attempts,
|
|
267
|
+
elapsedMs: Date.now() - startedAt,
|
|
268
|
+
warning: guardApplied
|
|
269
|
+
? `Stopped after ${effectiveTimeoutMs}ms to avoid host tool timeout (requested ${requestedTimeoutMs}ms). Re-run wait_for_lead_list_ready with the same findLeadsRunId.`
|
|
270
|
+
: undefined,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
207
273
|
let leadListId = input.leadListId;
|
|
208
274
|
let provider = input.provider;
|
|
209
275
|
let targetLeadCount = input.targetLeadCount;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { searchSignals } from "./leads.js";
|
|
2
|
-
import { type SchedulerExpectedTargetInput } from "./scheduler-run.js";
|
|
3
2
|
export type RefillSendsApprovalMode = "approve" | "mark_ready";
|
|
4
3
|
export type PaidInmailRefreshAction = {
|
|
5
4
|
senderId: string;
|
|
@@ -135,43 +134,6 @@ export declare function sleep(ms: number): Promise<unknown>;
|
|
|
135
134
|
export declare function recordValue(value: unknown): Record<string, unknown> | null;
|
|
136
135
|
export declare function stringValue(value: unknown): string | null;
|
|
137
136
|
export declare function numberValue(value: unknown): number | null;
|
|
138
|
-
export type SchedulerChangedCount = {
|
|
139
|
-
campaignId: string;
|
|
140
|
-
tableId: string;
|
|
141
|
-
actionType: string;
|
|
142
|
-
count: number;
|
|
143
|
-
};
|
|
144
|
-
export type SchedulerChangedCounts = {
|
|
145
|
-
complete: true;
|
|
146
|
-
truncated: false;
|
|
147
|
-
total: number;
|
|
148
|
-
byCampaignTableActionType: SchedulerChangedCount[];
|
|
149
|
-
byCampaignTableActionTypeSender: Array<SchedulerChangedCount & {
|
|
150
|
-
senderId: string;
|
|
151
|
-
}>;
|
|
152
|
-
};
|
|
153
|
-
export declare function normalizeSchedulerChangedCounts(value: unknown): SchedulerChangedCounts | null;
|
|
154
|
-
export declare function normalizeSchedulerPrimitiveResult(value: unknown, expected?: {
|
|
155
|
-
expectedTargets: SchedulerExpectedTargetInput[];
|
|
156
|
-
expectedTargetsHash: string;
|
|
157
|
-
maxPlacements: number;
|
|
158
|
-
}): {
|
|
159
|
-
status: "scheduler_receipt_incomplete";
|
|
160
|
-
schedulerStatus: string;
|
|
161
|
-
receipt: {} | null;
|
|
162
|
-
retryAfterMs: number | null;
|
|
163
|
-
changedCounts: null;
|
|
164
|
-
auditComplete: false;
|
|
165
|
-
blocker: "scheduler_receipt_incomplete";
|
|
166
|
-
} | {
|
|
167
|
-
status: string;
|
|
168
|
-
receipt: {} | null;
|
|
169
|
-
retryAfterMs: number | null;
|
|
170
|
-
changedCounts: SchedulerChangedCounts;
|
|
171
|
-
auditComplete: true;
|
|
172
|
-
schedulerStatus?: undefined;
|
|
173
|
-
blocker?: undefined;
|
|
174
|
-
};
|
|
175
137
|
export declare function stringArray(value: unknown): string[];
|
|
176
138
|
export declare function prepareRowSelectorValue(value: unknown): PrepareRowSelector | undefined;
|
|
177
139
|
export declare function uniqueStrings(values: Array<string | null | undefined>): string[];
|