@sellable/mcp 0.1.145 → 0.1.147
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/agents/post-find-leads-message-scout.md +8 -14
- package/agents/source-scout-linkedin-engagement.md +7 -3
- package/agents/source-scout-prospeo-contact.md +4 -1
- package/agents/source-scout-sales-nav.md +5 -0
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/tools/leads.js +18 -8
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +5 -2
- package/skills/create-campaign-v2/SKILL.md +15 -2
- package/skills/create-campaign-v2/SOUL.md +12 -3
- package/skills/create-campaign-v2/core/flow.v2.json +25 -3
- package/skills/create-campaign-v2/references/message-review-safety-gate.md +22 -44
- package/skills/create-campaign-v2/references/step-13-import-leads.md +8 -4
- package/skills/find-leads/SKILL.md +9 -0
- package/skills/providers/prospeo.md +4 -0
- package/skills/providers/sales-nav.md +5 -0
- package/skills/providers/signal-discovery.md +12 -3
- package/skills/research/config.json +0 -9
|
@@ -137,8 +137,12 @@ Return a concise status with:
|
|
|
137
137
|
- quality-gate pass/fail summary
|
|
138
138
|
- whether final template review is ready or needs revision
|
|
139
139
|
|
|
140
|
-
When the parent will show the recommendation in chat,
|
|
141
|
-
message review
|
|
140
|
+
When the parent will show the recommendation in chat, keep the customer-facing
|
|
141
|
+
message review lightweight. Format only the approval target and one strong
|
|
142
|
+
good-fill example as Markdown with distinct copy blocks. Keep token rules,
|
|
143
|
+
omit/fallback examples, and bad-fill avoidance notes in your internal
|
|
144
|
+
recommendation so the parent can persist them to the campaign brief after
|
|
145
|
+
approval; do not print them in the default chat approval packet.
|
|
142
146
|
|
|
143
147
|
````markdown
|
|
144
148
|
## Message Template
|
|
@@ -155,19 +159,9 @@ message review as Markdown with distinct copy blocks:
|
|
|
155
159
|
{{tokenized_message_body}}
|
|
156
160
|
```
|
|
157
161
|
|
|
158
|
-
## Rendered
|
|
162
|
+
## Rendered Example
|
|
159
163
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
```text
|
|
163
|
-
Subject: ...
|
|
164
|
-
|
|
165
|
-
Hey First,
|
|
166
|
-
|
|
167
|
-
...
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Good omit / fallback
|
|
164
|
+
Good token fill:
|
|
171
165
|
|
|
172
166
|
```text
|
|
173
167
|
Subject: ...
|
|
@@ -57,7 +57,8 @@ currentStep: "signal-discovery" })` before sampling so the watched Signal
|
|
|
57
57
|
leads per 100 engagers before and after a conservative dedupe/cleanup
|
|
58
58
|
factor, required engagers to scrape (`source target / fit rate`), average
|
|
59
59
|
reachable engagers per right-content post, expected usable leads per
|
|
60
|
-
right-content post after dedupe/cleanup,
|
|
60
|
+
right-content post after dedupe/cleanup, posts needed to hit the target, and
|
|
61
|
+
whether sampled/projected fit clears the 10% planning floor.
|
|
61
62
|
8. Select/promote enough right-content posts to plausibly hit the target. If the
|
|
62
63
|
warm Signals pool is useful but too small, return the expected warm range and
|
|
63
64
|
recommend Sales Nav/Prospeo for scale instead of padding with noisy posts.
|
|
@@ -74,8 +75,9 @@ Return a concise structured result with:
|
|
|
74
75
|
engagers, ICP-fit rate as `n/N` plus percentage/range, good-fit prospects per
|
|
75
76
|
100 engagers, required engagers to scrape, average reachable engagers per
|
|
76
77
|
post, expected usable prospects per post after cleanup, posts needed for
|
|
77
|
-
target,
|
|
78
|
-
range, and scale
|
|
78
|
+
target, whether the 10% planning floor clears after cleanup, selected post
|
|
79
|
+
count, review-batch import limit, expected usable lead range, and scale
|
|
80
|
+
fallback
|
|
79
81
|
- `estimated_good_fit_range`
|
|
80
82
|
- `message_context_strength`, directional and source-specific
|
|
81
83
|
- `false_positive_patterns`
|
|
@@ -99,3 +101,5 @@ Evidence standards:
|
|
|
99
101
|
bounded review batch.
|
|
100
102
|
- If `fetch_post_engagers` is unavailable or fails, report that explicitly and mark the estimate lower-confidence.
|
|
101
103
|
- Keep LinkedIn Engagement viable when selected posts can produce roughly 150+ ICP-fit warm prospects before final filtering, even if Sales Nav is more scalable.
|
|
104
|
+
- If sampled/projected fit after cleanup is below 10%, reject the Signals scrape
|
|
105
|
+
path and recommend Sales Nav recent activity as the next source.
|
|
@@ -27,7 +27,7 @@ Process:
|
|
|
27
27
|
1. Read the campaign brief, source intake, kickoff doc, or lane prompt supplied by the parent.
|
|
28
28
|
2. Identify whether this is domain/account targeting or broad persona expansion.
|
|
29
29
|
3. For domain targeting, use or create the standalone `domainFilterId` before searching; never pass raw domains directly into `search_prospeo`.
|
|
30
|
-
4. Run the narrowest useful Prospeo people preview and 1-2 refinements if quality or scale is unclear. Check scale against a default 300+ good-fit target, capped at 2,500 source candidates unless the parent supplies a different target.
|
|
30
|
+
4. Run the narrowest useful Prospeo people preview and 1-2 refinements if quality or scale is unclear. Check scale against a default 300+ good-fit target, capped at 2,500 source candidates unless the parent supplies a different target, and require at least 10% projected good-fit after cleanup.
|
|
31
31
|
5. Call out that Prospeo gives contact/account coverage but usually weaker LinkedIn intent than LinkedIn Engagement or Sales Nav activity slices.
|
|
32
32
|
|
|
33
33
|
Return a concise structured result with:
|
|
@@ -50,4 +50,7 @@ Evidence standards:
|
|
|
50
50
|
|
|
51
51
|
- Never pass raw domains, company website arrays, or company-name arrays into `search_prospeo`.
|
|
52
52
|
- If the user supplied company names rather than domains, report that domain resolution is required before this lane can run safely.
|
|
53
|
+
- Prospeo is the terminal fallback. If projected good-fit after cleanup remains
|
|
54
|
+
below 10% after reasonable refinement, recommend tightening the ICP/source
|
|
55
|
+
direction rather than switching providers again.
|
|
53
56
|
- Treat Prospeo as an account/contact coverage lane, not as proof of fresh LinkedIn intent.
|
|
@@ -35,6 +35,9 @@ Process:
|
|
|
35
35
|
Loosen nonessential filters in order: remove recent-activity first, widen
|
|
36
36
|
adjacent title variants, widen geography/company-size constraints, and only
|
|
37
37
|
keep hard ICP requirements from the brief.
|
|
38
|
+
Also check the 10% planning floor after cleanup. If the best reasonable
|
|
39
|
+
Sales Nav lane remains below 10% projected good-fit, move to Prospeo instead
|
|
40
|
+
of recommending Sales Nav.
|
|
38
41
|
6. Run the baseline plus 1-2 refinements or loosening passes if the first pass
|
|
39
42
|
is noisy or under-scaled. Label the final pool as constrained if it still
|
|
40
43
|
cannot plausibly reach the target after loosening.
|
|
@@ -69,5 +72,7 @@ Evidence standards:
|
|
|
69
72
|
larger than the warm-post path. If Sales Nav is offered for scale, it should
|
|
70
73
|
either project to the target good-fit count or clearly say it is too tight and
|
|
71
74
|
name the next broadening/Prospeo option.
|
|
75
|
+
- If projected good-fit after cleanup is below 10%, do not recommend Sales Nav
|
|
76
|
+
as the winning source; recommend Prospeo as the next provider.
|
|
72
77
|
- Do not hand-wave missing filter IDs.
|
|
73
78
|
- If Sales Nav returns a giant unfiltered pool, discard that result and retry with valid filters before recommending it.
|
package/dist/index-dev.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/tools/leads.js
CHANGED
|
@@ -31,6 +31,9 @@ const defaultCampaignSourceDefaults = {
|
|
|
31
31
|
defaultSize: 25,
|
|
32
32
|
minProjectedPass: 5,
|
|
33
33
|
},
|
|
34
|
+
planning: {
|
|
35
|
+
minFitRate: 0.1,
|
|
36
|
+
},
|
|
34
37
|
providers: {
|
|
35
38
|
"signal-discovery": {
|
|
36
39
|
targetGoodFitLeads: 150,
|
|
@@ -280,6 +283,10 @@ function loadCampaignSourceDefaults() {
|
|
|
280
283
|
...defaultCampaignSourceDefaults.reviewBatch,
|
|
281
284
|
...(parsed.reviewBatch ?? {}),
|
|
282
285
|
},
|
|
286
|
+
planning: {
|
|
287
|
+
...defaultCampaignSourceDefaults.planning,
|
|
288
|
+
...(parsed.planning ?? {}),
|
|
289
|
+
},
|
|
283
290
|
providers: {
|
|
284
291
|
...defaultCampaignSourceDefaults.providers,
|
|
285
292
|
...(parsed.providers ?? {}),
|
|
@@ -297,6 +304,7 @@ function getSignalDiscoverySourcePlanDefaults() {
|
|
|
297
304
|
return {
|
|
298
305
|
targetGoodFitLeads: signalDefaults.targetGoodFitLeads,
|
|
299
306
|
defaultFitRate: signalDefaults.defaultFitRate,
|
|
307
|
+
minPlanningFitRate: defaults.planning.minFitRate,
|
|
300
308
|
sourceCandidateTarget,
|
|
301
309
|
reviewBatchSize: defaults.reviewBatch.defaultSize,
|
|
302
310
|
};
|
|
@@ -499,17 +507,18 @@ function buildSourceImportWatchNarration({ provider, selectedPostCount, estimate
|
|
|
499
507
|
: ""}`
|
|
500
508
|
: `the approved ${providerLabel} source`;
|
|
501
509
|
const targetDetail = typeof targetLeadCount === "number"
|
|
502
|
-
? ` Targeting ${targetLeadCount.toLocaleString("en-US")} source
|
|
510
|
+
? ` Targeting ${targetLeadCount.toLocaleString("en-US")} source leads before the bounded review batch is cloned.`
|
|
503
511
|
: "";
|
|
504
512
|
return {
|
|
505
|
-
stage: "
|
|
513
|
+
stage: "find-leads",
|
|
506
514
|
headline: provider === "signal-discovery"
|
|
507
|
-
? "Scraping source
|
|
508
|
-
: "Importing source
|
|
515
|
+
? "Scraping source leads from posts"
|
|
516
|
+
: "Importing source leads",
|
|
509
517
|
visibleState: `The browser is showing ${providerLabel} import progress for ${sourceDetail}.${targetDetail}`,
|
|
510
518
|
agentIntent: "Codex is materializing the approved source into a lead list before cloning only the bounded review batch into the campaign.",
|
|
511
|
-
nextAction: "Wait for source
|
|
519
|
+
nextAction: "Wait for source leads, then import the 15-row review batch",
|
|
512
520
|
safety: "Import is limited to the review batch.",
|
|
521
|
+
progressLabel: "Source scouting",
|
|
513
522
|
};
|
|
514
523
|
}
|
|
515
524
|
function buildSourceImportRecoveryWatchNarration(args) {
|
|
@@ -601,7 +610,7 @@ function formatApproxInteger(value) {
|
|
|
601
610
|
return `~${rounded.toLocaleString("en-US")}`;
|
|
602
611
|
}
|
|
603
612
|
function buildSignalDiscoverySourceRecommendation({ selectedPosts, }) {
|
|
604
|
-
const { targetGoodFitLeads, defaultFitRate, sourceCandidateTarget, reviewBatchSize, } = getSignalDiscoverySourcePlanDefaults();
|
|
613
|
+
const { targetGoodFitLeads, defaultFitRate, minPlanningFitRate, sourceCandidateTarget, reviewBatchSize, } = getSignalDiscoverySourcePlanDefaults();
|
|
605
614
|
const selectedCount = selectedPosts.length;
|
|
606
615
|
const totalEngagement = selectedPosts.reduce((sum, post) => sum + (post.likes ?? 0) + (post.comments ?? 0), 0);
|
|
607
616
|
const tableRows = selectedPosts
|
|
@@ -617,6 +626,7 @@ Use Signal Discovery first.
|
|
|
617
626
|
|
|
618
627
|
**Good-fit target:** ~${targetGoodFitLeads.toLocaleString("en-US")} prospects after cleanup, enrichment, and filters<br>
|
|
619
628
|
**Source-candidate plan:** scrape ~${sourceCandidateTarget.toLocaleString("en-US")} raw engagers using a conservative ${Math.round(defaultFitRate * 100)}% fit-rate assumption<br>
|
|
629
|
+
**Planning floor:** continue with Signal Discovery only when sampled/projected fit is at least ${Math.round(minPlanningFitRate * 100)}% after cleanup; below that, switch to Sales Nav recent activity<br>
|
|
620
630
|
**Review checkpoint:** import the first ${reviewBatchSize.toLocaleString("en-US")} leads into the campaign for fit and message review before scaling
|
|
621
631
|
|
|
622
632
|
### Selected posts
|
|
@@ -636,7 +646,7 @@ This gives enough volume to work toward ~${targetGoodFitLeads.toLocaleString("en
|
|
|
636
646
|
|
|
637
647
|
**First pass:** build the source list, then import only the ${reviewBatchSize.toLocaleString("en-US")}-lead review batch so we can inspect fit and messages before scaling.
|
|
638
648
|
|
|
639
|
-
**Fallback:** if the review batch is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent activity.
|
|
649
|
+
**Fallback:** if the sampled/projected fit rate is below ${Math.round(minPlanningFitRate * 100)}%, or if the review batch is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent activity.
|
|
640
650
|
|
|
641
651
|
Approval card should say:
|
|
642
652
|
|
|
@@ -1222,7 +1232,7 @@ export const leadToolDefinitions = [
|
|
|
1222
1232
|
},
|
|
1223
1233
|
targetEngagerCount: {
|
|
1224
1234
|
type: "number",
|
|
1225
|
-
description: "Signal Discovery: target number of post engagers/source candidates to scrape. Compute from source target good-fit leads / sampled fit rate; e.g. 150 good fits at 15% fit requires about 1000 engagers. Limits selected posts before starting scrape.",
|
|
1235
|
+
description: "Signal Discovery: target number of post engagers/source candidates to scrape. Compute from source target good-fit leads / sampled fit rate; e.g. 150 good fits at 15% fit requires about 1000 engagers. If the sampled/projected fit rate is below the 10% planning floor after cleanup, switch to the next provider instead of scaling noisy engagers. Limits selected posts before starting scrape.",
|
|
1226
1236
|
},
|
|
1227
1237
|
maxPostsToScrape: {
|
|
1228
1238
|
type: "number",
|
package/package.json
CHANGED
|
@@ -155,14 +155,17 @@ should be a compact `## Source Recommendation` block with:
|
|
|
155
155
|
- good-fit target: about 150 prospects after cleanup, enrichment, and filters
|
|
156
156
|
- source-candidate plan: about 1,000 raw engagers using a conservative 15%
|
|
157
157
|
fit-rate assumption unless sampled data supports a different number
|
|
158
|
+
- planning floor: continue with Signal Discovery only when sampled/projected
|
|
159
|
+
fit is at least 10% after cleanup; below that, move to Sales Nav recent
|
|
160
|
+
activity instead of scraping noisy engagers
|
|
158
161
|
- review checkpoint: import the first 25 leads for fit and message review
|
|
159
162
|
- a selected-post table with post author/topic, why it fits, and visible
|
|
160
163
|
engagement
|
|
161
164
|
- total visible pool and estimated good-fit pool
|
|
162
165
|
- first pass: build the source list, then import only the review
|
|
163
166
|
batch
|
|
164
|
-
- fallback: switch to Sales Nav recent activity if
|
|
165
|
-
vendor-heavy, agency-heavy, or off-ICP
|
|
167
|
+
- fallback: switch to Sales Nav recent activity if sampled/projected fit falls
|
|
168
|
+
below 10%, or if the review batch is vendor-heavy, agency-heavy, or off-ICP
|
|
166
169
|
|
|
167
170
|
When the user has not supplied a source and multiple source angles are viable,
|
|
168
171
|
scout those angles as independent branches when the host can actually do it:
|
|
@@ -149,6 +149,11 @@ sequential by default. Run `source-scout-linkedin-engagement`,
|
|
|
149
149
|
`source-scout-sales-nav`, and `source-scout-prospeo-contact` in parallel only
|
|
150
150
|
when the user explicitly requested source comparison, a prior lane failed, or
|
|
151
151
|
the first viable lane is borderline and a cheap fallback check is needed.
|
|
152
|
+
Use a 10% planning floor after conservative cleanup. If Signal Discovery falls
|
|
153
|
+
below that floor, move to Sales Nav. If Sales Nav falls below that floor after
|
|
154
|
+
reasonable refinement, move to Prospeo. Prospeo is the terminal fallback; if it
|
|
155
|
+
also falls below 10%, tighten the ICP/source direction instead of inventing
|
|
156
|
+
another provider.
|
|
152
157
|
|
|
153
158
|
After scouting, show a second approval gate for the concrete source action. For
|
|
154
159
|
Signal Discovery, this gate must say how many selected posts will be scraped,
|
|
@@ -158,6 +163,12 @@ approval label must describe the action with the count, such as "Approve
|
|
|
158
163
|
scraping 3 Signal Discovery posts?" For Sales Nav or Prospeo, the label should
|
|
159
164
|
name the specific search/import lane. Do not call `import_leads` or
|
|
160
165
|
`confirm_lead_list` until this second source-action approval is granted.
|
|
166
|
+
After the user approves this concrete source-action gate, do not show the
|
|
167
|
+
Source Recommendation again and do not ask another source approval question.
|
|
168
|
+
Acknowledge once, then call `import_leads` immediately with the approved source
|
|
169
|
+
math. For Signal Discovery, pass `provider: "signal-discovery"`,
|
|
170
|
+
`targetEngagerCount`, `maxPostsToScrape`, and `confirmed: true`; the tool owns
|
|
171
|
+
moving the watch UI to source-list progress after a lead-list/job id exists.
|
|
161
172
|
|
|
162
173
|
For Signal Discovery, use this compact source-action approval shape after
|
|
163
174
|
selected posts exist:
|
|
@@ -169,6 +180,7 @@ Use Signal Discovery first.
|
|
|
169
180
|
|
|
170
181
|
**Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
|
|
171
182
|
**Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
|
|
183
|
+
**Planning floor:** continue only when sampled/projected fit is at least 10% after cleanup; below that, switch to Sales Nav recent activity<br>
|
|
172
184
|
**Review checkpoint:** import the first 25 leads into the campaign for fit and message review before scaling<br>
|
|
173
185
|
|
|
174
186
|
### Selected posts
|
|
@@ -193,8 +205,9 @@ AI-native sales workflows.
|
|
|
193
205
|
**First pass:** build the source list, then import only the 25-lead review
|
|
194
206
|
batch so we can inspect fit and messages before scaling.
|
|
195
207
|
|
|
196
|
-
**Fallback:** if
|
|
197
|
-
off-ICP, switch to Sales Nav recent
|
|
208
|
+
**Fallback:** if sampled/projected fit falls below 10%, or if the review batch
|
|
209
|
+
is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent
|
|
210
|
+
activity.
|
|
198
211
|
```
|
|
199
212
|
|
|
200
213
|
A source recommendation must show concrete evidence: source lane, filters or
|
|
@@ -239,9 +239,13 @@ for source approval before import.
|
|
|
239
239
|
For Signal Discovery, the second gate is not "approve source" in the abstract.
|
|
240
240
|
It is a concrete scrape approval: show a compact `## Source Recommendation`
|
|
241
241
|
with the ~150 good-fit prospect goal, 15% raw-engager assumption, selected-post
|
|
242
|
-
table, total visible pool, estimated good-fit pool,
|
|
243
|
-
batch, and fallback. The approval question should be "Approve
|
|
244
|
-
Discovery posts?"
|
|
242
|
+
table, total visible pool, estimated good-fit pool, 10% planning floor,
|
|
243
|
+
first-pass review batch, and fallback. The approval question should be "Approve
|
|
244
|
+
scraping N Signal Discovery posts?"
|
|
245
|
+
|
|
246
|
+
That scrape approval is single-use. Once the user approves it, do not replay
|
|
247
|
+
the source card or ask for the same approval again. Acknowledge the approval in
|
|
248
|
+
one sentence and call `import_leads` for the approved source immediately.
|
|
245
249
|
|
|
246
250
|
## Parallelism + Naming
|
|
247
251
|
|
|
@@ -253,6 +257,11 @@ borderline and needs a second source to avoid a bad recommendation. The fallback
|
|
|
253
257
|
order must stay plain: use Sales Nav to find ICP people who are actively posting
|
|
254
258
|
on LinkedIn; if that is not enough, search Sales Nav by titles; if that is still
|
|
255
259
|
not enough, use Prospeo for a broader account/contact path.
|
|
260
|
+
Use a 10% planning floor after conservative cleanup. If Signal Discovery falls
|
|
261
|
+
below that floor, move to Sales Nav. If Sales Nav falls below that floor after
|
|
262
|
+
reasonable refinement, move to Prospeo. Prospeo is the terminal fallback; if it
|
|
263
|
+
also falls below 10%, tighten the ICP/source direction instead of inventing
|
|
264
|
+
another provider.
|
|
256
265
|
|
|
257
266
|
Source-angle comparison should be real, not implied. Call
|
|
258
267
|
`get_source_scout_registry` before dispatching source scouts and use the
|
|
@@ -485,6 +485,16 @@
|
|
|
485
485
|
"signal-discovery": "Approve scraping {selectedPostCount} Signal Discovery posts?",
|
|
486
486
|
"sales-nav": "Import the approved Sales Nav review batch",
|
|
487
487
|
"prospeo": "Import the approved Prospeo review batch"
|
|
488
|
+
},
|
|
489
|
+
"postApprovalContract": {
|
|
490
|
+
"singleUseApproval": true,
|
|
491
|
+
"doNotRepeatAfterApproval": [
|
|
492
|
+
"Source Recommendation",
|
|
493
|
+
"show_source_decision_card",
|
|
494
|
+
"ask_source_review_choice"
|
|
495
|
+
],
|
|
496
|
+
"requiredNextActionAfterApproval": "acknowledge in one sentence, then call import_leads immediately",
|
|
497
|
+
"signalDiscoveryNextTool": "import_leads({ campaignOfferId, provider: \"signal-discovery\", targetEngagerCount, maxPostsToScrape, confirmed: true })"
|
|
488
498
|
}
|
|
489
499
|
}
|
|
490
500
|
],
|
|
@@ -925,12 +935,24 @@
|
|
|
925
935
|
"messageDraftRecommendation"
|
|
926
936
|
],
|
|
927
937
|
"requiredVisibleLabels": [
|
|
928
|
-
"
|
|
929
|
-
"
|
|
938
|
+
"## Message Template",
|
|
939
|
+
"## Rendered Example",
|
|
940
|
+
"Good token fill:",
|
|
930
941
|
"My take:",
|
|
931
|
-
"Concern:",
|
|
932
942
|
"Question: approve-message or revise-messaging?",
|
|
933
943
|
"Recommendation:"
|
|
944
|
+
],
|
|
945
|
+
"doNotShowByDefault": [
|
|
946
|
+
"Token Notes",
|
|
947
|
+
"Good omit / fallback",
|
|
948
|
+
"Bad fill to avoid",
|
|
949
|
+
"Token Adherence Table"
|
|
950
|
+
],
|
|
951
|
+
"internalPersistenceOnly": [
|
|
952
|
+
"Token Fill Rules",
|
|
953
|
+
"Token Fill Examples",
|
|
954
|
+
"fallback guidance",
|
|
955
|
+
"bad-fill avoidance notes"
|
|
934
956
|
]
|
|
935
957
|
},
|
|
936
958
|
{
|
|
@@ -31,8 +31,11 @@ instead of pulling the long prompt into the main thread.
|
|
|
31
31
|
local markdown/json artifacts in normal customer runs; emit debug artifacts
|
|
32
32
|
only when the parent explicitly asks for debug/UAT output.
|
|
33
33
|
5. Render the customer-facing message review in chat before asking for approval.
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
Keep chat lightweight: show the tokenized template and one strong rendered
|
|
35
|
+
good-fill example only. Do not print the token notes table, omit/fallback
|
|
36
|
+
example, or bad-fill analysis in chat unless the user explicitly asks.
|
|
37
|
+
After approval, the parent persists template, token rules, fallback guidance,
|
|
38
|
+
and bad-fill avoidance notes into campaign state with `update_campaign_brief`.
|
|
36
39
|
6. Ask exactly `approve-message` or `revise-messaging`. Do not import, queue,
|
|
37
40
|
attach sequence, or start before `approve-message`.
|
|
38
41
|
|
|
@@ -89,10 +92,17 @@ but the [topic] thread felt close enough to send`. Otherwise omit the
|
|
|
89
92
|
- If the message is plausible but not ready to send, set
|
|
90
93
|
`Recommendation: revise-messaging`.
|
|
91
94
|
|
|
95
|
+
## Internal Message Recommendation
|
|
96
|
+
|
|
97
|
+
The message scout or parent safety gate should still produce complete internal
|
|
98
|
+
review data: token-fill rules, one rendered omit/fallback example, and bad-fill
|
|
99
|
+
avoidance notes. This data is for campaign-brief persistence and safety checks,
|
|
100
|
+
not for the default chat approval packet.
|
|
101
|
+
|
|
92
102
|
## Customer-Facing Message Review
|
|
93
103
|
|
|
94
104
|
Render this in chat before asking. Use Markdown structure so the approval target
|
|
95
|
-
is visually scannable:
|
|
105
|
+
is visually scannable and low-overhead:
|
|
96
106
|
|
|
97
107
|
````markdown
|
|
98
108
|
Status: message-review
|
|
@@ -111,33 +121,11 @@ Status: message-review
|
|
|
111
121
|
{{tokenized_message_body}}
|
|
112
122
|
```
|
|
113
123
|
|
|
114
|
-
## Rendered
|
|
115
|
-
|
|
116
|
-
### Good token fill
|
|
117
|
-
|
|
118
|
-
Use when the row has a clean, supported fill.
|
|
119
|
-
|
|
120
|
-
```text
|
|
121
|
-
Subject: ...
|
|
122
|
-
|
|
123
|
-
Hey First,
|
|
124
|
-
|
|
125
|
-
...
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Good omit / fallback
|
|
129
|
-
|
|
130
|
-
Use when a row signal or company context is missing, weak, or awkward.
|
|
131
|
-
|
|
132
|
-
```text
|
|
133
|
-
Subject: ...
|
|
134
|
-
|
|
135
|
-
Hey First,
|
|
124
|
+
## Rendered Example
|
|
136
125
|
|
|
137
|
-
|
|
138
|
-
```
|
|
126
|
+
### Example
|
|
139
127
|
|
|
140
|
-
|
|
128
|
+
Good token fill:
|
|
141
129
|
|
|
142
130
|
```text
|
|
143
131
|
Subject: ...
|
|
@@ -147,14 +135,6 @@ Hey First,
|
|
|
147
135
|
...
|
|
148
136
|
```
|
|
149
137
|
|
|
150
|
-
**Why this is wrong:** one sentence naming the exact token-fill failure.
|
|
151
|
-
|
|
152
|
-
## Token Notes
|
|
153
|
-
|
|
154
|
-
| Token | Use when | Fallback |
|
|
155
|
-
| ---------------- | ------------------------ | -------- |
|
|
156
|
-
| `{{first_name}}` | Clean first name exists. | `there` |
|
|
157
|
-
|
|
158
138
|
## Recommendation
|
|
159
139
|
|
|
160
140
|
**My take:** ...
|
|
@@ -168,15 +148,13 @@ Hey First,
|
|
|
168
148
|
|
|
169
149
|
Formatting requirements:
|
|
170
150
|
|
|
171
|
-
- Put the tokenized template and
|
|
151
|
+
- Put the tokenized template and rendered example in fenced `text` blocks
|
|
172
152
|
so chat gives them a distinct background.
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
none found`.
|
|
179
|
-
- Use a token notes table, not paragraph-only token notes.
|
|
153
|
+
- The chat example must contain a complete rendered subject + body, not a
|
|
154
|
+
bullet list of token names or a single bridge-line fragment.
|
|
155
|
+
- Do not show `Good omit / fallback`, `Bad fill to avoid`, or `Token Notes` in
|
|
156
|
+
the default chat approval packet. Keep those in the internal recommendation
|
|
157
|
+
and persist them to the campaign brief after approval.
|
|
180
158
|
- Keep reasoning outside the code blocks so the blocks are easy to inspect and
|
|
181
159
|
approve.
|
|
182
160
|
|
|
@@ -57,7 +57,7 @@ Supported branches:
|
|
|
57
57
|
list from the approved source-capacity plan; it is not the same target as the
|
|
58
58
|
default 25-row campaign review batch.
|
|
59
59
|
- **Supplied LinkedIn profile CSV** — confirm `load_csv_linkedin_leads` only
|
|
60
|
-
after
|
|
60
|
+
after the user approves that supplied-list source. Batch/materialize the
|
|
61
61
|
uploaded CSV into a Sellable lead-list table. Persist the returned
|
|
62
62
|
`leadListId`, then import the bounded review batch into the campaign table
|
|
63
63
|
with
|
|
@@ -125,7 +125,9 @@ fallback fit rate is 15%, so the default source-candidate plan is about 1,000
|
|
|
125
125
|
raw engagers. If the sampled fit rate is stronger or weaker, use the sampled
|
|
126
126
|
rate with a conservative cleanup factor, cap the source candidates at the
|
|
127
127
|
approved provider limit, and select only enough posts to reach that engager
|
|
128
|
-
count. The
|
|
128
|
+
count. The planning floor is 10% projected fit after cleanup; if Signal
|
|
129
|
+
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. The subsequent
|
|
129
131
|
`confirm_lead_list` call still uses `targetLeadCount: <importLimit>` so only the
|
|
130
132
|
bounded review batch enters the campaign table.
|
|
131
133
|
|
|
@@ -219,8 +221,10 @@ cannot scale further without a new source lane.
|
|
|
219
221
|
- Zero-imported + zero-skipped ⇒ hard-fail escalate.
|
|
220
222
|
- Zero-imported + high-skipped ⇒ lane-exhausted operator notice (NOT a
|
|
221
223
|
silent proceed).
|
|
222
|
-
- `import_leads` is
|
|
223
|
-
|
|
224
|
+
- `import_leads` is allowed immediately after the concrete source-action
|
|
225
|
+
approval. It materializes the source list and then `confirm_lead_list` imports
|
|
226
|
+
only the bounded review batch. Enrichment, fit scoring, and message cells wait
|
|
227
|
+
for saved rubrics plus the approved message set.
|
|
224
228
|
- Step 13 MUST reuse an approved source already attached with `campaignOfferId`
|
|
225
229
|
before `import_leads`; it does not replay provider searches.
|
|
226
230
|
- `import_leads` is NOT called again in Step 14 (validate-sample). Full
|
|
@@ -321,6 +321,9 @@ Use first when the value is in conversation opportunity, competitor engagers, co
|
|
|
321
321
|
- Sample a representative first page only, scoring the first 25-40 engagers across the chosen posts against a rough yes/no headline rubric or `headlineICPCriteria`.
|
|
322
322
|
- Use headline and display-name cues only for the spot-check sample; do not enrich people during this phase.
|
|
323
323
|
- Base `estimatedReachableLeads` on the sampled engager pass rate, not only on a guessed discount from post themes.
|
|
324
|
+
- Use a 10% planning floor after conservative cleanup. If the sampled/projected
|
|
325
|
+
fit rate is below 10%, do not scale Signals; move to Sales Nav recent activity
|
|
326
|
+
instead.
|
|
324
327
|
- A Signals lane with ~150+ estimated ICP-fit reachable engagers from selected
|
|
325
328
|
posts is viable for a focused warm campaign, even if Sales Nav is more
|
|
326
329
|
scalable. Do not discard that lane solely for being smaller. If post-level
|
|
@@ -384,6 +387,9 @@ Use first when LinkedIn activity plus tighter role / company filters matter.
|
|
|
384
387
|
mark Sales Nav as a provider/tool issue and do not include it as a winning
|
|
385
388
|
source.
|
|
386
389
|
- If quality is good but scale is too small, widen the lane by adding/removing roles, expanding industries, widening headcount bands, or relaxing activity constraints.
|
|
390
|
+
- Use the same 10% planning floor after cleanup. If the final Sales Nav lane is
|
|
391
|
+
projected below 10% good-fit after reasonable refinement, move to Prospeo
|
|
392
|
+
rather than importing a noisy Sales Nav list.
|
|
387
393
|
- Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
|
|
388
394
|
- If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
|
|
389
395
|
- If you can name a specific next Sales Nav refinement that is still allowed by the probe budget, execute it before returning instead of listing it only as a recommendation.
|
|
@@ -404,6 +410,9 @@ Use first for broad persona expansion, ABM/domain targeting, hiring-led targetin
|
|
|
404
410
|
- If you widen with seniority labels such as `Head` or `Director`, keep a matching department/function constraint and inspect the sample for off-function leakage such as `Head of Social Media`, `Head of IT`, or `Director of Finance`.
|
|
405
411
|
- If quality is poor, tighten titles, company shape, seniority, geography, or hiring filters.
|
|
406
412
|
- If quality is good but scale is too small, widen titles, industries, company-size bands, or account scope.
|
|
413
|
+
- Prospeo is the terminal fallback for this chain. If projected fit is still
|
|
414
|
+
below the 10% planning floor after reasonable Prospeo refinement, stop and ask
|
|
415
|
+
for a tighter ICP/source direction instead of inventing another provider.
|
|
407
416
|
- When ABM/domain targeting exists, prefer refining around the account set before broadening away from it.
|
|
408
417
|
- Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
|
|
409
418
|
- If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
|
|
@@ -63,6 +63,10 @@ search_prospeo({
|
|
|
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
65
|
- Default source target is 300+ good-fit leads, capped at 2,500 source candidates for now.
|
|
66
|
+
- Apply the campaign source planning floor: the sampled/projected good-fit rate
|
|
67
|
+
after cleanup should be at least 10%. Prospeo is the terminal fallback; if the
|
|
68
|
+
best reasonable Prospeo lane is still below 10%, tighten the ICP/source
|
|
69
|
+
direction instead of switching to another provider.
|
|
66
70
|
- After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and the review-batch `targetLeadCount` from the active campaign defaults to import only the review batch into the campaign table.
|
|
67
71
|
- `import_leads` owns the watched move to `confirm-lead-list` after a lead list/job exists.
|
|
68
72
|
- `confirm_lead_list` owns the watched move to `filter-choice` after the bounded review batch exists.
|
|
@@ -96,6 +96,11 @@ Example search name: "Active CXOs at 201-500 companies"
|
|
|
96
96
|
- < 1,000 = remove a filter or widen criteria
|
|
97
97
|
- > 10,000 = add more filters
|
|
98
98
|
|
|
99
|
+
Also apply the campaign source planning floor: the sampled/projected good-fit
|
|
100
|
+
rate after cleanup should be at least 10%. If the best reasonable Sales Nav
|
|
101
|
+
lane remains below 10%, do not present it as the winning source; move to
|
|
102
|
+
Prospeo for broader account/contact coverage.
|
|
103
|
+
|
|
99
104
|
4. FINAL SEARCH + CONFIRM - Execute winning strategy, ask before saving
|
|
100
105
|
|
|
101
106
|
- Run the final search with the best filter combination
|
|
@@ -24,7 +24,7 @@ When the user asks to find posts or start searching, **IMMEDIATELY begin Round 1
|
|
|
24
24
|
|
|
25
25
|
<lead_target>
|
|
26
26
|
|
|
27
|
-
- **Default: provider max import count** (use this unless user specifies otherwise; see `lead-import-limits.json`, currently
|
|
27
|
+
- **Default: provider max import count** (use this unless user specifies otherwise; see `lead-import-limits.json`, currently 2,500)
|
|
28
28
|
- **Maximum: provider max import count**
|
|
29
29
|
- Quality > Quantity: a few hundred active users > 1000 potentially inactive profiles
|
|
30
30
|
- Focus on ACTIVE platform users who will actually see and respond to outreach
|
|
@@ -104,6 +104,9 @@ You must estimate:
|
|
|
104
104
|
- `ceil(targetGoodFitLeads / sampledFitRate)`; for example 15 good-fit
|
|
105
105
|
prospects per 100 engagers means a 150-good-fit source target needs about
|
|
106
106
|
1,000 engagers scraped
|
|
107
|
+
- `planningFloor`
|
|
108
|
+
- minimum acceptable sampled/projected fit rate after conservative cleanup;
|
|
109
|
+
default 10%. Below this, do not scale Signal Discovery.
|
|
107
110
|
- `projectedRange`
|
|
108
111
|
- the conservative range implied by the observed sample
|
|
109
112
|
|
|
@@ -130,7 +133,10 @@ Use conservative logic:
|
|
|
130
133
|
- preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 before cleanup / ~13-16 after cleanup, `requiredEngagersToScrape`: ~940-1,150 for a 150-good-fit target after cleanup, `avgReachableEngagersPerPost`: 240, `goodFitProspectsPerPost`: ~31-38, `postsNeededForTarget`: ~4-5, `recentStrongPostCount`: 15-25, `freshEnoughPostCount`: 8-12, `projectedRange`: 150-190 from selected posts"
|
|
131
134
|
- fallback: "I could not fetch engagers, so this is inferred from post and author quality only"
|
|
132
135
|
5. If the evidence is too weak, say so and return a low-confidence estimate instead of pretending precision.
|
|
133
|
-
6.
|
|
136
|
+
6. If sampled/projected fit after cleanup is below the 10% planning floor,
|
|
137
|
+
reject the Signal Discovery scrape path and recommend Sales Nav recent
|
|
138
|
+
activity as the next source.
|
|
139
|
+
7. Do not manually enumerate dozens of engagers in the final answer. Summarize the sample by `sampledCount`, `passCount`, `passRate`, `projectedRange`, and 3-6 representative examples.
|
|
134
140
|
|
|
135
141
|
</yield_estimation>
|
|
136
142
|
|
|
@@ -389,12 +395,15 @@ recommendation, estimate source capacity from real sample math:
|
|
|
389
395
|
- average reachable engagers per right-content post
|
|
390
396
|
- expected good-fit leads per selected post after dedupe/cleanup
|
|
391
397
|
- posts needed to reach the target
|
|
398
|
+
- whether sampled/projected fit clears the 10% planning floor
|
|
392
399
|
|
|
393
400
|
Then select the smallest right-content post set that plausibly hits the source
|
|
394
401
|
target. Do not scrape every promoted sample post by default; promoted sampling
|
|
395
402
|
state and final scrape plan are separate. If the math says the warm post lane
|
|
396
403
|
only supports a smaller first batch, say that and name the Sales Nav or Prospeo
|
|
397
|
-
scale fallback rather than padding the selection with noisy posts.
|
|
404
|
+
scale fallback rather than padding the selection with noisy posts. If the
|
|
405
|
+
sampled/projected fit rate is below 10% after cleanup, do not call
|
|
406
|
+
`import_leads`; move to Sales Nav recent activity.
|
|
398
407
|
|
|
399
408
|
```json
|
|
400
409
|
select_promising_posts({
|