@sellable/mcp 0.1.191 → 0.1.193
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 +1 -1
- package/agents/post-find-leads-message-scout.md +7 -7
- package/agents/registry.json +2 -2
- package/dist/auth.js +1 -1
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +22 -0
- package/dist/tools/campaign-processing.d.ts +383 -0
- package/dist/tools/campaign-processing.js +304 -0
- package/dist/tools/leads.d.ts +68 -19
- package/dist/tools/leads.js +65 -9
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +3 -3
- package/dist/tools/registry.d.ts +289 -37
- package/dist/tools/registry.js +2 -0
- package/dist/tools/rows.d.ts +2 -0
- package/dist/tools/rubrics.js +1 -1
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +8 -6
- package/skills/create-campaign-v2/SKILL.md +8 -9
- package/skills/create-campaign-v2/SOUL.md +2 -2
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/create-campaign-v2/core/policy.md +3 -3
- package/skills/create-campaign-v2/references/approval-gate-framing.md +5 -5
- package/skills/create-campaign-v2/references/filter-leads.md +5 -3
- package/skills/create-campaign-v2/references/parallel-critique-protocol.md +2 -2
- package/skills/create-campaign-v2/references/sample-validation-loop.md +46 -66
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +20 -13
- package/skills/create-campaign-v2-tail/SKILL.md +52 -65
- package/skills/generate-messages/SKILL.md +2 -2
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { getApi } from "../api.js";
|
|
2
|
+
import { resolveWaitTimeout } from "./readiness.js";
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 90000;
|
|
4
|
+
const DEFAULT_INTERVAL_MS = 2000;
|
|
5
|
+
function sleep(ms) {
|
|
6
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
}
|
|
8
|
+
function stableHash(value) {
|
|
9
|
+
const text = JSON.stringify(value, Object.keys(value).sort());
|
|
10
|
+
let hash = 2166136261;
|
|
11
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
12
|
+
hash ^= text.charCodeAt(index);
|
|
13
|
+
hash = Math.imul(hash, 16777619);
|
|
14
|
+
}
|
|
15
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
16
|
+
}
|
|
17
|
+
async function postCampaignProcessing(body) {
|
|
18
|
+
const api = getApi();
|
|
19
|
+
return api.post("/api/v3/mcp/campaign-processing", body);
|
|
20
|
+
}
|
|
21
|
+
async function resolveSchema(input) {
|
|
22
|
+
return postCampaignProcessing({
|
|
23
|
+
action: "schema",
|
|
24
|
+
campaignId: input.campaignId,
|
|
25
|
+
tableId: input.tableId,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export const campaignProcessingToolDefinitions = [
|
|
29
|
+
{
|
|
30
|
+
name: "get_campaign_table_schema",
|
|
31
|
+
description: "Return compact semantic campaign-table schema: column roles, row count, review-batch metadata, and current approved brief hash. Use for debugging or recovery, not normal queueing.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
campaignId: { type: "string" },
|
|
36
|
+
tableId: { type: "string" },
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "select_campaign_cells",
|
|
43
|
+
description: "Dry-run semantic campaign-cell selection. Returns compact counts and a tiny sample, never bulky row data. Use before queue_campaign_cells only when debugging or explaining a recovery action.",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
campaignId: { type: "string" },
|
|
48
|
+
tableId: { type: "string" },
|
|
49
|
+
columnRole: {
|
|
50
|
+
type: "string",
|
|
51
|
+
enum: [
|
|
52
|
+
"enrich",
|
|
53
|
+
"passesRubric",
|
|
54
|
+
"icpScore",
|
|
55
|
+
"generateMessage",
|
|
56
|
+
"approved",
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
rowSelector: {
|
|
60
|
+
type: "object",
|
|
61
|
+
properties: {
|
|
62
|
+
type: {
|
|
63
|
+
type: "string",
|
|
64
|
+
enum: [
|
|
65
|
+
"reviewBatch",
|
|
66
|
+
"rowIds",
|
|
67
|
+
"passedRows",
|
|
68
|
+
"needsGeneratedMessage",
|
|
69
|
+
"staleGeneratedMessages",
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
basisHash: { type: "string" },
|
|
73
|
+
rowIds: { type: "array", items: { type: "string" } },
|
|
74
|
+
limit: { type: "number" },
|
|
75
|
+
},
|
|
76
|
+
required: ["type"],
|
|
77
|
+
additionalProperties: false,
|
|
78
|
+
},
|
|
79
|
+
limit: { type: "number" },
|
|
80
|
+
},
|
|
81
|
+
required: ["columnRole", "rowSelector"],
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "queue_campaign_cells",
|
|
87
|
+
description: "Resolve and queue campaign cells by semantic role and row selector. Normal create-campaign tail should use this instead of fetching rows only to discover cell IDs. Use forceRerun:true for message-template revisions.",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: "object",
|
|
90
|
+
properties: {
|
|
91
|
+
campaignId: { type: "string" },
|
|
92
|
+
tableId: { type: "string" },
|
|
93
|
+
columnRole: {
|
|
94
|
+
type: "string",
|
|
95
|
+
enum: ["enrich", "generateMessage", "approved"],
|
|
96
|
+
},
|
|
97
|
+
rowSelector: {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
type: {
|
|
101
|
+
type: "string",
|
|
102
|
+
enum: [
|
|
103
|
+
"reviewBatch",
|
|
104
|
+
"rowIds",
|
|
105
|
+
"passedRows",
|
|
106
|
+
"needsGeneratedMessage",
|
|
107
|
+
"staleGeneratedMessages",
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
basisHash: { type: "string" },
|
|
111
|
+
rowIds: { type: "array", items: { type: "string" } },
|
|
112
|
+
limit: { type: "number" },
|
|
113
|
+
},
|
|
114
|
+
required: ["type"],
|
|
115
|
+
additionalProperties: false,
|
|
116
|
+
},
|
|
117
|
+
forceRerun: { type: "boolean" },
|
|
118
|
+
limit: { type: "number" },
|
|
119
|
+
reason: { type: "string" },
|
|
120
|
+
},
|
|
121
|
+
required: ["columnRole", "rowSelector"],
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "wait_for_campaign_processing",
|
|
127
|
+
description: "Stats-only campaign processing wait. Use for fit/message readiness instead of wait_for_rubric_results when waiting on campaign-table processing. Generated messages are counted separately from rubric passes; current template revision is enforced through messageDraftBasis.approvedBriefHash.",
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
campaignId: { type: "string" },
|
|
132
|
+
tableId: { type: "string" },
|
|
133
|
+
minPassedCount: { type: "number" },
|
|
134
|
+
minGeneratedMessages: { type: "number" },
|
|
135
|
+
templateRevision: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: '"current" (default when minGeneratedMessages is set) or an explicit current approved brief hash.',
|
|
138
|
+
},
|
|
139
|
+
timeoutMs: { type: "number" },
|
|
140
|
+
intervalMs: { type: "number" },
|
|
141
|
+
},
|
|
142
|
+
additionalProperties: false,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "revise_message_template_and_rerun",
|
|
147
|
+
description: "Update the approved message template in the campaign brief, mark prior generated messages stale, reset unsent approvals, and force-rerun Generate Message cells. Does not directly overwrite row message cells.",
|
|
148
|
+
inputSchema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
campaignId: { type: "string" },
|
|
152
|
+
tableId: { type: "string" },
|
|
153
|
+
templateMarkdown: { type: "string" },
|
|
154
|
+
approvedMessageTemplate: { type: "string" },
|
|
155
|
+
rowSelector: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {
|
|
158
|
+
type: {
|
|
159
|
+
type: "string",
|
|
160
|
+
enum: [
|
|
161
|
+
"passedRows",
|
|
162
|
+
"needsGeneratedMessage",
|
|
163
|
+
"staleGeneratedMessages",
|
|
164
|
+
"rowIds",
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
rowIds: { type: "array", items: { type: "string" } },
|
|
168
|
+
limit: { type: "number" },
|
|
169
|
+
},
|
|
170
|
+
required: ["type"],
|
|
171
|
+
additionalProperties: false,
|
|
172
|
+
},
|
|
173
|
+
limit: { type: "number" },
|
|
174
|
+
},
|
|
175
|
+
required: ["campaignId"],
|
|
176
|
+
additionalProperties: false,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
];
|
|
180
|
+
export async function getCampaignTableSchema(input) {
|
|
181
|
+
return resolveSchema(input);
|
|
182
|
+
}
|
|
183
|
+
export async function selectCampaignCells(input) {
|
|
184
|
+
return postCampaignProcessing({
|
|
185
|
+
action: "select",
|
|
186
|
+
...input,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
export async function queueCampaignCells(input) {
|
|
190
|
+
return postCampaignProcessing({
|
|
191
|
+
action: "queue",
|
|
192
|
+
...input,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
export async function reviseMessageTemplateAndRerun(input) {
|
|
196
|
+
return postCampaignProcessing({
|
|
197
|
+
action: "reviseTemplateAndRerun",
|
|
198
|
+
...input,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
export async function waitForCampaignProcessing(input) {
|
|
202
|
+
const api = getApi();
|
|
203
|
+
const schema = await resolveSchema(input);
|
|
204
|
+
const { effectiveTimeoutMs, guardApplied, requestedTimeoutMs } = resolveWaitTimeout(input.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
205
|
+
const intervalMs = Math.max(500, input.intervalMs ?? DEFAULT_INTERVAL_MS);
|
|
206
|
+
const minPassedCount = typeof input.minPassedCount === "number" &&
|
|
207
|
+
Number.isFinite(input.minPassedCount)
|
|
208
|
+
? Math.max(1, Math.floor(input.minPassedCount))
|
|
209
|
+
: null;
|
|
210
|
+
const minGeneratedMessages = typeof input.minGeneratedMessages === "number" &&
|
|
211
|
+
Number.isFinite(input.minGeneratedMessages)
|
|
212
|
+
? Math.max(1, Math.floor(input.minGeneratedMessages))
|
|
213
|
+
: null;
|
|
214
|
+
const templateRevision = input.templateRevision ?? (minGeneratedMessages !== null ? "current" : null);
|
|
215
|
+
const pollKey = stableHash({
|
|
216
|
+
tableId: schema.tableId,
|
|
217
|
+
minPassedCount,
|
|
218
|
+
minGeneratedMessages,
|
|
219
|
+
templateRevision,
|
|
220
|
+
});
|
|
221
|
+
const start = Date.now();
|
|
222
|
+
let attempts = 0;
|
|
223
|
+
let lastStats = null;
|
|
224
|
+
while (Date.now() - start <= effectiveTimeoutMs) {
|
|
225
|
+
attempts += 1;
|
|
226
|
+
const stats = await api.get(`/api/v3/workflow-tables/${schema.tableId}/stats`);
|
|
227
|
+
lastStats = stats;
|
|
228
|
+
const currentRevisionHash = stats.currentTemplateRevisionHash ?? null;
|
|
229
|
+
if (templateRevision &&
|
|
230
|
+
templateRevision !== "current" &&
|
|
231
|
+
currentRevisionHash &&
|
|
232
|
+
templateRevision !== currentRevisionHash) {
|
|
233
|
+
return {
|
|
234
|
+
ready: false,
|
|
235
|
+
reason: "template_revision_mismatch",
|
|
236
|
+
attempts,
|
|
237
|
+
elapsedMs: Date.now() - start,
|
|
238
|
+
tableId: schema.tableId,
|
|
239
|
+
pollKey,
|
|
240
|
+
requestedTemplateRevision: templateRevision,
|
|
241
|
+
currentTemplateRevisionHash: currentRevisionHash,
|
|
242
|
+
guidance: "The requested templateRevision is not current. Re-read campaign state or wait using templateRevision:'current'.",
|
|
243
|
+
stats,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
const passed = stats.passRate?.passed ?? 0;
|
|
247
|
+
const generated = templateRevision === "current" || templateRevision !== null
|
|
248
|
+
? (stats.currentRevisionGeneratedMessagesCount ?? 0)
|
|
249
|
+
: (stats.generatedMessagesCount ?? stats.messagesCount ?? 0);
|
|
250
|
+
const passFloorMet = minPassedCount === null || passed >= minPassedCount;
|
|
251
|
+
const generatedFloorMet = minGeneratedMessages === null || generated >= minGeneratedMessages;
|
|
252
|
+
if (passFloorMet && generatedFloorMet) {
|
|
253
|
+
return {
|
|
254
|
+
ready: true,
|
|
255
|
+
attempts,
|
|
256
|
+
elapsedMs: Date.now() - start,
|
|
257
|
+
tableId: schema.tableId,
|
|
258
|
+
pollKey,
|
|
259
|
+
floors: {
|
|
260
|
+
minPassedCount,
|
|
261
|
+
minGeneratedMessages,
|
|
262
|
+
templateRevision,
|
|
263
|
+
},
|
|
264
|
+
result: {
|
|
265
|
+
passedCount: passed,
|
|
266
|
+
generatedMessagesCount: stats.generatedMessagesCount ?? stats.messagesCount ?? 0,
|
|
267
|
+
currentRevisionGeneratedMessagesCount: stats.currentRevisionGeneratedMessagesCount ?? 0,
|
|
268
|
+
staleGeneratedMessagesCount: stats.staleGeneratedMessagesCount ?? 0,
|
|
269
|
+
generatedWithoutPassCount: stats.generatedWithoutPassCount ?? 0,
|
|
270
|
+
currentTemplateRevisionHash: currentRevisionHash,
|
|
271
|
+
},
|
|
272
|
+
stats,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
await sleep(intervalMs);
|
|
276
|
+
}
|
|
277
|
+
const passed = lastStats?.passRate?.passed ?? 0;
|
|
278
|
+
return {
|
|
279
|
+
ready: false,
|
|
280
|
+
reason: guardApplied ? "tool_timeout_guard" : "timeout",
|
|
281
|
+
attempts,
|
|
282
|
+
elapsedMs: Date.now() - start,
|
|
283
|
+
tableId: schema.tableId,
|
|
284
|
+
pollKey,
|
|
285
|
+
warning: guardApplied
|
|
286
|
+
? `Stopped after ${effectiveTimeoutMs}ms to avoid host tool timeout (requested ${requestedTimeoutMs}ms).`
|
|
287
|
+
: undefined,
|
|
288
|
+
partialResult: {
|
|
289
|
+
passedCount: passed,
|
|
290
|
+
generatedMessagesCount: lastStats?.generatedMessagesCount ?? lastStats?.messagesCount ?? 0,
|
|
291
|
+
currentRevisionGeneratedMessagesCount: lastStats?.currentRevisionGeneratedMessagesCount ?? 0,
|
|
292
|
+
staleGeneratedMessagesCount: lastStats?.staleGeneratedMessagesCount ?? 0,
|
|
293
|
+
generatedWithoutPassCount: lastStats?.generatedWithoutPassCount ?? 0,
|
|
294
|
+
currentTemplateRevisionHash: lastStats?.currentTemplateRevisionHash ??
|
|
295
|
+
schema.currentApprovedBriefHash,
|
|
296
|
+
passFloorMet: minPassedCount === null || passed >= minPassedCount,
|
|
297
|
+
generatedFloorMet: minGeneratedMessages === null ||
|
|
298
|
+
(lastStats?.currentRevisionGeneratedMessagesCount ?? 0) >=
|
|
299
|
+
minGeneratedMessages,
|
|
300
|
+
},
|
|
301
|
+
guidance: "Do not repoll with identical arguments after this timeout. Use the partial diagnostics to revise filters/messages, queue missing work, or surface the blocked sample state.",
|
|
302
|
+
stats: lastStats,
|
|
303
|
+
};
|
|
304
|
+
}
|
package/dist/tools/leads.d.ts
CHANGED
|
@@ -146,6 +146,7 @@ export type ConfirmLeadListInput = {
|
|
|
146
146
|
keepInSync?: boolean;
|
|
147
147
|
jobId?: string;
|
|
148
148
|
reviewBatchLimit?: number;
|
|
149
|
+
includeRawImportResult?: boolean;
|
|
149
150
|
allowPartialSourceList?: boolean;
|
|
150
151
|
/**
|
|
151
152
|
* Deprecated alias for reviewBatchLimit. Confirming a lead list now copies the
|
|
@@ -246,6 +247,7 @@ export declare const leadToolDefinitions: ({
|
|
|
246
247
|
jobId?: undefined;
|
|
247
248
|
reviewBatchLimit?: undefined;
|
|
248
249
|
allowPartialSourceList?: undefined;
|
|
250
|
+
includeRawImportResult?: undefined;
|
|
249
251
|
selections?: undefined;
|
|
250
252
|
selectionMode?: undefined;
|
|
251
253
|
};
|
|
@@ -423,6 +425,7 @@ export declare const leadToolDefinitions: ({
|
|
|
423
425
|
jobId?: undefined;
|
|
424
426
|
reviewBatchLimit?: undefined;
|
|
425
427
|
allowPartialSourceList?: undefined;
|
|
428
|
+
includeRawImportResult?: undefined;
|
|
426
429
|
selections?: undefined;
|
|
427
430
|
selectionMode?: undefined;
|
|
428
431
|
};
|
|
@@ -499,6 +502,7 @@ export declare const leadToolDefinitions: ({
|
|
|
499
502
|
jobId?: undefined;
|
|
500
503
|
reviewBatchLimit?: undefined;
|
|
501
504
|
allowPartialSourceList?: undefined;
|
|
505
|
+
includeRawImportResult?: undefined;
|
|
502
506
|
selections?: undefined;
|
|
503
507
|
selectionMode?: undefined;
|
|
504
508
|
};
|
|
@@ -647,6 +651,7 @@ export declare const leadToolDefinitions: ({
|
|
|
647
651
|
jobId?: undefined;
|
|
648
652
|
reviewBatchLimit?: undefined;
|
|
649
653
|
allowPartialSourceList?: undefined;
|
|
654
|
+
includeRawImportResult?: undefined;
|
|
650
655
|
selections?: undefined;
|
|
651
656
|
selectionMode?: undefined;
|
|
652
657
|
};
|
|
@@ -737,6 +742,7 @@ export declare const leadToolDefinitions: ({
|
|
|
737
742
|
jobId?: undefined;
|
|
738
743
|
reviewBatchLimit?: undefined;
|
|
739
744
|
allowPartialSourceList?: undefined;
|
|
745
|
+
includeRawImportResult?: undefined;
|
|
740
746
|
selections?: undefined;
|
|
741
747
|
selectionMode?: undefined;
|
|
742
748
|
};
|
|
@@ -836,6 +842,7 @@ export declare const leadToolDefinitions: ({
|
|
|
836
842
|
jobId?: undefined;
|
|
837
843
|
reviewBatchLimit?: undefined;
|
|
838
844
|
allowPartialSourceList?: undefined;
|
|
845
|
+
includeRawImportResult?: undefined;
|
|
839
846
|
selections?: undefined;
|
|
840
847
|
selectionMode?: undefined;
|
|
841
848
|
};
|
|
@@ -917,6 +924,7 @@ export declare const leadToolDefinitions: ({
|
|
|
917
924
|
jobId?: undefined;
|
|
918
925
|
reviewBatchLimit?: undefined;
|
|
919
926
|
allowPartialSourceList?: undefined;
|
|
927
|
+
includeRawImportResult?: undefined;
|
|
920
928
|
selections?: undefined;
|
|
921
929
|
selectionMode?: undefined;
|
|
922
930
|
};
|
|
@@ -1537,6 +1545,7 @@ export declare const leadToolDefinitions: ({
|
|
|
1537
1545
|
jobId?: undefined;
|
|
1538
1546
|
reviewBatchLimit?: undefined;
|
|
1539
1547
|
allowPartialSourceList?: undefined;
|
|
1548
|
+
includeRawImportResult?: undefined;
|
|
1540
1549
|
selections?: undefined;
|
|
1541
1550
|
selectionMode?: undefined;
|
|
1542
1551
|
};
|
|
@@ -1670,6 +1679,7 @@ export declare const leadToolDefinitions: ({
|
|
|
1670
1679
|
jobId?: undefined;
|
|
1671
1680
|
reviewBatchLimit?: undefined;
|
|
1672
1681
|
allowPartialSourceList?: undefined;
|
|
1682
|
+
includeRawImportResult?: undefined;
|
|
1673
1683
|
selections?: undefined;
|
|
1674
1684
|
selectionMode?: undefined;
|
|
1675
1685
|
};
|
|
@@ -1791,6 +1801,7 @@ export declare const leadToolDefinitions: ({
|
|
|
1791
1801
|
jobId?: undefined;
|
|
1792
1802
|
reviewBatchLimit?: undefined;
|
|
1793
1803
|
allowPartialSourceList?: undefined;
|
|
1804
|
+
includeRawImportResult?: undefined;
|
|
1794
1805
|
selections?: undefined;
|
|
1795
1806
|
selectionMode?: undefined;
|
|
1796
1807
|
};
|
|
@@ -1870,6 +1881,7 @@ export declare const leadToolDefinitions: ({
|
|
|
1870
1881
|
jobId?: undefined;
|
|
1871
1882
|
reviewBatchLimit?: undefined;
|
|
1872
1883
|
allowPartialSourceList?: undefined;
|
|
1884
|
+
includeRawImportResult?: undefined;
|
|
1873
1885
|
selections?: undefined;
|
|
1874
1886
|
selectionMode?: undefined;
|
|
1875
1887
|
};
|
|
@@ -1921,6 +1933,10 @@ export declare const leadToolDefinitions: ({
|
|
|
1921
1933
|
type: string;
|
|
1922
1934
|
description: string;
|
|
1923
1935
|
};
|
|
1936
|
+
includeRawImportResult: {
|
|
1937
|
+
type: string;
|
|
1938
|
+
description: string;
|
|
1939
|
+
};
|
|
1924
1940
|
provider?: undefined;
|
|
1925
1941
|
searchMode?: undefined;
|
|
1926
1942
|
organization_num_employees_ranges?: undefined;
|
|
@@ -2083,6 +2099,7 @@ export declare const leadToolDefinitions: ({
|
|
|
2083
2099
|
jobId?: undefined;
|
|
2084
2100
|
reviewBatchLimit?: undefined;
|
|
2085
2101
|
allowPartialSourceList?: undefined;
|
|
2102
|
+
includeRawImportResult?: undefined;
|
|
2086
2103
|
};
|
|
2087
2104
|
required: string[];
|
|
2088
2105
|
};
|
|
@@ -2164,6 +2181,7 @@ export declare const leadToolDefinitions: ({
|
|
|
2164
2181
|
jobId?: undefined;
|
|
2165
2182
|
reviewBatchLimit?: undefined;
|
|
2166
2183
|
allowPartialSourceList?: undefined;
|
|
2184
|
+
includeRawImportResult?: undefined;
|
|
2167
2185
|
selections?: undefined;
|
|
2168
2186
|
selectionMode?: undefined;
|
|
2169
2187
|
};
|
|
@@ -2376,6 +2394,8 @@ export declare function searchSignals(input: SignalSearchInput): Promise<{
|
|
|
2376
2394
|
id: string;
|
|
2377
2395
|
url: string | undefined;
|
|
2378
2396
|
matchedKeyword: string | null;
|
|
2397
|
+
searchType: "company" | "keyword" | "profile" | "post" | null;
|
|
2398
|
+
displayLabel: string | null;
|
|
2379
2399
|
authorName: string;
|
|
2380
2400
|
authorHeadline: string;
|
|
2381
2401
|
authorProfileUrl: string;
|
|
@@ -2393,6 +2413,9 @@ export declare function searchSignals(input: SignalSearchInput): Promise<{
|
|
|
2393
2413
|
}[];
|
|
2394
2414
|
keywordResults: {
|
|
2395
2415
|
keyword: string;
|
|
2416
|
+
searchType: "company" | "keyword" | "profile" | "post";
|
|
2417
|
+
displayLabel: string;
|
|
2418
|
+
tabId: string | null;
|
|
2396
2419
|
postCount: number;
|
|
2397
2420
|
avgEngagement: number | null;
|
|
2398
2421
|
hasMore: boolean;
|
|
@@ -2608,25 +2631,13 @@ export declare function cancelLeadImport(input: CancelLeadImportInput): Promise<
|
|
|
2608
2631
|
previousStatus?: undefined;
|
|
2609
2632
|
}>;
|
|
2610
2633
|
export declare function confirmLeadList(input: ConfirmLeadListInput): Promise<{
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
leadsSkipped?: number;
|
|
2619
|
-
rowIds?: string[];
|
|
2620
|
-
requestedTargetLeadCount?: number;
|
|
2621
|
-
sourceRowLimit?: number;
|
|
2622
|
-
async?: boolean;
|
|
2623
|
-
hybrid?: boolean;
|
|
2624
|
-
campaignTableReady?: boolean;
|
|
2625
|
-
importStatus?: string | null;
|
|
2626
|
-
remainingRowCount?: number | null;
|
|
2627
|
-
rowCount?: number | null;
|
|
2628
|
-
sourceRowCount?: number | null;
|
|
2629
|
-
clonedSourceRowCount?: number | null;
|
|
2634
|
+
reviewBatch: {
|
|
2635
|
+
tableId: string | null;
|
|
2636
|
+
rowCount: number;
|
|
2637
|
+
rowIds: string[];
|
|
2638
|
+
enrichCellIds: string[];
|
|
2639
|
+
basisHash: string | null;
|
|
2640
|
+
recordedAt: string | null;
|
|
2630
2641
|
};
|
|
2631
2642
|
messageDraftBuilder: {
|
|
2632
2643
|
firstAllowedStartPoint: string;
|
|
@@ -2637,6 +2648,7 @@ export declare function confirmLeadList(input: ConfirmLeadListInput): Promise<{
|
|
|
2637
2648
|
selectedLeadListId: string;
|
|
2638
2649
|
workflowTableId: string | null;
|
|
2639
2650
|
reviewBatchRowIds: string[];
|
|
2651
|
+
reviewBatchBasisHash: string | null;
|
|
2640
2652
|
reviewBatchRowCount: number;
|
|
2641
2653
|
copiedCampaignRowCount: number;
|
|
2642
2654
|
};
|
|
@@ -2665,6 +2677,43 @@ export declare function confirmLeadList(input: ConfirmLeadListInput): Promise<{
|
|
|
2665
2677
|
warning: string | null;
|
|
2666
2678
|
};
|
|
2667
2679
|
message: string;
|
|
2680
|
+
importResult?: {
|
|
2681
|
+
workflowTableId?: string;
|
|
2682
|
+
campaignTableId?: string;
|
|
2683
|
+
campaignTableName?: string;
|
|
2684
|
+
leadsImported?: number;
|
|
2685
|
+
leadsSkipped?: number;
|
|
2686
|
+
rowIds?: string[];
|
|
2687
|
+
requestedTargetLeadCount?: number;
|
|
2688
|
+
sourceRowLimit?: number;
|
|
2689
|
+
async?: boolean;
|
|
2690
|
+
hybrid?: boolean;
|
|
2691
|
+
campaignTableReady?: boolean;
|
|
2692
|
+
importStatus?: string | null;
|
|
2693
|
+
remainingRowCount?: number | null;
|
|
2694
|
+
rowCount?: number | null;
|
|
2695
|
+
sourceRowCount?: number | null;
|
|
2696
|
+
clonedSourceRowCount?: number | null;
|
|
2697
|
+
} | undefined;
|
|
2698
|
+
sourceLeadListId: string;
|
|
2699
|
+
campaignTableId: string | null;
|
|
2700
|
+
importSummary: {
|
|
2701
|
+
workflowTableId: string | null;
|
|
2702
|
+
campaignTableId: string | null;
|
|
2703
|
+
campaignTableName: string | null;
|
|
2704
|
+
leadsImported: number | null;
|
|
2705
|
+
leadsSkipped: number | null;
|
|
2706
|
+
rowCount: number;
|
|
2707
|
+
requestedTargetLeadCount: number | null;
|
|
2708
|
+
sourceRowLimit: number | null;
|
|
2709
|
+
async: boolean;
|
|
2710
|
+
hybrid: boolean;
|
|
2711
|
+
campaignTableReady: true;
|
|
2712
|
+
importStatus: string | null;
|
|
2713
|
+
remainingRowCount: number;
|
|
2714
|
+
sourceRowCount: number | null;
|
|
2715
|
+
clonedSourceRowCount: number | null;
|
|
2716
|
+
};
|
|
2668
2717
|
}>;
|
|
2669
2718
|
export declare function getProviderPrompt(input: GetProviderPromptInput): string;
|
|
2670
2719
|
export declare function selectPromisingPosts(input: SelectPromisingPostsInput): Promise<{
|
package/dist/tools/leads.js
CHANGED
|
@@ -471,6 +471,8 @@ function summarizeSignalPost(post) {
|
|
|
471
471
|
id: post.id,
|
|
472
472
|
url: post.url,
|
|
473
473
|
matchedKeyword: post.matchedKeyword ?? null,
|
|
474
|
+
searchType: post.searchType ?? null,
|
|
475
|
+
displayLabel: post.displayLabel ?? null,
|
|
474
476
|
authorName: post.author?.name ?? "",
|
|
475
477
|
authorHeadline: post.author?.headline ?? "",
|
|
476
478
|
authorProfileUrl: post.author?.profileUrl ?? "",
|
|
@@ -500,6 +502,9 @@ function summarizeSignalSearchResponse(response) {
|
|
|
500
502
|
.map(summarizeSignalPost);
|
|
501
503
|
const keywordResults = (response.keywordResults ?? []).map((kw) => ({
|
|
502
504
|
keyword: kw.keyword,
|
|
505
|
+
searchType: kw.searchType ?? "keyword",
|
|
506
|
+
displayLabel: kw.displayLabel ?? kw.keyword,
|
|
507
|
+
tabId: kw.tabId ?? null,
|
|
503
508
|
postCount: kw.postCount,
|
|
504
509
|
avgEngagement: kw.avgEngagement ?? null,
|
|
505
510
|
hasMore: kw.hasMore ?? false,
|
|
@@ -529,7 +534,7 @@ function buildSourceImportWatchNarration({ provider, selectedPostCount, estimate
|
|
|
529
534
|
: "Apollo";
|
|
530
535
|
const sourceDetail = provider === "signal-discovery"
|
|
531
536
|
? `${selectedPostCount ?? "selected"} approved post${selectedPostCount === 1 ? "" : "s"}${typeof estimatedEngagers === "number"
|
|
532
|
-
? ` with
|
|
537
|
+
? ` with about ${estimatedEngagers.toLocaleString("en-US")} people to check`
|
|
533
538
|
: ""}`
|
|
534
539
|
: `the approved ${providerLabel} source`;
|
|
535
540
|
const targetDetail = typeof targetLeadCount === "number"
|
|
@@ -806,8 +811,8 @@ function buildSignalDiscoverySourceRecommendation({ selectedPosts, targetEngager
|
|
|
806
811
|
? "the approved buyer-search target"
|
|
807
812
|
: `the ${Math.round(defaultFitRate * 100)}% starting estimate`;
|
|
808
813
|
const selectedPoolCopy = recommendedCount < selectedCount
|
|
809
|
-
? `**Posts considered:** ${selectedCount.toLocaleString("en-US")} selected posts with ${formatApproxInteger(totalVisibleEngagement)}
|
|
810
|
-
: `**
|
|
814
|
+
? `**Posts considered:** ${selectedCount.toLocaleString("en-US")} selected posts with ${formatApproxInteger(totalVisibleEngagement)} public reactions/comments<br>\n**Recommended first set:** ${recommendedCount.toLocaleString("en-US")} post${recommendedCount === 1 ? "" : "s"} with ${formatApproxInteger(recommendedVisibleEngagement)} public reactions/comments and up to ${formatApproxInteger(scrapePlan.estimatedEngagers)} people to check<br>`
|
|
815
|
+
: `**Public activity in the selected posts:** ${formatApproxInteger(totalVisibleEngagement)} reactions/comments<br>\n**People we can check from this set:** up to ${formatApproxInteger(scrapePlan.estimatedEngagers)}<br>`;
|
|
811
816
|
const message = `## Source Recommendation
|
|
812
817
|
|
|
813
818
|
Start with LinkedIn posts.
|
|
@@ -821,7 +826,7 @@ I found ${recommendedCount.toLocaleString("en-US")} recommended LinkedIn post${r
|
|
|
821
826
|
|
|
822
827
|
### Recommended posts
|
|
823
828
|
|
|
824
|
-
| Post | Why this post |
|
|
829
|
+
| Post | Why this post | Public activity | People we can check |
|
|
825
830
|
|---|---|---:|---:|
|
|
826
831
|
${tableRows || "| Recommended posts | Campaign-matched public activity | - | - |"}
|
|
827
832
|
|
|
@@ -1518,6 +1523,10 @@ export const leadToolDefinitions = [
|
|
|
1518
1523
|
type: "boolean",
|
|
1519
1524
|
description: "Set true after user approval when interaction mode requires confirmation for confirm/import.",
|
|
1520
1525
|
},
|
|
1526
|
+
includeRawImportResult: {
|
|
1527
|
+
type: "boolean",
|
|
1528
|
+
description: "Debug only. When true, include the raw import response; default compact output omits large row-id payloads.",
|
|
1529
|
+
},
|
|
1521
1530
|
},
|
|
1522
1531
|
required: ["campaignOfferId"],
|
|
1523
1532
|
},
|
|
@@ -2579,7 +2588,7 @@ export async function importLeads(input) {
|
|
|
2579
2588
|
maxPostsToScrape: normalizePositiveInteger(maxPostsToScrape) ?? null,
|
|
2580
2589
|
limitedSelectedPosts: importSelection.limited,
|
|
2581
2590
|
targetLeadCount: cappedTargetLeadCount ?? null,
|
|
2582
|
-
message: `Started scraping ${postsToScrape.length} posts (up to ~${result.estimatedEngagers} people to check
|
|
2591
|
+
message: `Started scraping ${postsToScrape.length} posts (up to ~${result.estimatedEngagers} people to check). Leads will appear as scraping completes.${importSelection.limited
|
|
2583
2592
|
? ` Limited from ${uniqueSelectedPosts.length} selected posts by the approved source-capacity scrape plan.`
|
|
2584
2593
|
: ""} The watched campaign has been moved to confirm-lead-list with import progress copy. Keep calling wait_for_lead_list_ready until it reports ready, failed, or cancelled before confirm_lead_list; only confirm a partial list with allowPartialSourceList after the user explicitly asks to keep going early. Do not call update_campaign to fix that step.`,
|
|
2585
2594
|
};
|
|
@@ -2741,7 +2750,7 @@ export async function cancelLeadImport(input) {
|
|
|
2741
2750
|
}
|
|
2742
2751
|
export async function confirmLeadList(input) {
|
|
2743
2752
|
const api = getApi();
|
|
2744
|
-
const { campaignOfferId, currentStep, confirmed, sourceLeadListId, campaignName, keepInSync, jobId, reviewBatchLimit, allowPartialSourceList, targetLeadCount, } = input;
|
|
2753
|
+
const { campaignOfferId, currentStep, confirmed, sourceLeadListId, campaignName, keepInSync, jobId, reviewBatchLimit, includeRawImportResult, allowPartialSourceList, targetLeadCount, } = input;
|
|
2745
2754
|
assertInteractionApproval({
|
|
2746
2755
|
campaignId: campaignOfferId,
|
|
2747
2756
|
action: "confirm-lead-list",
|
|
@@ -2873,7 +2882,7 @@ export async function confirmLeadList(input) {
|
|
|
2873
2882
|
rowCount: leadListRowCount,
|
|
2874
2883
|
status: typeof readiness.status === "string"
|
|
2875
2884
|
? readiness.status
|
|
2876
|
-
: leadListConfig?.importStatus ?? null,
|
|
2885
|
+
: (leadListConfig?.importStatus ?? null),
|
|
2877
2886
|
targetLeadCount: typeof readiness.targetLeadCount === "number"
|
|
2878
2887
|
? readiness.targetLeadCount
|
|
2879
2888
|
: typeof leadListConfig?.targetLeadCount === "number"
|
|
@@ -2988,6 +2997,50 @@ export async function confirmLeadList(input) {
|
|
|
2988
2997
|
reviewSampleRows = [];
|
|
2989
2998
|
}
|
|
2990
2999
|
}
|
|
3000
|
+
const sampleReviewRowIds = reviewSampleRows
|
|
3001
|
+
.map((row) => row.id)
|
|
3002
|
+
.filter((rowId) => typeof rowId === "string");
|
|
3003
|
+
const reviewBatchRowIds = importedRowIds.length > 0
|
|
3004
|
+
? importedRowIds.slice(0, keptReviewRowCount)
|
|
3005
|
+
: sampleReviewRowIds.slice(0, keptReviewRowCount);
|
|
3006
|
+
const reviewBatchEnrichCellIds = reviewSampleRows
|
|
3007
|
+
.map((row) => row.enrichCellId)
|
|
3008
|
+
.filter((cellId) => typeof cellId === "string");
|
|
3009
|
+
let recordedReviewBatch = null;
|
|
3010
|
+
if (campaignTableId && reviewBatchRowIds.length > 0) {
|
|
3011
|
+
const recordResult = await api.post("/api/v3/mcp/campaign-processing", {
|
|
3012
|
+
action: "recordReviewBatch",
|
|
3013
|
+
tableId: campaignTableId,
|
|
3014
|
+
rowIds: reviewBatchRowIds,
|
|
3015
|
+
enrichCellIds: reviewBatchEnrichCellIds,
|
|
3016
|
+
});
|
|
3017
|
+
recordedReviewBatch = recordResult.reviewBatch ?? null;
|
|
3018
|
+
}
|
|
3019
|
+
const compactReviewBatch = {
|
|
3020
|
+
tableId: campaignTableId ?? null,
|
|
3021
|
+
rowCount: recordedReviewBatch?.rowCount ?? reviewBatchRowIds.length,
|
|
3022
|
+
rowIds: recordedReviewBatch?.rowIds ?? reviewBatchRowIds,
|
|
3023
|
+
enrichCellIds: recordedReviewBatch?.enrichCellIds ?? reviewBatchEnrichCellIds,
|
|
3024
|
+
basisHash: recordedReviewBatch?.basisHash ?? null,
|
|
3025
|
+
recordedAt: recordedReviewBatch?.recordedAt ?? null,
|
|
3026
|
+
};
|
|
3027
|
+
const importSummary = {
|
|
3028
|
+
workflowTableId: campaignTableId ?? null,
|
|
3029
|
+
campaignTableId: campaignTableId ?? null,
|
|
3030
|
+
campaignTableName: importResult.campaignTableName ?? null,
|
|
3031
|
+
leadsImported: importResult.leadsImported ?? null,
|
|
3032
|
+
leadsSkipped: importResult.leadsSkipped ?? null,
|
|
3033
|
+
rowCount: importResult.rowCount ?? importedRowCount,
|
|
3034
|
+
requestedTargetLeadCount: importResult.requestedTargetLeadCount ?? null,
|
|
3035
|
+
sourceRowLimit: importResult.sourceRowLimit ?? null,
|
|
3036
|
+
async: importResult.async ?? false,
|
|
3037
|
+
hybrid: importResult.hybrid ?? false,
|
|
3038
|
+
campaignTableReady,
|
|
3039
|
+
importStatus: importResult.importStatus ?? null,
|
|
3040
|
+
remainingRowCount,
|
|
3041
|
+
sourceRowCount: importResult.sourceRowCount ?? null,
|
|
3042
|
+
clonedSourceRowCount: importResult.clonedSourceRowCount ?? null,
|
|
3043
|
+
};
|
|
2991
3044
|
// Persist currentStep if the caller asked for it. Do NOT touch
|
|
2992
3045
|
// selectedLeadListId here: the campaign table id is already saved to
|
|
2993
3046
|
// CampaignOffer.workflowTableId by /api/v3/campaign-builder/import-leads,
|
|
@@ -3014,7 +3067,9 @@ export async function confirmLeadList(input) {
|
|
|
3014
3067
|
return {
|
|
3015
3068
|
sourceLeadListId: resolvedLeadListId,
|
|
3016
3069
|
campaignTableId: campaignTableId ?? null,
|
|
3017
|
-
|
|
3070
|
+
importSummary,
|
|
3071
|
+
...(includeRawImportResult ? { importResult } : {}),
|
|
3072
|
+
reviewBatch: compactReviewBatch,
|
|
3018
3073
|
messageDraftBuilder: {
|
|
3019
3074
|
firstAllowedStartPoint: "confirm_lead_list",
|
|
3020
3075
|
startAllowed: true,
|
|
@@ -3023,7 +3078,8 @@ export async function confirmLeadList(input) {
|
|
|
3023
3078
|
campaignOfferId,
|
|
3024
3079
|
selectedLeadListId: resolvedLeadListId,
|
|
3025
3080
|
workflowTableId: campaignTableId ?? null,
|
|
3026
|
-
reviewBatchRowIds
|
|
3081
|
+
reviewBatchRowIds,
|
|
3082
|
+
reviewBatchBasisHash: compactReviewBatch.basisHash,
|
|
3027
3083
|
reviewBatchRowCount: keptReviewRowCount,
|
|
3028
3084
|
copiedCampaignRowCount: importedRowCount,
|
|
3029
3085
|
},
|