@sellable/mcp 0.1.504 → 0.1.505
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/api.d.ts +5 -5
- package/dist/api.js +10 -10
- package/dist/server.js +2 -2
- package/dist/tools/campaign-fill-routing.d.ts +5 -0
- package/dist/tools/campaign-fill-routing.js +13 -3
- package/dist/tools/campaign-message-preparation.d.ts +9 -0
- package/dist/tools/campaign-message-preparation.js +21 -5
- package/dist/tools/campaign-processing.d.ts +19 -0
- package/dist/tools/campaign-processing.js +31 -8
- package/dist/tools/campaign-refill-state.d.ts +5 -0
- package/dist/tools/campaign-refill-state.js +13 -3
- package/dist/tools/leads.d.ts +6 -0
- package/dist/tools/leads.js +16 -6
- package/dist/tools/readiness.d.ts +6 -0
- package/dist/tools/readiness.js +12 -5
- package/dist/tools/refill-sends.d.ts +34 -1
- package/dist/tools/refill-sends.js +58 -10
- package/dist/tools/refill-target-plan.d.ts +5 -0
- package/dist/tools/refill-target-plan.js +24 -4
- package/dist/tools/registry.d.ts +148 -0
- package/dist/tools/scheduler-fill-capacity.d.ts +5 -0
- package/dist/tools/scheduler-fill-capacity.js +13 -3
- package/dist/tools/sender-routing.d.ts +8 -1
- package/dist/tools/sender-routing.js +12 -3
- package/dist/tools/senders.d.ts +14 -1
- package/dist/tools/senders.js +31 -5
- package/dist/tools/workspace-context.d.ts +36 -0
- package/dist/tools/workspace-context.js +39 -0
- package/package.json +1 -1
- package/skills/refill-sends/SKILL.md +41 -6
- package/skills/refill-sends-workflow/SKILL.md +13 -1
package/dist/tools/readiness.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
2
|
import { hydrateCampaignContextFromNavigation } from "./context.js";
|
|
3
3
|
import { getCampaignNavigationState } from "./navigation.js";
|
|
4
|
+
import { workspaceRequestOptions } from "./workspace-context.js";
|
|
4
5
|
const DEFAULT_TIMEOUT_MS = 90000;
|
|
5
6
|
const DEFAULT_INTERVAL_MS = 2000;
|
|
6
7
|
const TOOL_CALL_TIMEOUT_GUARD_MS = 55000;
|
|
@@ -108,6 +109,10 @@ export const readinessToolDefinitions = [
|
|
|
108
109
|
type: "string",
|
|
109
110
|
description: "Campaign offer ID (used to resolve selectedLeadListId if leadListId is missing).",
|
|
110
111
|
},
|
|
112
|
+
workspaceId: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation.",
|
|
115
|
+
},
|
|
111
116
|
provider: {
|
|
112
117
|
type: "string",
|
|
113
118
|
description: "Lead provider (apollo, sales-nav, prospeo, signal-discovery). If omitted, derived from campaignOfferId when possible.",
|
|
@@ -193,6 +198,8 @@ export async function waitForCampaignTableReady(input) {
|
|
|
193
198
|
}
|
|
194
199
|
export async function waitForLeadListReady(input) {
|
|
195
200
|
const api = getApi();
|
|
201
|
+
const requestOptions = workspaceRequestOptions(input.workspaceId);
|
|
202
|
+
const apiGet = (path) => requestOptions ? api.get(path, requestOptions) : api.get(path);
|
|
196
203
|
const { effectiveTimeoutMs, guardApplied, requestedTimeoutMs } = resolveWaitTimeout(input.timeoutMs);
|
|
197
204
|
const intervalMs = Math.max(500, input.intervalMs ?? DEFAULT_INTERVAL_MS);
|
|
198
205
|
const requireRows = input.requireRows !== false;
|
|
@@ -201,7 +208,7 @@ export async function waitForLeadListReady(input) {
|
|
|
201
208
|
let provider = input.provider;
|
|
202
209
|
let targetLeadCount = input.targetLeadCount;
|
|
203
210
|
if (input.campaignOfferId && (!leadListId || !provider)) {
|
|
204
|
-
const campaign = await
|
|
211
|
+
const campaign = await apiGet(`/api/v2/campaign-offers/${input.campaignOfferId}`);
|
|
205
212
|
if (!leadListId) {
|
|
206
213
|
leadListId = campaign?.selectedLeadListId ?? undefined;
|
|
207
214
|
}
|
|
@@ -231,7 +238,7 @@ export async function waitForLeadListReady(input) {
|
|
|
231
238
|
while (Date.now() - start <= effectiveTimeoutMs) {
|
|
232
239
|
attempts += 1;
|
|
233
240
|
try {
|
|
234
|
-
const meta = await
|
|
241
|
+
const meta = await apiGet(`/api/v3/workflow-tables/${leadListId}?mode=meta`);
|
|
235
242
|
const rowCount = meta?.rowCount ?? 0;
|
|
236
243
|
lastRowCount = rowCount;
|
|
237
244
|
const config = meta?.table?.config ?? null;
|
|
@@ -321,7 +328,7 @@ export async function waitForLeadListReady(input) {
|
|
|
321
328
|
// If config didn't provide a status, fall back to provider-specific checks.
|
|
322
329
|
if (!configStatus) {
|
|
323
330
|
if (provider === "apollo") {
|
|
324
|
-
const statusResponse = await
|
|
331
|
+
const statusResponse = await apiGet(`/api/v3/lead-lists/${leadListId}/apollo-import/status`);
|
|
325
332
|
const status = statusResponse?.status ?? null;
|
|
326
333
|
lastStatus = status;
|
|
327
334
|
statusTarget = statusResponse?.progress?.targetLeadCount ?? null;
|
|
@@ -364,7 +371,7 @@ export async function waitForLeadListReady(input) {
|
|
|
364
371
|
}
|
|
365
372
|
else if (provider === "sales-nav") {
|
|
366
373
|
if (jobId) {
|
|
367
|
-
const statusResponse = await
|
|
374
|
+
const statusResponse = await apiGet(`/api/v3/sales-nav/export?jobId=${jobId}`);
|
|
368
375
|
const status = statusResponse?.job?.status ?? null;
|
|
369
376
|
lastStatus = status;
|
|
370
377
|
statusTarget = statusResponse?.job?.targetLeadCount ?? null;
|
|
@@ -410,7 +417,7 @@ export async function waitForLeadListReady(input) {
|
|
|
410
417
|
}
|
|
411
418
|
else if (provider === "prospeo") {
|
|
412
419
|
if (jobId) {
|
|
413
|
-
const statusResponse = await
|
|
420
|
+
const statusResponse = await apiGet(`/api/v3/lead-lists/${leadListId}/prospeo-import/status?jobId=${jobId}`);
|
|
414
421
|
const status = statusResponse?.job?.status ?? null;
|
|
415
422
|
lastStatus = status;
|
|
416
423
|
statusTarget = statusResponse?.job?.targetLeadCount ?? null;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
type RefillSendsIntent = "plain" | "active" | "evergreen";
|
|
2
2
|
type RefillSendsApprovalMode = "approve" | "mark_ready";
|
|
3
|
+
type RefillSendsExecutionMode = "manual" | "scheduled" | "yolo";
|
|
3
4
|
type RefillSendsCommandInput = {
|
|
4
5
|
yolo?: boolean;
|
|
6
|
+
executionMode?: RefillSendsExecutionMode;
|
|
7
|
+
requireWorkspace?: boolean;
|
|
8
|
+
workspaceId?: string | null;
|
|
5
9
|
senders?: string[];
|
|
6
10
|
senderIds?: string[];
|
|
7
11
|
senderNames?: string[];
|
|
@@ -23,6 +27,19 @@ export declare const refillSendsToolDefinitions: {
|
|
|
23
27
|
type: string;
|
|
24
28
|
description: string;
|
|
25
29
|
};
|
|
30
|
+
executionMode: {
|
|
31
|
+
type: string;
|
|
32
|
+
enum: string[];
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
requireWorkspace: {
|
|
36
|
+
type: string;
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
workspaceId: {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
};
|
|
26
43
|
senders: {
|
|
27
44
|
type: string;
|
|
28
45
|
items: {
|
|
@@ -89,6 +106,9 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
|
|
|
89
106
|
promptName: string;
|
|
90
107
|
workflowPromptName: string;
|
|
91
108
|
yolo: boolean;
|
|
109
|
+
executionMode: RefillSendsExecutionMode;
|
|
110
|
+
workspaceId: string | null;
|
|
111
|
+
workspaceResolution: string;
|
|
92
112
|
intent: RefillSendsIntent;
|
|
93
113
|
targetDate: string | null;
|
|
94
114
|
untilDate: string | null;
|
|
@@ -144,11 +164,12 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
|
|
|
144
164
|
tableId: string | undefined;
|
|
145
165
|
intent: RefillSendsIntent;
|
|
146
166
|
approvalMode: RefillSendsApprovalMode;
|
|
167
|
+
workspaceId: string | null;
|
|
147
168
|
};
|
|
148
169
|
};
|
|
149
170
|
};
|
|
150
171
|
};
|
|
151
|
-
export declare function executeRefillSendsCommand(input?: RefillSendsCommandInput): Promise<{
|
|
172
|
+
export declare function executeRefillSendsCommand(input?: RefillSendsCommandInput): Promise<import("./workspace-context.js").WorkspaceRequiredResult | {
|
|
152
173
|
autoPaidInmailRefresh: {
|
|
153
174
|
enabled: boolean;
|
|
154
175
|
status: string;
|
|
@@ -158,6 +179,8 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
158
179
|
refreshReceipts?: undefined;
|
|
159
180
|
attemptedSenderIds?: undefined;
|
|
160
181
|
targetPlanReread?: undefined;
|
|
182
|
+
workspaceId?: undefined;
|
|
183
|
+
workspaceResolution?: undefined;
|
|
161
184
|
};
|
|
162
185
|
yoloExecution: {
|
|
163
186
|
enabled: false;
|
|
@@ -173,6 +196,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
173
196
|
promptName: string;
|
|
174
197
|
workflowPromptName: string;
|
|
175
198
|
yolo: boolean;
|
|
199
|
+
executionMode: RefillSendsExecutionMode;
|
|
200
|
+
workspaceId: string | null;
|
|
201
|
+
workspaceResolution: string;
|
|
176
202
|
intent: RefillSendsIntent;
|
|
177
203
|
targetDate: string | null;
|
|
178
204
|
untilDate: string | null;
|
|
@@ -228,6 +254,7 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
228
254
|
tableId: string | undefined;
|
|
229
255
|
intent: RefillSendsIntent;
|
|
230
256
|
approvalMode: RefillSendsApprovalMode;
|
|
257
|
+
workspaceId: string | null;
|
|
231
258
|
};
|
|
232
259
|
};
|
|
233
260
|
};
|
|
@@ -254,6 +281,8 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
254
281
|
}[];
|
|
255
282
|
attemptedSenderIds: string[];
|
|
256
283
|
targetPlanReread: boolean;
|
|
284
|
+
workspaceId: string | null;
|
|
285
|
+
workspaceResolution: string;
|
|
257
286
|
note: string;
|
|
258
287
|
};
|
|
259
288
|
yoloExecution: {
|
|
@@ -278,6 +307,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
278
307
|
promptName: string;
|
|
279
308
|
workflowPromptName: string;
|
|
280
309
|
yolo: boolean;
|
|
310
|
+
executionMode: RefillSendsExecutionMode;
|
|
311
|
+
workspaceId: string | null;
|
|
312
|
+
workspaceResolution: string;
|
|
281
313
|
intent: RefillSendsIntent;
|
|
282
314
|
targetDate: string | null;
|
|
283
315
|
untilDate: string | null;
|
|
@@ -333,6 +365,7 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
333
365
|
tableId: string | undefined;
|
|
334
366
|
intent: RefillSendsIntent;
|
|
335
367
|
approvalMode: RefillSendsApprovalMode;
|
|
368
|
+
workspaceId: string | null;
|
|
336
369
|
};
|
|
337
370
|
};
|
|
338
371
|
};
|
|
@@ -4,6 +4,7 @@ import { confirmLeadList, importLeads, searchSignals, selectPromisingPosts, } fr
|
|
|
4
4
|
import { markProviderPromptLoaded } from "./provider-preflight.js";
|
|
5
5
|
import { getRefillTargetPlan } from "./refill-target-plan.js";
|
|
6
6
|
import { refreshPaidInmailCredits } from "./senders.js";
|
|
7
|
+
import { createWorkspaceContext, normalizeExplicitWorkspaceId, } from "./workspace-context.js";
|
|
7
8
|
const DEFAULT_SCHEDULER_FORWARD_HOURS = 48;
|
|
8
9
|
const PAID_INMAIL_REFRESH_MAX_ATTEMPTS = 3;
|
|
9
10
|
const PAID_INMAIL_REFRESH_RETRY_DELAY_MS = Number(process.env.SELLABLE_MCP_PAID_REFRESH_RETRY_DELAY_MS ?? "1000");
|
|
@@ -94,6 +95,19 @@ export const refillSendsToolDefinitions = [
|
|
|
94
95
|
type: "boolean",
|
|
95
96
|
description: "When true, auto-accept the rendered bounded refill packet after the required fresh state reread. Without sender selectors, yolo means all eligible healthy senders enrolled in active campaign-backed sequence campaigns.",
|
|
96
97
|
},
|
|
98
|
+
executionMode: {
|
|
99
|
+
type: "string",
|
|
100
|
+
enum: ["manual", "scheduled", "yolo"],
|
|
101
|
+
description: "Explicit run mode. scheduled and yolo require workspaceId and never fall back to the shared active workspace.",
|
|
102
|
+
},
|
|
103
|
+
requireWorkspace: {
|
|
104
|
+
type: "boolean",
|
|
105
|
+
description: "When true, require an explicit request-scoped workspaceId before any refill API call. Scheduled automation should set this.",
|
|
106
|
+
},
|
|
107
|
+
workspaceId: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this on every refill call instead of switching the shared active workspace.",
|
|
110
|
+
},
|
|
97
111
|
senders: {
|
|
98
112
|
type: "array",
|
|
99
113
|
items: { type: "string" },
|
|
@@ -150,11 +164,13 @@ export const refillSendsToolDefinitions = [
|
|
|
150
164
|
},
|
|
151
165
|
];
|
|
152
166
|
export function refillSendsCommand(input = {}) {
|
|
167
|
+
const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
|
|
153
168
|
const senders = normalizeStrings(input.senders);
|
|
154
169
|
const senderIds = normalizeStrings(input.senderIds);
|
|
155
170
|
const senderNames = normalizeStrings(input.senderNames);
|
|
156
171
|
const hasSenderSelectors = senders.length > 0 || senderIds.length > 0 || senderNames.length > 0;
|
|
157
172
|
const yolo = input.yolo === true;
|
|
173
|
+
const executionMode = input.executionMode ?? (yolo ? "yolo" : "manual");
|
|
158
174
|
const targetDate = normalizeTargetDate(input.targetDate);
|
|
159
175
|
const untilDate = targetDate ? null : normalizeUntilDate(input.untilDate);
|
|
160
176
|
const horizonSendDays = targetDate || untilDate
|
|
@@ -173,6 +189,9 @@ export function refillSendsCommand(input = {}) {
|
|
|
173
189
|
promptName: "refill-sends",
|
|
174
190
|
workflowPromptName: "refill-sends-workflow",
|
|
175
191
|
yolo,
|
|
192
|
+
executionMode,
|
|
193
|
+
workspaceId,
|
|
194
|
+
workspaceResolution: workspaceId ? "explicit" : "active_config",
|
|
176
195
|
intent,
|
|
177
196
|
targetDate,
|
|
178
197
|
untilDate,
|
|
@@ -211,7 +230,7 @@ export function refillSendsCommand(input = {}) {
|
|
|
211
230
|
firstOperationalSteps: [
|
|
212
231
|
'Load get_subskill_prompt({ subskillName: "refill-sends-workflow" }) before any product operation.',
|
|
213
232
|
"A skill cannot create or invoke /goal by itself. If this refill is already running inside an active Codex goal, keep that goal open until every selected sender lane is horizon-filled by projected coverage (sent + scheduled), Christian explicitly stops/statuses the run, or a concrete non-scheduler blocker appears.",
|
|
214
|
-
`Call get_refill_target_plan({ intent: "${intent}"${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""}${senderIds.length > 0 ? `, senderIds: ${JSON.stringify(senderIds)}` : ""}${senderNames.length > 0
|
|
233
|
+
`Call get_refill_target_plan({ intent: "${intent}"${workspaceId ? `, workspaceId: "${workspaceId}"` : ""}${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""}${senderIds.length > 0 ? `, senderIds: ${JSON.stringify(senderIds)}` : ""}${senderNames.length > 0
|
|
215
234
|
? `, senderNames: ${JSON.stringify(senderNames)}`
|
|
216
235
|
: ""}${senders.length > 0 ? `, senders: ${JSON.stringify(senders)}` : ""}${targetDate
|
|
217
236
|
? `, targetDate: "${targetDate}"`
|
|
@@ -225,9 +244,11 @@ export function refillSendsCommand(input = {}) {
|
|
|
225
244
|
"If get_refill_target_plan returns status complete, report eligible sender ledger, target.senderRefillPlans, gross target, selected days, sent count, scheduled count, projected count, campaign ids, targetShapeRevision, and no-op proof without asking for approval.",
|
|
226
245
|
"Refill target lanes are connection invites (send_invite), standalone paid InMails (send_inmail_closed), or unified Sales Nav cascades represented publicly as send_inmail_closed with campaign classification sales_nav_cascade. For a Sales Nav cascade, refill the selected campaign first; its sequence can route prospects to Open InMail, paid InMail while fresh credits are >= 5, or same-campaign connection fallback without asking for separate open/paid/connection campaigns. Do not count send_dm as horizon target capacity.",
|
|
227
246
|
"If remainingReadyOrProjectedGap is 0 but remainingProjectedGap is positive, run only a persistent read-only scheduler wait/reread loop; do not ask for prep/import/approval and do not close out while scheduler pickup is the only remaining state.",
|
|
228
|
-
`Resolve route with resolve_campaign_fill_route({ intent: "${intent}"${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""} }).`,
|
|
229
|
-
|
|
230
|
-
|
|
247
|
+
`Resolve route with resolve_campaign_fill_route({ intent: "${intent}"${workspaceId ? `, workspaceId: "${workspaceId}"` : ""}${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""} }).`,
|
|
248
|
+
`If the plain route shows stale managed waterfall evidence, archived/completed shared slots, or targets that do not cover the selected sender set, immediately call resolve_campaign_fill_route({ intent: "active"${workspaceId ? `, workspaceId: "${workspaceId}"` : ""} }) and inspect current dashboard-active ACTIVE/PAUSED campaign-backed sequence campaigns before declaring a sender blocked.`,
|
|
249
|
+
workspaceId
|
|
250
|
+
? `Call list_senders({ workspaceId: "${workspaceId}" }) and get_sender_routing({ workspaceId: "${workspaceId}" }), then resolve sender selectors against active enrolled campaign-backed sequence senders.`
|
|
251
|
+
: "Call list_senders and get_sender_routing, then resolve sender selectors against active enrolled campaign-backed sequence senders.",
|
|
231
252
|
targetDate
|
|
232
253
|
? `Use fill window targetDate="${targetDate}" as one exact sender-local date; prepare rows only for scheduler-fillable slots on that date. Do not treat it as an inclusive through-date.`
|
|
233
254
|
: untilDate
|
|
@@ -288,12 +309,14 @@ export function refillSendsCommand(input = {}) {
|
|
|
288
309
|
tableId: input.tableId,
|
|
289
310
|
intent,
|
|
290
311
|
approvalMode,
|
|
312
|
+
workspaceId,
|
|
291
313
|
},
|
|
292
314
|
},
|
|
293
315
|
},
|
|
294
316
|
};
|
|
295
317
|
}
|
|
296
318
|
function targetPlanInputFor(input = {}) {
|
|
319
|
+
const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
|
|
297
320
|
const senders = normalizeStrings(input.senders);
|
|
298
321
|
const senderIds = normalizeStrings(input.senderIds);
|
|
299
322
|
const senderNames = normalizeStrings(input.senderNames);
|
|
@@ -318,6 +341,7 @@ function targetPlanInputFor(input = {}) {
|
|
|
318
341
|
? {}
|
|
319
342
|
: { horizonSendDays }),
|
|
320
343
|
approvalMode,
|
|
344
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
321
345
|
};
|
|
322
346
|
}
|
|
323
347
|
function recordValue(value) {
|
|
@@ -721,11 +745,14 @@ async function continueSignalDiscoverySource(action) {
|
|
|
721
745
|
},
|
|
722
746
|
};
|
|
723
747
|
}
|
|
724
|
-
async function refreshPaidInmailCreditsWithRetry(senderId) {
|
|
748
|
+
async function refreshPaidInmailCreditsWithRetry(senderId, workspaceId) {
|
|
725
749
|
const errors = [];
|
|
726
750
|
for (let attempt = 1; attempt <= PAID_INMAIL_REFRESH_MAX_ATTEMPTS; attempt += 1) {
|
|
727
751
|
try {
|
|
728
|
-
const receipt = await refreshPaidInmailCredits({
|
|
752
|
+
const receipt = await refreshPaidInmailCredits({
|
|
753
|
+
senderId,
|
|
754
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
755
|
+
});
|
|
729
756
|
return { receipt, attempts: attempt, errors };
|
|
730
757
|
}
|
|
731
758
|
catch (error) {
|
|
@@ -899,8 +926,24 @@ async function executeOneYoloPrimitive(action) {
|
|
|
899
926
|
}
|
|
900
927
|
}
|
|
901
928
|
export async function executeRefillSendsCommand(input = {}) {
|
|
902
|
-
const
|
|
903
|
-
|
|
929
|
+
const yolo = input.yolo === true;
|
|
930
|
+
const executionMode = input.executionMode ?? (yolo ? "yolo" : "manual");
|
|
931
|
+
const mustHaveWorkspace = yolo || input.requireWorkspace === true || executionMode === "scheduled";
|
|
932
|
+
const workspaceContext = mustHaveWorkspace
|
|
933
|
+
? createWorkspaceContext({
|
|
934
|
+
workspaceId: input.workspaceId,
|
|
935
|
+
executionMode,
|
|
936
|
+
toolName: "refill_sends",
|
|
937
|
+
})
|
|
938
|
+
: null;
|
|
939
|
+
if (workspaceContext && !workspaceContext.ok) {
|
|
940
|
+
return workspaceContext;
|
|
941
|
+
}
|
|
942
|
+
const scopedInput = workspaceContext && workspaceContext.ok
|
|
943
|
+
? { ...input, workspaceId: workspaceContext.context.workspaceId }
|
|
944
|
+
: input;
|
|
945
|
+
const command = refillSendsCommand(scopedInput);
|
|
946
|
+
if (!yolo) {
|
|
904
947
|
return {
|
|
905
948
|
...command,
|
|
906
949
|
autoPaidInmailRefresh: {
|
|
@@ -918,14 +961,17 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
918
961
|
},
|
|
919
962
|
};
|
|
920
963
|
}
|
|
921
|
-
const
|
|
964
|
+
const workspaceId = workspaceContext && workspaceContext.ok
|
|
965
|
+
? workspaceContext.context.workspaceId
|
|
966
|
+
: normalizeExplicitWorkspaceId(scopedInput.workspaceId);
|
|
967
|
+
const targetPlanInput = targetPlanInputFor(scopedInput);
|
|
922
968
|
const targetPlanBeforePaidRefresh = await getRefillTargetPlan(targetPlanInput);
|
|
923
969
|
const refreshActions = collectPaidInmailRefreshActions(targetPlanBeforePaidRefresh);
|
|
924
970
|
const refreshedPaidInmailSenderIds = [];
|
|
925
971
|
const failedPaidInmailRefreshes = [];
|
|
926
972
|
const refreshReceipts = [];
|
|
927
973
|
for (const action of refreshActions) {
|
|
928
|
-
const refreshResult = await refreshPaidInmailCreditsWithRetry(action.senderId);
|
|
974
|
+
const refreshResult = await refreshPaidInmailCreditsWithRetry(action.senderId, workspaceId ?? undefined);
|
|
929
975
|
if (refreshResult.receipt) {
|
|
930
976
|
refreshedPaidInmailSenderIds.push(action.senderId);
|
|
931
977
|
refreshReceipts.push({
|
|
@@ -976,6 +1022,8 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
976
1022
|
refreshReceipts,
|
|
977
1023
|
attemptedSenderIds: refreshActions.map((action) => action.senderId),
|
|
978
1024
|
targetPlanReread: refreshActions.length > 0,
|
|
1025
|
+
workspaceId,
|
|
1026
|
+
workspaceResolution: workspaceId ? "explicit" : "active_config",
|
|
979
1027
|
note: refreshActions.length > 0
|
|
980
1028
|
? "refill_sends refreshed stale paid InMail credit facts internally with bounded retries, once per sender, then returned the post-refresh targetPlan."
|
|
981
1029
|
: "No stale or missing paid InMail credit refresh candidates were present in the initial target plan.",
|
|
@@ -12,6 +12,7 @@ type GetRefillTargetPlanInput = {
|
|
|
12
12
|
senders?: string[];
|
|
13
13
|
actionTypes?: string[];
|
|
14
14
|
approvalMode?: RefillTargetPlanApprovalMode;
|
|
15
|
+
workspaceId?: string;
|
|
15
16
|
};
|
|
16
17
|
export declare const refillTargetPlanToolDefinitions: {
|
|
17
18
|
name: string;
|
|
@@ -82,6 +83,10 @@ export declare const refillTargetPlanToolDefinitions: {
|
|
|
82
83
|
enum: string[];
|
|
83
84
|
description: string;
|
|
84
85
|
};
|
|
86
|
+
workspaceId: {
|
|
87
|
+
type: string;
|
|
88
|
+
description: string;
|
|
89
|
+
};
|
|
85
90
|
};
|
|
86
91
|
required: never[];
|
|
87
92
|
additionalProperties: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
|
+
import { normalizeExplicitWorkspaceId, workspaceRequestOptions, } from "./workspace-context.js";
|
|
2
3
|
const REFILL_TARGET_ACTION_TYPES = [
|
|
3
4
|
"send_invite",
|
|
4
5
|
"send_inmail_closed",
|
|
@@ -48,9 +49,12 @@ const SOURCE_PLAN_STATES = new Set([
|
|
|
48
49
|
"provider_missing",
|
|
49
50
|
"blocked",
|
|
50
51
|
]);
|
|
51
|
-
async function postRefillTargetPlan(body) {
|
|
52
|
+
async function postRefillTargetPlan(body, workspaceId) {
|
|
52
53
|
const api = getApi();
|
|
53
|
-
|
|
54
|
+
const requestOptions = workspaceRequestOptions(workspaceId);
|
|
55
|
+
return requestOptions
|
|
56
|
+
? api.post("/api/v3/mcp/refill-target-plan", body, requestOptions)
|
|
57
|
+
: api.post("/api/v3/mcp/refill-target-plan", body);
|
|
54
58
|
}
|
|
55
59
|
function isRecord(value) {
|
|
56
60
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
@@ -745,6 +749,10 @@ export const refillTargetPlanToolDefinitions = [
|
|
|
745
749
|
enum: ["approve", "mark_ready"],
|
|
746
750
|
description: 'Requested downstream approval mode. Use "approve" only for explicit fill/schedule requests.',
|
|
747
751
|
},
|
|
752
|
+
workspaceId: {
|
|
753
|
+
type: "string",
|
|
754
|
+
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
755
|
+
},
|
|
748
756
|
},
|
|
749
757
|
required: [],
|
|
750
758
|
additionalProperties: false,
|
|
@@ -752,6 +760,7 @@ export const refillTargetPlanToolDefinitions = [
|
|
|
752
760
|
},
|
|
753
761
|
];
|
|
754
762
|
export async function getRefillTargetPlan(input = {}) {
|
|
763
|
+
const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
|
|
755
764
|
const result = await postRefillTargetPlan({
|
|
756
765
|
intent: input.intent,
|
|
757
766
|
horizonSendDays: input.horizonSendDays,
|
|
@@ -764,6 +773,17 @@ export async function getRefillTargetPlan(input = {}) {
|
|
|
764
773
|
senders: input.senders,
|
|
765
774
|
actionTypes: input.actionTypes,
|
|
766
775
|
approvalMode: input.approvalMode,
|
|
767
|
-
|
|
768
|
-
|
|
776
|
+
...(workspaceId ? { workspaceId } : {}),
|
|
777
|
+
}, workspaceId ?? undefined);
|
|
778
|
+
const sanitized = sanitizeRefillTargetPlanResult(result);
|
|
779
|
+
if (!workspaceId || !isRecord(sanitized))
|
|
780
|
+
return sanitized;
|
|
781
|
+
return {
|
|
782
|
+
...sanitized,
|
|
783
|
+
request: isRecord(sanitized.request)
|
|
784
|
+
? { ...sanitized.request, workspaceId }
|
|
785
|
+
: { workspaceId },
|
|
786
|
+
workspaceId,
|
|
787
|
+
workspaceResolution: "explicit",
|
|
788
|
+
};
|
|
769
789
|
}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -499,6 +499,10 @@ export declare const allTools: ({
|
|
|
499
499
|
maximum: number;
|
|
500
500
|
description: string;
|
|
501
501
|
};
|
|
502
|
+
workspaceId: {
|
|
503
|
+
type: string;
|
|
504
|
+
description: string;
|
|
505
|
+
};
|
|
502
506
|
};
|
|
503
507
|
required: string[];
|
|
504
508
|
additionalProperties: boolean;
|
|
@@ -596,6 +600,10 @@ export declare const allTools: ({
|
|
|
596
600
|
tableId: {
|
|
597
601
|
type: string;
|
|
598
602
|
};
|
|
603
|
+
workspaceId: {
|
|
604
|
+
type: string;
|
|
605
|
+
description?: undefined;
|
|
606
|
+
};
|
|
599
607
|
targetPreparedMessages?: undefined;
|
|
600
608
|
maxRowsToCheck?: undefined;
|
|
601
609
|
batchSize?: undefined;
|
|
@@ -655,6 +663,10 @@ export declare const allTools: ({
|
|
|
655
663
|
enum: string[];
|
|
656
664
|
description: string;
|
|
657
665
|
};
|
|
666
|
+
workspaceId: {
|
|
667
|
+
type: string;
|
|
668
|
+
description: string;
|
|
669
|
+
};
|
|
658
670
|
};
|
|
659
671
|
required: string[];
|
|
660
672
|
additionalProperties: boolean;
|
|
@@ -688,6 +700,7 @@ export declare const allTools: ({
|
|
|
688
700
|
};
|
|
689
701
|
leadListId?: undefined;
|
|
690
702
|
campaignOfferId?: undefined;
|
|
703
|
+
workspaceId?: undefined;
|
|
691
704
|
provider?: undefined;
|
|
692
705
|
jobId?: undefined;
|
|
693
706
|
targetLeadCount?: undefined;
|
|
@@ -708,6 +721,9 @@ export declare const allTools: ({
|
|
|
708
721
|
tableId: {
|
|
709
722
|
type: string;
|
|
710
723
|
};
|
|
724
|
+
workspaceId: {
|
|
725
|
+
type: string;
|
|
726
|
+
};
|
|
711
727
|
columnRole?: undefined;
|
|
712
728
|
rowSelector?: undefined;
|
|
713
729
|
limit?: undefined;
|
|
@@ -738,6 +754,9 @@ export declare const allTools: ({
|
|
|
738
754
|
tableId: {
|
|
739
755
|
type: string;
|
|
740
756
|
};
|
|
757
|
+
workspaceId: {
|
|
758
|
+
type: string;
|
|
759
|
+
};
|
|
741
760
|
columnRole: {
|
|
742
761
|
type: string;
|
|
743
762
|
enum: string[];
|
|
@@ -795,6 +814,9 @@ export declare const allTools: ({
|
|
|
795
814
|
tableId: {
|
|
796
815
|
type: string;
|
|
797
816
|
};
|
|
817
|
+
workspaceId: {
|
|
818
|
+
type: string;
|
|
819
|
+
};
|
|
798
820
|
columnRole: {
|
|
799
821
|
type: string;
|
|
800
822
|
enum: string[];
|
|
@@ -856,6 +878,9 @@ export declare const allTools: ({
|
|
|
856
878
|
tableId: {
|
|
857
879
|
type: string;
|
|
858
880
|
};
|
|
881
|
+
workspaceId: {
|
|
882
|
+
type: string;
|
|
883
|
+
};
|
|
859
884
|
minPassedCount: {
|
|
860
885
|
type: string;
|
|
861
886
|
};
|
|
@@ -894,6 +919,9 @@ export declare const allTools: ({
|
|
|
894
919
|
tableId: {
|
|
895
920
|
type: string;
|
|
896
921
|
};
|
|
922
|
+
workspaceId: {
|
|
923
|
+
type: string;
|
|
924
|
+
};
|
|
897
925
|
rowIds: {
|
|
898
926
|
type: string;
|
|
899
927
|
items: {
|
|
@@ -935,6 +963,9 @@ export declare const allTools: ({
|
|
|
935
963
|
tableId: {
|
|
936
964
|
type: string;
|
|
937
965
|
};
|
|
966
|
+
workspaceId: {
|
|
967
|
+
type: string;
|
|
968
|
+
};
|
|
938
969
|
templateMarkdown: {
|
|
939
970
|
type: string;
|
|
940
971
|
};
|
|
@@ -2360,6 +2391,10 @@ export declare const allTools: ({
|
|
|
2360
2391
|
type: string;
|
|
2361
2392
|
description: string;
|
|
2362
2393
|
};
|
|
2394
|
+
workspaceId: {
|
|
2395
|
+
type: string;
|
|
2396
|
+
description: string;
|
|
2397
|
+
};
|
|
2363
2398
|
};
|
|
2364
2399
|
required: string[];
|
|
2365
2400
|
additionalProperties: boolean;
|
|
@@ -2412,6 +2447,96 @@ export declare const allTools: ({
|
|
|
2412
2447
|
required: string[];
|
|
2413
2448
|
additionalProperties: boolean;
|
|
2414
2449
|
};
|
|
2450
|
+
} | {
|
|
2451
|
+
name: string;
|
|
2452
|
+
description: string;
|
|
2453
|
+
inputSchema: {
|
|
2454
|
+
type: string;
|
|
2455
|
+
properties: {
|
|
2456
|
+
markdown: {
|
|
2457
|
+
type: string;
|
|
2458
|
+
description: string;
|
|
2459
|
+
};
|
|
2460
|
+
senderId: {
|
|
2461
|
+
type: string;
|
|
2462
|
+
description: string;
|
|
2463
|
+
};
|
|
2464
|
+
keyword?: undefined;
|
|
2465
|
+
totalReturned?: undefined;
|
|
2466
|
+
postsYielded?: undefined;
|
|
2467
|
+
name?: undefined;
|
|
2468
|
+
linkedinUrl?: undefined;
|
|
2469
|
+
reason?: undefined;
|
|
2470
|
+
fromSenderId?: undefined;
|
|
2471
|
+
toSenderId?: undefined;
|
|
2472
|
+
};
|
|
2473
|
+
required: string[];
|
|
2474
|
+
additionalProperties: boolean;
|
|
2475
|
+
};
|
|
2476
|
+
} | {
|
|
2477
|
+
name: string;
|
|
2478
|
+
description: string;
|
|
2479
|
+
inputSchema: {
|
|
2480
|
+
type: string;
|
|
2481
|
+
properties: {
|
|
2482
|
+
keyword: {
|
|
2483
|
+
type: string;
|
|
2484
|
+
description: string;
|
|
2485
|
+
};
|
|
2486
|
+
totalReturned: {
|
|
2487
|
+
type: string;
|
|
2488
|
+
description: string;
|
|
2489
|
+
};
|
|
2490
|
+
postsYielded: {
|
|
2491
|
+
type: string;
|
|
2492
|
+
description: string;
|
|
2493
|
+
};
|
|
2494
|
+
senderId: {
|
|
2495
|
+
type: string;
|
|
2496
|
+
description: string;
|
|
2497
|
+
};
|
|
2498
|
+
markdown?: undefined;
|
|
2499
|
+
name?: undefined;
|
|
2500
|
+
linkedinUrl?: undefined;
|
|
2501
|
+
reason?: undefined;
|
|
2502
|
+
fromSenderId?: undefined;
|
|
2503
|
+
toSenderId?: undefined;
|
|
2504
|
+
};
|
|
2505
|
+
required: string[];
|
|
2506
|
+
additionalProperties: boolean;
|
|
2507
|
+
};
|
|
2508
|
+
} | {
|
|
2509
|
+
name: string;
|
|
2510
|
+
description: string;
|
|
2511
|
+
inputSchema: {
|
|
2512
|
+
type: string;
|
|
2513
|
+
properties: {
|
|
2514
|
+
name: {
|
|
2515
|
+
type: string;
|
|
2516
|
+
description: string;
|
|
2517
|
+
};
|
|
2518
|
+
linkedinUrl: {
|
|
2519
|
+
type: string;
|
|
2520
|
+
description: string;
|
|
2521
|
+
};
|
|
2522
|
+
reason: {
|
|
2523
|
+
type: string;
|
|
2524
|
+
description: string;
|
|
2525
|
+
};
|
|
2526
|
+
senderId: {
|
|
2527
|
+
type: string;
|
|
2528
|
+
description: string;
|
|
2529
|
+
};
|
|
2530
|
+
markdown?: undefined;
|
|
2531
|
+
keyword?: undefined;
|
|
2532
|
+
totalReturned?: undefined;
|
|
2533
|
+
postsYielded?: undefined;
|
|
2534
|
+
fromSenderId?: undefined;
|
|
2535
|
+
toSenderId?: undefined;
|
|
2536
|
+
};
|
|
2537
|
+
required: string[];
|
|
2538
|
+
additionalProperties: boolean;
|
|
2539
|
+
};
|
|
2415
2540
|
} | {
|
|
2416
2541
|
name: string;
|
|
2417
2542
|
description: string;
|
|
@@ -2438,6 +2563,29 @@ export declare const allTools: ({
|
|
|
2438
2563
|
required: string[];
|
|
2439
2564
|
additionalProperties: boolean;
|
|
2440
2565
|
};
|
|
2566
|
+
} | {
|
|
2567
|
+
name: string;
|
|
2568
|
+
description: string;
|
|
2569
|
+
inputSchema: {
|
|
2570
|
+
type: string;
|
|
2571
|
+
properties: {
|
|
2572
|
+
senderId: {
|
|
2573
|
+
type: string;
|
|
2574
|
+
description: string;
|
|
2575
|
+
};
|
|
2576
|
+
markdown?: undefined;
|
|
2577
|
+
keyword?: undefined;
|
|
2578
|
+
totalReturned?: undefined;
|
|
2579
|
+
postsYielded?: undefined;
|
|
2580
|
+
name?: undefined;
|
|
2581
|
+
linkedinUrl?: undefined;
|
|
2582
|
+
reason?: undefined;
|
|
2583
|
+
fromSenderId?: undefined;
|
|
2584
|
+
toSenderId?: undefined;
|
|
2585
|
+
};
|
|
2586
|
+
required: string[];
|
|
2587
|
+
additionalProperties: boolean;
|
|
2588
|
+
};
|
|
2441
2589
|
} | {
|
|
2442
2590
|
name: string;
|
|
2443
2591
|
description: string;
|
|
@@ -10,6 +10,7 @@ type GetSchedulerFillCapacityInput = {
|
|
|
10
10
|
capacityRequests: SchedulerFillCapacityRequest[];
|
|
11
11
|
targetDate?: string;
|
|
12
12
|
mode?: SchedulerFillCapacityMode;
|
|
13
|
+
workspaceId?: string;
|
|
13
14
|
};
|
|
14
15
|
export declare const schedulerFillCapacityToolDefinitions: {
|
|
15
16
|
name: string;
|
|
@@ -56,6 +57,10 @@ export declare const schedulerFillCapacityToolDefinitions: {
|
|
|
56
57
|
enum: string[];
|
|
57
58
|
description: string;
|
|
58
59
|
};
|
|
60
|
+
workspaceId: {
|
|
61
|
+
type: string;
|
|
62
|
+
description: string;
|
|
63
|
+
};
|
|
59
64
|
};
|
|
60
65
|
required: string[];
|
|
61
66
|
additionalProperties: boolean;
|