@sellable/mcp 0.1.69 → 0.1.70
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 +7 -4
- package/agents/registry.json +57 -18
- package/dist/server.js +4 -1
- package/dist/tools/prompts.d.ts +58 -0
- package/dist/tools/prompts.js +64 -0
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +6 -3
- package/skills/create-campaign-v2/SKILL.md +21 -11
- package/skills/create-campaign-v2/SOUL.md +15 -8
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/find-leads/SKILL.md +17 -11
- /package/agents/{linkedin-engagement-scout.md → source-scout-linkedin-engagement.md} +0 -0
- /package/agents/{prospeo-contact-scout.md → source-scout-prospeo-contact.md} +0 -0
- /package/agents/{sales-nav-scout.md → source-scout-sales-nav.md} +0 -0
package/README.md
CHANGED
|
@@ -240,13 +240,16 @@ Provider preflight contract:
|
|
|
240
240
|
|
|
241
241
|
Parallel execution contract:
|
|
242
242
|
|
|
243
|
-
-
|
|
244
|
-
`
|
|
243
|
+
- Source scout names come from `agents/registry.json` and are exposed at runtime
|
|
244
|
+
through `get_source_scout_registry`. Add new scouts there first; installer,
|
|
245
|
+
Codex config, Claude agent files, and prompts should consume the registry.
|
|
246
|
+
- Claude host: use the installed `source-scout-linkedin-engagement`,
|
|
247
|
+
`source-scout-sales-nav`, and `source-scout-prospeo-contact` Task/Agent subagents
|
|
245
248
|
for parallel lead-source scouting. Launch all credible lanes in one assistant
|
|
246
249
|
message so Claude Code can run them concurrently/background.
|
|
247
250
|
- Codex host: use named custom scouts for source-angle work when subagents are
|
|
248
|
-
available: `
|
|
249
|
-
`
|
|
251
|
+
available: `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
252
|
+
`source-scout-prospeo-contact`. Use `multi_tool_use.parallel` for independent
|
|
250
253
|
tool-call batches when subagents are unavailable or the work is only simple
|
|
251
254
|
batched lookups.
|
|
252
255
|
- If neither backend is available, run sequentially with the same output schema.
|
package/agents/registry.json
CHANGED
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
"version": 1,
|
|
3
3
|
"agents": [
|
|
4
4
|
{
|
|
5
|
-
"id": "linkedin-engagement
|
|
6
|
-
"
|
|
5
|
+
"id": "linkedin-engagement",
|
|
6
|
+
"name": "source-scout-linkedin-engagement",
|
|
7
|
+
"promptFile": "source-scout-linkedin-engagement.md",
|
|
7
8
|
"displayName": "LinkedIn Engagement Scout",
|
|
9
|
+
"provider": "signal-discovery",
|
|
10
|
+
"lane": "linkedin-engagement",
|
|
11
|
+
"legacy": {
|
|
12
|
+
"codex": [
|
|
13
|
+
{
|
|
14
|
+
"name": "linkedin_engagement_scout",
|
|
15
|
+
"filename": "linkedin-engagement-scout.toml"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"claude": [
|
|
19
|
+
{
|
|
20
|
+
"name": "lead-explorer-signals",
|
|
21
|
+
"filename": "lead-explorer-signals.md"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
8
25
|
"codex": {
|
|
9
|
-
"name": "linkedin_engagement_scout",
|
|
10
|
-
"filename": "linkedin-engagement-scout.toml",
|
|
11
26
|
"description": "Sellable lead-source scout for LinkedIn post engagement and active conversation signals.",
|
|
12
27
|
"modelReasoningEffort": "medium",
|
|
13
28
|
"sandboxMode": "read-only",
|
|
@@ -18,8 +33,6 @@
|
|
|
18
33
|
]
|
|
19
34
|
},
|
|
20
35
|
"claude": {
|
|
21
|
-
"name": "lead-explorer-signals",
|
|
22
|
-
"filename": "lead-explorer-signals.md",
|
|
23
36
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs LinkedIn post engagement, Signals, or active conversation evidence.",
|
|
24
37
|
"model": "inherit",
|
|
25
38
|
"background": true,
|
|
@@ -36,12 +49,27 @@
|
|
|
36
49
|
}
|
|
37
50
|
},
|
|
38
51
|
{
|
|
39
|
-
"id": "sales-nav
|
|
40
|
-
"
|
|
52
|
+
"id": "sales-nav",
|
|
53
|
+
"name": "source-scout-sales-nav",
|
|
54
|
+
"promptFile": "source-scout-sales-nav.md",
|
|
41
55
|
"displayName": "Sales Nav Scout",
|
|
56
|
+
"provider": "sales-nav",
|
|
57
|
+
"lane": "sales-nav",
|
|
58
|
+
"legacy": {
|
|
59
|
+
"codex": [
|
|
60
|
+
{
|
|
61
|
+
"name": "sales_nav_scout",
|
|
62
|
+
"filename": "sales-nav-scout.toml"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"claude": [
|
|
66
|
+
{
|
|
67
|
+
"name": "lead-explorer-sales-nav",
|
|
68
|
+
"filename": "lead-explorer-sales-nav.md"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
42
72
|
"codex": {
|
|
43
|
-
"name": "sales_nav_scout",
|
|
44
|
-
"filename": "sales-nav-scout.toml",
|
|
45
73
|
"description": "Sellable lead-source scout for Sales Navigator role, company, and activity filters.",
|
|
46
74
|
"modelReasoningEffort": "medium",
|
|
47
75
|
"sandboxMode": "read-only",
|
|
@@ -52,8 +80,6 @@
|
|
|
52
80
|
]
|
|
53
81
|
},
|
|
54
82
|
"claude": {
|
|
55
|
-
"name": "lead-explorer-sales-nav",
|
|
56
|
-
"filename": "lead-explorer-sales-nav.md",
|
|
57
83
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Sales Navigator title, company, geography, or activity-filter evidence.",
|
|
58
84
|
"model": "inherit",
|
|
59
85
|
"background": true,
|
|
@@ -70,12 +96,27 @@
|
|
|
70
96
|
}
|
|
71
97
|
},
|
|
72
98
|
{
|
|
73
|
-
"id": "prospeo-contact
|
|
74
|
-
"
|
|
99
|
+
"id": "prospeo-contact",
|
|
100
|
+
"name": "source-scout-prospeo-contact",
|
|
101
|
+
"promptFile": "source-scout-prospeo-contact.md",
|
|
75
102
|
"displayName": "Prospeo Contact Scout",
|
|
103
|
+
"provider": "prospeo",
|
|
104
|
+
"lane": "prospeo-contact",
|
|
105
|
+
"legacy": {
|
|
106
|
+
"codex": [
|
|
107
|
+
{
|
|
108
|
+
"name": "prospeo_contact_scout",
|
|
109
|
+
"filename": "prospeo-contact-scout.toml"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"claude": [
|
|
113
|
+
{
|
|
114
|
+
"name": "lead-explorer-prospeo",
|
|
115
|
+
"filename": "lead-explorer-prospeo.md"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
},
|
|
76
119
|
"codex": {
|
|
77
|
-
"name": "prospeo_contact_scout",
|
|
78
|
-
"filename": "prospeo-contact-scout.toml",
|
|
79
120
|
"description": "Sellable lead-source scout for Prospeo account/domain and broad contact expansion.",
|
|
80
121
|
"modelReasoningEffort": "medium",
|
|
81
122
|
"sandboxMode": "read-only",
|
|
@@ -86,8 +127,6 @@
|
|
|
86
127
|
]
|
|
87
128
|
},
|
|
88
129
|
"claude": {
|
|
89
|
-
"name": "lead-explorer-prospeo",
|
|
90
|
-
"filename": "lead-explorer-prospeo.md",
|
|
91
130
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Prospeo account, domain-list, CSV-domain, or verified-contact evidence.",
|
|
92
131
|
"model": "inherit",
|
|
93
132
|
"background": true,
|
package/dist/server.js
CHANGED
|
@@ -21,7 +21,7 @@ import { fetchCompany, fetchCompanyPosts, fetchLinkedInPosts, fetchLinkedInProfi
|
|
|
21
21
|
import { getCampaignNavigationState, navigationToolDefinitions, } from "./tools/navigation.js";
|
|
22
22
|
import { addOnDemandLeads, createOnDemandCampaign, createOnDemandTable, initOnDemandSequence, onDemandToolDefinitions, pauseOnDemandCampaign, startOnDemandCampaign, } from "./tools/one-off.js";
|
|
23
23
|
import { processingToolDefinitions, upsertRubric } from "./tools/processing.js";
|
|
24
|
-
import { completeSenderResearch, getMessagePrompt, getSubskillAsset, getSubskillPrompt, listSubskillPrompts, promptToolDefinitions, searchSubskillPrompts, } from "./tools/prompts.js";
|
|
24
|
+
import { completeSenderResearch, getMessagePrompt, getSourceScoutRegistry, getSubskillAsset, getSubskillPrompt, listSubskillPrompts, promptToolDefinitions, searchSubskillPrompts, } from "./tools/prompts.js";
|
|
25
25
|
import { readinessToolDefinitions, waitForCampaignTableReady, waitForLeadListReady, } from "./tools/readiness.js";
|
|
26
26
|
import { getRows, getTableRows, getTableRowsMinimal, rowToolDefinitions, } from "./tools/rows.js";
|
|
27
27
|
import { addRubricItem, checkRubric, deleteRubricItem, draftRubrics, rubricToolDefinitions, saveRubrics, selectNecessaryRubrics, updateRubricItem, waitForRubricResults, } from "./tools/rubrics.js";
|
|
@@ -408,6 +408,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
408
408
|
case "search_subskill_prompts":
|
|
409
409
|
result = searchSubskillPrompts(args?.query, args?.limit, args?.includePublic, args?.includeInternal);
|
|
410
410
|
break;
|
|
411
|
+
case "get_source_scout_registry":
|
|
412
|
+
result = getSourceScoutRegistry();
|
|
413
|
+
break;
|
|
411
414
|
case "complete_sender_research":
|
|
412
415
|
result = completeSenderResearch(args);
|
|
413
416
|
break;
|
package/dist/tools/prompts.d.ts
CHANGED
|
@@ -60,6 +60,40 @@ export interface CompleteSenderResearchInput {
|
|
|
60
60
|
credibilitySignalsFound?: number;
|
|
61
61
|
notes?: string;
|
|
62
62
|
}
|
|
63
|
+
export interface SourceScoutRegistryResponse {
|
|
64
|
+
version: number;
|
|
65
|
+
agents: Array<{
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
displayName: string;
|
|
69
|
+
provider: string;
|
|
70
|
+
lane: string;
|
|
71
|
+
codex: {
|
|
72
|
+
filename: string;
|
|
73
|
+
description: string;
|
|
74
|
+
};
|
|
75
|
+
claude: {
|
|
76
|
+
filename: string;
|
|
77
|
+
description: string;
|
|
78
|
+
tools: string[];
|
|
79
|
+
};
|
|
80
|
+
legacy?: {
|
|
81
|
+
codex?: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
filename: string;
|
|
84
|
+
}>;
|
|
85
|
+
claude?: Array<{
|
|
86
|
+
name: string;
|
|
87
|
+
filename: string;
|
|
88
|
+
}>;
|
|
89
|
+
};
|
|
90
|
+
}>;
|
|
91
|
+
usage: {
|
|
92
|
+
codex: string;
|
|
93
|
+
claude: string;
|
|
94
|
+
parentThreadRule: string;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
63
97
|
export declare const DEFAULT_SUBSKILL_PROMPT_CHUNK_CHARS = 48000;
|
|
64
98
|
export declare const MAX_SUBSKILL_PROMPT_CHUNK_CHARS = 48000;
|
|
65
99
|
export declare const promptToolDefinitions: ({
|
|
@@ -223,6 +257,29 @@ export declare const promptToolDefinitions: ({
|
|
|
223
257
|
additionalProperties: boolean;
|
|
224
258
|
};
|
|
225
259
|
_meta?: undefined;
|
|
260
|
+
} | {
|
|
261
|
+
name: string;
|
|
262
|
+
description: string;
|
|
263
|
+
inputSchema: {
|
|
264
|
+
type: string;
|
|
265
|
+
properties: {
|
|
266
|
+
limit?: undefined;
|
|
267
|
+
includePublic?: undefined;
|
|
268
|
+
includeInternal?: undefined;
|
|
269
|
+
subskillName?: undefined;
|
|
270
|
+
offset?: undefined;
|
|
271
|
+
assetPath?: undefined;
|
|
272
|
+
query?: undefined;
|
|
273
|
+
depth?: undefined;
|
|
274
|
+
proofItemsFound?: undefined;
|
|
275
|
+
caseStudyItemsFound?: undefined;
|
|
276
|
+
credibilitySignalsFound?: undefined;
|
|
277
|
+
notes?: undefined;
|
|
278
|
+
};
|
|
279
|
+
required: never[];
|
|
280
|
+
additionalProperties: boolean;
|
|
281
|
+
};
|
|
282
|
+
_meta?: undefined;
|
|
226
283
|
} | {
|
|
227
284
|
name: string;
|
|
228
285
|
description: string;
|
|
@@ -263,6 +320,7 @@ export declare const promptToolDefinitions: ({
|
|
|
263
320
|
};
|
|
264
321
|
_meta?: undefined;
|
|
265
322
|
})[];
|
|
323
|
+
export declare function getSourceScoutRegistry(): SourceScoutRegistryResponse;
|
|
266
324
|
export declare function getMessagePrompt(): Promise<PromptResponse>;
|
|
267
325
|
export declare function listSubskillPrompts(limit?: number, includePublic?: boolean, includeInternal?: boolean): ListSubskillPromptsResponse;
|
|
268
326
|
export declare function getSubskillPrompt(subskillName: string, offset?: number, limit?: number): SubskillPromptResponse;
|
package/dist/tools/prompts.js
CHANGED
|
@@ -130,6 +130,16 @@ export const promptToolDefinitions = [
|
|
|
130
130
|
additionalProperties: false,
|
|
131
131
|
},
|
|
132
132
|
},
|
|
133
|
+
{
|
|
134
|
+
name: "get_source_scout_registry",
|
|
135
|
+
description: "Return the canonical Sellable source-scout agent names and host filenames. Use this before lead-source scouting so Codex and Claude launch the same named scouts from one registry.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: {},
|
|
139
|
+
required: [],
|
|
140
|
+
additionalProperties: false,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
133
143
|
{
|
|
134
144
|
name: "complete_sender_research",
|
|
135
145
|
description: "Mark sender research as completed for create-campaign preflight. Call this after research-sender synthesis and before create_campaign.",
|
|
@@ -162,6 +172,60 @@ export const promptToolDefinitions = [
|
|
|
162
172
|
},
|
|
163
173
|
},
|
|
164
174
|
];
|
|
175
|
+
function resolveAgentsDir() {
|
|
176
|
+
const candidates = [];
|
|
177
|
+
if (process.env.SELLABLE_AGENTS_DIR) {
|
|
178
|
+
candidates.push(path.resolve(process.env.SELLABLE_AGENTS_DIR));
|
|
179
|
+
}
|
|
180
|
+
if (process.argv[1]) {
|
|
181
|
+
candidates.push(path.resolve(path.dirname(process.argv[1]), "../agents"));
|
|
182
|
+
try {
|
|
183
|
+
const realEntryPath = fs.realpathSync(process.argv[1]);
|
|
184
|
+
candidates.push(path.resolve(path.dirname(realEntryPath), "../agents"));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Module-relative and cwd fallbacks remain.
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
candidates.push(path.resolve(process.cwd(), "mcp/sellable/agents"));
|
|
191
|
+
candidates.push(path.resolve(process.cwd(), "agents"));
|
|
192
|
+
for (const candidate of candidates) {
|
|
193
|
+
if (fs.existsSync(path.join(candidate, "registry.json"))) {
|
|
194
|
+
return candidate;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return candidates[0] ?? path.resolve(process.cwd(), "mcp/sellable/agents");
|
|
198
|
+
}
|
|
199
|
+
export function getSourceScoutRegistry() {
|
|
200
|
+
const registryPath = path.join(resolveAgentsDir(), "registry.json");
|
|
201
|
+
const registry = JSON.parse(fs.readFileSync(registryPath, "utf8"));
|
|
202
|
+
const agents = Array.isArray(registry.agents) ? registry.agents : [];
|
|
203
|
+
return {
|
|
204
|
+
version: Number(registry.version || 1),
|
|
205
|
+
agents: agents.map((agent) => ({
|
|
206
|
+
id: String(agent.id || ""),
|
|
207
|
+
name: String(agent.name || ""),
|
|
208
|
+
displayName: String(agent.displayName || agent.name || ""),
|
|
209
|
+
provider: String(agent.provider || ""),
|
|
210
|
+
lane: String(agent.lane || agent.id || ""),
|
|
211
|
+
codex: {
|
|
212
|
+
filename: String(agent.codex?.filename || `${agent.name}.toml`),
|
|
213
|
+
description: String(agent.codex?.description || ""),
|
|
214
|
+
},
|
|
215
|
+
claude: {
|
|
216
|
+
filename: String(agent.claude?.filename || `${agent.name}.md`),
|
|
217
|
+
description: String(agent.claude?.description || ""),
|
|
218
|
+
tools: Array.isArray(agent.claude?.tools) ? agent.claude.tools : [],
|
|
219
|
+
},
|
|
220
|
+
legacy: agent.legacy,
|
|
221
|
+
})),
|
|
222
|
+
usage: {
|
|
223
|
+
codex: "Spawn credible scouts by the returned `name` values in one assistant turn when the user approved background source scouts.",
|
|
224
|
+
claude: "Invoke Claude Code Task/Agent subagents with subagent_type equal to the returned `name` values.",
|
|
225
|
+
parentThreadRule: "Do not preload every provider prompt in the parent; each scout loads only the provider prompt for its lane.",
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
165
229
|
export async function getMessagePrompt() {
|
|
166
230
|
const api = getApi();
|
|
167
231
|
return api.get("/api/v3/prompts/edit-message");
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ allowed-tools:
|
|
|
11
11
|
- mcp__sellable__get_subskill_asset
|
|
12
12
|
- mcp__sellable__search_subskill_prompts
|
|
13
13
|
- mcp__sellable__get_provider_prompt
|
|
14
|
+
- mcp__sellable__get_source_scout_registry
|
|
14
15
|
- mcp__sellable__get_message_prompt
|
|
15
16
|
- mcp__sellable__get_active_workspace
|
|
16
17
|
- mcp__sellable__list_senders
|
|
@@ -102,12 +103,14 @@ scout those angles as independent branches when the host can actually do it:
|
|
|
102
103
|
LinkedIn Engagement / active post engagers (internal `signal-discovery`
|
|
103
104
|
provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
|
|
104
105
|
domains only when relevant. In Codex, explicitly spawn the named custom scouts
|
|
105
|
-
`
|
|
106
|
+
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and `source-scout-prospeo-contact` for
|
|
106
107
|
the credible lanes; Codex does not infer subagent fan-out from generic source
|
|
107
|
-
comparison wording. In Claude Code, invoke the generated `
|
|
108
|
+
comparison wording. In Claude Code, invoke the generated `source-scout-*`
|
|
108
109
|
Task/Agent subagents for all credible lanes in one assistant message; the
|
|
109
110
|
installer writes them from the same canonical Sellable agent registry with
|
|
110
|
-
explicit Sellable MCP tool allowlists.
|
|
111
|
+
explicit Sellable MCP tool allowlists. The create-campaign-v2 subskill calls
|
|
112
|
+
`get_source_scout_registry` before dispatch so the current registry, not this
|
|
113
|
+
copy, is the runtime source of truth. If the host runs them sequentially, do not
|
|
111
114
|
claim they ran in parallel. In chat, call the downstream copy stage `message generation`;
|
|
112
115
|
`message-validation.md` is only an internal proof artifact.
|
|
113
116
|
|
|
@@ -360,6 +360,11 @@ me`, `I’ll paste a different sender profile`, and `Other / custom`.
|
|
|
360
360
|
user-facing choice should be approve/revise language, not "looks good".
|
|
361
361
|
Approval options should refer to what the user just read, e.g. `Approve this
|
|
362
362
|
brief`, `Revise target`, `Revise offer/proof`, and `Other / custom`.
|
|
363
|
+
When the user chose `Find people for me` and the host supports subagents,
|
|
364
|
+
make the recommended approval label explicit: `Approve brief + use background
|
|
365
|
+
source scouts`. That gives Codex/Claude a user-visible request to launch
|
|
366
|
+
source-scout subagents after approval instead of silently falling back to
|
|
367
|
+
parent-thread provider probes.
|
|
363
368
|
Include an `Open artifact:` link to `brief.md` before the approval question.
|
|
364
369
|
The visible brief must come before local persistence chrome. After the brief
|
|
365
370
|
is synthesized, render the approval-ready brief in chat before running visible
|
|
@@ -433,15 +438,18 @@ should test for this campaign. Those can run in parallel and usually take
|
|
|
433
438
|
`message-validation.md`, then reconciles that the selected message basis rows
|
|
434
439
|
still pass the final filter.
|
|
435
440
|
- Parallel means real parallel execution, not optimistic progress copy. For the
|
|
436
|
-
lead-source scout
|
|
437
|
-
|
|
441
|
+
lead-source scout, first call `get_source_scout_registry` and use the
|
|
442
|
+
returned canonical `name` values. In Codex, explicitly spawn one named custom scout per
|
|
443
|
+
credible source lane when subagents are available: `source-scout-linkedin-engagement`
|
|
438
444
|
(display: LinkedIn Engagement Scout, powered by the `signal-discovery`
|
|
439
|
-
provider prompt), `
|
|
440
|
-
`
|
|
441
|
-
invoke the generated `.claude/agents/
|
|
445
|
+
provider prompt), `source-scout-sales-nav` (Sales Nav Scout), and
|
|
446
|
+
`source-scout-prospeo-contact` (Prospeo Contact Scout). For Claude Code, explicitly
|
|
447
|
+
invoke the generated `.claude/agents/source-scout-*.md` Task/Agent subagents
|
|
442
448
|
for all credible lanes in one assistant message; they are installed from the
|
|
443
449
|
same canonical Sellable agent registry and carry explicit Sellable MCP tool
|
|
444
|
-
allowlists.
|
|
450
|
+
allowlists. The parent thread should not preload every provider prompt before
|
|
451
|
+
spawning scouts; each scout loads only its own provider prompt. If host
|
|
452
|
+
subagents are unavailable, use independent MCP/tool calls
|
|
445
453
|
in the same model turn or dedicated Sellable MCP tools that perform
|
|
446
454
|
server-side `Promise.all` fan-out. If real parallel execution is not available
|
|
447
455
|
or not allowed, run the same DAG sequentially and use honest copy: `I’ll tighten the filter first,
|
|
@@ -603,15 +611,17 @@ Required behavior:
|
|
|
603
611
|
- do not mutate DB-backed campaign state
|
|
604
612
|
- run a real parallel source-angle scout when the source is not supplied and at
|
|
605
613
|
least two viable source angles exist. Treat source scouting as independent
|
|
606
|
-
branches, then compare the outputs in `lead-review.md`.
|
|
607
|
-
|
|
608
|
-
|
|
614
|
+
branches, then compare the outputs in `lead-review.md`. Call
|
|
615
|
+
`get_source_scout_registry` first so new scouts can be added without prompt
|
|
616
|
+
rewrites. In Codex, explicitly
|
|
617
|
+
spawn named custom subagents in the same turn: `source-scout-linkedin-engagement`,
|
|
618
|
+
`source-scout-sales-nav`, and `source-scout-prospeo-contact` for the credible lanes. Codex
|
|
609
619
|
does not infer this from generic "compare paths" wording. If the realistic
|
|
610
620
|
source set is LinkedIn Engagement + Sales Nav (Signals + Sales Nav), run both.
|
|
611
621
|
If it is LinkedIn Engagement + Prospeo Contact (Signals + Prospeo), run both.
|
|
612
622
|
If all three are credible, run all three when the host/runtime supports it.
|
|
613
|
-
In Claude Code, launch the matching `
|
|
614
|
-
`
|
|
623
|
+
In Claude Code, launch the matching `source-scout-linkedin-engagement`,
|
|
624
|
+
`source-scout-sales-nav`, and/or `source-scout-prospeo-contact` Task/Agent subagents
|
|
615
625
|
in the same assistant message, not as sequential scout turns.
|
|
616
626
|
- Branch A: LinkedIn Engagement / active LinkedIn posts (internal provider:
|
|
617
627
|
Signals / `signal-discovery`). Search relevant keyword lanes, review
|
|
@@ -224,17 +224,24 @@ setting: `~/.codex/config.toml` with
|
|
|
224
224
|
Source-angle comparison should be real, not implied. When the source is not
|
|
225
225
|
supplied and multiple source angles are viable, scout Signals, Sales Nav, and
|
|
226
226
|
relevant domain/contact paths as independent branches when the host can do so.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
`
|
|
227
|
+
Call `get_source_scout_registry` first and use the returned canonical `name`
|
|
228
|
+
values; the names below are the current registry entries. In Codex, explicitly
|
|
229
|
+
spawn named custom scouts in the same turn:
|
|
230
|
+
`source-scout-linkedin-engagement` (LinkedIn Engagement Scout, backed by the
|
|
231
|
+
`signal-discovery` provider prompt), `source-scout-sales-nav` (Sales Nav Scout), and
|
|
232
|
+
`source-scout-prospeo-contact` (Prospeo Contact Scout) for the credible lanes. Codex
|
|
231
233
|
does not infer subagent fan-out from generic "compare paths" wording. In Claude
|
|
232
|
-
Code, invoke the generated `
|
|
233
|
-
and/or `
|
|
234
|
+
Code, invoke the generated `source-scout-linkedin-engagement`, `source-scout-sales-nav`,
|
|
235
|
+
and/or `source-scout-prospeo-contact` Task/Agent subagents in one assistant message so
|
|
234
236
|
Claude can run the source lanes concurrently/background. These agents come from
|
|
235
237
|
the same canonical Sellable registry and must load their matching provider
|
|
236
|
-
prompt before searching.
|
|
237
|
-
|
|
238
|
+
prompt before searching. The parent thread should not fetch every provider
|
|
239
|
+
prompt first; that burns time and often degenerates into parallel tool calls
|
|
240
|
+
instead of true subagents. When asking the user to approve a brief with
|
|
241
|
+
Sellable finding leads, use an explicit label like `Approve brief + use
|
|
242
|
+
background source scouts` so the next turn has a user-visible request to spawn
|
|
243
|
+
scouts. If the host runs them sequentially, keep the output numeric but do not
|
|
244
|
+
claim the source scout was parallel.
|
|
238
245
|
|
|
239
246
|
Only promise parallel post-lead work when parallel work actually started. If the
|
|
240
247
|
host cannot or should not launch background branches, say the real sequence:
|
|
@@ -341,7 +341,7 @@
|
|
|
341
341
|
"action": "run_subskill",
|
|
342
342
|
"target": "find-leads",
|
|
343
343
|
"mode": "campaignless-preview",
|
|
344
|
-
"sourceScoutRule": "When source is not user-supplied and at least two viable source angles exist, scout independent source angles with real parallelism when host/tooling permits. In Codex, explicitly spawn one named custom scout per credible lane in the same turn:
|
|
344
|
+
"sourceScoutRule": "When source is not user-supplied and at least two viable source angles exist, call get_source_scout_registry and use the returned canonical agent names, then scout independent source angles with real parallelism when host/tooling permits. In Codex, explicitly spawn one named custom scout per credible lane in the same turn: source-scout-linkedin-engagement for LinkedIn Engagement / active post engagers (internal signal-discovery provider prompt), source-scout-sales-nav for Sales Nav title/company/activity filters, and source-scout-prospeo-contact for Prospeo account/domain/contact expansion. In Claude Code, explicitly invoke the generated source-scout-linkedin-engagement, source-scout-sales-nav, and/or source-scout-prospeo-contact Task agents / Agent subagents in one assistant message so the lanes can run concurrently/background; those agents are installed from the canonical Sellable agent registry and carry explicit Sellable MCP tool allowlists. Fallback to independent MCP/tool calls in the same model turn or dedicated Sellable MCP tools that perform server-side fan-out. Run LinkedIn Engagement + Sales Nav, LinkedIn Engagement + Prospeo Contact, or all three when credible. If real parallel execution is unavailable, run the same scouts sequentially and do not claim parallel execution. Compare outputs by raw volume, n/N sampled fit, estimated good-fit range, expected reply range, and tradeoff. Keep Signals/LinkedIn Engagement as viable when selected posts can produce ~150+ ICP-fit warm prospects before final filtering, even if Sales Nav is more scalable; when both are viable, present the choice and recommend the stronger default."
|
|
345
345
|
},
|
|
346
346
|
{
|
|
347
347
|
"action": "write_artifacts",
|
|
@@ -65,16 +65,19 @@ The kickoff doc is the resume surface. Re-open it before repeating discovery wor
|
|
|
65
65
|
|
|
66
66
|
## Execution Backend Routing
|
|
67
67
|
|
|
68
|
+
- Before source-scout dispatch, call `get_source_scout_registry` and use the
|
|
69
|
+
returned `name` values. The current canonical names are listed below for
|
|
70
|
+
readability, but the registry is the source of truth for install/runtime.
|
|
68
71
|
- If Codex subagents are available, run the scout lanes with named custom
|
|
69
72
|
agents. Spawn one agent per credible lane in the same turn, then wait for all
|
|
70
73
|
lane results before synthesizing `lead-review.md`:
|
|
71
|
-
- `
|
|
74
|
+
- `source-scout-linkedin-engagement` (display: LinkedIn Engagement Scout) for
|
|
72
75
|
active LinkedIn posts and engagers; internally this uses the
|
|
73
76
|
`signal-discovery` provider prompt plus `search_signals` /
|
|
74
77
|
`fetch_post_engagers`.
|
|
75
|
-
- `
|
|
78
|
+
- `source-scout-sales-nav` (display: Sales Nav Scout) for Sales Navigator title,
|
|
76
79
|
company, geography, and activity filters.
|
|
77
|
-
- `
|
|
80
|
+
- `source-scout-prospeo-contact` (display: Prospeo Contact Scout) for Prospeo
|
|
78
81
|
account/domain and verified-contact expansion.
|
|
79
82
|
- Common parallel comparisons are LinkedIn Engagement + Sales Nav, LinkedIn
|
|
80
83
|
Engagement + Prospeo Contact, or all three when each lane is credible.
|
|
@@ -82,11 +85,14 @@ The kickoff doc is the resume surface. Re-open it before repeating discovery wor
|
|
|
82
85
|
Claude explorer agents installed from the same canonical Sellable agent
|
|
83
86
|
registry. Launch every credible lane in the same assistant message so Claude
|
|
84
87
|
Code can run them concurrently/background:
|
|
85
|
-
- `./.claude/agents/
|
|
86
|
-
- `./.claude/agents/
|
|
87
|
-
- `./.claude/agents/
|
|
88
|
+
- `./.claude/agents/source-scout-linkedin-engagement.md`
|
|
89
|
+
- `./.claude/agents/source-scout-sales-nav.md`
|
|
90
|
+
- `./.claude/agents/source-scout-prospeo-contact.md`
|
|
88
91
|
- These Claude agents must have explicit Sellable MCP tool allowlists and must
|
|
89
92
|
load the matching provider prompt before searching.
|
|
93
|
+
- The parent thread should not preload every provider prompt before launching
|
|
94
|
+
scouts. Spawn the credible scouts first; each scout loads only the provider
|
|
95
|
+
prompt for its lane and returns structured evidence.
|
|
90
96
|
- Else if `multi_tool_use.parallel` is available, run independent discovery calls in parallel and synthesize locally.
|
|
91
97
|
- Else run sequentially.
|
|
92
98
|
- Never claim agents were used when they were not.
|
|
@@ -257,7 +263,7 @@ When two or more source angles are viable, run the provider probes in real
|
|
|
257
263
|
parallel when the host/runtime allows it. For Codex, explicitly spawn the
|
|
258
264
|
named source scout agents above; Codex will not infer subagent fan-out from
|
|
259
265
|
general "compare sources" wording. For Claude Code, explicitly invoke the
|
|
260
|
-
matching `
|
|
266
|
+
matching `source-scout-*` Task/Agent subagents in one message instead of
|
|
261
267
|
probing one lane, waiting, then probing the next. Examples: LinkedIn Engagement
|
|
262
268
|
|
|
263
269
|
- Sales Nav, LinkedIn Engagement + Prospeo Contact, or Sales Nav + Prospeo
|
|
@@ -424,12 +430,12 @@ Show the light-touch results and ask whether to deep-dispatch or iterate.
|
|
|
424
430
|
## Layer 3: Selective deep exploration
|
|
425
431
|
|
|
426
432
|
Spawn only the validated paths from Gate 1. In Claude Code, invoke all selected
|
|
427
|
-
`
|
|
433
|
+
`source-scout-*` agents in one turn so source scouting is concurrent when the
|
|
428
434
|
runtime supports it.
|
|
429
435
|
|
|
430
|
-
- `
|
|
431
|
-
- `
|
|
432
|
-
- `
|
|
436
|
+
- `source-scout-linkedin-engagement`
|
|
437
|
+
- `source-scout-sales-nav`
|
|
438
|
+
- `source-scout-prospeo-contact`
|
|
433
439
|
|
|
434
440
|
Each explorer must return:
|
|
435
441
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|