@sellable/mcp 0.1.70 → 0.1.72
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/registry.json +6 -3
- package/dist/tools/campaigns.js +21 -21
- package/dist/tools/one-off.d.ts +1 -1
- package/dist/tools/one-off.js +11 -6
- package/dist/tools/prompts.d.ts +2 -0
- package/dist/tools/prompts.js +2 -0
- package/package.json +1 -1
package/agents/registry.json
CHANGED
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"codex": {
|
|
26
26
|
"description": "Sellable lead-source scout for LinkedIn post engagement and active conversation signals.",
|
|
27
|
-
"
|
|
27
|
+
"model": "gpt-5.5",
|
|
28
|
+
"modelReasoningEffort": "high",
|
|
28
29
|
"sandboxMode": "read-only",
|
|
29
30
|
"nicknameCandidates": [
|
|
30
31
|
"LinkedIn Engagement Scout",
|
|
@@ -71,7 +72,8 @@
|
|
|
71
72
|
},
|
|
72
73
|
"codex": {
|
|
73
74
|
"description": "Sellable lead-source scout for Sales Navigator role, company, and activity filters.",
|
|
74
|
-
"
|
|
75
|
+
"model": "gpt-5.5",
|
|
76
|
+
"modelReasoningEffort": "high",
|
|
75
77
|
"sandboxMode": "read-only",
|
|
76
78
|
"nicknameCandidates": [
|
|
77
79
|
"Sales Nav Scout",
|
|
@@ -118,7 +120,8 @@
|
|
|
118
120
|
},
|
|
119
121
|
"codex": {
|
|
120
122
|
"description": "Sellable lead-source scout for Prospeo account/domain and broad contact expansion.",
|
|
121
|
-
"
|
|
123
|
+
"model": "gpt-5.5",
|
|
124
|
+
"modelReasoningEffort": "high",
|
|
122
125
|
"sandboxMode": "read-only",
|
|
123
126
|
"nicknameCandidates": [
|
|
124
127
|
"Prospeo Contact Scout",
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
2
|
import { getConfig } from "../auth.js";
|
|
3
|
-
import { assertCreateCampaignPromptLoaded
|
|
3
|
+
import { assertCreateCampaignPromptLoaded } from "./flow-preflight.js";
|
|
4
4
|
import { setCampaignInteractionMode, } from "./interaction-mode.js";
|
|
5
5
|
import { fetchCampaignRubrics } from "./processing.js";
|
|
6
6
|
const LEAD_SOURCE_PROVIDERS = {
|
|
@@ -123,7 +123,9 @@ export const campaignToolDefinitions = [
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
name: "create_campaign",
|
|
126
|
-
description: 'Create a new campaign offer OR resume an existing one. Low-level write tool: load create-campaign workflow instructions first via get_subskill_prompt({ subskillName: "create-campaign" }) (or bootstrap_create_campaign + nextStep). If campaignId is provided, this tool returns the watchUrl + state for that campaign instead of creating a new campaign.\n\
|
|
126
|
+
description: 'Create a new campaign offer OR resume an existing one. Low-level write tool: load create-campaign workflow instructions first via get_subskill_prompt({ subskillName: "create-campaign" }) (or bootstrap_create_campaign + nextStep). If campaignId is provided, this tool returns the watchUrl + state for that campaign instead of creating a new campaign.\n\n' +
|
|
127
|
+
"INPUTS:\n- Pass either `clientProspectId` (preferred) or `senderLinkedinUrl` for net-new campaigns.\n- `clientProspectId` is the EnrichedProspect row ID for the campaign sender, used by ICP scoring, message generation, and brief rendering.\n- `senderLinkedinUrl` may be passed when `clientProspectId` is not yet materialized; the backend will attempt to resolve a sender prospect from it.\n\n" +
|
|
128
|
+
"PREREQUISITES:\n- If you provide `senderLinkedinUrl`, it is used as a sender bootstrap signal.\n- `clientProspectId` is optional when sender URL is available and allows a direct materialized sender context.\n- `clientProspectId` is preferred for deterministic sender resolution.",
|
|
127
129
|
inputSchema: {
|
|
128
130
|
type: "object",
|
|
129
131
|
properties: {
|
|
@@ -137,13 +139,13 @@ export const campaignToolDefinitions = [
|
|
|
137
139
|
},
|
|
138
140
|
clientProspectId: {
|
|
139
141
|
type: "string",
|
|
140
|
-
description: "
|
|
142
|
+
description: "Use this for existing sender prospects. For brand-new senders, pass `senderLinkedinUrl` and the backend will attempt sender lookup/creation during campaign mint.",
|
|
141
143
|
},
|
|
142
144
|
// `senderLinkedinUrl` (not `linkedinUrl`) to disambiguate from
|
|
143
145
|
// prospect-side `linkedinUrl` fields used in other tools (research-prospect etc.).
|
|
144
146
|
senderLinkedinUrl: {
|
|
145
147
|
type: "string",
|
|
146
|
-
description: "Optional
|
|
148
|
+
description: "Optional sender LinkedIn profile URL. Use when sender prospect ID is not yet materialized and backend bootstrap should be used.",
|
|
147
149
|
},
|
|
148
150
|
offerPositioning: {
|
|
149
151
|
type: "object",
|
|
@@ -597,32 +599,32 @@ export async function createCampaign(input) {
|
|
|
597
599
|
missing.push("name");
|
|
598
600
|
if (!input.campaignBrief)
|
|
599
601
|
missing.push("campaignBrief");
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
602
|
+
const hasClientProspectId = typeof input.clientProspectId === "string" &&
|
|
603
|
+
input.clientProspectId.trim().length > 0;
|
|
604
|
+
const senderLinkedinUrl = typeof input.senderLinkedinUrl === "string"
|
|
605
|
+
? input.senderLinkedinUrl.trim()
|
|
606
|
+
: "";
|
|
607
|
+
// For net-new campaigns, require at least one sender identity signal.
|
|
608
|
+
if (!hasClientProspectId && !senderLinkedinUrl) {
|
|
609
|
+
missing.push("clientProspectId or senderLinkedinUrl");
|
|
607
610
|
}
|
|
608
611
|
// Cheap URL sanity check on senderLinkedinUrl when supplied.
|
|
609
|
-
if (
|
|
610
|
-
typeof input.senderLinkedinUrl === "string" &&
|
|
611
|
-
!input.senderLinkedinUrl.includes("linkedin.com")) {
|
|
612
|
+
if (senderLinkedinUrl && !senderLinkedinUrl.includes("linkedin.com")) {
|
|
612
613
|
throw new Error("VALIDATION_ERROR: senderLinkedinUrl must be a LinkedIn URL (must contain 'linkedin.com'). Got: " +
|
|
613
|
-
|
|
614
|
+
senderLinkedinUrl);
|
|
614
615
|
}
|
|
615
616
|
if (missing.length > 0) {
|
|
616
617
|
throw new Error("VALIDATION_ERROR: create_campaign requires either campaignId (resume) " +
|
|
617
618
|
`or all create fields. Missing: ${missing.join(", ")}.\n\n` +
|
|
618
619
|
"Remediation:\n" +
|
|
619
620
|
'- For full workflow, call get_subskill_prompt({ subskillName: "create-campaign" }) and follow it.\n' +
|
|
620
|
-
"- For net-new campaign creation:
|
|
621
|
+
"- For net-new campaign creation: pass either `clientProspectId` (preferred) or `senderLinkedinUrl` and let the backend resolve sender context at mint time.\n" +
|
|
621
622
|
"- For resume, call create_campaign with campaignId only.");
|
|
622
623
|
}
|
|
623
|
-
assertNetNewCreateCampaignResearchReady();
|
|
624
624
|
const name = input.name;
|
|
625
|
-
const clientProspectId =
|
|
625
|
+
const clientProspectId = hasClientProspectId
|
|
626
|
+
? input.clientProspectId?.trim()
|
|
627
|
+
: null;
|
|
626
628
|
const campaignBrief = input.campaignBrief;
|
|
627
629
|
// Validate required campaignBrief - must be non-empty markdown
|
|
628
630
|
// Normalize escaped newlines - MCP tool calls pass literal "\n" text (backslash + n)
|
|
@@ -677,15 +679,13 @@ export async function createCampaign(input) {
|
|
|
677
679
|
...apiInput,
|
|
678
680
|
name,
|
|
679
681
|
clientProspectId,
|
|
680
|
-
// Forward senderLinkedinUrl alongside clientProspectId. Downstream API may
|
|
681
|
-
// ignore it for now; future phase wires it.
|
|
682
|
-
senderLinkedinUrl: input.senderLinkedinUrl ?? null,
|
|
683
682
|
offerPositioning,
|
|
684
683
|
...(input.leadSourceProvider !== undefined
|
|
685
684
|
? { leadSourceProvider: normalizedLeadSourceProvider }
|
|
686
685
|
: {}),
|
|
687
686
|
currentStep: currentStep ?? "create-offer",
|
|
688
687
|
leadSourceType: input.leadSourceType ?? "new",
|
|
688
|
+
senderLinkedinUrl,
|
|
689
689
|
campaignBrief: {
|
|
690
690
|
name, // Use campaign name as brief name
|
|
691
691
|
content: briefContent, // The markdown content
|
package/dist/tools/one-off.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type CreateOnDemandCampaignInput = {
|
|
|
29
29
|
name: string;
|
|
30
30
|
clientProspectId?: string;
|
|
31
31
|
senderLinkedinUrl?: string;
|
|
32
|
-
senderIds
|
|
32
|
+
senderIds?: string[];
|
|
33
33
|
campaignBrief?: unknown;
|
|
34
34
|
offerPositioning?: Record<string, unknown>;
|
|
35
35
|
sequenceTemplate?: Record<string, unknown>;
|
package/dist/tools/one-off.js
CHANGED
|
@@ -111,7 +111,7 @@ export const onDemandToolDefinitions = [
|
|
|
111
111
|
description: "Set true to overwrite existing sequence columns",
|
|
112
112
|
},
|
|
113
113
|
},
|
|
114
|
-
required: ["name"
|
|
114
|
+
required: ["name"],
|
|
115
115
|
},
|
|
116
116
|
},
|
|
117
117
|
{
|
|
@@ -194,7 +194,15 @@ export async function createOnDemandTable(input) {
|
|
|
194
194
|
throw new Error("VALIDATION_ERROR: create_on_demand_table requires either clientProspectId (existing prospect ID) or senderLinkedinUrl (sender's LinkedIn profile URL). Pass one.");
|
|
195
195
|
}
|
|
196
196
|
const api = getApi();
|
|
197
|
-
|
|
197
|
+
const payload = { ...input };
|
|
198
|
+
const senderIds = Array.isArray(input.senderIds) ? input.senderIds : [];
|
|
199
|
+
if (senderIds.length > 0) {
|
|
200
|
+
payload.senderIds = senderIds;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
delete payload.senderIds;
|
|
204
|
+
}
|
|
205
|
+
return api.post("/api/v3/on-demand-campaigns", payload);
|
|
198
206
|
}
|
|
199
207
|
export async function addOnDemandLeads(input) {
|
|
200
208
|
const api = getApi();
|
|
@@ -237,9 +245,6 @@ export async function createOnDemandCampaign(input) {
|
|
|
237
245
|
if (!input.clientProspectId && !input.senderLinkedinUrl) {
|
|
238
246
|
throw new Error("VALIDATION_ERROR: create_on_demand_campaign requires either clientProspectId (existing prospect ID) or senderLinkedinUrl (sender's LinkedIn profile URL). Pass one.");
|
|
239
247
|
}
|
|
240
|
-
if (!Array.isArray(input.senderIds) || input.senderIds.length === 0) {
|
|
241
|
-
throw new Error("senderIds must be a non-empty array");
|
|
242
|
-
}
|
|
243
248
|
const campaign = await createOnDemandTable({
|
|
244
249
|
name: input.name,
|
|
245
250
|
senderIds: input.senderIds,
|
|
@@ -284,7 +289,7 @@ export async function createOnDemandCampaign(input) {
|
|
|
284
289
|
return {
|
|
285
290
|
tableId,
|
|
286
291
|
campaignOfferId,
|
|
287
|
-
senderIds: input.senderIds,
|
|
292
|
+
senderIds: input.senderIds ?? [],
|
|
288
293
|
sequenceInitialized: true,
|
|
289
294
|
};
|
|
290
295
|
}
|
package/dist/tools/prompts.d.ts
CHANGED
package/dist/tools/prompts.js
CHANGED
|
@@ -211,6 +211,8 @@ export function getSourceScoutRegistry() {
|
|
|
211
211
|
codex: {
|
|
212
212
|
filename: String(agent.codex?.filename || `${agent.name}.toml`),
|
|
213
213
|
description: String(agent.codex?.description || ""),
|
|
214
|
+
model: String(agent.codex?.model || "gpt-5.5"),
|
|
215
|
+
modelReasoningEffort: String(agent.codex?.modelReasoningEffort || "high"),
|
|
214
216
|
},
|
|
215
217
|
claude: {
|
|
216
218
|
filename: String(agent.claude?.filename || `${agent.name}.md`),
|