@sellable/mcp 0.1.540 → 0.1.541

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.
Files changed (34) hide show
  1. package/README.md +2 -5
  2. package/dist/index-dev.js +0 -0
  3. package/dist/index.js +0 -0
  4. package/dist/refill-run-loop.d.ts +1 -9
  5. package/dist/refill-run-loop.js +91 -156
  6. package/dist/server.js +1 -1
  7. package/dist/tools/campaigns.d.ts +50 -1
  8. package/dist/tools/campaigns.js +6 -2
  9. package/dist/tools/evergreen-refill-plan.d.ts +0 -19
  10. package/dist/tools/evergreen-refill-plan.js +0 -19
  11. package/dist/tools/refill-executors.d.ts +7 -0
  12. package/dist/tools/refill-executors.js +23 -1
  13. package/dist/tools/refill-sends-v2.d.ts +0 -19
  14. package/dist/tools/refill-sends-v2.js +2 -31
  15. package/dist/tools/refill-sends.d.ts +12 -0
  16. package/dist/tools/refill-sends.js +58 -36
  17. package/dist/tools/refill-target-plan.js +6 -19
  18. package/dist/tools/registry.d.ts +49 -32
  19. package/dist/tools/scheduler-fill-capacity.js +1 -1
  20. package/dist/tools/scheduler-run.d.ts +1 -1
  21. package/dist/tools/scheduler-run.js +17 -20
  22. package/dist/tools/senders.d.ts +14 -8
  23. package/dist/tools/senders.js +21 -10
  24. package/package.json +1 -1
  25. package/skills/refill-sends/SKILL.md +1 -9
  26. package/skills/refill-sends-v2/SKILL.md +5 -18
  27. package/skills/refill-sends-v2-workflow/SKILL.md +2 -16
  28. package/skills/refill-sends-v2-workflow/core/flow.v1.json +3 -19
  29. package/skills/refill-sends-workflow/SKILL.md +3 -5
  30. package/skills/refill-sends-workflow/core/flow.v1.json +1 -1
  31. package/dist/refill-date-window.d.ts +0 -34
  32. package/dist/refill-date-window.js +0 -210
  33. package/dist/tools/refill-sends-evergreen.d.ts +0 -28
  34. package/dist/tools/refill-sends-evergreen.js +0 -47
package/README.md CHANGED
@@ -74,12 +74,9 @@ sending from:
74
74
 
75
75
  The refill-sends public command wrapper plans and executes approval-gated send
76
76
  refills. It supports `--yolo` and optional sender selectors such as
