@sellable/mcp 0.1.148 → 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/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/tools/leads.d.ts +5 -1
- package/dist/tools/leads.js +192 -16
- package/dist/tools/prompts.js +3 -3
- package/dist/tools/readiness.js +18 -1
- package/dist/tools/registry.d.ts +2 -1
- package/dist/tools/rows.d.ts +1 -0
- package/dist/tools/rows.js +2 -0
- package/dist/tools/rubrics.js +2 -0
- 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 +56 -21
- package/skills/create-campaign-v2/SOUL.md +11 -7
- package/skills/create-campaign-v2/core/flow.v2.json +54 -33
- package/skills/create-campaign-v2/references/step-13-import-leads.md +15 -7
- package/skills/create-campaign-v2/references/watch-guide-narration.md +11 -9
- package/skills/providers/apollo.md +8 -1
- package/skills/providers/prospeo.md +11 -1
- package/skills/providers/sales-nav.md +1 -1
- package/skills/providers/signal-discovery.md +3 -0
|
@@ -588,20 +588,9 @@
|
|
|
588
588
|
]
|
|
589
589
|
},
|
|
590
590
|
{
|
|
591
|
-
"action": "
|
|
592
|
-
"
|
|
593
|
-
"
|
|
594
|
-
"requiresNonEmptyRows": true,
|
|
595
|
-
"mustRunBefore": [
|
|
596
|
-
"filter-choice question",
|
|
597
|
-
"filter approval",
|
|
598
|
-
"save_rubrics"
|
|
599
|
-
],
|
|
600
|
-
"mode": "background_when_host_supports_subagents",
|
|
601
|
-
"fallback": "if no real background branch can start, say the real sequence and do not claim background drafting is running",
|
|
602
|
-
"toolCallRequiredInBranch": "get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false",
|
|
603
|
-
"runtimeProofTransport": "CampaignOffer.watchNarration.workerDetails.messageDraftBuilder",
|
|
604
|
-
"purpose": "start the provisional message draft from the imported review batch immediately; do not defer this to filter approval"
|
|
591
|
+
"action": "summarize_review_batch_and_advance_to_filter_choice",
|
|
592
|
+
"purpose": "ask filter choice immediately; no post-lead registries, filter refs, or message prompts first",
|
|
593
|
+
"maxCustomerCopyLines": 4
|
|
605
594
|
}
|
|
606
595
|
],
|
|
607
596
|
"requiredCampaignState": [
|
|
@@ -611,8 +600,6 @@
|
|
|
611
600
|
],
|
|
612
601
|
"allowedTools": [
|
|
613
602
|
"get_subskill_prompt",
|
|
614
|
-
"get_subskill_asset",
|
|
615
|
-
"get_post_find_leads_scout_registry",
|
|
616
603
|
"import_leads",
|
|
617
604
|
"wait_for_lead_list_ready",
|
|
618
605
|
"confirm_lead_list",
|
|
@@ -620,16 +607,18 @@
|
|
|
620
607
|
"get_rows_minimal",
|
|
621
608
|
"update_campaign",
|
|
622
609
|
"AskUserQuestion",
|
|
623
|
-
"request_user_input"
|
|
624
|
-
"Task",
|
|
625
|
-
"spawn_agent"
|
|
610
|
+
"request_user_input"
|
|
626
611
|
],
|
|
627
612
|
"doNotAllow": [
|
|
613
|
+
"get_post_find_leads_scout_registry",
|
|
614
|
+
"Task",
|
|
615
|
+
"spawn_agent",
|
|
628
616
|
"list_senders",
|
|
629
617
|
"queue_cells",
|
|
630
618
|
"start_campaign",
|
|
631
619
|
"enrich_with_prospeo",
|
|
632
|
-
"bulk_enrich_with_prospeo"
|
|
620
|
+
"bulk_enrich_with_prospeo",
|
|
621
|
+
"save_rubrics"
|
|
633
622
|
],
|
|
634
623
|
"waitFor": "review_batch_imported",
|
|
635
624
|
"transitions": {
|
|
@@ -659,6 +648,13 @@
|
|
|
659
648
|
]
|
|
660
649
|
}
|
|
661
650
|
],
|
|
651
|
+
"hardRules": [
|
|
652
|
+
"ask_filter_choice_immediately_after_review_batch_import",
|
|
653
|
+
"do_not_call_get_subskill_prompt_before_filter_choice",
|
|
654
|
+
"do_not_call_get_subskill_asset_before_filter_choice",
|
|
655
|
+
"do_not_call_get_post_find_leads_scout_registry_before_filter_choice",
|
|
656
|
+
"do_not_spawn_post_lead_agents_before_filter_choice"
|
|
657
|
+
],
|
|
662
658
|
"requiredCampaignState": [
|
|
663
659
|
"campaignId",
|
|
664
660
|
"campaignBrief",
|
|
@@ -672,6 +668,11 @@
|
|
|
672
668
|
"get_campaign_navigation_state"
|
|
673
669
|
],
|
|
674
670
|
"doNotAllow": [
|
|
671
|
+
"get_subskill_prompt",
|
|
672
|
+
"get_subskill_asset",
|
|
673
|
+
"get_post_find_leads_scout_registry",
|
|
674
|
+
"Task",
|
|
675
|
+
"spawn_agent",
|
|
675
676
|
"create_campaign",
|
|
676
677
|
"list_senders",
|
|
677
678
|
"import_leads",
|
|
@@ -693,7 +694,7 @@
|
|
|
693
694
|
},
|
|
694
695
|
{
|
|
695
696
|
"id": "post-lead-workstreams",
|
|
696
|
-
"label": "Filter
|
|
697
|
+
"label": "Filter workstream",
|
|
697
698
|
"onEnter": [
|
|
698
699
|
{
|
|
699
700
|
"action": "persist_add_filters_approval",
|
|
@@ -715,17 +716,18 @@
|
|
|
715
716
|
},
|
|
716
717
|
"mustRunBefore": [
|
|
717
718
|
"get_post_find_leads_scout_registry",
|
|
718
|
-
"
|
|
719
|
+
"launch_lead_fit_builder_after_filter_choice",
|
|
719
720
|
"save_rubrics"
|
|
720
721
|
]
|
|
721
722
|
},
|
|
722
723
|
{
|
|
723
724
|
"tool": "get_post_find_leads_scout_registry",
|
|
724
|
-
"purpose": "load canonical post-lead worker names"
|
|
725
|
+
"purpose": "load canonical post-lead worker names only after the user has chosen filters"
|
|
725
726
|
},
|
|
726
727
|
{
|
|
727
|
-
"action": "
|
|
728
|
+
"action": "launch_lead_fit_builder_after_filter_choice",
|
|
728
729
|
"mode": "parallel_when_host_supports_subagents",
|
|
730
|
+
"target": "post-find-leads-filter-scout",
|
|
729
731
|
"inputs": [
|
|
730
732
|
"campaignId",
|
|
731
733
|
"campaignBrief",
|
|
@@ -734,9 +736,16 @@
|
|
|
734
736
|
"reviewBatchRowIds/hash",
|
|
735
737
|
"filterChoice"
|
|
736
738
|
],
|
|
737
|
-
"stateSource": "
|
|
738
|
-
"debugFilesOptionalOnly": true
|
|
739
|
-
|
|
739
|
+
"stateSource": "live campaign/table",
|
|
740
|
+
"debugFilesOptionalOnly": true
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
"action": "launch_message_draft_builder_after_filter_decision",
|
|
744
|
+
"mode": "parallel_when_host_supports_subagents",
|
|
745
|
+
"target": "post-find-leads-message-scout",
|
|
746
|
+
"when": "filters_enabled",
|
|
747
|
+
"doesNotQueueCells": true,
|
|
748
|
+
"customerNarration": "Say message agent is drafting."
|
|
740
749
|
},
|
|
741
750
|
{
|
|
742
751
|
"action": "save_filter_rubrics_to_campaign",
|
|
@@ -793,10 +802,13 @@
|
|
|
793
802
|
"hardRules": [
|
|
794
803
|
"after_save_rubrics_currentStep_must_be_apply-icp-rubric",
|
|
795
804
|
"do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped",
|
|
796
|
-
"
|
|
805
|
+
"no_post_lead_worker_or_deep_prompt_before_filter_choice",
|
|
806
|
+
"lead_fit_builder_starts_only_after_filters_enabled",
|
|
807
|
+
"msg_draft_after_filter_choice",
|
|
808
|
+
"msg_draft_no_cells"
|
|
797
809
|
],
|
|
798
810
|
"transitions": {
|
|
799
|
-
"post_lead_workstreams_ready": "message-
|
|
811
|
+
"post_lead_workstreams_ready": "message-generation",
|
|
800
812
|
"revise_leads": "find-leads",
|
|
801
813
|
"revise_rubric": "filter-rubric",
|
|
802
814
|
"revise_messaging": "message-generation",
|
|
@@ -865,14 +877,23 @@
|
|
|
865
877
|
"id": "message-generation",
|
|
866
878
|
"label": "Message generation",
|
|
867
879
|
"onEnter": [
|
|
880
|
+
{
|
|
881
|
+
"action": "set_message_review_visible_step_by_filter_choice",
|
|
882
|
+
"tool": "update_campaign",
|
|
883
|
+
"branchRules": [
|
|
884
|
+
"yes: currentStep=apply-icp-rubric; wait on Filter Leads",
|
|
885
|
+
"no: currentStep=messages; message review"
|
|
886
|
+
],
|
|
887
|
+
"watchNarration.stage": "fit-message"
|
|
888
|
+
},
|
|
868
889
|
{
|
|
869
890
|
"action": "run_or_reconcile_message_draft_builder",
|
|
870
891
|
"target": "post-find-leads-message-scout",
|
|
871
892
|
"toolCallRequiredBeforeDraft": [
|
|
872
893
|
"get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false",
|
|
873
|
-
"
|
|
894
|
+
"parent approval uses references/message-review-safety-gate.md only"
|
|
874
895
|
],
|
|
875
|
-
"stateSource": "campaignBrief,
|
|
896
|
+
"stateSource": "campaignBrief, source, selectedLeadListId, workflowTableId, review-batch row ids/hash",
|
|
876
897
|
"outputState": "messageDraftRecommendation"
|
|
877
898
|
}
|
|
878
899
|
],
|
|
@@ -887,11 +908,12 @@
|
|
|
887
908
|
"get_subskill_asset",
|
|
888
909
|
"get_campaign",
|
|
889
910
|
"get_rows_minimal",
|
|
911
|
+
"update_campaign",
|
|
890
912
|
"AskUserQuestion",
|
|
891
913
|
"request_user_input"
|
|
892
914
|
],
|
|
893
915
|
"toolRules": [
|
|
894
|
-
"
|
|
916
|
+
"Message Draft Builder loads full get_subskill_prompt({ subskillName: \"generate-messages\" }) from live state. Parent approval uses message-review-safety-gate only.",
|
|
895
917
|
"Do not use brief.md, lead-review.md, or lead-sample.json as required live state; those files are optional debug context only.",
|
|
896
918
|
"The compact messageDraftRecommendation must return templateRecommendation, tokenFillRules, renderedSample, concerns, status, basisToken, outputAt, outputHash, and error or retry detail.",
|
|
897
919
|
"If campaign/source/table/review-batch basis does not match, classify the output stale or blocked."
|
|
@@ -902,7 +924,6 @@
|
|
|
902
924
|
"save_rubrics",
|
|
903
925
|
"import_leads",
|
|
904
926
|
"confirm_lead_list",
|
|
905
|
-
"update_campaign",
|
|
906
927
|
"queue_cells",
|
|
907
928
|
"start_campaign",
|
|
908
929
|
"generate_messages"
|
|
@@ -106,7 +106,7 @@ fills the source lead list; it does **not** clone rows into the campaign table:
|
|
|
106
106
|
```text
|
|
107
107
|
import_leads({
|
|
108
108
|
campaignOfferId,
|
|
109
|
-
targetLeadCount: <sourceCandidateTarget
|
|
109
|
+
targetLeadCount: <sourceCandidateTarget from approved good-fit math>,
|
|
110
110
|
// Signal Discovery only:
|
|
111
111
|
targetEngagerCount: <ceil(targetGoodFitLeads / sampledFitRateAfterCleanup)>,
|
|
112
112
|
maxPostsToScrape: <postsNeeded from approved math>
|
|
@@ -114,9 +114,15 @@ import_leads({
|
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
Provider is inherited from the selected source decision (not re-selected here)
|
|
117
|
-
and should already be saved on the campaign before import.
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
and should already be saved on the campaign before import. For Sales Nav and
|
|
118
|
+
Prospeo, `<sourceCandidateTarget>` is not the 25-row review batch. It is the
|
|
119
|
+
source-list export/materialization count from the approved source math:
|
|
120
|
+
`min(rawResultCount, providerMax, ceil(targetGoodFitLeads /
|
|
121
|
+
projectedFitRateAfterCleanup))`. If projected good fits remain below the target
|
|
122
|
+
(often about 150+ usable prospects unless the campaign/source defaults specify
|
|
123
|
+
otherwise), return to find-leads and refine filters before import. Response
|
|
124
|
+
returns `{ imported, skipped, duplicates }` — surface all three to the
|
|
125
|
+
escalation logic so dedup ratios are visible.
|
|
120
126
|
|
|
121
127
|
For Signal Discovery, do not scrape every currently selected/promoted sample
|
|
122
128
|
post by default. Before `import_leads`, reconcile selected posts with the
|
|
@@ -127,9 +133,11 @@ rate with a conservative cleanup factor, cap the source candidates at the
|
|
|
127
133
|
approved provider limit, and select only enough posts to reach that engager
|
|
128
134
|
count. The planning floor is 10% projected fit after cleanup; if Signal
|
|
129
135
|
Discovery falls below that floor, do not import the source list. Route back to
|
|
130
|
-
find-leads and move to Sales Nav recent activity instead.
|
|
131
|
-
`
|
|
132
|
-
|
|
136
|
+
find-leads and move to Sales Nav recent activity instead. After the scrape,
|
|
137
|
+
`wait_for_lead_list_ready` must clear the approved source-candidate target; if
|
|
138
|
+
it reports `source_under_capacity`, do not call `confirm_lead_list`. The
|
|
139
|
+
subsequent `confirm_lead_list` call still uses `targetLeadCount: <importLimit>`
|
|
140
|
+
so only the bounded review batch enters the campaign table.
|
|
133
141
|
|
|
134
142
|
For supplied direct lists, `confirm_lead_list` must receive
|
|
135
143
|
`targetLeadCount: <importLimit>` or explicit `sourceRowIds` so a 100-row source
|
|
@@ -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`
|
|
@@ -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
|
|
@@ -459,6 +459,9 @@ targetLeadCount, targetEngagerCount, maxPostsToScrape })` for the approved
|
|
|
459
459
|
source-capacity plan without asking for another yes/no gate. Then
|
|
460
460
|
`confirm_lead_list` imports only the bounded review batch into the campaign
|
|
461
461
|
table. Do not confuse the source-candidate target with the review-batch size.
|
|
462
|
+
If the completed source scrape comes back below the approved source-candidate
|
|
463
|
+
target, do not call `confirm_lead_list`; select more posts, rerun source
|
|
464
|
+
discovery, or move to Sales Nav.
|
|
462
465
|
|
|
463
466
|
The promotion/select step is required campaign state. Use post IDs from the
|
|
464
467
|
current campaign-scoped search result, not stale IDs copied from a source review
|