@sellable/mcp 0.1.557 → 0.1.558
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 +2 -13
- package/agents/registry.json +2 -2
- package/dist/api.js +6 -3
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +44 -2
- package/dist/refill-contract.d.ts +157 -0
- package/dist/refill-contract.js +487 -0
- package/dist/refill-run-client.d.ts +10 -0
- package/dist/refill-run-client.js +22 -0
- package/dist/refill-run-loop.d.ts +14 -2
- package/dist/refill-run-loop.js +160 -15
- package/dist/server.js +0 -23
- package/dist/tools/auth.d.ts +5 -0
- package/dist/tools/auth.js +49 -12
- package/dist/tools/campaign-message-preparation.d.ts +62 -0
- package/dist/tools/campaign-message-preparation.js +41 -0
- package/dist/tools/campaigns.js +2 -2
- package/dist/tools/csv-dnc.js +2 -2
- package/dist/tools/evergreen-refill-plan.d.ts +3 -0
- package/dist/tools/evergreen-refill-plan.js +29 -7
- package/dist/tools/leads.d.ts +32 -317
- package/dist/tools/leads.js +10 -171
- package/dist/tools/model-quality.js +6 -4
- package/dist/tools/prompts.d.ts +3 -3
- package/dist/tools/prompts.js +15 -7
- package/dist/tools/provider-preflight.d.ts +2 -65
- package/dist/tools/provider-preflight.js +10 -97
- package/dist/tools/readiness.d.ts +5 -89
- package/dist/tools/readiness.js +0 -66
- package/dist/tools/refill-executors.d.ts +38 -0
- package/dist/tools/refill-executors.js +222 -3
- package/dist/tools/refill-sends-v2.d.ts +118 -1
- package/dist/tools/refill-sends-v2.js +312 -3
- package/dist/tools/refill-sends.d.ts +678 -32
- package/dist/tools/refill-sends.js +274 -13
- package/dist/tools/refill-target-plan.js +486 -14
- package/dist/tools/registry.d.ts +115 -330
- package/dist/tools/registry.js +1 -7
- package/dist/tools/scheduler-fill-capacity.js +1 -1
- package/dist/tools/scheduler-run.d.ts +71 -0
- package/dist/tools/scheduler-run.js +203 -1
- package/dist/tools/setup-evergreen-campaigns.js +1 -1
- package/dist/tools/workspace-context.d.ts +1 -1
- package/dist/tools/workspace-context.js +8 -3
- package/dist/tools/workspace-export.js +2 -2
- package/dist/tools/workspaces.d.ts +48 -2
- package/dist/tools/workspaces.js +48 -5
- 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 +630 -48
- package/skills/refill-sends/SKILL.md +91 -353
- 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 +100 -743
- package/skills/refill-sends-workflow/core/contract.v2.json +543 -0
- package/skills/refill-sends-workflow/core/flow.v1.json +185 -1
- package/dist/tools/find-leads-runs.d.ts +0 -151
- package/dist/tools/find-leads-runs.js +0 -98
- package/skills/find-leads-v2/SKILL.md +0 -70
- package/skills/find-leads-v2/core/flow.v1.json +0 -31
|
@@ -1,84 +1,10 @@
|
|
|
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
|
-
];
|
|
75
1
|
const providerPromptLoadedState = new Map();
|
|
76
|
-
function scopedKey(provider, campaignOfferId
|
|
77
|
-
return `${campaignOfferId
|
|
2
|
+
function scopedKey(provider, campaignOfferId) {
|
|
3
|
+
return `${campaignOfferId ?? "*"}::${provider}`;
|
|
78
4
|
}
|
|
79
|
-
function resolveLoadedState(provider, campaignOfferId
|
|
80
|
-
if (campaignOfferId
|
|
81
|
-
return (providerPromptLoadedState.get(scopedKey(provider, campaignOfferId
|
|
5
|
+
function resolveLoadedState(provider, campaignOfferId) {
|
|
6
|
+
if (campaignOfferId) {
|
|
7
|
+
return (providerPromptLoadedState.get(scopedKey(provider, campaignOfferId)) ??
|
|
82
8
|
null);
|
|
83
9
|
}
|
|
84
10
|
const providerScoped = providerPromptLoadedState.get(scopedKey(provider));
|
|
@@ -88,45 +14,32 @@ export function markProviderPromptLoaded(params) {
|
|
|
88
14
|
const entry = {
|
|
89
15
|
provider: params.provider,
|
|
90
16
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
91
|
-
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
92
17
|
loadedAt: new Date().toISOString(),
|
|
93
18
|
};
|
|
94
|
-
providerPromptLoadedState.set(scopedKey(params.provider, params.campaignOfferId
|
|
19
|
+
providerPromptLoadedState.set(scopedKey(params.provider, params.campaignOfferId), entry);
|
|
95
20
|
return {
|
|
96
21
|
...entry,
|
|
97
|
-
scope: entry.campaignOfferId
|
|
98
|
-
? "campaign"
|
|
99
|
-
: entry.findLeadsRunId
|
|
100
|
-
? "find-leads-run"
|
|
101
|
-
: "provider",
|
|
22
|
+
scope: entry.campaignOfferId ? "campaign" : "provider",
|
|
102
23
|
};
|
|
103
24
|
}
|
|
104
25
|
export function assertProviderPromptLoaded(params) {
|
|
105
|
-
const loadedState = resolveLoadedState(params.provider, params.campaignOfferId
|
|
26
|
+
const loadedState = resolveLoadedState(params.provider, params.campaignOfferId);
|
|
106
27
|
if (loadedState) {
|
|
107
28
|
return {
|
|
108
29
|
ok: true,
|
|
109
30
|
provider: params.provider,
|
|
110
31
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
111
|
-
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
112
32
|
loadedAt: loadedState.loadedAt,
|
|
113
|
-
scope: loadedState.campaignOfferId
|
|
114
|
-
? "campaign"
|
|
115
|
-
: loadedState.findLeadsRunId
|
|
116
|
-
? "find-leads-run"
|
|
117
|
-
: "provider",
|
|
33
|
+
scope: loadedState.campaignOfferId ? "campaign" : "provider",
|
|
118
34
|
};
|
|
119
35
|
}
|
|
120
36
|
const scopeText = params.campaignOfferId
|
|
121
37
|
? `campaign ${params.campaignOfferId}`
|
|
122
|
-
:
|
|
123
|
-
? `Find Leads run ${params.findLeadsRunId}`
|
|
124
|
-
: "this provider session";
|
|
38
|
+
: "this run";
|
|
125
39
|
const blockingMessage = `Provider prompt preflight missing for ${params.provider} (${scopeText}).`;
|
|
126
40
|
const diagnostics = {
|
|
127
41
|
provider: params.provider,
|
|
128
42
|
campaignOfferId: params.campaignOfferId ?? null,
|
|
129
|
-
findLeadsRunId: params.findLeadsRunId ?? null,
|
|
130
43
|
safeToProceed: false,
|
|
131
44
|
blockingErrors: [
|
|
132
45
|
`${blockingMessage} Call get_provider_prompt({ provider: "${params.provider}"${params.campaignOfferId
|
|
@@ -8,7 +8,6 @@ type WaitForCampaignTableReadyInput = {
|
|
|
8
8
|
type WaitForLeadListReadyInput = {
|
|
9
9
|
leadListId?: string;
|
|
10
10
|
campaignOfferId?: string;
|
|
11
|
-
findLeadsRunId?: string;
|
|
12
11
|
workspaceId?: string;
|
|
13
12
|
provider?: "apollo" | "sales-nav" | "prospeo" | "signal-discovery" | "csv-linkedin";
|
|
14
13
|
jobId?: string;
|
|
@@ -53,7 +52,6 @@ export declare const readinessToolDefinitions: ({
|
|
|
53
52
|
};
|
|
54
53
|
leadListId?: undefined;
|
|
55
54
|
campaignOfferId?: undefined;
|
|
56
|
-
findLeadsRunId?: undefined;
|
|
57
55
|
workspaceId?: undefined;
|
|
58
56
|
provider?: undefined;
|
|
59
57
|
jobId?: undefined;
|
|
@@ -77,10 +75,6 @@ export declare const readinessToolDefinitions: ({
|
|
|
77
75
|
type: string;
|
|
78
76
|
description: string;
|
|
79
77
|
};
|
|
80
|
-
findLeadsRunId: {
|
|
81
|
-
type: string;
|
|
82
|
-
description: string;
|
|
83
|
-
};
|
|
84
78
|
workspaceId: {
|
|
85
79
|
type: string;
|
|
86
80
|
description: string;
|
|
@@ -284,76 +278,18 @@ export declare function waitForCampaignTableReady(input: WaitForCampaignTableRea
|
|
|
284
278
|
warning: string | undefined;
|
|
285
279
|
}>;
|
|
286
280
|
export declare function waitForLeadListReady(input: WaitForLeadListReadyInput): Promise<{
|
|
287
|
-
ready: boolean;
|
|
288
|
-
reason: string;
|
|
289
|
-
runId: string;
|
|
290
|
-
leadListId: string;
|
|
291
|
-
attempts: number;
|
|
292
|
-
elapsedMs: number;
|
|
293
|
-
provider?: undefined;
|
|
294
|
-
jobId?: undefined;
|
|
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;
|
|
336
|
-
targetLeadCount?: undefined;
|
|
337
|
-
error?: undefined;
|
|
338
|
-
sourceShortfall?: undefined;
|
|
339
|
-
materializing?: undefined;
|
|
340
|
-
} | {
|
|
341
281
|
ready: boolean;
|
|
342
282
|
reason: string;
|
|
343
283
|
attempts: number;
|
|
344
284
|
elapsedMs: number;
|
|
345
285
|
leadListId: null;
|
|
346
|
-
runId?: undefined;
|
|
347
286
|
provider?: undefined;
|
|
348
|
-
jobId?: undefined;
|
|
349
|
-
status?: undefined;
|
|
350
287
|
rowCount?: undefined;
|
|
351
|
-
|
|
352
|
-
retryable?: undefined;
|
|
353
|
-
warning?: undefined;
|
|
288
|
+
status?: undefined;
|
|
354
289
|
targetLeadCount?: undefined;
|
|
355
290
|
error?: undefined;
|
|
356
291
|
sourceShortfall?: undefined;
|
|
292
|
+
warning?: undefined;
|
|
357
293
|
materializing?: undefined;
|
|
358
294
|
} | {
|
|
359
295
|
ready: boolean;
|
|
@@ -365,13 +301,9 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
365
301
|
rowCount: number;
|
|
366
302
|
status: string;
|
|
367
303
|
targetLeadCount: number | undefined;
|
|
368
|
-
runId?: undefined;
|
|
369
|
-
jobId?: undefined;
|
|
370
|
-
counts?: undefined;
|
|
371
|
-
retryable?: undefined;
|
|
372
|
-
warning?: undefined;
|
|
373
304
|
error?: undefined;
|
|
374
305
|
sourceShortfall?: undefined;
|
|
306
|
+
warning?: undefined;
|
|
375
307
|
materializing?: undefined;
|
|
376
308
|
} | {
|
|
377
309
|
ready: boolean;
|
|
@@ -384,12 +316,8 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
384
316
|
status: string | null;
|
|
385
317
|
targetLeadCount: number | undefined;
|
|
386
318
|
error: string;
|
|
387
|
-
runId?: undefined;
|
|
388
|
-
jobId?: undefined;
|
|
389
|
-
counts?: undefined;
|
|
390
|
-
retryable?: undefined;
|
|
391
|
-
warning?: undefined;
|
|
392
319
|
sourceShortfall?: undefined;
|
|
320
|
+
warning?: undefined;
|
|
393
321
|
materializing?: undefined;
|
|
394
322
|
} | {
|
|
395
323
|
ready: boolean;
|
|
@@ -402,12 +330,8 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
402
330
|
status: string;
|
|
403
331
|
targetLeadCount: number | undefined;
|
|
404
332
|
error: string | null;
|
|
405
|
-
runId?: undefined;
|
|
406
|
-
jobId?: undefined;
|
|
407
|
-
counts?: undefined;
|
|
408
|
-
retryable?: undefined;
|
|
409
|
-
warning?: undefined;
|
|
410
333
|
sourceShortfall?: undefined;
|
|
334
|
+
warning?: undefined;
|
|
411
335
|
materializing?: undefined;
|
|
412
336
|
} | {
|
|
413
337
|
ready: boolean;
|
|
@@ -421,10 +345,6 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
421
345
|
sourceShortfall: boolean;
|
|
422
346
|
warning: string | undefined;
|
|
423
347
|
reason?: undefined;
|
|
424
|
-
runId?: undefined;
|
|
425
|
-
jobId?: undefined;
|
|
426
|
-
counts?: undefined;
|
|
427
|
-
retryable?: undefined;
|
|
428
348
|
error?: undefined;
|
|
429
349
|
materializing?: undefined;
|
|
430
350
|
} | {
|
|
@@ -440,10 +360,6 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
|
|
|
440
360
|
materializing: boolean | undefined;
|
|
441
361
|
warning: string | undefined;
|
|
442
362
|
error: string | undefined;
|
|
443
|
-
runId?: undefined;
|
|
444
|
-
jobId?: undefined;
|
|
445
|
-
counts?: undefined;
|
|
446
|
-
retryable?: undefined;
|
|
447
363
|
sourceShortfall?: undefined;
|
|
448
364
|
}>;
|
|
449
365
|
export {};
|
package/dist/tools/readiness.js
CHANGED
|
@@ -109,10 +109,6 @@ 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
|
-
},
|
|
116
112
|
workspaceId: {
|
|
117
113
|
type: "string",
|
|
118
114
|
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation.",
|
|
@@ -208,68 +204,6 @@ export async function waitForLeadListReady(input) {
|
|
|
208
204
|
const intervalMs = Math.max(500, input.intervalMs ?? DEFAULT_INTERVAL_MS);
|
|
209
205
|
const requireRows = input.requireRows !== false;
|
|
210
206
|
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
|
-
}
|
|
273
207
|
let leadListId = input.leadListId;
|
|
274
208
|
let provider = input.provider;
|
|
275
209
|
let targetLeadCount = input.targetLeadCount;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { searchSignals } from "./leads.js";
|
|
2
|
+
import { type SchedulerExpectedTargetInput } from "./scheduler-run.js";
|
|
2
3
|
export type RefillSendsApprovalMode = "approve" | "mark_ready";
|
|
3
4
|
export type PaidInmailRefreshAction = {
|
|
4
5
|
senderId: string;
|
|
@@ -134,6 +135,43 @@ export declare function sleep(ms: number): Promise<unknown>;
|
|
|
134
135
|
export declare function recordValue(value: unknown): Record<string, unknown> | null;
|
|
135
136
|
export declare function stringValue(value: unknown): string | null;
|
|
136
137
|
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
|
+
};
|
|
137
175
|
export declare function stringArray(value: unknown): string[];
|
|
138
176
|
export declare function prepareRowSelectorValue(value: unknown): PrepareRowSelector | undefined;
|
|
139
177
|
export declare function uniqueStrings(values: Array<string | null | undefined>): string[];
|