@sellable/mcp 0.1.149 → 0.1.150
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 +8 -4
- package/agents/source-scout-prospeo-contact.md +12 -5
- package/agents/source-scout-sales-nav.md +13 -3
- package/dist/tools/leads.d.ts +2 -1
- package/dist/tools/leads.js +162 -15
- package/dist/tools/prompts.js +3 -3
- package/dist/tools/registry.d.ts +9 -1
- package/dist/tools/rows.d.ts +1 -0
- package/dist/tools/rows.js +2 -0
- package/dist/tools/rubrics.d.ts +55 -23
- package/dist/tools/rubrics.js +95 -10
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +51 -23
- package/skills/create-campaign/core/providers/apollo.json +4 -2
- package/skills/create-campaign/core/providers/prospeo.json +3 -2
- package/skills/create-campaign/references/provider-selection-strategy.md +66 -25
- package/skills/create-campaign-v2/SKILL.md +60 -24
- package/skills/create-campaign-v2/SOUL.md +11 -7
- package/skills/create-campaign-v2/core/flow.v2.json +67 -40
- package/skills/create-campaign-v2/references/sample-validation-loop.md +9 -5
- package/skills/create-campaign-v2/references/step-13-import-leads.md +10 -4
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +12 -7
- package/skills/create-campaign-v2/references/watch-guide-narration.md +16 -13
- package/skills/create-campaign-v2-tail/SKILL.md +24 -16
- package/skills/providers/apollo.md +8 -1
- package/skills/providers/prospeo.md +11 -1
- package/skills/providers/sales-nav.md +1 -1
- package/skills/research/config.json +9 -0
|
@@ -4,15 +4,16 @@ This reference governs Step 15 (`auto-execute-messaging`) re-cascade
|
|
|
4
4
|
behavior when Step 14's validate-sample loop graduates additional rows
|
|
5
5
|
from pending → passed after the first Generate Message cells have already run.
|
|
6
6
|
|
|
7
|
-
Load whenever Step 15 is about to transition
|
|
8
|
-
`awaiting-user-greenlight`, and on every resume into Step 15.
|
|
7
|
+
Load whenever Step 15 is about to ask for generated-message review or transition
|
|
8
|
+
to `awaiting-user-greenlight`, and on every resume into Step 15.
|
|
9
9
|
|
|
10
10
|
## Principle
|
|
11
11
|
|
|
12
|
-
Generate Message cells are cascade-scoped. If Step 14's rubric flips rows
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
Generate Message cells are cascade-scoped. If Step 14's rubric flips rows from
|
|
13
|
+
pending → passed AFTER Step 15 first observes messages for the review batch, the
|
|
14
|
+
new rows can sit pending with no message. That must not block the first review
|
|
15
|
+
handoff. Step 15 opens review as soon as one passing generated message exists;
|
|
16
|
+
late-passed rows can be re-cascaded after explicit user continuation or resume.
|
|
16
17
|
|
|
17
18
|
Observed on manual Phase-85 signal-discovery run (2026-04-20): 15 new
|
|
18
19
|
rows graduated pending → passed mid-tail while `messagesCount` stayed
|
|
@@ -22,13 +23,17 @@ flat at 257. The new rows never got messages.
|
|
|
22
23
|
|
|
23
24
|
Re-cascade runs whenever ALL of the following are true:
|
|
24
25
|
|
|
25
|
-
1.
|
|
26
|
+
1. The user has already approved the first generated message or explicitly asked
|
|
27
|
+
to continue processing more review-batch rows.
|
|
26
28
|
2. A subsequent check of rubric state shows rows that were pending at
|
|
27
29
|
first message-generation pass are now passed.
|
|
28
30
|
3. Those newly-passed rows do NOT yet have generated messages
|
|
29
31
|
(`messagesCount` flat relative to pre-cascade).
|
|
30
32
|
4. Step 15 has NOT yet transitioned to `awaiting-user-greenlight`.
|
|
31
33
|
|
|
34
|
+
Before that first generated-message approval, do not run this loop just to wait
|
|
35
|
+
for a bigger sample. One passing generated message is enough for review.
|
|
36
|
+
|
|
32
37
|
If condition 4 already fired (i.e. we're in Step 16), the re-cascade
|
|
33
38
|
runs on resume into Step 15 if validate-sample was re-entered and new
|
|
34
39
|
rows graduated.
|
|
@@ -194,10 +194,10 @@ After review batch import:
|
|
|
194
194
|
```json
|
|
195
195
|
{
|
|
196
196
|
"stage": "fit-message",
|
|
197
|
-
"headline": "
|
|
198
|
-
"visibleState": "
|
|
199
|
-
"agentIntent": "Codex is
|
|
200
|
-
"nextAction": "
|
|
197
|
+
"headline": "Filtering may not be needed",
|
|
198
|
+
"visibleState": "25 review leads are in the campaign table from 181 source candidates. Sample read: 23/25 look like senior target-role fits; 2 need cleanup or manual review. The browser is showing the filter-choice screen.",
|
|
199
|
+
"agentIntent": "Codex is not recommending filters because the sample already looks clean. Fit examples: Dave Kranowitz (Chief Revenue Officer); Marie Didominica (Head of Growth Marketing). Add filters only for a narrow exclusion.",
|
|
200
|
+
"nextAction": "Skip filters or add a narrow cleanup rule",
|
|
201
201
|
"workerStatuses": {
|
|
202
202
|
"leadFitBuilder": "idle",
|
|
203
203
|
"messageDraftBuilder": "running"
|
|
@@ -206,11 +206,13 @@ After review batch import:
|
|
|
206
206
|
```
|
|
207
207
|
|
|
208
208
|
Use this after the selected review rows are present and before filters are
|
|
209
|
-
saved.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
209
|
+
saved. The filter recommendation must be row-specific: say why filters are
|
|
210
|
+
recommended from the sample counts and examples, or say filtering may not be
|
|
211
|
+
needed when the visible review rows already look clean. This is a user decision
|
|
212
|
+
gate, not active filtering; do not say filtering the batch before rubrics and
|
|
213
|
+
message approval are saved. The Message Draft Builder should start immediately
|
|
214
|
+
after the bounded review batch exists; mark it running only when that branch
|
|
215
|
+
actually started.
|
|
214
216
|
When the user chooses filters, immediately persist `enableICPFilters: true` and
|
|
215
217
|
move to `create-icp-rubric` so the watched app shows Filter Rules while Codex
|
|
216
218
|
defines the rules in chat. After `save_rubrics`, move to `apply-icp-rubric`
|
|
@@ -252,16 +254,17 @@ Template approved, bounded filter test running:
|
|
|
252
254
|
"stage": "fit-message",
|
|
253
255
|
"headline": "Template saved",
|
|
254
256
|
"visibleState": "The browser stays on Filter Leads while the bounded enrichment and filter test runs.",
|
|
255
|
-
"agentIntent": "Codex saved the approved message template, queued the review-batch Enrich Prospect cells, and is waiting for
|
|
256
|
-
"nextAction": "
|
|
257
|
+
"agentIntent": "Codex saved the approved message template, queued the review-batch Enrich Prospect cells, and is waiting for one passing row with one generated message before moving to review.",
|
|
258
|
+
"nextAction": "Review the first passing generated message"
|
|
257
259
|
}
|
|
258
260
|
```
|
|
259
261
|
|
|
260
262
|
Do not move to Messages immediately after `approve-message`. The visible route
|
|
261
263
|
is already Filter Leads after `save_rubrics`; approving the message only unlocks
|
|
262
264
|
the bounded cascade from that screen. Move to Messages only once at least one
|
|
263
|
-
review-batch row passes and
|
|
264
|
-
|
|
265
|
+
review-batch row passes and one generated message is ready for review. Do not
|
|
266
|
+
wait for the rest of the review batch or a stronger sample before asking the
|
|
267
|
+
user to approve the generated message.
|
|
265
268
|
|
|
266
269
|
Messages waiting for template:
|
|
267
270
|
|
|
@@ -58,11 +58,12 @@ Step 14 — kick bounded cascade + observe sample
|
|
|
58
58
|
passing filtered row exists.)
|
|
59
59
|
|
|
60
60
|
Step 15 — observe messaging
|
|
61
|
-
|
|
61
|
+
wait_for_rubric_results({ minPassedCount: 1, minMessagesCount: 1, includeRows: false })
|
|
62
|
+
get_rows_minimal # confirm the first passing generated message exists
|
|
62
63
|
(rare) queue_cells on any pending Generate Message cells
|
|
63
64
|
token-contract spot check via get_rows
|
|
64
65
|
update_campaign(currentStep=auto-execute-messaging) with review-ready narration
|
|
65
|
-
ask the user to approve generated
|
|
66
|
+
ask the user to approve the generated message before Settings
|
|
66
67
|
only after approval: update_campaign(currentStep=awaiting-user-greenlight)
|
|
67
68
|
(generate_messages is NOT an MCP tool; messages come from the cascade)
|
|
68
69
|
|
|
@@ -291,8 +292,10 @@ Do not route to a visible `validate-sample` step. Full decision tree lives in
|
|
|
291
292
|
review batch only. After `save_rubrics` and the approved message template are
|
|
292
293
|
persisted, Step 14 queues the review-batch Enrich Prospect cells, waits until
|
|
293
294
|
filter results start landing, then moves to message observation as soon as one
|
|
294
|
-
row passes.
|
|
295
|
-
|
|
295
|
+
row passes. Step 15 opens review as soon as one passing generated message
|
|
296
|
+
exists. Do not wait for a larger or stronger sample once that first passing
|
|
297
|
+
message is ready. It does NOT call `check_rubric`,
|
|
298
|
+
`bulk_enrich_with_prospeo`, or any other direct enrichment/scoring tool.
|
|
296
299
|
|
|
297
300
|
Shape:
|
|
298
301
|
|
|
@@ -307,6 +310,7 @@ projectedPass = round(passInSample / sampleSize * importLimit)
|
|
|
307
310
|
if wait_for_rubric_results.ready === true and passRate.passed >= 1:
|
|
308
311
|
advance to Step 15 to observe or queue Generate Message for currently passing rows
|
|
309
312
|
do not wait for every sample row to finish before message generation starts
|
|
313
|
+
stop for review as soon as one passing generated message is ready
|
|
310
314
|
else if wait_for_rubric_results.ready === false and reason === "timeout":
|
|
311
315
|
use the partial passRate/stats as the sample diagnostic
|
|
312
316
|
if passRate.passed >= 1:
|
|
@@ -382,17 +386,20 @@ Template`. If it does not, fail before the cascade runs. Do not repair
|
|
|
382
386
|
already (cascade auto-fired it). If it is still `pending`, queue
|
|
383
387
|
it explicitly: `queue_cells({ tableId, cellIds:
|
|
384
388
|
<generateMessageCellIds> })`.
|
|
385
|
-
3. `
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
+
3. `wait_for_rubric_results({ tableId, targetCount: reviewBatchSize,
|
|
390
|
+
minPassedCount: 1, minMessagesCount: 1, includeRows: false })` until the
|
|
391
|
+
first passing generated message is ready. Do not wait for every passing row's
|
|
392
|
+
Generate Message cell, and do not add "one more wait" for a stronger sample.
|
|
393
|
+
Remaining review-batch rows can continue processing in the background.
|
|
394
|
+
4. Read the first ready generated message back via `get_rows` (full) and
|
|
395
|
+
sanity-check that sample against the Phase 84 token contract: no unresolved
|
|
389
396
|
`{{tokens}}`, no invented proof, one sentence per line, etc.
|
|
390
397
|
5. If the sample fails the token contract, diagnose brief-vs-list
|
|
391
398
|
(same revision loop as Step 14) and escalate if over
|
|
392
399
|
`maxRevisionRounds`.
|
|
393
|
-
6. On success, keep `currentStep: "auto-execute-messaging"` and ask the user
|
|
394
|
-
|
|
395
|
-
the campaign to Settings / `awaiting-user-greenlight`.
|
|
400
|
+
6. On success, keep `currentStep: "auto-execute-messaging"` and ask the user to
|
|
401
|
+
approve the generated message before continuing to Settings. Only that
|
|
402
|
+
approval may move the campaign to Settings / `awaiting-user-greenlight`.
|
|
396
403
|
|
|
397
404
|
**Do NOT hand-write message bodies via `update_cell`.** `update_cell`
|
|
398
405
|
is reachable for legitimate operator overrides AFTER the tail hands
|
|
@@ -432,15 +439,16 @@ strings, which is why Step 16 requires Step 15 to be complete.
|
|
|
432
439
|
4. Check `messaging.tokenContract`. When `strict`, reject any sample
|
|
433
440
|
message that contains unresolved or unsupported tokens (including
|
|
434
441
|
any critique rewrite that tried to introduce one).
|
|
435
|
-
5. If the
|
|
436
|
-
stop at the review-batch handoff. Do NOT
|
|
437
|
-
|
|
442
|
+
5. If the first passing generated message passes the token contract (and
|
|
443
|
+
critique when enabled), stop at the review-batch handoff. Do NOT wait for the
|
|
444
|
+
remaining review-batch rows and do NOT scale to the full source list before
|
|
445
|
+
explicit user expansion approval.
|
|
438
446
|
6. If the sample fails the token contract or critique, diagnose +
|
|
439
447
|
loop the same way Step 14 does (brief-vs-list), subject to the same
|
|
440
448
|
`maxRevisionRounds` cap.
|
|
441
449
|
7. On success, keep `currentStep: "auto-execute-messaging"`, show that the
|
|
442
|
-
|
|
443
|
-
Settings. Only after the user approves
|
|
450
|
+
first passing generated message is ready in Messages, and ask for approval
|
|
451
|
+
before Settings. Only after the user approves the generated message should
|
|
444
452
|
`update_campaign({ campaignId, currentStep: "awaiting-user-greenlight" })`
|
|
445
453
|
run.
|
|
446
454
|
|
|
@@ -378,7 +378,14 @@ search_apollo({
|
|
|
378
378
|
|
|
379
379
|
### ABM / Domain List Targeting
|
|
380
380
|
|
|
381
|
-
For
|
|
381
|
+
For campaign routing, supplied company-domain lists should go to Prospeo first
|
|
382
|
+
using `load_csv_domains` or `save_domain_filters`, then `domainFilterId`.
|
|
383
|
+
Apollo still supports `q_organization_domains_list` as a secondary/legacy
|
|
384
|
+
capability when the user explicitly chooses Apollo or needs an Apollo-only
|
|
385
|
+
filter such as a technographic constraint.
|
|
386
|
+
|
|
387
|
+
If Apollo is explicitly selected for account-based targeting, use
|
|
388
|
+
`q_organization_domains_list` to search specific companies:
|
|
382
389
|
|
|
383
390
|
```json
|
|
384
391
|
search_apollo({
|
|
@@ -62,7 +62,7 @@ search_prospeo({
|
|
|
62
62
|
- Pass `searchId` on subsequent pages to paginate.
|
|
63
63
|
- Use `import_leads` with `provider: \"prospeo\"` and the `searchId` to create a lead list and start import.
|
|
64
64
|
- **IMPORTANT:** If `import_leads` returns `needsModeSelection: true`, use `AskUserQuestion` to ask "add to existing leads or replace?" Do NOT assume.
|
|
65
|
-
- Default source target is
|
|
65
|
+
- Default source target is about 150 good-fit leads, capped at 2,500 source candidates for now.
|
|
66
66
|
- Apply the campaign source planning floor: the sampled/projected good-fit rate
|
|
67
67
|
after cleanup should be at least 10%. Prospeo is the terminal fallback; if the
|
|
68
68
|
best reasonable Prospeo lane is still below 10%, tighten the ICP/source
|
|
@@ -95,6 +95,11 @@ Prospeo filters are split into person vs company. Most filters use `include` / `
|
|
|
95
95
|
|
|
96
96
|
Preference rules:
|
|
97
97
|
|
|
98
|
+
- For hiring-led campaigns, use `company_job_posting_hiring_for` to target the
|
|
99
|
+
open-role themes and `company_job_posting_quantity` when the campaign needs
|
|
100
|
+
an active hiring floor. Pair those company hiring filters with buyer/referrer
|
|
101
|
+
person filters such as founders, GTM leaders, talent leaders, or revenue
|
|
102
|
+
owners.
|
|
98
103
|
- For ABM lists, use `load_csv_domains` + `domainFilterId` when the accounts are already in a CSV file on disk.
|
|
99
104
|
- For pasted/raw domain lists, use `save_domain_filters` + `domainFilterId` instead of inline domains or `company.websites.include`.
|
|
100
105
|
- If user input starts as company names, resolve names to domains first, then use `save_domain_filters`.
|
|
@@ -167,6 +172,11 @@ search_prospeo({
|
|
|
167
172
|
|
|
168
173
|
## When to Use Prospeo
|
|
169
174
|
|
|
175
|
+
- **Hiring-led targeting**: Find companies hiring for specific roles with
|
|
176
|
+
`company_job_posting_hiring_for` and `company_job_posting_quantity`, then
|
|
177
|
+
identify reachable buyer/referrer contacts at those companies
|
|
178
|
+
- **Account/domain targeting**: Use `domainFilterId` from `load_csv_domains` or
|
|
179
|
+
`save_domain_filters` for ABM searches
|
|
170
180
|
- **Email Finding**: Get verified work emails from LinkedIn URLs
|
|
171
181
|
- **Lead Enrichment**: Add company data, job history, and contact info to leads
|
|
172
182
|
- **Bulk Operations**: Enrich up to 100 leads at once
|
|
@@ -387,7 +387,7 @@ User: "Save it"
|
|
|
387
387
|
<limits>
|
|
388
388
|
- 25 results per page
|
|
389
389
|
- Maximum 100 pages (2,500 leads)
|
|
390
|
-
- Default source target:
|
|
390
|
+
- Default source target: about 150 good-fit leads, capped at 2,500 source
|
|
391
391
|
candidates for now
|
|
392
392
|
- Maximum 5 search calls per session
|
|
393
393
|
- If user needs more than 2,500: explain limit, suggest splitting by region
|