@sellable/mcp 0.1.503 → 0.1.504
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/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +2 -2
- package/dist/tools/campaign-fill-routing.d.ts +0 -5
- package/dist/tools/campaign-fill-routing.js +3 -13
- package/dist/tools/campaign-message-preparation.d.ts +48 -7
- package/dist/tools/campaign-message-preparation.js +44 -21
- package/dist/tools/campaign-processing.d.ts +0 -19
- package/dist/tools/campaign-processing.js +8 -31
- package/dist/tools/campaign-refill-state.d.ts +0 -5
- package/dist/tools/campaign-refill-state.js +3 -13
- package/dist/tools/leads.d.ts +47 -6
- package/dist/tools/leads.js +30 -26
- package/dist/tools/prompts.js +1 -1
- package/dist/tools/readiness.d.ts +0 -6
- package/dist/tools/readiness.js +5 -12
- package/dist/tools/refill-sends.d.ts +32 -34
- package/dist/tools/refill-sends.js +608 -67
- package/dist/tools/refill-target-plan.d.ts +0 -5
- package/dist/tools/refill-target-plan.js +65 -32
- package/dist/tools/registry.d.ts +48 -205
- package/dist/tools/scheduler-fill-capacity.d.ts +0 -5
- package/dist/tools/scheduler-fill-capacity.js +3 -13
- package/dist/tools/sender-routing.d.ts +1 -8
- package/dist/tools/sender-routing.js +3 -12
- package/dist/tools/senders.d.ts +1 -14
- package/dist/tools/senders.js +5 -31
- package/package.json +1 -1
- package/skills/refill-sends/SKILL.md +28 -49
- package/skills/refill-sends-workflow/SKILL.md +10 -15
- package/dist/tools/workspace-context.d.ts +0 -36
- package/dist/tools/workspace-context.js +0 -39
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
|
-
|
|
3
|
-
async function postSchedulerFillCapacity(body, workspaceId) {
|
|
2
|
+
async function postSchedulerFillCapacity(body) {
|
|
4
3
|
const api = getApi();
|
|
5
|
-
|
|
6
|
-
return requestOptions
|
|
7
|
-
? api.post("/api/v3/mcp/scheduler-fill-capacity", body, requestOptions)
|
|
8
|
-
: api.post("/api/v3/mcp/scheduler-fill-capacity", body);
|
|
4
|
+
return api.post("/api/v3/mcp/scheduler-fill-capacity", body);
|
|
9
5
|
}
|
|
10
6
|
export const schedulerFillCapacityToolDefinitions = [
|
|
11
7
|
{
|
|
@@ -59,10 +55,6 @@ export const schedulerFillCapacityToolDefinitions = [
|
|
|
59
55
|
enum: ["default_horizon", "target_date"],
|
|
60
56
|
description: "Optional mode hint. Omit for default_horizon; target_date requires targetDate.",
|
|
61
57
|
},
|
|
62
|
-
workspaceId: {
|
|
63
|
-
type: "string",
|
|
64
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
65
|
-
},
|
|
66
58
|
},
|
|
67
59
|
required: ["capacityRequests"],
|
|
68
60
|
additionalProperties: false,
|
|
@@ -70,11 +62,9 @@ export const schedulerFillCapacityToolDefinitions = [
|
|
|
70
62
|
},
|
|
71
63
|
];
|
|
72
64
|
export function getSchedulerFillCapacity(input) {
|
|
73
|
-
const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
|
|
74
65
|
return postSchedulerFillCapacity({
|
|
75
66
|
capacityRequests: input.capacityRequests,
|
|
76
67
|
targetDate: input.targetDate,
|
|
77
68
|
mode: input.mode,
|
|
78
|
-
|
|
79
|
-
}, workspaceId ?? undefined);
|
|
69
|
+
});
|
|
80
70
|
}
|
|
@@ -14,10 +14,6 @@ export declare const senderRoutingToolDefinitions: ({
|
|
|
14
14
|
inputSchema: {
|
|
15
15
|
type: string;
|
|
16
16
|
properties: {
|
|
17
|
-
workspaceId: {
|
|
18
|
-
type: string;
|
|
19
|
-
description: string;
|
|
20
|
-
};
|
|
21
17
|
rulesMarkdown?: undefined;
|
|
22
18
|
};
|
|
23
19
|
required: never[];
|
|
@@ -33,15 +29,12 @@ export declare const senderRoutingToolDefinitions: ({
|
|
|
33
29
|
type: string;
|
|
34
30
|
description: string;
|
|
35
31
|
};
|
|
36
|
-
workspaceId?: undefined;
|
|
37
32
|
};
|
|
38
33
|
required: never[];
|
|
39
34
|
additionalProperties: boolean;
|
|
40
35
|
};
|
|
41
36
|
})[];
|
|
42
|
-
export declare function getSenderRoutingTool(
|
|
43
|
-
workspaceId?: string;
|
|
44
|
-
}): Promise<SenderRoutingResponse>;
|
|
37
|
+
export declare function getSenderRoutingTool(): Promise<SenderRoutingResponse>;
|
|
45
38
|
export declare function setSenderRoutingTool(input?: {
|
|
46
39
|
rulesMarkdown?: string;
|
|
47
40
|
}): Promise<{
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
|
-
import { workspaceRequestOptions } from "./workspace-context.js";
|
|
3
2
|
const MAX_RULES_MARKDOWN_LENGTH = 65536;
|
|
4
3
|
export const senderRoutingToolDefinitions = [
|
|
5
4
|
{
|
|
@@ -7,12 +6,7 @@ export const senderRoutingToolDefinitions = [
|
|
|
7
6
|
description: "Return the workspace's territory routing rules markdown plus the connected sender roster. If configured is false, routing is inactive and all campaign senders are eligible everywhere.",
|
|
8
7
|
inputSchema: {
|
|
9
8
|
type: "object",
|
|
10
|
-
properties: {
|
|
11
|
-
workspaceId: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
14
|
-
},
|
|
15
|
-
},
|
|
9
|
+
properties: {},
|
|
16
10
|
required: [],
|
|
17
11
|
additionalProperties: false,
|
|
18
12
|
},
|
|
@@ -33,12 +27,9 @@ export const senderRoutingToolDefinitions = [
|
|
|
33
27
|
},
|
|
34
28
|
},
|
|
35
29
|
];
|
|
36
|
-
export async function getSenderRoutingTool(
|
|
30
|
+
export async function getSenderRoutingTool() {
|
|
37
31
|
const api = getApi();
|
|
38
|
-
|
|
39
|
-
return requestOptions
|
|
40
|
-
? api.get("/api/v3/sender-routing", requestOptions)
|
|
41
|
-
: api.get("/api/v3/sender-routing");
|
|
32
|
+
return api.get("/api/v3/sender-routing");
|
|
42
33
|
}
|
|
43
34
|
export async function setSenderRoutingTool(input = {}) {
|
|
44
35
|
if (input.rulesMarkdown &&
|
package/dist/tools/senders.d.ts
CHANGED
|
@@ -22,19 +22,14 @@ export type SenderListItem = {
|
|
|
22
22
|
export type ListSendersResponse = {
|
|
23
23
|
senders: SenderListItem[];
|
|
24
24
|
};
|
|
25
|
-
export type ListSendersInput = {
|
|
26
|
-
workspaceId?: string;
|
|
27
|
-
};
|
|
28
25
|
export type GetSenderInput = {
|
|
29
26
|
senderId: string;
|
|
30
|
-
workspaceId?: string;
|
|
31
27
|
};
|
|
32
28
|
export type SenderDetailResponse = {
|
|
33
29
|
sender: any;
|
|
34
30
|
};
|
|
35
31
|
export type RefreshPaidInmailCreditsInput = {
|
|
36
32
|
senderId: string;
|
|
37
|
-
workspaceId?: string;
|
|
38
33
|
};
|
|
39
34
|
export type PaidInmailCreditStatus = {
|
|
40
35
|
available: number;
|
|
@@ -62,10 +57,6 @@ export declare const senderToolDefinitions: ({
|
|
|
62
57
|
inputSchema: {
|
|
63
58
|
type: string;
|
|
64
59
|
properties: {
|
|
65
|
-
workspaceId: {
|
|
66
|
-
type: string;
|
|
67
|
-
description: string;
|
|
68
|
-
};
|
|
69
60
|
senderId?: undefined;
|
|
70
61
|
};
|
|
71
62
|
required: never[];
|
|
@@ -81,16 +72,12 @@ export declare const senderToolDefinitions: ({
|
|
|
81
72
|
type: string;
|
|
82
73
|
description: string;
|
|
83
74
|
};
|
|
84
|
-
workspaceId: {
|
|
85
|
-
type: string;
|
|
86
|
-
description: string;
|
|
87
|
-
};
|
|
88
75
|
};
|
|
89
76
|
required: string[];
|
|
90
77
|
additionalProperties: boolean;
|
|
91
78
|
};
|
|
92
79
|
})[];
|
|
93
|
-
export declare function listSenders(
|
|
80
|
+
export declare function listSenders(): Promise<ListSendersResponse>;
|
|
94
81
|
export declare function getSender(input: GetSenderInput): Promise<SenderDetailResponse>;
|
|
95
82
|
export declare function refreshPaidInmailCredits(input: RefreshPaidInmailCreditsInput): Promise<RefreshPaidInmailCreditsResponse>;
|
|
96
83
|
export {};
|
package/dist/tools/senders.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
2
|
import { isLinkedInProfileInput, normalizeLinkedInProfileInput, } from "./linkedin-url.js";
|
|
3
|
-
import { normalizeExplicitWorkspaceId, workspaceRequestOptions, } from "./workspace-context.js";
|
|
4
3
|
function pickString(...values) {
|
|
5
4
|
for (const value of values) {
|
|
6
5
|
if (typeof value !== "string")
|
|
@@ -108,12 +107,7 @@ export const senderToolDefinitions = [
|
|
|
108
107
|
description: "List outbound sender identities available in the active workspace, including LinkedIn profile URL and verified identity proof when available. In create-campaign flows, use this at Settings/final launch handoff to verify available connected senders; auto-select only when a sender has an exact identity match to the researched campaign identity. If identity proof is missing, ask the user to confirm the sender.",
|
|
109
108
|
inputSchema: {
|
|
110
109
|
type: "object",
|
|
111
|
-
properties: {
|
|
112
|
-
workspaceId: {
|
|
113
|
-
type: "string",
|
|
114
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
115
|
-
},
|
|
116
|
-
},
|
|
110
|
+
properties: {},
|
|
117
111
|
required: [],
|
|
118
112
|
additionalProperties: false,
|
|
119
113
|
},
|
|
@@ -125,10 +119,6 @@ export const senderToolDefinitions = [
|
|
|
125
119
|
type: "object",
|
|
126
120
|
properties: {
|
|
127
121
|
senderId: { type: "string", description: "Outbound sender ID" },
|
|
128
|
-
workspaceId: {
|
|
129
|
-
type: "string",
|
|
130
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation.",
|
|
131
|
-
},
|
|
132
122
|
},
|
|
133
123
|
required: ["senderId"],
|
|
134
124
|
additionalProperties: false,
|
|
@@ -144,22 +134,15 @@ export const senderToolDefinitions = [
|
|
|
144
134
|
type: "string",
|
|
145
135
|
description: "Exact Sender.id to refresh. The API verifies the sender belongs to the active workspace.",
|
|
146
136
|
},
|
|
147
|
-
workspaceId: {
|
|
148
|
-
type: "string",
|
|
149
|
-
description: "Explicit request-scoped workspace id for scheduled/yolo refill automation. Pass this instead of switching the shared active workspace.",
|
|
150
|
-
},
|
|
151
137
|
},
|
|
152
138
|
required: ["senderId"],
|
|
153
139
|
additionalProperties: false,
|
|
154
140
|
},
|
|
155
141
|
},
|
|
156
142
|
];
|
|
157
|
-
export async function listSenders(
|
|
143
|
+
export async function listSenders() {
|
|
158
144
|
const api = getApi();
|
|
159
|
-
const
|
|
160
|
-
const senders = requestOptions
|
|
161
|
-
? await api.get("/api/v1/outbound-sender-identities", requestOptions)
|
|
162
|
-
: await api.get("/api/v1/outbound-sender-identities");
|
|
145
|
+
const senders = await api.get("/api/v1/outbound-sender-identities");
|
|
163
146
|
return {
|
|
164
147
|
senders: (senders || []).map((s) => {
|
|
165
148
|
const linkedinProfileUrl = computeLinkedinProfileUrl(s);
|
|
@@ -180,11 +163,7 @@ export async function listSenders(input = {}) {
|
|
|
180
163
|
}
|
|
181
164
|
export async function getSender(input) {
|
|
182
165
|
const api = getApi();
|
|
183
|
-
const
|
|
184
|
-
const path = `/api/v1/outbound-sender-identities/${encodeURIComponent(input.senderId)}`;
|
|
185
|
-
const sender = requestOptions
|
|
186
|
-
? await api.get(path, requestOptions)
|
|
187
|
-
: await api.get(path);
|
|
166
|
+
const sender = await api.get(`/api/v1/outbound-sender-identities/${encodeURIComponent(input.senderId)}`);
|
|
188
167
|
return { sender };
|
|
189
168
|
}
|
|
190
169
|
function normalizeCreditStatus(raw) {
|
|
@@ -208,12 +187,7 @@ export async function refreshPaidInmailCredits(input) {
|
|
|
208
187
|
throw new Error("senderId is required.");
|
|
209
188
|
}
|
|
210
189
|
const api = getApi();
|
|
211
|
-
const
|
|
212
|
-
const requestOptions = workspaceRequestOptions(workspaceId);
|
|
213
|
-
const body = workspaceId ? { workspaceId } : {};
|
|
214
|
-
const result = requestOptions
|
|
215
|
-
? await api.post(`/api/v3/senders/${encodeURIComponent(senderId)}/refresh-inmail-credits`, body, requestOptions)
|
|
216
|
-
: await api.post(`/api/v3/senders/${encodeURIComponent(senderId)}/refresh-inmail-credits`, body);
|
|
190
|
+
const result = await api.post(`/api/v3/senders/${encodeURIComponent(senderId)}/refresh-inmail-credits`, {});
|
|
217
191
|
return {
|
|
218
192
|
senderId,
|
|
219
193
|
refreshed: true,
|
package/package.json
CHANGED
|
@@ -68,9 +68,6 @@ Accepted invocation flags in the same user request:
|
|
|
68
68
|
|
|
69
69
|
- `--yolo`: auto-accept the rendered bounded refill packet after the required
|
|
70
70
|
fresh state reread.
|
|
71
|
-
- `workspaceId: <id>`: required for scheduled automation and `--yolo`; pass it
|
|
72
|
-
through on every refill MCP tool call instead of relying on shared config
|
|
73
|
-
state.
|
|
74
71
|
- `--sender <name-or-id>`: scope to a specific sender; repeat for multiple
|
|
75
72
|
senders.
|
|
76
73
|
- `--until <YYYY-MM-DD>`: fill through that sender-local date, inclusive,
|
|
@@ -89,48 +86,23 @@ Accepted invocation flags in the same user request:
|
|
|
89
86
|
When the host can call typed MCP tools, start with:
|
|
90
87
|
|
|
91
88
|
```text
|
|
92
|
-
refill_sends({ yolo?: boolean,
|
|
89
|
+
refill_sends({ yolo?: boolean, senders?: string[], senderIds?: string[], senderNames?: string[], horizonSendDays?: number, untilDate?: "YYYY-MM-DD", targetDate?: "YYYY-MM-DD" })
|
|
93
90
|
```
|
|
94
91
|
|
|
95
|
-
That command helper
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
`
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
`--yolo` mode is a blocker; stop with `WORKSPACE_REQUIRED` instead of running
|
|
110
|
-
against an implicit or guessed workspace.
|
|
111
|
-
|
|
112
|
-
Do not solve scheduled or `--yolo` workspace uncertainty by changing the shared
|
|
113
|
-
active workspace. Manual interactive workspace switching remains a separate
|
|
114
|
-
diagnostic/setup flow, outside automation.
|
|
115
|
-
|
|
116
|
-
Examples:
|
|
117
|
-
|
|
118
|
-
```text
|
|
119
|
-
refill_sends({ yolo:true, executionMode:"yolo", requireWorkspace:true, workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
|
|
120
|
-
get_refill_target_plan({ intent:"plain", approvalMode:"approve", workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
|
|
121
|
-
list_senders({ workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Clover scheduled automation must name the Clover workspace explicitly:
|
|
125
|
-
|
|
126
|
-
```text
|
|
127
|
-
refill_sends({ yolo:false, executionMode:"scheduled", requireWorkspace:true, workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
|
|
128
|
-
get_refill_target_plan({ intent:"plain", approvalMode:"mark_ready", workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
First call `get_auth_status({})`. If auth is not OK, follow the returned login
|
|
132
|
-
guidance before route resolution. Do not run refill research against an implicit
|
|
133
|
-
or guessed workspace.
|
|
92
|
+
That command helper normalizes arguments and returns the execution contract. In
|
|
93
|
+
non-yolo mode it does not mutate. In `--yolo`, it may execute exactly one safe
|
|
94
|
+
bounded primitive from the fresh `target.globalActionQueue[0]`, then reread and
|
|
95
|
+
return the new target plan; currently safe primitives are paid-credit refresh,
|
|
96
|
+
existing-row message preparation, same-source row copy, and read-only wait
|
|
97
|
+
rereads. It does not run unbounded approval, lower
|
|
98
|
+
paid-InMail thresholds, switch source families, create campaigns, launch, send,
|
|
99
|
+
or write scheduler rows. Continue with the workflow below for route selection,
|
|
100
|
+
state rereads, approval gating, source import, preparation, and bounded
|
|
101
|
+
approval.
|
|
102
|
+
|
|
103
|
+
First call `get_auth_status({})`. If auth or active workspace is not OK, follow
|
|
104
|
+
the returned login/workspace guidance before route resolution. Do not run refill
|
|
105
|
+
research against an implicit or guessed workspace.
|
|
134
106
|
|
|
135
107
|
Treat "refill senders", "fill senders", "load everyone up", and "max out
|
|
136
108
|
senders" as sender-scoped requests. The target set is senders enrolled in active
|
|
@@ -193,18 +165,25 @@ Structured planner packet:
|
|
|
193
165
|
`Still need`.
|
|
194
166
|
- `target.globalActionQueue` is the only cross-sender yolo execution queue.
|
|
195
167
|
Execute exactly one globally ranked primitive from
|
|
196
|
-
`target.globalActionQueue[0]`, then rerun `get_refill_target_plan`
|
|
197
|
-
same `workspaceId` before
|
|
168
|
+
`target.globalActionQueue[0]`, then rerun `get_refill_target_plan` before
|
|
198
169
|
choosing another action.
|
|
199
170
|
- `manualAlternates` are not yolo actions. Threshold lowering and campaign
|
|
200
171
|
creation are manual continuations only.
|
|
201
172
|
|
|
173
|
+
Refill action ladder: approve generated rows only when an explicit bounded
|
|
174
|
+
approval gate exists, process all existing same-campaign unenriched/unprepared
|
|
175
|
+
rows in bounded batches before any source work, then copy bounded net-new rows
|
|
176
|
+
from the selected source (`selectedLeadListId`, provider, and source
|
|
177
|
+
fingerprint preserved), then use provider-aligned source-more. A new source or
|
|
178
|
+
provider switch changes the reply-rate baseline and is a manual alternate, not a
|
|
179
|
+
`--yolo` side effect.
|
|
180
|
+
|
|
202
181
|
Run-local paid-credit guard: in `--yolo`, the `refill_sends` MCP command
|
|
203
182
|
automatically maintains a `refreshedPaidInmailSenderIds` set for the current
|
|
204
183
|
command call. If its first target plan has stale/missing paid-InMail credit
|
|
205
184
|
facts, it refreshes each selected sender at most once, reruns
|
|
206
185
|
`get_refill_target_plan`, and returns the post-refresh `targetPlan` before
|
|
207
|
-
choosing the next prep/approval/
|
|
186
|
+
choosing the next prep/source-copy/bounded-approval/read-only wait action. If fresh facts are still below
|
|
208
187
|
threshold, below-threshold paid-InMail facts fall back to an existing connection
|
|
209
188
|
lane, the same Sales Nav cascade campaign's connection branch, or a manual
|
|
210
189
|
continuation.
|
|
@@ -271,7 +250,7 @@ If Christian includes `--yolo` in the same refill request, treat that flag as
|
|
|
271
250
|
auto-accept for the rendered bounded refill packet after the required fresh state
|
|
272
251
|
reread. For sender-scoped language with no named senders, `--yolo` means all
|
|
273
252
|
eligible healthy senders enrolled in active campaign-backed sequence campaigns in
|
|
274
|
-
the
|
|
253
|
+
the active workspace. Without `--yolo`, if Christian did not name senders, ask
|
|
275
254
|
which eligible enrolled senders to refill before choosing campaigns or mutating.
|
|
276
255
|
|
|
277
256
|
`--yolo` only covers the exact sender set, per-sender target campaigns, caps,
|
|
@@ -293,7 +272,7 @@ they change `stateRevision`, not `targetShapeRevision`, and do not require a
|
|
|
293
272
|
second approval.
|
|
294
273
|
|
|
295
274
|
In `--yolo`, continue as far as the rendered packet safely allows. After each
|
|
296
|
-
apply/prep/
|
|
275
|
+
apply/prep/source-copy/bounded-approval/read-only wait result, reread state, settle processing when needed, and move to
|
|
297
276
|
the next selected sender or start-eligible same-packet campaign instead of
|
|
298
277
|
stopping after the first partial result. If no in-packet safe action remains,
|
|
299
278
|
return concrete continuation options with campaign names, exact ids, which option
|
|
@@ -307,7 +286,7 @@ selected sender: selected send days, gross capacity, actual sent cells, future
|
|
|
307
286
|
scheduler-owned scheduled cells with non-null `scheduledFor`, projected count,
|
|
308
287
|
ready-to-schedule buffer, remaining projected gap, paid-InMail feasibility,
|
|
309
288
|
`targetShapeRevision`, `stateRevision`, and the next MCP primitive that can
|
|
310
|
-
reduce the gap. After every apply/prep/
|
|
289
|
+
reduce the gap. After every apply/prep/source-copy/bounded-approval/read-only wait result, wait for processing, reread
|
|
311
290
|
the target plan/refill state, recompute the ledger, then keep applying safe
|
|
312
291
|
bounded actions until projected coverage fills the target window or a concrete
|
|
313
292
|
non-scheduler blocker is proven.
|
|
@@ -61,17 +61,6 @@ senders", and "load everyone up". A sender-scoped request targets senders
|
|
|
61
61
|
enrolled in active campaign-backed sequence campaigns, not one arbitrary active
|
|
62
62
|
campaign.
|
|
63
63
|
|
|
64
|
-
Workspace contract: scheduled automation and `--yolo` must carry an explicit
|
|
65
|
-
request-scoped `workspaceId`. Pass that same `workspaceId` on every refill tool
|
|
66
|
-
call in this workflow: `get_refill_target_plan`, `list_senders`,
|
|
67
|
-
`get_sender_routing`, `resolve_campaign_fill_route`,
|
|
68
|
-
`get_campaign_refill_state`, `get_scheduler_fill_capacity`,
|
|
69
|
-
`refresh_paid_inmail_credits`, source import/readiness calls, preparation calls,
|
|
70
|
-
approval calls, and campaign start calls. Missing `workspaceId` in scheduled or
|
|
71
|
-
`--yolo` mode is a blocker; return or report `WORKSPACE_REQUIRED` instead of
|
|
72
|
-
falling back to shared config state. Manual interactive workspace switching is
|
|
73
|
-
diagnostic setup only and is not an automation control path.
|
|
74
|
-
|
|
75
64
|
Goal-mode continuation: a skill cannot create or invoke `/goal` by itself. When
|
|
76
65
|
this workflow is already running inside an active Codex goal, keep that goal
|
|
77
66
|
open until every selected sender lane is horizon-filled by projected coverage
|
|
@@ -114,18 +103,24 @@ in-progress wait state, not a reason to mark the goal complete or blocked.
|
|
|
114
103
|
`Still need`.
|
|
115
104
|
- `target.globalActionQueue` is the only cross-sender yolo execution queue.
|
|
116
105
|
execute exactly one globally ranked primitive from
|
|
117
|
-
`target.globalActionQueue[0]`, then rerun `get_refill_target_plan`
|
|
118
|
-
the same `workspaceId` before
|
|
106
|
+
`target.globalActionQueue[0]`, then rerun `get_refill_target_plan` before
|
|
119
107
|
choosing another action.
|
|
120
108
|
- `nextActions[0]` is the current sender's smallest safe primitive.
|
|
121
109
|
- `manualAlternates` are not yolo actions. Threshold lowering and campaign
|
|
122
110
|
creation are manual continuations only.
|
|
111
|
+
Refill action ladder: approve generated rows only when an explicit bounded
|
|
112
|
+
approval gate exists, process all existing same-campaign
|
|
113
|
+
unenriched/unprepared rows in bounded batches before any source work, then
|
|
114
|
+
copy bounded net-new rows from the selected source (`selectedLeadListId`,
|
|
115
|
+
provider, and source fingerprint preserved), then use provider-aligned
|
|
116
|
+
source-more. A new source or provider switch changes the reply-rate baseline
|
|
117
|
+
and is a manual alternate, not a `--yolo` side effect.
|
|
123
118
|
Run-local paid-credit guard: in `--yolo`, the `refill_sends` MCP command
|
|
124
119
|
automatically maintains a `refreshedPaidInmailSenderIds` set for the current
|
|
125
120
|
command call. If its first target plan has stale/missing paid-InMail credit
|
|
126
121
|
facts, it refreshes each selected sender at most once, reruns
|
|
127
122
|
`get_refill_target_plan`, and returns the post-refresh `targetPlan` before
|
|
128
|
-
choosing the next prep/approval/
|
|
123
|
+
choosing the next prep/source-copy/bounded-approval/read-only wait action. If fresh facts are still below
|
|
129
124
|
threshold, below-threshold paid-InMail facts fall back to an existing
|
|
130
125
|
connection lane, the same Sales Nav cascade campaign's connection branch, or
|
|
131
126
|
a manual continuation.
|
|
@@ -564,7 +559,7 @@ same refill request, do not ask the `Accept` / `Decline` question. Instead:
|
|
|
564
559
|
caps/dates, approval mode, blockers, and side-effect class still match the
|
|
565
560
|
packet;
|
|
566
561
|
4. execute only the exact packet;
|
|
567
|
-
5. after each terminal credit-refresh/apply/prep/
|
|
562
|
+
5. after each terminal credit-refresh/apply/prep/source-copy/bounded-approval/read-only wait result, rerun
|
|
568
563
|
`get_refill_target_plan`, reread state, settle processing when needed,
|
|
569
564
|
recompute the target-window saturation ledger, and continue with the next smallest
|
|
570
565
|
safe action inside the same bounded packet until every selected sender is
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { ApiRequestOptions } from "../api.js";
|
|
2
|
-
export type WorkspaceExecutionMode = "manual" | "scheduled" | "yolo";
|
|
3
|
-
export interface CreateWorkspaceContextInput {
|
|
4
|
-
workspaceId?: string | null;
|
|
5
|
-
executionMode: WorkspaceExecutionMode;
|
|
6
|
-
toolName?: string;
|
|
7
|
-
runId?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface WorkspaceContext {
|
|
10
|
-
workspaceId: string;
|
|
11
|
-
requestOptions: Readonly<ApiRequestOptions>;
|
|
12
|
-
executionMode: WorkspaceExecutionMode;
|
|
13
|
-
toolName?: string;
|
|
14
|
-
runId: string;
|
|
15
|
-
workspaceResolution: "explicit";
|
|
16
|
-
}
|
|
17
|
-
export interface WorkspaceRequiredResult {
|
|
18
|
-
ok: false;
|
|
19
|
-
code: "WORKSPACE_REQUIRED";
|
|
20
|
-
message: string;
|
|
21
|
-
executionMode: WorkspaceExecutionMode;
|
|
22
|
-
toolName?: string;
|
|
23
|
-
workspaceResolution: "missing";
|
|
24
|
-
}
|
|
25
|
-
export interface WorkspaceContextResult {
|
|
26
|
-
ok: true;
|
|
27
|
-
context: Readonly<WorkspaceContext>;
|
|
28
|
-
}
|
|
29
|
-
export type CreateWorkspaceContextResult = WorkspaceContextResult | WorkspaceRequiredResult;
|
|
30
|
-
export declare function workspaceRequired(params: {
|
|
31
|
-
executionMode: WorkspaceExecutionMode;
|
|
32
|
-
toolName?: string;
|
|
33
|
-
}): WorkspaceRequiredResult;
|
|
34
|
-
export declare function normalizeExplicitWorkspaceId(value: unknown): string | null;
|
|
35
|
-
export declare function workspaceRequestOptions(workspaceId: unknown): Readonly<ApiRequestOptions> | undefined;
|
|
36
|
-
export declare function createWorkspaceContext(input: CreateWorkspaceContextInput): CreateWorkspaceContextResult;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
export function workspaceRequired(params) {
|
|
3
|
-
const toolLabel = params.toolName ? ` for ${params.toolName}` : "";
|
|
4
|
-
return {
|
|
5
|
-
ok: false,
|
|
6
|
-
code: "WORKSPACE_REQUIRED",
|
|
7
|
-
message: `Explicit workspaceId is required${toolLabel} in ${params.executionMode} mode. ` +
|
|
8
|
-
"Pass workspaceId on the tool call instead of switching the shared active workspace.",
|
|
9
|
-
executionMode: params.executionMode,
|
|
10
|
-
toolName: params.toolName,
|
|
11
|
-
workspaceResolution: "missing",
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export function normalizeExplicitWorkspaceId(value) {
|
|
15
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
16
|
-
}
|
|
17
|
-
export function workspaceRequestOptions(workspaceId) {
|
|
18
|
-
const normalized = normalizeExplicitWorkspaceId(workspaceId);
|
|
19
|
-
return normalized ? Object.freeze({ workspaceId: normalized }) : undefined;
|
|
20
|
-
}
|
|
21
|
-
export function createWorkspaceContext(input) {
|
|
22
|
-
const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
|
|
23
|
-
if (!workspaceId) {
|
|
24
|
-
return workspaceRequired({
|
|
25
|
-
executionMode: input.executionMode,
|
|
26
|
-
toolName: input.toolName,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
const requestOptions = Object.freeze({ workspaceId });
|
|
30
|
-
const context = Object.freeze({
|
|
31
|
-
workspaceId,
|
|
32
|
-
requestOptions,
|
|
33
|
-
executionMode: input.executionMode,
|
|
34
|
-
toolName: input.toolName,
|
|
35
|
-
runId: input.runId?.trim() || randomUUID(),
|
|
36
|
-
workspaceResolution: "explicit",
|
|
37
|
-
});
|
|
38
|
-
return { ok: true, context };
|
|
39
|
-
}
|