@sellable/mcp 0.1.510 → 0.1.512
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/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/refill-journal.d.ts +49 -0
- package/dist/refill-journal.js +134 -0
- package/dist/refill-local-state.d.ts +31 -0
- package/dist/refill-local-state.js +96 -0
- package/dist/server.js +9 -4
- package/dist/tools/campaigns.d.ts +1 -54
- package/dist/tools/campaigns.js +3 -18
- package/dist/tools/evergreen-refill-plan.d.ts +49 -0
- package/dist/tools/evergreen-refill-plan.js +196 -0
- package/dist/tools/leads.d.ts +40 -2
- package/dist/tools/leads.js +107 -135
- package/dist/tools/prompts.d.ts +3 -3
- package/dist/tools/prompts.js +3 -1
- package/dist/tools/refill-sends-evergreen.d.ts +28 -0
- package/dist/tools/refill-sends-evergreen.js +47 -0
- package/dist/tools/refill-sends.d.ts +40 -38
- package/dist/tools/refill-sends.js +130 -261
- package/dist/tools/refill-target-plan.js +22 -3
- package/dist/tools/registry.d.ts +32 -141
- package/dist/tools/registry.js +4 -0
- package/dist/tools/senders.d.ts +2 -1
- package/dist/tools/senders.js +9 -7
- package/package.json +1 -1
- package/skills/refill-sends/SKILL.md +30 -10
- package/skills/refill-sends-evergreen/SKILL.md +84 -0
- package/skills/refill-sends-evergreen-workflow/SKILL.md +107 -0
- package/skills/refill-sends-evergreen-workflow/core/flow.v1.json +247 -0
- package/skills/refill-sends-workflow/SKILL.md +27 -2
- package/skills/refill-sends-workflow/core/flow.v1.json +281 -0
package/dist/index-dev.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export declare const DRY_RUN_MARKER = "**DRY RUN \u2014 no mutations performed**";
|
|
2
|
+
export declare const JOURNAL_SECTION_HEADINGS: {
|
|
3
|
+
readonly bootstrap: "## Bootstrap";
|
|
4
|
+
readonly plan: "## Plan";
|
|
5
|
+
readonly terminal: "## Terminal";
|
|
6
|
+
};
|
|
7
|
+
export declare function resolveRefillRunsRoot(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Throws on path-safety and permission failures. Callers must wrap the entire
|
|
10
|
+
* journal block and degrade to journalPath: null; journal failure must never
|
|
11
|
+
* abort a plan response.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createRunJournal(params: {
|
|
14
|
+
workspaceId: string;
|
|
15
|
+
runId?: string;
|
|
16
|
+
dryRun: boolean;
|
|
17
|
+
now?: Date;
|
|
18
|
+
}): {
|
|
19
|
+
filePath: string;
|
|
20
|
+
runId: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function appendJournalEvent(filePath: string, block: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* The index is a rebuildable cache. Directory listing is the source of truth;
|
|
25
|
+
* Phase 85 appends dry-run lines, Phase 86 maintains real-run entries.
|
|
26
|
+
*/
|
|
27
|
+
export declare function appendIndexLine(entry: {
|
|
28
|
+
runId: string;
|
|
29
|
+
fileName: string;
|
|
30
|
+
workspaceId: string;
|
|
31
|
+
dryRun: boolean;
|
|
32
|
+
summary: string;
|
|
33
|
+
}): void;
|
|
34
|
+
export declare function renderBootstrapSection(params: {
|
|
35
|
+
summary: string;
|
|
36
|
+
senderSummary?: string;
|
|
37
|
+
laneSummary?: string;
|
|
38
|
+
targetSummary?: string;
|
|
39
|
+
creditSummary?: string;
|
|
40
|
+
}): string;
|
|
41
|
+
export declare function renderPlanSection(params: {
|
|
42
|
+
chosenSummary: string;
|
|
43
|
+
itinerarySummaries?: string[];
|
|
44
|
+
fallbackSummary?: string;
|
|
45
|
+
}): string;
|
|
46
|
+
export declare function renderTerminalSection(params: {
|
|
47
|
+
summary: string;
|
|
48
|
+
finalNumbers?: string;
|
|
49
|
+
}): string;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
const REFILL_RUNS_ROOT_ENV = "SELLABLE_REFILL_RUNS_DIR";
|
|
6
|
+
export const DRY_RUN_MARKER = "**DRY RUN — no mutations performed**";
|
|
7
|
+
export const JOURNAL_SECTION_HEADINGS = {
|
|
8
|
+
bootstrap: "## Bootstrap",
|
|
9
|
+
plan: "## Plan",
|
|
10
|
+
terminal: "## Terminal",
|
|
11
|
+
};
|
|
12
|
+
function expandLeadingTilde(value) {
|
|
13
|
+
if (value === "~")
|
|
14
|
+
return os.homedir();
|
|
15
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
16
|
+
return path.join(os.homedir(), value.slice(2));
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function normalizeConfiguredRoot(value, label) {
|
|
21
|
+
const expanded = expandLeadingTilde(value);
|
|
22
|
+
if (!path.isAbsolute(expanded)) {
|
|
23
|
+
throw new Error(`${label} must be an absolute path.`);
|
|
24
|
+
}
|
|
25
|
+
return path.resolve(expanded);
|
|
26
|
+
}
|
|
27
|
+
export function resolveRefillRunsRoot() {
|
|
28
|
+
const envValue = process.env[REFILL_RUNS_ROOT_ENV]?.trim();
|
|
29
|
+
if (envValue) {
|
|
30
|
+
return normalizeConfiguredRoot(envValue, REFILL_RUNS_ROOT_ENV);
|
|
31
|
+
}
|
|
32
|
+
const home = os.homedir();
|
|
33
|
+
if (!home || !path.isAbsolute(home)) {
|
|
34
|
+
throw new Error(`Unable to resolve Sellable refill runs root: ${REFILL_RUNS_ROOT_ENV} is unset and home directory is unavailable.`);
|
|
35
|
+
}
|
|
36
|
+
return path.resolve(home, ".sellable/refill/runs");
|
|
37
|
+
}
|
|
38
|
+
function isPathInside(candidate, root) {
|
|
39
|
+
const relative = path.relative(root, candidate);
|
|
40
|
+
return (Boolean(relative) &&
|
|
41
|
+
!relative.startsWith("..") &&
|
|
42
|
+
!path.isAbsolute(relative));
|
|
43
|
+
}
|
|
44
|
+
function assertSafeRunId(runId) {
|
|
45
|
+
if (!/^[A-Za-z0-9_-]+$/.test(runId) ||
|
|
46
|
+
runId.includes("..") ||
|
|
47
|
+
runId.includes("/") ||
|
|
48
|
+
runId.includes("\\") ||
|
|
49
|
+
runId.includes("\0")) {
|
|
50
|
+
throw new Error("runId must be a safe filename segment.");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function utcBasicTimestamp(now) {
|
|
54
|
+
return `${now.toISOString().slice(0, 19).replace(/[-:]/g, "")}Z`;
|
|
55
|
+
}
|
|
56
|
+
function normalizeBlock(block) {
|
|
57
|
+
return block.endsWith("\n") ? block : `${block}\n`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Throws on path-safety and permission failures. Callers must wrap the entire
|
|
61
|
+
* journal block and degrade to journalPath: null; journal failure must never
|
|
62
|
+
* abort a plan response.
|
|
63
|
+
*/
|
|
64
|
+
export function createRunJournal(params) {
|
|
65
|
+
const runId = params.runId ?? randomBytes(4).toString("hex");
|
|
66
|
+
assertSafeRunId(runId);
|
|
67
|
+
const root = resolveRefillRunsRoot();
|
|
68
|
+
fs.mkdirSync(root, { recursive: true });
|
|
69
|
+
const normalizedRoot = path.resolve(root);
|
|
70
|
+
const fileName = `${utcBasicTimestamp(params.now ?? new Date())}-${runId}${params.dryRun ? "-dry" : ""}.md`;
|
|
71
|
+
const filePath = path.resolve(normalizedRoot, fileName);
|
|
72
|
+
if (!isPathInside(filePath, normalizedRoot)) {
|
|
73
|
+
throw new Error("Resolved journal path escapes refill runs root.");
|
|
74
|
+
}
|
|
75
|
+
const startedAt = (params.now ?? new Date()).toISOString();
|
|
76
|
+
const header = [
|
|
77
|
+
`# Refill Sends Evergreen Run ${runId}`,
|
|
78
|
+
"",
|
|
79
|
+
`- Run ID: ${runId}`,
|
|
80
|
+
`- Workspace ID: ${params.workspaceId}`,
|
|
81
|
+
`- Started at: ${startedAt}`,
|
|
82
|
+
params.dryRun ? `- ${DRY_RUN_MARKER}` : null,
|
|
83
|
+
"",
|
|
84
|
+
]
|
|
85
|
+
.filter((line) => line !== null)
|
|
86
|
+
.join("\n");
|
|
87
|
+
fs.appendFileSync(filePath, normalizeBlock(header), "utf8");
|
|
88
|
+
return { filePath, runId };
|
|
89
|
+
}
|
|
90
|
+
export function appendJournalEvent(filePath, block) {
|
|
91
|
+
try {
|
|
92
|
+
fs.appendFileSync(filePath, normalizeBlock(block), "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Best effort by design.
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The index is a rebuildable cache. Directory listing is the source of truth;
|
|
100
|
+
* Phase 85 appends dry-run lines, Phase 86 maintains real-run entries.
|
|
101
|
+
*/
|
|
102
|
+
export function appendIndexLine(entry) {
|
|
103
|
+
try {
|
|
104
|
+
const root = resolveRefillRunsRoot();
|
|
105
|
+
fs.mkdirSync(root, { recursive: true });
|
|
106
|
+
const marker = entry.dryRun ? " (dry)" : "";
|
|
107
|
+
fs.appendFileSync(path.join(root, "index.md"), `- ${entry.runId}${marker} [${entry.workspaceId}] ${entry.fileName} — ${entry.summary}\n`, "utf8");
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Best effort by design.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function renderLines(heading, lines) {
|
|
114
|
+
return normalizeBlock([heading, "", ...lines, ""].join("\n"));
|
|
115
|
+
}
|
|
116
|
+
export function renderBootstrapSection(params) {
|
|
117
|
+
return renderLines(JOURNAL_SECTION_HEADINGS.bootstrap, [
|
|
118
|
+
params.summary,
|
|
119
|
+
params.senderSummary,
|
|
120
|
+
params.laneSummary,
|
|
121
|
+
params.targetSummary,
|
|
122
|
+
params.creditSummary,
|
|
123
|
+
].filter((line) => Boolean(line)));
|
|
124
|
+
}
|
|
125
|
+
export function renderPlanSection(params) {
|
|
126
|
+
return renderLines(JOURNAL_SECTION_HEADINGS.plan, [
|
|
127
|
+
`Chosen: ${params.chosenSummary}`,
|
|
128
|
+
...(params.itinerarySummaries ?? []).map((summary) => `Next: ${summary}`),
|
|
129
|
+
params.fallbackSummary ? `Fallback: ${params.fallbackSummary}` : null,
|
|
130
|
+
].filter((line) => Boolean(line)));
|
|
131
|
+
}
|
|
132
|
+
export function renderTerminalSection(params) {
|
|
133
|
+
return renderLines(JOURNAL_SECTION_HEADINGS.terminal, [params.summary, params.finalNumbers].filter((line) => Boolean(line)));
|
|
134
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface RefillLaneMemoryEntry {
|
|
2
|
+
senderId: string;
|
|
3
|
+
laneKey: string;
|
|
4
|
+
outcome: string;
|
|
5
|
+
cooldownUntil: string;
|
|
6
|
+
reason: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RefillPassRateObservation {
|
|
9
|
+
campaignId: string;
|
|
10
|
+
enrichedCount: number;
|
|
11
|
+
passedCount: number;
|
|
12
|
+
observedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface RefillRunSummaryEntry {
|
|
15
|
+
runId: string;
|
|
16
|
+
endedAt: string;
|
|
17
|
+
terminalState: string;
|
|
18
|
+
sendsLoaded: number;
|
|
19
|
+
lanesTouched: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface RefillWorkspaceState {
|
|
22
|
+
laneMemory: RefillLaneMemoryEntry[];
|
|
23
|
+
passRates: RefillPassRateObservation[];
|
|
24
|
+
recentRuns: RefillRunSummaryEntry[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Advisory hints only. A missing, stale, corrupt, or malformed file means no
|
|
28
|
+
* hints; live planner reads remain the source of correctness. Phase 85 reads
|
|
29
|
+
* this section only. Phase 86 adds the writer plus writeJsonAtomic.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readRefillWorkspaceState(workspaceId: string): RefillWorkspaceState | null;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { getConfig } from "./auth.js";
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function isStringArray(value) {
|
|
6
|
+
return (Array.isArray(value) && value.every((entry) => typeof entry === "string"));
|
|
7
|
+
}
|
|
8
|
+
function readString(record, key) {
|
|
9
|
+
const value = record[key];
|
|
10
|
+
return typeof value === "string" ? value : null;
|
|
11
|
+
}
|
|
12
|
+
function readNumber(record, key) {
|
|
13
|
+
const value = record[key];
|
|
14
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
15
|
+
}
|
|
16
|
+
function parseLaneMemoryEntry(value) {
|
|
17
|
+
if (!isRecord(value))
|
|
18
|
+
return null;
|
|
19
|
+
const senderId = readString(value, "senderId");
|
|
20
|
+
const laneKey = readString(value, "laneKey");
|
|
21
|
+
const outcome = readString(value, "outcome");
|
|
22
|
+
const cooldownUntil = readString(value, "cooldownUntil");
|
|
23
|
+
const reason = readString(value, "reason");
|
|
24
|
+
if (!senderId || !laneKey || !outcome || !cooldownUntil || !reason) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return { senderId, laneKey, outcome, cooldownUntil, reason };
|
|
28
|
+
}
|
|
29
|
+
function parsePassRateObservation(value) {
|
|
30
|
+
if (!isRecord(value))
|
|
31
|
+
return null;
|
|
32
|
+
const campaignId = readString(value, "campaignId");
|
|
33
|
+
const enrichedCount = readNumber(value, "enrichedCount");
|
|
34
|
+
const passedCount = readNumber(value, "passedCount");
|
|
35
|
+
const observedAt = readString(value, "observedAt");
|
|
36
|
+
if (!campaignId ||
|
|
37
|
+
enrichedCount === null ||
|
|
38
|
+
passedCount === null ||
|
|
39
|
+
!observedAt) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return { campaignId, enrichedCount, passedCount, observedAt };
|
|
43
|
+
}
|
|
44
|
+
function parseRunSummaryEntry(value) {
|
|
45
|
+
if (!isRecord(value))
|
|
46
|
+
return null;
|
|
47
|
+
const runId = readString(value, "runId");
|
|
48
|
+
const endedAt = readString(value, "endedAt");
|
|
49
|
+
const terminalState = readString(value, "terminalState");
|
|
50
|
+
const sendsLoaded = readNumber(value, "sendsLoaded");
|
|
51
|
+
const lanesTouched = value.lanesTouched;
|
|
52
|
+
if (!runId ||
|
|
53
|
+
!endedAt ||
|
|
54
|
+
!terminalState ||
|
|
55
|
+
sendsLoaded === null ||
|
|
56
|
+
!isStringArray(lanesTouched)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return { runId, endedAt, terminalState, sendsLoaded, lanesTouched };
|
|
60
|
+
}
|
|
61
|
+
function parseArray(value, parser) {
|
|
62
|
+
if (!Array.isArray(value))
|
|
63
|
+
return [];
|
|
64
|
+
return value.flatMap((entry) => {
|
|
65
|
+
const parsed = parser(entry);
|
|
66
|
+
return parsed ? [parsed] : [];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Advisory hints only. A missing, stale, corrupt, or malformed file means no
|
|
71
|
+
* hints; live planner reads remain the source of correctness. Phase 85 reads
|
|
72
|
+
* this section only. Phase 86 adds the writer plus writeJsonAtomic.
|
|
73
|
+
*/
|
|
74
|
+
export function readRefillWorkspaceState(workspaceId) {
|
|
75
|
+
try {
|
|
76
|
+
const config = getConfig();
|
|
77
|
+
const refill = config.skillState
|
|
78
|
+
?.refill;
|
|
79
|
+
if (!isRecord(refill) || refill.version !== 1)
|
|
80
|
+
return null;
|
|
81
|
+
const byWorkspace = refill.byWorkspace;
|
|
82
|
+
if (!isRecord(byWorkspace))
|
|
83
|
+
return null;
|
|
84
|
+
const workspaceState = byWorkspace[workspaceId];
|
|
85
|
+
if (!isRecord(workspaceState))
|
|
86
|
+
return null;
|
|
87
|
+
return {
|
|
88
|
+
laneMemory: parseArray(workspaceState.laneMemory, parseLaneMemoryEntry),
|
|
89
|
+
passRates: parseArray(workspaceState.passRates, parsePassRateObservation),
|
|
90
|
+
recentRuns: parseArray(workspaceState.recentRuns, parseRunSummaryEntry),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -10,7 +10,9 @@ import { resolveCampaignFillRoute } from "./tools/campaign-fill-routing.js";
|
|
|
10
10
|
import { fillCampaignHorizon } from "./tools/campaign-horizon-fill.js";
|
|
11
11
|
import { cancelPrepareCampaignMessages, getPrepareCampaignMessagesStatus, startPrepareCampaignMessages, } from "./tools/campaign-message-preparation.js";
|
|
12
12
|
import { getCampaignRefillState } from "./tools/campaign-refill-state.js";
|
|
13
|
+
import { getEvergreenRefillPlan } from "./tools/evergreen-refill-plan.js";
|
|
13
14
|
import { getRefillTargetPlan } from "./tools/refill-target-plan.js";
|
|
15
|
+
import { refillSendsEvergreenCommand } from "./tools/refill-sends-evergreen.js";
|
|
14
16
|
import { getSchedulerFillCapacity } from "./tools/scheduler-fill-capacity.js";
|
|
15
17
|
import { getCampaignTableSchema, queueCampaignCells, recordCampaignReviewBatch, reviseMessageTemplateAndRerun, selectCampaignCells, waitForCampaignProcessing, } from "./tools/campaign-processing.js";
|
|
16
18
|
import { archiveCampaign, createCampaign, duplicateCampaign, getCampaign, getCampaignMessagesPreview, getCampaigns, pauseCampaign, startCampaign, updateCampaign, updateCampaignBrief, } from "./tools/campaigns.js";
|
|
@@ -223,6 +225,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
223
225
|
case "get_campaign_refill_state":
|
|
224
226
|
result = await getCampaignRefillState(args);
|
|
225
227
|
break;
|
|
228
|
+
case "get_evergreen_refill_plan":
|
|
229
|
+
result = await getEvergreenRefillPlan(args);
|
|
230
|
+
break;
|
|
226
231
|
case "get_refill_target_plan":
|
|
227
232
|
result = await getRefillTargetPlan(args);
|
|
228
233
|
break;
|
|
@@ -232,6 +237,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
232
237
|
case "refill_sends":
|
|
233
238
|
result = await executeRefillSendsCommand(args);
|
|
234
239
|
break;
|
|
240
|
+
case "refill_sends_evergreen":
|
|
241
|
+
result = refillSendsEvergreenCommand(args);
|
|
242
|
+
break;
|
|
235
243
|
case "setup_evergreen_campaigns":
|
|
236
244
|
result = await setupEvergreenCampaigns(args);
|
|
237
245
|
markEvergreenSetupCampaignsDirty(args);
|
|
@@ -305,10 +313,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
305
313
|
}
|
|
306
314
|
break;
|
|
307
315
|
case "start_campaign":
|
|
308
|
-
result = await startCampaign(
|
|
309
|
-
campaignId: args?.campaignId,
|
|
310
|
-
workspaceId: args?.workspaceId,
|
|
311
|
-
});
|
|
316
|
+
result = await startCampaign(args?.campaignId);
|
|
312
317
|
if (args?.campaignId && result?.success) {
|
|
313
318
|
markCampaignContextDirty(args.campaignId, "start_campaign");
|
|
314
319
|
}
|
|
@@ -185,7 +185,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
185
185
|
useMessagingTemplate?: undefined;
|
|
186
186
|
rubric?: undefined;
|
|
187
187
|
flowVersion?: undefined;
|
|
188
|
-
workspaceId?: undefined;
|
|
189
188
|
};
|
|
190
189
|
required: string[];
|
|
191
190
|
additionalProperties: boolean;
|
|
@@ -224,7 +223,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
224
223
|
useMessagingTemplate?: undefined;
|
|
225
224
|
rubric?: undefined;
|
|
226
225
|
flowVersion?: undefined;
|
|
227
|
-
workspaceId?: undefined;
|
|
228
226
|
};
|
|
229
227
|
required: never[];
|
|
230
228
|
additionalProperties?: undefined;
|
|
@@ -263,7 +261,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
263
261
|
useMessagingTemplate?: undefined;
|
|
264
262
|
rubric?: undefined;
|
|
265
263
|
flowVersion?: undefined;
|
|
266
|
-
workspaceId?: undefined;
|
|
267
264
|
};
|
|
268
265
|
required: string[];
|
|
269
266
|
additionalProperties?: undefined;
|
|
@@ -345,7 +342,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
345
342
|
useMessagingTemplate?: undefined;
|
|
346
343
|
rubric?: undefined;
|
|
347
344
|
flowVersion?: undefined;
|
|
348
|
-
workspaceId?: undefined;
|
|
349
345
|
};
|
|
350
346
|
required: string[];
|
|
351
347
|
additionalProperties: boolean;
|
|
@@ -540,7 +536,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
540
536
|
useMessagingTemplate?: undefined;
|
|
541
537
|
rubric?: undefined;
|
|
542
538
|
flowVersion?: undefined;
|
|
543
|
-
workspaceId?: undefined;
|
|
544
539
|
};
|
|
545
540
|
required: never[];
|
|
546
541
|
additionalProperties?: undefined;
|
|
@@ -746,49 +741,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
746
741
|
clientProspectId?: undefined;
|
|
747
742
|
senderLinkedinUrl?: undefined;
|
|
748
743
|
messageGenerationMode?: undefined;
|
|
749
|
-
workspaceId?: undefined;
|
|
750
|
-
};
|
|
751
|
-
required: string[];
|
|
752
|
-
additionalProperties?: undefined;
|
|
753
|
-
};
|
|
754
|
-
} | {
|
|
755
|
-
name: string;
|
|
756
|
-
description: string;
|
|
757
|
-
inputSchema: {
|
|
758
|
-
type: string;
|
|
759
|
-
properties: {
|
|
760
|
-
campaignId: {
|
|
761
|
-
type: string;
|
|
762
|
-
description: string;
|
|
763
|
-
};
|
|
764
|
-
workspaceId: {
|
|
765
|
-
type: string;
|
|
766
|
-
description: string;
|
|
767
|
-
};
|
|
768
|
-
limit?: undefined;
|
|
769
|
-
tableId?: undefined;
|
|
770
|
-
leadLimit?: undefined;
|
|
771
|
-
page?: undefined;
|
|
772
|
-
filters?: undefined;
|
|
773
|
-
name?: undefined;
|
|
774
|
-
clientProspectId?: undefined;
|
|
775
|
-
senderLinkedinUrl?: undefined;
|
|
776
|
-
offerPositioning?: undefined;
|
|
777
|
-
campaignBrief?: undefined;
|
|
778
|
-
messageGenerationMode?: undefined;
|
|
779
|
-
currentStep?: undefined;
|
|
780
|
-
watchNarration?: undefined;
|
|
781
|
-
leadSourceType?: undefined;
|
|
782
|
-
leadSourceProvider?: undefined;
|
|
783
|
-
selectedLeadListId?: undefined;
|
|
784
|
-
senderIds?: undefined;
|
|
785
|
-
currentStepTransition?: undefined;
|
|
786
|
-
clearCurrentStepIfMatches?: undefined;
|
|
787
|
-
interactionMode?: undefined;
|
|
788
|
-
enableICPFilters?: undefined;
|
|
789
|
-
useMessagingTemplate?: undefined;
|
|
790
|
-
rubric?: undefined;
|
|
791
|
-
flowVersion?: undefined;
|
|
792
744
|
};
|
|
793
745
|
required: string[];
|
|
794
746
|
additionalProperties?: undefined;
|
|
@@ -830,7 +782,6 @@ export declare const campaignToolDefinitions: ({
|
|
|
830
782
|
useMessagingTemplate?: undefined;
|
|
831
783
|
rubric?: undefined;
|
|
832
784
|
flowVersion?: undefined;
|
|
833
|
-
workspaceId?: undefined;
|
|
834
785
|
};
|
|
835
786
|
required: string[];
|
|
836
787
|
additionalProperties?: undefined;
|
|
@@ -870,11 +821,7 @@ export interface UpdateCampaignResult {
|
|
|
870
821
|
_campaign?: CampaignOfferNavigation;
|
|
871
822
|
}
|
|
872
823
|
export declare function updateCampaign(campaignId: string, input: UpdateCampaignInput): Promise<UpdateCampaignResult>;
|
|
873
|
-
|
|
874
|
-
campaignId?: string | null;
|
|
875
|
-
workspaceId?: string | null;
|
|
876
|
-
};
|
|
877
|
-
export declare function startCampaign(input: StartCampaignInput): Promise<{
|
|
824
|
+
export declare function startCampaign(campaignId: string): Promise<{
|
|
878
825
|
success: boolean;
|
|
879
826
|
}>;
|
|
880
827
|
export declare function pauseCampaign(campaignId: string): Promise<{
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -4,7 +4,6 @@ import { assertCreateCampaignPromptLoaded, assertNetNewCreateCampaignResearchRea
|
|
|
4
4
|
import { setCampaignInteractionMode, } from "./interaction-mode.js";
|
|
5
5
|
import { isLinkedInProfileInput, normalizeLinkedInProfileInput, } from "./linkedin-url.js";
|
|
6
6
|
import { fetchCampaignRubrics } from "./processing.js";
|
|
7
|
-
import { normalizeExplicitWorkspaceId, workspaceRequestOptions, } from "./workspace-context.js";
|
|
8
7
|
const LEAD_SOURCE_PROVIDERS = {
|
|
9
8
|
APOLLO: "apollo-ai",
|
|
10
9
|
SALES_NAV: "sales-nav",
|
|
@@ -457,7 +456,7 @@ export const campaignToolDefinitions = [
|
|
|
457
456
|
},
|
|
458
457
|
{
|
|
459
458
|
name: "start_campaign",
|
|
460
|
-
description: "Start a paused campaign, enabling the sweeper to send messages. This is an explicit human launch/start action
|
|
459
|
+
description: "Start a paused campaign, enabling the sweeper to send messages. This is an explicit human launch/start action and must not be used as part of fill-send-horizon, message preparation, or scheduling-proof flows.",
|
|
461
460
|
inputSchema: {
|
|
462
461
|
type: "object",
|
|
463
462
|
properties: {
|
|
@@ -465,10 +464,6 @@ export const campaignToolDefinitions = [
|
|
|
465
464
|
type: "string",
|
|
466
465
|
description: "Campaign ID to start",
|
|
467
466
|
},
|
|
468
|
-
workspaceId: {
|
|
469
|
-
type: "string",
|
|
470
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation.",
|
|
471
|
-
},
|
|
472
467
|
},
|
|
473
468
|
required: ["campaignId"],
|
|
474
469
|
},
|
|
@@ -1019,19 +1014,9 @@ export async function updateCampaign(campaignId, input) {
|
|
|
1019
1014
|
_campaign: result,
|
|
1020
1015
|
};
|
|
1021
1016
|
}
|
|
1022
|
-
export async function startCampaign(
|
|
1023
|
-
const campaignId = typeof input === "string" ? input : input.campaignId?.trim();
|
|
1024
|
-
if (!campaignId) {
|
|
1025
|
-
throw new Error("start_campaign requires campaignId");
|
|
1026
|
-
}
|
|
1027
|
-
const workspaceId = typeof input === "string"
|
|
1028
|
-
? null
|
|
1029
|
-
: normalizeExplicitWorkspaceId(input.workspaceId);
|
|
1030
|
-
const requestOptions = workspaceRequestOptions(workspaceId);
|
|
1017
|
+
export async function startCampaign(campaignId) {
|
|
1031
1018
|
const api = getApi();
|
|
1032
|
-
return
|
|
1033
|
-
? api.post(`/api/v3/campaigns/${campaignId}/start`, { workspaceId }, requestOptions)
|
|
1034
|
-
: api.post(`/api/v3/campaigns/${campaignId}/start`);
|
|
1019
|
+
return api.post(`/api/v3/campaigns/${campaignId}/start`);
|
|
1035
1020
|
}
|
|
1036
1021
|
export async function pauseCampaign(campaignId) {
|
|
1037
1022
|
const api = getApi();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type GetEvergreenRefillPlanInput = {
|
|
2
|
+
workspaceId?: string;
|
|
3
|
+
senderIds?: string[];
|
|
4
|
+
runState?: Record<string, unknown>;
|
|
5
|
+
journal?: boolean;
|
|
6
|
+
journalNote?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function sanitizeEvergreenRefillPlanResult(value: unknown): Record<string, unknown>;
|
|
9
|
+
export declare const evergreenRefillPlanToolDefinitions: {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: {
|
|
15
|
+
workspaceId: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
senderIds: {
|
|
20
|
+
type: string;
|
|
21
|
+
items: {
|
|
22
|
+
type: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
runState: {
|
|
26
|
+
type: string;
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
journal: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
journalNote: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
required: string[];
|
|
39
|
+
additionalProperties: boolean;
|
|
40
|
+
};
|
|
41
|
+
}[];
|
|
42
|
+
export declare function getEvergreenRefillPlan(input: GetEvergreenRefillPlanInput): Promise<{
|
|
43
|
+
warnings: any[];
|
|
44
|
+
journalPath: string | null;
|
|
45
|
+
text: string;
|
|
46
|
+
workspaceId: string;
|
|
47
|
+
workspaceResolution: string;
|
|
48
|
+
}>;
|
|
49
|
+
export {};
|