77
- `--sender "Christian Reyes"`, exact-date selectors such as
78
- `--target-date 2026-06-30`, optional through-date selectors such as
77
+ `--sender "Christian Reyes"`, optional through-date selectors such as
79
78
  `--until 2026-06-30`, or typed MCP calls to `refill_sends({ yolo, senders,
80
- horizonSendDays, targetDate, untilDate })`. Date selectors resolve by
81
- `targetDate > untilDate > horizonSendDays`, where `targetDate` means one exact
82
- sender-local date and `untilDate` means an inclusive through-date, from:
79
+ untilDate })` from:
83
80
 
84
81
  - `mcp/sellable/skills/refill-sends/SKILL.md`
85
82
 
package/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
@@ -13,9 +13,6 @@ export interface RefillV2LoopInput {
13
13
  };
14
14
  approvalMode?: "approve" | "mark_ready";
15
15
  dryRun?: boolean;
16
- targetDate?: string | null;
17
- untilDate?: string | null;
18
- horizonSendDays?: number | null;
19
16
  }
20
17
  export interface RefillV2LoopBudgets {
21
18
  maxGateCyclesPerInvocation: number;
@@ -63,9 +60,6 @@ export interface RefillV2LoopDeps {
63
60
  intent?: string;
64
61
  senderIds?: string[];
65
62
  runState?: Record<string, unknown>;
66
- targetDate?: string;
67
- untilDate?: string;
68
- horizonSendDays?: number;
69
63
  journal?: boolean;
70
64
  }) => Promise<Record<string, unknown>>;
71
65
  executors: RefillV2Executors;
@@ -74,9 +68,7 @@ export interface RefillV2LoopDeps {
74
68
  budgets?: Partial<RefillV2LoopBudgets>;
75
69
  now?: () => Date;
76
70
  sleep?: (ms: number) => Promise<void>;
77
- requestSchedulerRun?: (workspaceId: string, options?: {
78
- targetDate?: string;
79
- }) => Promise<unknown>;
71
+ requestSchedulerRun?: (workspaceId: string) => Promise<unknown>;
80
72
  }
81
73
  export type RefillV2LoopResult = {
82
74
  status: "dry_run";
@@ -1,7 +1,6 @@
1
1
  import { SellableApiError } from "./api.js";
2
- import { dateSelectorMatchesWindow, dateWindowFromPlan, dateWindowFromRunState, dateWindowFromSelector, normalizeRefillDateSelector, refillDateSelectorBody, schedulerSweepTargetDates, selectorFromDateWindow, } from "./refill-date-window.js";
3
2
  import { buildRunStateFromLocalHints } from "./tools/evergreen-refill-plan.js";
4
- import { prepareRowSelectorValue as defaultPrepareRowSelectorValue, refillPrepareRequestHash as defaultRefillPrepareRequestHash, } from "./tools/refill-executors.js";
3
+ import { classifyPaidInmailRefreshReceipt, prepareRowSelectorValue as defaultPrepareRowSelectorValue, refillPrepareRequestHash as defaultRefillPrepareRequestHash, } from "./tools/refill-executors.js";
5
4
  const DEFAULT_BUDGETS = {
6
5
  maxGateCyclesPerInvocation: 8,
7
6
  pollIntervalMs: 15_000,
@@ -380,16 +379,9 @@ function firstAction(plan) {
380
379
  }
381
380
  function doneReasonFromPlan(plan) {
382
381
  const action = firstAction(plan);
383
- const packet = recordValue(plan.packet) ?? {};
384
- const status = stringValue(plan.status) ?? stringValue(packet.status);
385
382
  return (stringValue(action?.doneReason) ??
386
- stringValue(packet.doneReason) ??
387
- stringValue(plan.doneReason) ??
388
- (status === "complete" ? "complete" : null) ??
389
- (status === "awaiting_scheduler_after_ready_buffer"
390
- ? "loaded_awaiting_scheduler"
391
- : null) ??
392
- (status === "blocked" ? "blocked" : null));
383
+ stringValue(recordValue(plan.packet)?.doneReason) ??
384
+ stringValue(plan.doneReason));
393
385
  }
394
386
  function selectedLaneAuthority(plan, action) {
395
387
  const senderId = actionSenderId(action);
@@ -425,41 +417,6 @@ function mergeRunState(current, updates) {
425
417
  ...updates,
426
418
  };
427
419
  }
428
- function dateSelectorFromInput(input) {
429
- return normalizeRefillDateSelector({
430
- targetDate: input.targetDate,
431
- untilDate: input.untilDate,
432
- horizonSendDays: input.horizonSendDays,
433
- });
434
- }
435
- function runStateWithDateWindow(runState, dateWindow) {
436
- return mergeRunState(runState, { dateWindow });
437
- }
438
- function readPlanRequest(input) {
439
- return {
440
- workspaceId: input.workspaceId,
441
- intent: input.intent,
442
- senderIds: input.senderIds,
443
- runState: input.runState,
444
- journal: input.journal,
445
- ...refillDateSelectorBody(input.dateSelector),
446
- };
447
- }
448
- async function readLoopPlan(input, deps, ctx, journal) {
449
- return deps.readPlan(readPlanRequest({
450
- workspaceId: input.workspaceId,
451
- intent: input.intent,
452
- senderIds: input.senderIds,
453
- runState: ctx.runState,
454
- journal,
455
- dateSelector: ctx.dateSelector,
456
- }));
457
- }
458
- function applyPlanDateWindow(ctx, plan) {
459
- ctx.dateWindow = dateWindowFromPlan(plan, ctx.dateSelector);
460
- ctx.dateSelector = selectorFromDateWindow(ctx.dateWindow);
461
- ctx.runState = runStateWithDateWindow(ctx.runState, ctx.dateWindow);
462
- }
463
420
  function normalizeDoneReason(value) {
464
421
  const raw = stringValue(value);
465
422
  if (!raw)
@@ -642,21 +599,17 @@ function getPlanLine(plan) {
642
599
  };
643
600
  }
644
601
  function packetCoherenceFailure(plan) {
602
+ const fingerprint = fingerprintFromPlan(plan);
603
+ if (!fingerprint.planRevision || !fingerprint.targetShapeRevision) {
604
+ return "missing_fingerprint";
605
+ }
645
606
  const action = firstAction(plan);
646
607
  const doneReason = doneReasonFromPlan(plan);
647
608
  if (doneReason && action && action.type !== "done") {
648
- const type = stringValue(action.type);
649
- if (!(doneReason === "loaded_awaiting_scheduler" &&
650
- type === "wait_for_scheduler")) {
651
- return "terminal_with_action_queue";
652
- }
609
+ return "terminal_with_action_queue";
653
610
  }
654
611
  if (!action)
655
612
  return null;
656
- const fingerprint = fingerprintFromPlan(plan);
657
- if (!fingerprint.planRevision || !fingerprint.targetShapeRevision) {
658
- return "missing_fingerprint";
659
- }
660
613
  const toolInput = actionToolInput(action);
661
614
  const type = stringValue(action.type);
662
615
  if (type === "prepare_messages" &&
@@ -717,63 +670,14 @@ async function createJournal(input, deps, runId) {
717
670
  return null;
718
671
  }
719
672
  }
720
- async function preflightResumeDateWindow(input, deps, requestedSelector) {
721
- const requestedWindow = dateWindowFromSelector(requestedSelector);
722
- if (!input.resume) {
723
- return { ok: true, selector: requestedSelector, window: requestedWindow };
724
- }
725
- const status = await deps.runClient.refillRunStatus({
726
- workspaceId: input.workspaceId,
727
- runId: input.resume.runId,
728
- });
729
- if (hasBlocker(status, "lease_lost")) {
730
- return {
731
- status: "blocked",
732
- blocker: "lease_lost",
733
- runId: input.resume.runId,
734
- fence: input.resume.fence,
735
- guidance: "Refill run lease was lost before resume date-window preflight.",
736
- };
737
- }
738
- const storedWindow = dateWindowFromRunState(recordValue(status)?.runState);
739
- const explicitSelector = requestedSelector.source !== "default_scheduler_forward";
740
- if (!storedWindow) {
741
- if (explicitSelector) {
742
- return {
743
- status: "blocked",
744
- blocker: "date_window_conflict",
745
- runId: input.resume.runId,
746
- fence: input.resume.fence,
747
- guidance: "This legacy refill_sends_v2 run has no stored date window. Resume it without a new date selector or start a new run.",
748
- report: { requestedDateWindow: requestedWindow },
749
- };
750
- }
751
- return { ok: true, selector: requestedSelector, window: requestedWindow };
752
- }
753
- if (explicitSelector && !dateSelectorMatchesWindow(requestedSelector, storedWindow)) {
754
- return {
755
- status: "blocked",
756
- blocker: "date_window_conflict",
757
- runId: input.resume.runId,
758
- fence: input.resume.fence,
759
- guidance: "Resume date selector conflicts with the stored refill run date window.",
760
- report: { requestedDateWindow: requestedWindow, storedDateWindow: storedWindow },
761
- };
762
- }
763
- const selector = explicitSelector
764
- ? requestedSelector
765
- : selectorFromDateWindow(storedWindow);
766
- return { ok: true, selector, window: storedWindow };
767
- }
768
- async function startOrResume(input, deps, dateWindow) {
769
- const initialRunState = runStateWithDateWindow(buildRunStateFromLocalHints(input.workspaceId), dateWindow);
673
+ async function startOrResume(input, deps) {
674
+ const initialRunState = buildRunStateFromLocalHints(input.workspaceId);
770
675
  const started = await deps.runClient.startRefillRunRemote({
771
676
  workspaceId: input.workspaceId,
772
677
  config: {
773
678
  intent: input.intent ?? "auto",
774
679
  senderIds: input.senderIds,
775
680
  approvalMode: input.approvalMode ?? "approve",
776
- dateWindow,
777
681
  },
778
682
  runState: initialRunState,
779
683
  resume: input.resume,
@@ -815,8 +719,6 @@ async function startOrResume(input, deps, dateWindow) {
815
719
  laneCooldowns: [],
816
720
  passRates: [],
817
721
  };
818
- const storedDateWindow = dateWindowFromRunState(runState) ?? dateWindow;
819
- const storedDateSelector = selectorFromDateWindow(storedDateWindow);
820
722
  const journalPath = await createJournal(input, deps, runId);
821
723
  const ctx = {
822
724
  workspaceId: input.workspaceId,
@@ -829,8 +731,6 @@ async function startOrResume(input, deps, dateWindow) {
829
731
  plan: null,
830
732
  headAction: null,
831
733
  lastFingerprint: null,
832
- dateSelector: storedDateSelector,
833
- dateWindow: storedDateWindow,
834
734
  recoveryPoint: recordValue(result.recoveryPoint),
835
735
  gateCycles: 0,
836
736
  sleptMs: 0,
@@ -849,31 +749,45 @@ async function startOrResume(input, deps, dateWindow) {
849
749
  return ctx;
850
750
  }
851
751
  async function gateBootstrap(input, deps, ctx) {
852
- const plan = await readLoopPlan(input, deps, ctx, false);
853
- applyPlanDateWindow(ctx, plan);
752
+ const plan = await deps.readPlan({
753
+ workspaceId: input.workspaceId,
754
+ intent: input.intent,
755
+ senderIds: input.senderIds,
756
+ runState: ctx.runState,
757
+ journal: false,
758
+ });
854
759
  const paidCredit = arrayValue(recordValue(plan.bootstrap)?.paidCredit).filter(isRecord);
855
760
  const refreshedSenderIds = new Set(arrayValue(recordValue(ctx.runState.creditTrust)?.senderIds)
856
761
  .map((entry) => stringValue(entry))
857
762
  .filter((entry) => Boolean(entry)));
763
+ const attemptedSenderIds = new Set(arrayValue(recordValue(ctx.runState.creditTrust)?.attemptedSenderIds)
764
+ .map((entry) => stringValue(entry))
765
+ .filter((entry) => Boolean(entry)));
858
766
  const receipts = [];
859
767
  for (const entry of paidCredit) {
860
768
  const senderId = stringValue(entry.senderId);
861
769
  if (!senderId ||
862
770
  !entry.plannedJitRefresh ||
863
- refreshedSenderIds.has(senderId)) {
771
+ refreshedSenderIds.has(senderId) ||
772
+ attemptedSenderIds.has(senderId)) {
864
773
  continue;
865
774
  }
866
775
  const receipt = await deps.executors.refreshPaidInmailCreditsWithRetry(senderId, input.workspaceId);
867
- receipts.push({ senderId, receipt });
868
- refreshedSenderIds.add(senderId);
776
+ attemptedSenderIds.add(senderId);
777
+ const classification = classifyPaidInmailRefreshReceipt(receipt.receipt);
778
+ receipts.push({ senderId, receipt, classification });
779
+ if (classification.usableCurrentFacts) {
780
+ refreshedSenderIds.add(senderId);
781
+ }
869
782
  }
870
- const nextRunState = runStateWithDateWindow(mergeRunState(ctx.runState, {
783
+ const nextRunState = mergeRunState(ctx.runState, {
871
784
  creditTrust: {
872
785
  refreshedAt: (deps.now?.() ?? new Date()).toISOString(),
873
786
  senderIds: [...refreshedSenderIds],
787
+ attemptedSenderIds: [...attemptedSenderIds],
874
788
  receipts,
875
789
  },
876
- }), ctx.dateWindow);
790
+ });
877
791
  await safeJournalAppend(ctx, deps, deps.journal.renderBootstrapSection({
878
792
  summary: "Refill v2 execution bootstrap",
879
793
  senderSummary: safeJson(recordValue(plan.bootstrap)?.senders ?? []),
@@ -981,8 +895,13 @@ async function completeTerminal(input, deps, ctx, doneReasonInput, reportInput =
981
895
  };
982
896
  }
983
897
  async function gatePlan(input, deps, ctx) {
984
- const plan = await readLoopPlan(input, deps, ctx, false);
985
- applyPlanDateWindow(ctx, plan);
898
+ const plan = await deps.readPlan({
899
+ workspaceId: input.workspaceId,
900
+ intent: input.intent,
901
+ senderIds: input.senderIds,
902
+ runState: ctx.runState,
903
+ journal: false,
904
+ });
986
905
  if (plan.blocker === "workspace_access") {
987
906
  return {
988
907
  status: "blocked",
@@ -1085,7 +1004,13 @@ async function verifyRecoveryPoint(input, deps, ctx) {
1085
1004
  stateRevision: stringValue(planned.stateRevision),
1086
1005
  targetShapeRevision: stringValue(planned.targetShapeRevision),
1087
1006
  };
1088
- const fresh = await readLoopPlan(input, deps, ctx, false);
1007
+ const fresh = await deps.readPlan({
1008
+ workspaceId: input.workspaceId,
1009
+ intent: input.intent,
1010
+ senderIds: input.senderIds,
1011
+ runState: ctx.runState,
1012
+ journal: false,
1013
+ });
1089
1014
  const changed = fingerprintChanged(expected, fingerprintFromPlan(fresh));
1090
1015
  if (changed.length > 0) {
1091
1016
  await deps.runClient.recordRunOutcome({
@@ -1347,8 +1272,13 @@ async function verifyPrepareAction(input, deps, ctx, action, budgets) {
1347
1272
  }
1348
1273
  async function verifyReadOnlyWait(input, deps, ctx, budgets, waitKind) {
1349
1274
  for (let poll = 0; poll < budgets.maxPollsPerWait; poll += 1) {
1350
- const fresh = await readLoopPlan(input, deps, ctx, false);
1351
- applyPlanDateWindow(ctx, fresh);
1275
+ const fresh = await deps.readPlan({
1276
+ workspaceId: input.workspaceId,
1277
+ intent: input.intent,
1278
+ senderIds: input.senderIds,
1279
+ runState: ctx.runState,
1280
+ journal: false,
1281
+ });
1352
1282
  ctx.plan = fresh;
1353
1283
  const doneReason = doneReasonFromPlan(fresh);
1354
1284
  if (doneReason) {
@@ -1380,30 +1310,31 @@ async function verifySchedulerWait(input, deps, ctx, action, budgets) {
1380
1310
  if (!jitFired) {
1381
1311
  const senderId = actionSenderId(action);
1382
1312
  if (senderId) {
1383
- await deps.executors.refreshPaidInmailCreditsWithRetry(senderId, input.workspaceId);
1313
+ const refresh = await deps.executors.refreshPaidInmailCreditsWithRetry(senderId, input.workspaceId);
1314
+ const classification = classifyPaidInmailRefreshReceipt(refresh.receipt);
1315
+ if (!classification.usableCurrentFacts) {
1316
+ return {
1317
+ status: "blocked",
1318
+ blocker: "paid_inmail_refresh_failed",
1319
+ runId: ctx.runId,
1320
+ fence: ctx.fence,
1321
+ gate: ctx.gate,
1322
+ guidance: "Paid InMail credit refresh did not return usable current facts, so scheduler JIT was not requested.",
1323
+ report: {
1324
+ senderId,
1325
+ receiptStatus: classification.status,
1326
+ error: classification.error,
1327
+ receipt: refresh.receipt,
1328
+ attempts: refresh.attempts,
1329
+ errors: refresh.errors,
1330
+ },
1331
+ journalPath: ctx.journalPath,
1332
+ };
1333
+ }
1384
1334
  }
1385
1335
  if (deps.requestSchedulerRun) {
1386
1336
  try {
1387
- const targetDates = schedulerSweepTargetDates(ctx.dateWindow);
1388
- const sweepReceipts = [];
1389
- if (targetDates.length === 0) {
1390
- schedulerRunReceipt = sanitizeSchedulerRunReceipt(await deps.requestSchedulerRun(input.workspaceId));
1391
- }
1392
- else {
1393
- for (const targetDate of targetDates) {
1394
- const receipt = sanitizeSchedulerRunReceipt(await deps.requestSchedulerRun(input.workspaceId, { targetDate }));
1395
- if (receipt)
1396
- sweepReceipts.push({ targetDate, ...receipt });
1397
- }
1398
- schedulerRunReceipt = sweepReceipts[0] ?? null;
1399
- }
1400
- if (sweepReceipts.length > 1) {
1401
- ctx.runState = mergeRunState(ctx.runState, {
1402
- progress: mergeProgress(ctx, {
1403
- schedulerRunReceipts: sweepReceipts,
1404
- }),
1405
- });
1406
- }
1337
+ schedulerRunReceipt = sanitizeSchedulerRunReceipt(await deps.requestSchedulerRun(input.workspaceId));
1407
1338
  }
1408
1339
  catch {
1409
1340
  schedulerRunReceipt = null;
@@ -1423,8 +1354,13 @@ async function verifySchedulerWait(input, deps, ctx, action, budgets) {
1423
1354
  // full wait budget when the fresh receipt says nothing was placeable now.
1424
1355
  const readbackBudget = zeroScheduledFresh ? 1 : budgets.maxSchedulerReadbacks;
1425
1356
  for (let poll = 0; poll < readbackBudget; poll += 1) {
1426
- const fresh = await readLoopPlan(input, deps, ctx, false);
1427
- applyPlanDateWindow(ctx, fresh);
1357
+ const fresh = await deps.readPlan({
1358
+ workspaceId: input.workspaceId,
1359
+ intent: input.intent,
1360
+ senderIds: input.senderIds,
1361
+ runState: ctx.runState,
1362
+ journal: false,
1363
+ });
1428
1364
  ctx.plan = fresh;
1429
1365
  const doneReason = normalizeDoneReason(doneReasonFromPlan(fresh));
1430
1366
  if (doneReason === "complete" || doneReason === "capped_by_scheduler") {
@@ -1480,8 +1416,13 @@ async function gateVerify(input, deps, ctx, budgets) {
1480
1416
  actionType === "wait_for_source_import") {
1481
1417
  return verifyReadOnlyWait(input, deps, ctx, budgets, actionType);
1482
1418
  }
1483
- const fresh = await readLoopPlan(input, deps, ctx, false);
1484
- applyPlanDateWindow(ctx, fresh);
1419
+ const fresh = await deps.readPlan({
1420
+ workspaceId: input.workspaceId,
1421
+ intent: input.intent,
1422
+ senderIds: input.senderIds,
1423
+ runState: ctx.runState,
1424
+ journal: false,
1425
+ });
1485
1426
  ctx.plan = fresh;
1486
1427
  const doneReason = doneReasonFromPlan(fresh);
1487
1428
  if (doneReason) {
@@ -1554,21 +1495,15 @@ export async function runRefillV2Loop(input, deps) {
1554
1495
  let ctx = null;
1555
1496
  try {
1556
1497
  if (input.dryRun) {
1557
- const dateSelector = dateSelectorFromInput(input);
1558
- const plan = await deps.readPlan(readPlanRequest({
1498
+ const plan = await deps.readPlan({
1559
1499
  workspaceId: input.workspaceId,
1560
1500
  intent: input.intent,
1561
1501
  senderIds: input.senderIds,
1562
1502
  journal: true,
1563
- dateSelector,
1564
- }));
1503
+ });
1565
1504
  return { status: "dry_run", plan };
1566
1505
  }
1567
- const requestedSelector = dateSelectorFromInput(input);
1568
- const preflight = await preflightResumeDateWindow(input, deps, requestedSelector);
1569
- if ("status" in preflight)
1570
- return preflight;
1571
- const started = await startOrResume(input, deps, preflight.window);
1506
+ const started = await startOrResume(input, deps);
1572
1507
  if ("status" in started)
1573
1508
  return started;
1574
1509
  ctx = started;
package/dist/server.js CHANGED
@@ -319,7 +319,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
319
319
  }
320
320
  break;
321
321
  case "start_campaign":
322
- result = await startCampaign(args?.campaignId);
322
+ result = await startCampaign(args?.campaignId, args?.workspaceId);
323
323
  if (args?.campaignId && result?.success) {
324
324
  markCampaignContextDirty(args.campaignId, "start_campaign");
325
325
  }
@@ -185,6 +185,7 @@ export declare const campaignToolDefinitions: ({
185
185
  useMessagingTemplate?: undefined;
186
186
  rubric?: undefined;
187
187
  flowVersion?: undefined;
188
+ workspaceId?: undefined;
188
189
  };
189
190
  required: string[];
190
191
  additionalProperties: boolean;
@@ -223,6 +224,7 @@ export declare const campaignToolDefinitions: ({
223
224
  useMessagingTemplate?: undefined;
224
225
  rubric?: undefined;
225
226
  flowVersion?: undefined;
227
+ workspaceId?: undefined;
226
228
  };
227
229
  required: never[];
228
230
  additionalProperties?: undefined;
@@ -261,6 +263,7 @@ export declare const campaignToolDefinitions: ({
261
263
  useMessagingTemplate?: undefined;
262
264
  rubric?: undefined;
263
265
  flowVersion?: undefined;
266
+ workspaceId?: undefined;
264
267
  };
265
268
  required: string[];
266
269
  additionalProperties?: undefined;
@@ -342,6 +345,7 @@ export declare const campaignToolDefinitions: ({
342
345
  useMessagingTemplate?: undefined;
343
346
  rubric?: undefined;
344
347
  flowVersion?: undefined;
348
+ workspaceId?: undefined;
345
349
  };
346
350
  required: string[];
347
351
  additionalProperties: boolean;
@@ -536,6 +540,7 @@ export declare const campaignToolDefinitions: ({
536
540
  useMessagingTemplate?: undefined;
537
541
  rubric?: undefined;
538
542
  flowVersion?: undefined;
543
+ workspaceId?: undefined;
539
544
  };
540
545
  required: never[];
541
546
  additionalProperties?: undefined;
@@ -741,6 +746,49 @@ export declare const campaignToolDefinitions: ({
741
746
  clientProspectId?: undefined;
742
747
  senderLinkedinUrl?: undefined;
743
748
  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;
744
792
  };
745
793
  required: string[];
746
794
  additionalProperties?: undefined;
@@ -782,6 +830,7 @@ export declare const campaignToolDefinitions: ({
782
830
  useMessagingTemplate?: undefined;
783
831
  rubric?: undefined;
784
832
  flowVersion?: undefined;
833
+ workspaceId?: undefined;
785
834
  };
786
835
  required: string[];
787
836
  additionalProperties?: undefined;
@@ -821,7 +870,7 @@ export interface UpdateCampaignResult {
821
870
  _campaign?: CampaignOfferNavigation;
822
871
  }
823
872
  export declare function updateCampaign(campaignId: string, input: UpdateCampaignInput): Promise<UpdateCampaignResult>;
824
- export declare function startCampaign(campaignId: string): Promise<{
873
+ export declare function startCampaign(campaignId: string, workspaceId?: string | null): Promise<{
825
874
  success: boolean;
826
875
  }>;
827
876
  export declare function pauseCampaign(campaignId: string): Promise<{
@@ -476,6 +476,10 @@ export const campaignToolDefinitions = [
476
476
  type: "string",
477
477
  description: "Campaign ID to start",
478
478
  },
479
+ workspaceId: {
480
+ type: "string",
481
+ description: "Optional explicit request-scoped workspace id. Pass this for scheduled/yolo refill automation instead of relying on the shared active workspace.",
482
+ },
479
483
  },
480
484
  required: ["campaignId"],
481
485
  },
@@ -1026,9 +1030,9 @@ export async function updateCampaign(campaignId, input) {
1026
1030
  _campaign: result,
1027
1031
  };
1028
1032
  }
1029
- export async function startCampaign(campaignId) {
1033
+ export async function startCampaign(campaignId, workspaceId) {
1030
1034
  const api = getApi();
1031
- return api.post(`/api/v3/campaigns/${campaignId}/start`);
1035
+ return api.post(`/api/v3/campaigns/${campaignId}/start`, undefined, workspaceId ? { workspaceId } : undefined);
1032
1036
  }
1033
1037
  export async function pauseCampaign(campaignId) {
1034
1038
  const api = getApi();
@@ -3,9 +3,6 @@ type GetRefillPlanV2Input = {
3
3
  intent?: "auto" | "evergreen" | "plain" | "active";
4
4
  senderIds?: string[];
5
5
  runState?: Record<string, unknown>;
6
- targetDate?: string | null;
7
- untilDate?: string | null;
8
- horizonSendDays?: number | null;
9
6
  journal?: boolean;
10
7
  journalNote?: string;
11
8
  };
@@ -41,22 +38,6 @@ export declare const refillPlanV2ToolDefinitions: {
41
38
  enum: string[];
42
39
  description: string;
43
40
  };
44
- targetDate: {
45
- type: string;
46
- pattern: string;
47
- description: string;
48
- };
49
- untilDate: {
50
- type: string;
51
- pattern: string;
52
- description: string;
53
- };
54
- horizonSendDays: {
55
- type: string;
56
- minimum: number;
57
- maximum: number;
58
- description: string;
59
- };
60
41
  journal: {
61
42
  type: string;
62
43
  description: string;
@@ -1,6 +1,5 @@
1
1
  import * as path from "node:path";
2
2
  import { getApi, SellableApiError } from "../api.js";
3
- import { normalizeRefillDateSelector, refillDateSelectorBody, } from "../refill-date-window.js";
4
3
  import { appendIndexLine, appendJournalEvent, createRunJournal, renderBootstrapSection, renderPlanSection, renderTerminalSection, } from "../refill-journal.js";
5
4
  import { readRefillWorkspaceState } from "../refill-local-state.js";
6
5
  import { normalizeExplicitWorkspaceId, workspaceRequestOptions, } from "./workspace-context.js";
@@ -176,22 +175,6 @@ export const refillPlanV2ToolDefinitions = [
176
175
  enum: ["auto", "evergreen", "plain", "active"],
177
176
  description: 'Planner intent. Defaults to "auto" for refill-sends-v2.',
178
177
  },
179
- targetDate: {
180
- type: "string",
181
- pattern: "^\\d{4}-\\d{2}-\\d{2}$",
182
- description: "Optional one exact sender-local date (YYYY-MM-DD) to plan. Takes precedence over untilDate and horizonSendDays.",
183
- },
184
- untilDate: {
185
- type: "string",
186
- pattern: "^\\d{4}-\\d{2}-\\d{2}$",
187
- description: "Optional inclusive sender-local through-date (YYYY-MM-DD) to plan.",
188
- },
189
- horizonSendDays: {
190
- type: "number",
191
- minimum: 1,
192
- maximum: 7,
193
- description: "Optional explicit next N sender-local send days to plan.",
194
- },
195
178
  journal: {
196
179
  type: "boolean",
197
180
  description: "Set false to skip the local dry-run journal write.",
@@ -214,7 +197,6 @@ export async function getRefillPlanV2(input) {
214
197
  const runState = input.runState !== undefined
215
198
  ? input.runState
216
199
  : buildRunStateFromLocalHints(workspaceId);
217
- const dateSelector = normalizeRefillDateSelector(input);
218
200
  let raw;
219
201
  try {
220
202
  raw = await postRefillPlanV2({
@@ -222,7 +204,6 @@ export async function getRefillPlanV2(input) {
222
204
  intent: input.intent ?? "auto",
223
205
  senderIds: input.senderIds,
224
206
  runState,
225
- ...refillDateSelectorBody(dateSelector),
226
207
  }, workspaceId);
227
208
  }
228
209
  catch (error) {
@@ -14,6 +14,12 @@ export type PaidInmailCreditRefreshOptions = {
14
14
  maxStalenessSeconds?: number | null;
15
15
  paidInmailCreditsMaxStalenessSeconds?: number | null;
16
16
  };
17
+ export type PaidInmailRefreshReceiptClassification = {
18
+ usableCurrentFacts: boolean;
19
+ status: string;
20
+ error: string | null;
21
+ refreshed: boolean;
22
+ };
17
23
  export type YoloPrimitiveExecution = {
18
24
  enabled: true;
19
25
  status: "no_action" | "read_only_reread" | "executed_and_reread" | "refused" | "skipped_after_paid_refresh";
@@ -135,6 +141,7 @@ export declare function userAddedRowsLimitPayloadFromError(error: unknown): User
135
141
  export declare function sourceImportInProgressPayloadFromError(error: unknown): SourceImportInProgressPayload | null;
136
142
  export declare function paidRefreshActionFrom(value: unknown): PaidInmailRefreshAction | null;
137
143
  export declare function collectPaidInmailRefreshActions(plan: unknown): PaidInmailRefreshAction[];
144
+ export declare function classifyPaidInmailRefreshReceipt(value: unknown): PaidInmailRefreshReceiptClassification;
138
145
  export declare function firstGlobalAction(plan: unknown): Record<string, unknown> | null;
139
146
  export declare function actionIds(action: Record<string, unknown>): Record<string, unknown>;
140
147
  export declare function actionToolInput(action: Record<string, unknown>): Record<string, unknown>;