@signaliz/sdk 1.0.10 → 1.0.12
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/README.md +16 -0
- package/dist/{chunk-2EXN3RAX.mjs → chunk-XJQ6KGNQ.mjs} +184 -0
- package/dist/cli.js +362 -1
- package/dist/cli.mjs +179 -2
- package/dist/index.d.mts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +184 -0
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +184 -0
- package/dist/mcp-config.mjs +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
Signaliz,
|
|
4
4
|
createCampaignBuilderAgentRequestTemplate,
|
|
5
5
|
createCampaignBuilderApproval
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XJQ6KGNQ.mjs";
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { readFileSync, writeFileSync } from "fs";
|
|
@@ -379,6 +379,10 @@ async function handleCampaignAgentCommand(signaliz, argv) {
|
|
|
379
379
|
}
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
|
+
if (["review", "status", "rows", "artifacts", "approve", "approve-delivery"].includes(subcommand)) {
|
|
383
|
+
await handleCampaignAgentReviewCommand(signaliz, subcommand, argv.slice(1));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
382
386
|
if (!["plan", "proof", "smoke", "commit-plan", "dry-run", "build-approved", "launch-approved"].includes(subcommand)) {
|
|
383
387
|
printCampaignAgentHelp();
|
|
384
388
|
return;
|
|
@@ -478,6 +482,90 @@ async function handleCampaignAgentCommand(signaliz, argv) {
|
|
|
478
482
|
printCampaignAgentPlan(plan);
|
|
479
483
|
}
|
|
480
484
|
}
|
|
485
|
+
async function handleCampaignAgentReviewCommand(signaliz, subcommand, argv) {
|
|
486
|
+
const flags = parseFlags(argv);
|
|
487
|
+
const buildId = argv[0] && !argv[0].startsWith("--") ? argv[0] : stringFlag(flags, "campaign-build-id", "build-id");
|
|
488
|
+
if (!buildId) throw new Error(`campaign-agent ${subcommand} requires <campaign_build_id> or --campaign-build-id`);
|
|
489
|
+
if (subcommand === "review") {
|
|
490
|
+
const review = await signaliz.campaignBuilderAgent.reviewBuild(buildId, {
|
|
491
|
+
limit: numberFlag(flags, "limit") ?? 100,
|
|
492
|
+
cursor: stringFlag(flags, "cursor"),
|
|
493
|
+
segment: stringFlag(flags, "segment"),
|
|
494
|
+
rowStatus: stringFlag(flags, "row-status"),
|
|
495
|
+
qualified: booleanFlag(flags, "qualified") ? true : booleanFlag(flags, "disqualified") ? false : void 0
|
|
496
|
+
});
|
|
497
|
+
const operatorReview = {
|
|
498
|
+
...review,
|
|
499
|
+
rows: {
|
|
500
|
+
...review.rows,
|
|
501
|
+
rows: formatCampaignAgentRows(review.rows.rows)
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
if (booleanFlag(flags, "json")) {
|
|
505
|
+
printJson(operatorReview);
|
|
506
|
+
} else {
|
|
507
|
+
printCampaignAgentBuildReview(operatorReview);
|
|
508
|
+
}
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
if (subcommand === "status") {
|
|
512
|
+
const status = await signaliz.campaignBuilderAgent.getBuildStatus(buildId);
|
|
513
|
+
if (booleanFlag(flags, "json")) {
|
|
514
|
+
printJson(status);
|
|
515
|
+
} else {
|
|
516
|
+
printCampaignAgentBuildStatus(status);
|
|
517
|
+
}
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (subcommand === "rows") {
|
|
521
|
+
const result2 = await signaliz.campaignBuilderAgent.getBuildRows(buildId, {
|
|
522
|
+
limit: numberFlag(flags, "limit"),
|
|
523
|
+
cursor: stringFlag(flags, "cursor"),
|
|
524
|
+
segment: stringFlag(flags, "segment"),
|
|
525
|
+
rowStatus: stringFlag(flags, "row-status"),
|
|
526
|
+
qualified: booleanFlag(flags, "qualified") ? true : booleanFlag(flags, "disqualified") ? false : void 0
|
|
527
|
+
});
|
|
528
|
+
const operatorResult = {
|
|
529
|
+
...result2,
|
|
530
|
+
rows: formatCampaignAgentRows(result2.rows)
|
|
531
|
+
};
|
|
532
|
+
if (booleanFlag(flags, "json")) {
|
|
533
|
+
printJson(operatorResult);
|
|
534
|
+
} else {
|
|
535
|
+
printCampaignAgentRows(operatorResult);
|
|
536
|
+
}
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (subcommand === "artifacts") {
|
|
540
|
+
const artifacts = await signaliz.campaignBuilderAgent.listBuildArtifacts(buildId);
|
|
541
|
+
if (booleanFlag(flags, "json")) {
|
|
542
|
+
printJson(artifacts);
|
|
543
|
+
} else if (artifacts.length === 0) {
|
|
544
|
+
console.log("No artifacts yet.");
|
|
545
|
+
console.log(`Next: signaliz campaign-agent status ${buildId}`);
|
|
546
|
+
} else {
|
|
547
|
+
for (const artifact of artifacts) {
|
|
548
|
+
console.log(`${artifact.artifactType || "artifact"}: ${artifact.rowCount} rows${artifact.signedUrl ? `
|
|
549
|
+
${artifact.signedUrl}` : ""}`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const destinationType = stringFlag(flags, "destination-type", "delivery-destination-type", "type");
|
|
555
|
+
if (!destinationType || !["json", "csv", "webhook"].includes(destinationType)) {
|
|
556
|
+
throw new Error("campaign-agent approve requires --destination-type json|csv|webhook");
|
|
557
|
+
}
|
|
558
|
+
const result = await signaliz.campaignBuilderAgent.approveDelivery(buildId, destinationType, {
|
|
559
|
+
destinationId: stringFlag(flags, "destination-id", "delivery-destination-id"),
|
|
560
|
+
destinationConfig: jsonObjectFlag(flags, "destination-config", "delivery-config")
|
|
561
|
+
});
|
|
562
|
+
if (booleanFlag(flags, "json")) {
|
|
563
|
+
printJson(result);
|
|
564
|
+
} else {
|
|
565
|
+
console.log(`Delivery ${result.status}: ${result.destinationType}`);
|
|
566
|
+
if (result.message) console.log(result.message);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
481
569
|
function campaignAgentRequestTemplateFromFlags(flags) {
|
|
482
570
|
const goal = stringFlag(flags, "goal", "brief") || "Build a strategy-template campaign for mature operators in the target ICP.";
|
|
483
571
|
const request = campaignAgentRequestFromFlags(goal, flags, { includeDefaults: true });
|
|
@@ -814,6 +902,87 @@ function printCampaignAgentExecution(payload, flags) {
|
|
|
814
902
|
console.log("\nResult:");
|
|
815
903
|
printJson(payload.result);
|
|
816
904
|
}
|
|
905
|
+
function printCampaignAgentBuildStatus(status) {
|
|
906
|
+
console.log(`Campaign: ${status.name || status.campaignBuildId}`);
|
|
907
|
+
if (status.campaignId) console.log(`Campaign ID: ${status.campaignId}`);
|
|
908
|
+
console.log(`Status: ${status.status}`);
|
|
909
|
+
console.log(`Phase: ${status.currentPhase || "N/A"}`);
|
|
910
|
+
console.log(`Rows: ${status.recordsSucceeded}/${status.recordsTotal} succeeded, ${status.recordsFailed} failed`);
|
|
911
|
+
console.log(`Artifacts: ${status.artifactCount}`);
|
|
912
|
+
if (status.triggerRunId) console.log(`Trigger: ${status.triggerRunId}`);
|
|
913
|
+
if (Array.isArray(status.warnings) && status.warnings.length > 0) {
|
|
914
|
+
console.log(`Warnings: ${status.warnings.slice(0, 3).join("; ")}`);
|
|
915
|
+
}
|
|
916
|
+
if (Array.isArray(status.errors) && status.errors.length > 0) {
|
|
917
|
+
console.log(`Errors: ${status.errors.slice(0, 3).join("; ")}`);
|
|
918
|
+
}
|
|
919
|
+
if (status.status === "completed") {
|
|
920
|
+
console.log(`Next: signaliz campaign-agent rows ${status.campaignBuildId} --limit 100`);
|
|
921
|
+
} else if (status.status === "pending_approval") {
|
|
922
|
+
console.log(`Next: signaliz campaign-agent approve ${status.campaignBuildId} --destination-type webhook`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function printCampaignAgentBuildReview(review) {
|
|
926
|
+
const summary = asRecord(review.summary);
|
|
927
|
+
console.log(`Campaign: ${review.status?.name || review.campaignBuildId}`);
|
|
928
|
+
console.log(`Status: ${summary.status || review.status?.status}`);
|
|
929
|
+
console.log(`Phase: ${summary.phase || review.status?.currentPhase || "N/A"}`);
|
|
930
|
+
console.log(`Rows: ${summary.sampledRows || 0} sampled, ${summary.availableRows || 0} available`);
|
|
931
|
+
console.log(`Qualified: ${summary.qualifiedRows || 0}`);
|
|
932
|
+
console.log(`Emails: ${summary.rowsWithEmail || 0}`);
|
|
933
|
+
console.log(`Copy ready: ${summary.copyReadyRows || 0}`);
|
|
934
|
+
console.log(`Artifacts: ${summary.artifactCount || 0}`);
|
|
935
|
+
console.log(`Delivery approval ready: ${summary.readyForDeliveryApproval === true ? "yes" : "no"}`);
|
|
936
|
+
if (Array.isArray(review.gates) && review.gates.length > 0) {
|
|
937
|
+
console.log("\nGates:");
|
|
938
|
+
for (const gate of review.gates) {
|
|
939
|
+
console.log(`- ${gate.passed ? "PASS" : "BLOCKED"} ${gate.label}: ${gate.detail}`);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
const warnings = Array.isArray(summary.warnings) ? summary.warnings : [];
|
|
943
|
+
if (warnings.length > 0) {
|
|
944
|
+
console.log("\nWarnings:");
|
|
945
|
+
for (const warning of warnings.slice(0, 5)) console.log(`- ${warning}`);
|
|
946
|
+
}
|
|
947
|
+
const nextActions = Array.isArray(review.nextActions) ? review.nextActions : [];
|
|
948
|
+
if (nextActions.length > 0) {
|
|
949
|
+
console.log("\nNext:");
|
|
950
|
+
for (const action of nextActions) console.log(`- ${action}`);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
function formatCampaignAgentRows(rows) {
|
|
954
|
+
return rows.map((row) => {
|
|
955
|
+
const data = asRecord(row.data);
|
|
956
|
+
const fallbackName = `${data.first_name || ""} ${data.last_name || ""}`.trim() || null;
|
|
957
|
+
return {
|
|
958
|
+
...row,
|
|
959
|
+
email: data.email ?? null,
|
|
960
|
+
name: data.full_name ?? fallbackName,
|
|
961
|
+
title: data.title ?? null,
|
|
962
|
+
company: data.company_name ?? null,
|
|
963
|
+
domain: data.company_domain ?? null,
|
|
964
|
+
score: data.overall_score ?? null,
|
|
965
|
+
has_copy: Boolean(data.subject || data.opener || data.body || data.cta || asRecord(data.raw_copy).subject)
|
|
966
|
+
};
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
function printCampaignAgentRows(result) {
|
|
970
|
+
if (!Array.isArray(result.rows) || result.rows.length === 0) {
|
|
971
|
+
console.log("No rows found.");
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
console.table(result.rows.map((row) => ({
|
|
975
|
+
email: row.email || "",
|
|
976
|
+
name: row.name || "",
|
|
977
|
+
title: row.title || "",
|
|
978
|
+
company: row.company || row.domain || "",
|
|
979
|
+
status: row.status || "",
|
|
980
|
+
segment: row.segment || "",
|
|
981
|
+
score: row.score ?? ""
|
|
982
|
+
})));
|
|
983
|
+
console.log(`Showing ${result.rows.length} row(s)${result.hasMore ? " (more available)" : ""}`);
|
|
984
|
+
if (result.nextCursor) console.log(`Next: signaliz campaign-agent rows ${result.campaignBuildId} --cursor ${result.nextCursor}`);
|
|
985
|
+
}
|
|
817
986
|
function asRecord(value) {
|
|
818
987
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
819
988
|
}
|
|
@@ -990,6 +1159,9 @@ Usage:
|
|
|
990
1159
|
signaliz campaign-agent dry-run --goal "Build a strategy-template campaign..." --target-count 500 --use-local-leads --json
|
|
991
1160
|
signaliz campaign-agent build-approved --goal "Build a strategy-template campaign..." --confirm-launch --approve-all --approved-by you@example.com --spend-limit 500
|
|
992
1161
|
signaliz campaign-agent build-approved --request-file campaign-request.json --confirm-launch --approve-all --approved-by you@example.com --spend-limit 500 --wait --approve-delivery --delivery-destination-type json
|
|
1162
|
+
signaliz campaign-agent review <campaign_build_id> --limit 100 --json
|
|
1163
|
+
signaliz campaign-agent status <campaign_build_id> --json
|
|
1164
|
+
signaliz campaign-agent rows <campaign_build_id> --limit 100 --json
|
|
993
1165
|
|
|
994
1166
|
Environment:
|
|
995
1167
|
SIGNALIZ_API_KEY Your API key (not required for campaign-agent init)
|
|
@@ -1021,8 +1193,13 @@ Signaliz campaign-agent commands:
|
|
|
1021
1193
|
signaliz campaign-agent commit-plan (--goal TEXT | --request-file FILE) [--confirm-write --approved-by EMAIL] [--idempotency-key KEY] [--json]
|
|
1022
1194
|
signaliz campaign-agent dry-run (--goal TEXT | --request-file FILE) [--gtm-campaign-id ID] [--delivery-risk JSON] [--idempotency-key KEY] [--json]
|
|
1023
1195
|
signaliz campaign-agent build-approved (--goal TEXT | --request-file FILE) --confirm-launch --approved-by EMAIL (--approve-all | --approved-types a,b) [--commit-before-launch] [--spend-limit N] [--approved-route-ids a,b] [--wait] [--approve-delivery] [--delivery-destination-type json|csv|webhook] [--idempotency-key KEY] [--json]
|
|
1196
|
+
signaliz campaign-agent review <campaign_build_id> [--limit N] [--qualified|--disqualified] [--json]
|
|
1197
|
+
signaliz campaign-agent status <campaign_build_id> [--json]
|
|
1198
|
+
signaliz campaign-agent rows <campaign_build_id> [--limit N] [--cursor CURSOR] [--qualified|--disqualified] [--json]
|
|
1199
|
+
signaliz campaign-agent artifacts <campaign_build_id> [--json]
|
|
1200
|
+
signaliz campaign-agent approve <campaign_build_id> --destination-type json|csv|webhook [--destination-config JSON] [--json]
|
|
1024
1201
|
|
|
1025
|
-
The init command emits a reusable JSON CampaignBuilderAgentRequest. The plan command composes an approval-gated strategy-template MCP flow. Proof runs the same plan path plus build_campaign dry_run=true and returns a no-spend receipt. Use --request-file to load a reusable request, then override fields such as --target-count or --strategy-template from the command line. Use --strategy-template to merge a private-safe strategy pattern into the plan without exposing private account labels, and --operating-playbooks to add reusable build-loop gates such as proof-first vertical qualification, net-new suppression, cache-first inventory, and signal-led copy approval. Built-ins map to Signaliz-native tools: lead_generation -> generate_leads, local_leads -> generate_local_leads, email_finding -> find_and_verify_emails, email_verification -> verify_emails, signals -> enrich_company_signals. Add BYO tools with --custom-tool provider:layer:tool[:mcp] or key=value pairs such as provider=apollo,layer=source,tool=apollo_search,mcp=apollo. Use --no-strategy-patterns or --no-workflow-patterns to disable default private strategy memory hints. Commit-plan dry-runs by default and writes only with --confirm-write plus approval identity. Dry-run executes build_campaign with dry_run=true. Approved build requires explicit launch confirmation and approval metadata; add --commit-before-launch to persist the reviewed plan as a GTM campaign before launch, --wait to poll until completion or pending approval, and --approve-delivery to approve reviewed
|
|
1202
|
+
The init command emits a reusable JSON CampaignBuilderAgentRequest. The plan command composes an approval-gated strategy-template MCP flow. Proof runs the same plan path plus build_campaign dry_run=true and returns a no-spend receipt. Use --request-file to load a reusable request, then override fields such as --target-count or --strategy-template from the command line. Use --strategy-template to merge a private-safe strategy pattern into the plan without exposing private account labels, and --operating-playbooks to add reusable build-loop gates such as proof-first vertical qualification, net-new suppression, cache-first inventory, and signal-led copy approval. Built-ins map to Signaliz-native tools: lead_generation -> generate_leads, local_leads -> generate_local_leads, email_finding -> find_and_verify_emails, email_verification -> verify_emails, signals -> enrich_company_signals. Add BYO tools with --custom-tool provider:layer:tool[:mcp] or key=value pairs such as provider=apollo,layer=source,tool=apollo_search,mcp=apollo. Use --no-strategy-patterns or --no-workflow-patterns to disable default private strategy memory hints. Commit-plan dry-runs by default and writes only with --confirm-write plus approval identity. Dry-run executes build_campaign with dry_run=true. Approved build requires explicit launch confirmation and approval metadata; add --commit-before-launch to persist the reviewed plan as a GTM campaign before launch, --wait to poll until completion or pending approval, and --approve-delivery to approve reviewed webhook delivery after pending_approval. Use review to inspect status, sampled rows, artifacts, and delivery-readiness gates before approving delivery or routing rows to external tools.
|
|
1026
1203
|
`);
|
|
1027
1204
|
}
|
|
1028
1205
|
main().catch((e) => {
|
package/dist/index.d.mts
CHANGED
|
@@ -1094,6 +1094,38 @@ interface CampaignBuilderApprovedRunResult {
|
|
|
1094
1094
|
finalStatus?: CampaignBuildStatus;
|
|
1095
1095
|
deliveryApproval?: ApproveDeliveryResult;
|
|
1096
1096
|
}
|
|
1097
|
+
interface CampaignBuilderBuildReviewOptions extends CampaignRowsOptions {
|
|
1098
|
+
/** Number of rows to sample for review. Defaults to 100. */
|
|
1099
|
+
limit?: number;
|
|
1100
|
+
}
|
|
1101
|
+
interface CampaignBuilderBuildReviewGate {
|
|
1102
|
+
id: string;
|
|
1103
|
+
label: string;
|
|
1104
|
+
passed: boolean;
|
|
1105
|
+
detail: string;
|
|
1106
|
+
}
|
|
1107
|
+
interface CampaignBuilderBuildReviewSummary {
|
|
1108
|
+
status: string;
|
|
1109
|
+
phase: string | null;
|
|
1110
|
+
sampledRows: number;
|
|
1111
|
+
availableRows: number;
|
|
1112
|
+
qualifiedRows: number;
|
|
1113
|
+
rowsWithEmail: number;
|
|
1114
|
+
copyReadyRows: number;
|
|
1115
|
+
artifactCount: number;
|
|
1116
|
+
readyForDeliveryApproval: boolean;
|
|
1117
|
+
blockedReasons: string[];
|
|
1118
|
+
warnings: string[];
|
|
1119
|
+
}
|
|
1120
|
+
interface CampaignBuilderBuildReview {
|
|
1121
|
+
campaignBuildId: string;
|
|
1122
|
+
status: CampaignBuildStatus;
|
|
1123
|
+
rows: CampaignRowsResult;
|
|
1124
|
+
artifacts: CampaignArtifact[];
|
|
1125
|
+
gates: CampaignBuilderBuildReviewGate[];
|
|
1126
|
+
summary: CampaignBuilderBuildReviewSummary;
|
|
1127
|
+
nextActions: string[];
|
|
1128
|
+
}
|
|
1097
1129
|
declare const DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS: Required<Pick<SignalizCampaignBuilderDefaults, 'requireVerifiedEmail' | 'dedupKeys' | 'allowDownscale'>> & SignalizCampaignBuilderDefaults;
|
|
1098
1130
|
declare const DEFAULT_CAMPAIGN_BUILDER_BUILT_INS: CampaignBuilderBuiltInTool[];
|
|
1099
1131
|
declare const DEFAULT_CAMPAIGN_BUILDER_APPROVAL_TYPES: CampaignBuilderApprovalType[];
|
|
@@ -1107,6 +1139,14 @@ declare class CampaignBuilderAgent {
|
|
|
1107
1139
|
dryRunPlan(plan: CampaignBuilderAgentPlan, options?: BuildOptions): Promise<CampaignBuildResult>;
|
|
1108
1140
|
buildApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderBuildOptions): Promise<CampaignBuildResult>;
|
|
1109
1141
|
runApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderApprovedRunOptions): Promise<CampaignBuilderApprovedRunResult>;
|
|
1142
|
+
getBuildStatus(campaignBuildId: string): Promise<CampaignBuildStatus>;
|
|
1143
|
+
getBuildRows(campaignBuildId: string, options?: CampaignRowsOptions): Promise<CampaignRowsResult>;
|
|
1144
|
+
listBuildArtifacts(campaignBuildId: string): Promise<CampaignArtifact[]>;
|
|
1145
|
+
approveDelivery(campaignBuildId: string, destinationType: CampaignDeliveryMode, options?: {
|
|
1146
|
+
destinationId?: string;
|
|
1147
|
+
destinationConfig?: UnknownRecord$1;
|
|
1148
|
+
}): Promise<ApproveDeliveryResult>;
|
|
1149
|
+
reviewBuild(campaignBuildId: string, options?: CampaignBuilderBuildReviewOptions): Promise<CampaignBuilderBuildReview>;
|
|
1110
1150
|
private getCampaignBuildStatus;
|
|
1111
1151
|
private waitForCampaignBuildStatus;
|
|
1112
1152
|
private approveCampaignDelivery;
|
package/dist/index.d.ts
CHANGED
|
@@ -1094,6 +1094,38 @@ interface CampaignBuilderApprovedRunResult {
|
|
|
1094
1094
|
finalStatus?: CampaignBuildStatus;
|
|
1095
1095
|
deliveryApproval?: ApproveDeliveryResult;
|
|
1096
1096
|
}
|
|
1097
|
+
interface CampaignBuilderBuildReviewOptions extends CampaignRowsOptions {
|
|
1098
|
+
/** Number of rows to sample for review. Defaults to 100. */
|
|
1099
|
+
limit?: number;
|
|
1100
|
+
}
|
|
1101
|
+
interface CampaignBuilderBuildReviewGate {
|
|
1102
|
+
id: string;
|
|
1103
|
+
label: string;
|
|
1104
|
+
passed: boolean;
|
|
1105
|
+
detail: string;
|
|
1106
|
+
}
|
|
1107
|
+
interface CampaignBuilderBuildReviewSummary {
|
|
1108
|
+
status: string;
|
|
1109
|
+
phase: string | null;
|
|
1110
|
+
sampledRows: number;
|
|
1111
|
+
availableRows: number;
|
|
1112
|
+
qualifiedRows: number;
|
|
1113
|
+
rowsWithEmail: number;
|
|
1114
|
+
copyReadyRows: number;
|
|
1115
|
+
artifactCount: number;
|
|
1116
|
+
readyForDeliveryApproval: boolean;
|
|
1117
|
+
blockedReasons: string[];
|
|
1118
|
+
warnings: string[];
|
|
1119
|
+
}
|
|
1120
|
+
interface CampaignBuilderBuildReview {
|
|
1121
|
+
campaignBuildId: string;
|
|
1122
|
+
status: CampaignBuildStatus;
|
|
1123
|
+
rows: CampaignRowsResult;
|
|
1124
|
+
artifacts: CampaignArtifact[];
|
|
1125
|
+
gates: CampaignBuilderBuildReviewGate[];
|
|
1126
|
+
summary: CampaignBuilderBuildReviewSummary;
|
|
1127
|
+
nextActions: string[];
|
|
1128
|
+
}
|
|
1097
1129
|
declare const DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS: Required<Pick<SignalizCampaignBuilderDefaults, 'requireVerifiedEmail' | 'dedupKeys' | 'allowDownscale'>> & SignalizCampaignBuilderDefaults;
|
|
1098
1130
|
declare const DEFAULT_CAMPAIGN_BUILDER_BUILT_INS: CampaignBuilderBuiltInTool[];
|
|
1099
1131
|
declare const DEFAULT_CAMPAIGN_BUILDER_APPROVAL_TYPES: CampaignBuilderApprovalType[];
|
|
@@ -1107,6 +1139,14 @@ declare class CampaignBuilderAgent {
|
|
|
1107
1139
|
dryRunPlan(plan: CampaignBuilderAgentPlan, options?: BuildOptions): Promise<CampaignBuildResult>;
|
|
1108
1140
|
buildApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderBuildOptions): Promise<CampaignBuildResult>;
|
|
1109
1141
|
runApprovedPlan(plan: CampaignBuilderAgentPlan, approval: CampaignBuilderApproval, options?: CampaignBuilderApprovedRunOptions): Promise<CampaignBuilderApprovedRunResult>;
|
|
1142
|
+
getBuildStatus(campaignBuildId: string): Promise<CampaignBuildStatus>;
|
|
1143
|
+
getBuildRows(campaignBuildId: string, options?: CampaignRowsOptions): Promise<CampaignRowsResult>;
|
|
1144
|
+
listBuildArtifacts(campaignBuildId: string): Promise<CampaignArtifact[]>;
|
|
1145
|
+
approveDelivery(campaignBuildId: string, destinationType: CampaignDeliveryMode, options?: {
|
|
1146
|
+
destinationId?: string;
|
|
1147
|
+
destinationConfig?: UnknownRecord$1;
|
|
1148
|
+
}): Promise<ApproveDeliveryResult>;
|
|
1149
|
+
reviewBuild(campaignBuildId: string, options?: CampaignBuilderBuildReviewOptions): Promise<CampaignBuilderBuildReview>;
|
|
1110
1150
|
private getCampaignBuildStatus;
|
|
1111
1151
|
private waitForCampaignBuildStatus;
|
|
1112
1152
|
private approveCampaignDelivery;
|
package/dist/index.js
CHANGED
|
@@ -1896,6 +1896,42 @@ var CampaignBuilderAgent = class {
|
|
|
1896
1896
|
}
|
|
1897
1897
|
return result;
|
|
1898
1898
|
}
|
|
1899
|
+
async getBuildStatus(campaignBuildId) {
|
|
1900
|
+
return this.getCampaignBuildStatus(campaignBuildId);
|
|
1901
|
+
}
|
|
1902
|
+
async getBuildRows(campaignBuildId, options = {}) {
|
|
1903
|
+
const filters = compact({
|
|
1904
|
+
segment: options.segment,
|
|
1905
|
+
qualified: options.qualified,
|
|
1906
|
+
row_status: options.rowStatus
|
|
1907
|
+
});
|
|
1908
|
+
const args = compact({
|
|
1909
|
+
campaign_build_id: campaignBuildId,
|
|
1910
|
+
page_size: options.limit,
|
|
1911
|
+
cursor: options.cursor
|
|
1912
|
+
});
|
|
1913
|
+
if (Object.keys(filters).length > 0) args.filters = filters;
|
|
1914
|
+
const data = await this.callMcp("get_campaign_build_rows", args);
|
|
1915
|
+
return mapAgentCampaignRowsResult(data);
|
|
1916
|
+
}
|
|
1917
|
+
async listBuildArtifacts(campaignBuildId) {
|
|
1918
|
+
const data = await this.callMcp("list_campaign_build_artifacts", {
|
|
1919
|
+
campaign_build_id: campaignBuildId
|
|
1920
|
+
});
|
|
1921
|
+
return Array.isArray(data.artifacts) ? data.artifacts.map(mapAgentCampaignArtifact) : [];
|
|
1922
|
+
}
|
|
1923
|
+
async approveDelivery(campaignBuildId, destinationType, options) {
|
|
1924
|
+
return this.approveCampaignDelivery(campaignBuildId, destinationType, options);
|
|
1925
|
+
}
|
|
1926
|
+
async reviewBuild(campaignBuildId, options = {}) {
|
|
1927
|
+
const status = await this.getBuildStatus(campaignBuildId);
|
|
1928
|
+
const rows = await this.getBuildRows(campaignBuildId, {
|
|
1929
|
+
...options,
|
|
1930
|
+
limit: options.limit ?? 100
|
|
1931
|
+
});
|
|
1932
|
+
const artifacts = await this.listBuildArtifacts(campaignBuildId);
|
|
1933
|
+
return createCampaignBuilderBuildReview(status, rows, artifacts);
|
|
1934
|
+
}
|
|
1899
1935
|
async getCampaignBuildStatus(campaignBuildId) {
|
|
1900
1936
|
const data = await this.callMcp("get_campaign_build_status", {
|
|
1901
1937
|
campaign_build_id: campaignBuildId
|
|
@@ -3289,6 +3325,154 @@ function mapAgentCampaignBuildStatus(data) {
|
|
|
3289
3325
|
completedAt: stringValue(data.completed_at) ?? null
|
|
3290
3326
|
};
|
|
3291
3327
|
}
|
|
3328
|
+
function mapAgentCampaignRowsResult(data) {
|
|
3329
|
+
const rows = Array.isArray(data.rows) ? data.rows : [];
|
|
3330
|
+
return {
|
|
3331
|
+
campaignBuildId: stringValue(data.campaign_build_id) ?? "",
|
|
3332
|
+
rows: rows.map((row, index) => {
|
|
3333
|
+
const record = asRecord(row);
|
|
3334
|
+
return {
|
|
3335
|
+
index: numberOrUndefined2(record.index) ?? index,
|
|
3336
|
+
status: stringValue(record.status) ?? stringValue(record.row_status) ?? "unknown",
|
|
3337
|
+
qualified: record.qualified !== false,
|
|
3338
|
+
segment: stringValue(record.segment) ?? null,
|
|
3339
|
+
data: nullableRecord(record.data) ?? record
|
|
3340
|
+
};
|
|
3341
|
+
}),
|
|
3342
|
+
count: numberOrUndefined2(data.count) ?? rows.length,
|
|
3343
|
+
pageSize: numberOrUndefined2(data.page_size) ?? rows.length,
|
|
3344
|
+
nextCursor: stringValue(data.next_cursor) ?? null,
|
|
3345
|
+
hasMore: data.has_more === true
|
|
3346
|
+
};
|
|
3347
|
+
}
|
|
3348
|
+
function mapAgentCampaignArtifact(data) {
|
|
3349
|
+
return {
|
|
3350
|
+
id: stringValue(data.id) ?? "",
|
|
3351
|
+
campaignBuildId: stringValue(data.campaign_build_id) ?? "",
|
|
3352
|
+
artifactType: stringValue(data.artifact_type) ?? "",
|
|
3353
|
+
destination: stringValue(data.destination) ?? "",
|
|
3354
|
+
storagePath: stringValue(data.storage_path) ?? "",
|
|
3355
|
+
signedUrl: stringValue(data.signed_url) ?? null,
|
|
3356
|
+
rowCount: numberOrUndefined2(data.row_count) ?? 0,
|
|
3357
|
+
checksum: stringValue(data.checksum) ?? null,
|
|
3358
|
+
metadata: nullableRecord(data.metadata) ?? {},
|
|
3359
|
+
createdAt: stringValue(data.created_at) ?? ""
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
function createCampaignBuilderBuildReview(status, rows, artifacts) {
|
|
3363
|
+
const sampledRows = rows.rows.length;
|
|
3364
|
+
const availableRows = rows.count || sampledRows;
|
|
3365
|
+
const qualifiedRows = rows.rows.filter((row) => row.qualified !== false).length;
|
|
3366
|
+
const rowsWithEmail = rows.rows.filter(campaignReviewRowHasEmail).length;
|
|
3367
|
+
const copyReadyRows = rows.rows.filter(campaignReviewRowHasCopy).length;
|
|
3368
|
+
const artifactCount = artifacts.length || status.artifactCount || 0;
|
|
3369
|
+
const gates = [
|
|
3370
|
+
{
|
|
3371
|
+
id: "build_completed",
|
|
3372
|
+
label: "Build completed",
|
|
3373
|
+
passed: status.status === "completed",
|
|
3374
|
+
detail: status.status === "completed" ? "The campaign build is completed." : `The campaign build is ${status.status}; review again after completion.`
|
|
3375
|
+
},
|
|
3376
|
+
{
|
|
3377
|
+
id: "rows_available",
|
|
3378
|
+
label: "Rows available",
|
|
3379
|
+
passed: sampledRows > 0,
|
|
3380
|
+
detail: sampledRows > 0 ? `${sampledRows} sampled row(s) are available for review.` : "No rows were returned for review."
|
|
3381
|
+
},
|
|
3382
|
+
{
|
|
3383
|
+
id: "qualified_sample",
|
|
3384
|
+
label: "Sample rows qualified",
|
|
3385
|
+
passed: sampledRows > 0 && qualifiedRows === sampledRows,
|
|
3386
|
+
detail: sampledRows > 0 ? `${qualifiedRows}/${sampledRows} sampled row(s) are marked qualified.` : "Qualification could not be checked without sampled rows."
|
|
3387
|
+
},
|
|
3388
|
+
{
|
|
3389
|
+
id: "email_coverage",
|
|
3390
|
+
label: "Email coverage",
|
|
3391
|
+
passed: sampledRows > 0 && rowsWithEmail === sampledRows,
|
|
3392
|
+
detail: sampledRows > 0 ? `${rowsWithEmail}/${sampledRows} sampled row(s) include an email.` : "Email coverage could not be checked without sampled rows."
|
|
3393
|
+
},
|
|
3394
|
+
{
|
|
3395
|
+
id: "artifact_available",
|
|
3396
|
+
label: "Artifact available",
|
|
3397
|
+
passed: artifactCount > 0,
|
|
3398
|
+
detail: artifactCount > 0 ? `${artifactCount} artifact(s) are available.` : "No delivery artifact is available yet."
|
|
3399
|
+
},
|
|
3400
|
+
{
|
|
3401
|
+
id: "no_failed_rows",
|
|
3402
|
+
label: "No failed rows",
|
|
3403
|
+
passed: status.recordsFailed === 0,
|
|
3404
|
+
detail: status.recordsFailed === 0 ? "The build reports zero failed rows." : `${status.recordsFailed} row(s) failed during the build.`
|
|
3405
|
+
}
|
|
3406
|
+
];
|
|
3407
|
+
const blockedReasons = gates.filter((gate) => !gate.passed).map((gate) => gate.detail);
|
|
3408
|
+
const warnings = [
|
|
3409
|
+
rows.hasMore ? "This review is based on a row sample; page through remaining rows before final approval." : void 0,
|
|
3410
|
+
sampledRows > 0 && copyReadyRows < sampledRows ? `${copyReadyRows}/${sampledRows} sampled row(s) include generated copy.` : void 0,
|
|
3411
|
+
...status.warnings
|
|
3412
|
+
].filter((item) => Boolean(item));
|
|
3413
|
+
const readyForDeliveryApproval = blockedReasons.length === 0;
|
|
3414
|
+
return {
|
|
3415
|
+
campaignBuildId: status.campaignBuildId || rows.campaignBuildId,
|
|
3416
|
+
status,
|
|
3417
|
+
rows,
|
|
3418
|
+
artifacts,
|
|
3419
|
+
gates,
|
|
3420
|
+
summary: {
|
|
3421
|
+
status: status.status,
|
|
3422
|
+
phase: status.currentPhase,
|
|
3423
|
+
sampledRows,
|
|
3424
|
+
availableRows,
|
|
3425
|
+
qualifiedRows,
|
|
3426
|
+
rowsWithEmail,
|
|
3427
|
+
copyReadyRows,
|
|
3428
|
+
artifactCount,
|
|
3429
|
+
readyForDeliveryApproval,
|
|
3430
|
+
blockedReasons,
|
|
3431
|
+
warnings
|
|
3432
|
+
},
|
|
3433
|
+
nextActions: campaignReviewNextActions(status, readyForDeliveryApproval)
|
|
3434
|
+
};
|
|
3435
|
+
}
|
|
3436
|
+
function campaignReviewNextActions(status, readyForDeliveryApproval) {
|
|
3437
|
+
const buildId = status.campaignBuildId;
|
|
3438
|
+
if (!buildId) return [];
|
|
3439
|
+
if (status.status === "completed" && readyForDeliveryApproval) {
|
|
3440
|
+
return [
|
|
3441
|
+
`signaliz campaign-agent approve ${buildId} --destination-type json`,
|
|
3442
|
+
`signaliz campaign-agent artifacts ${buildId}`
|
|
3443
|
+
];
|
|
3444
|
+
}
|
|
3445
|
+
if (status.status === "completed") {
|
|
3446
|
+
return [
|
|
3447
|
+
`signaliz campaign-agent rows ${buildId} --limit 100`,
|
|
3448
|
+
`signaliz campaign-agent artifacts ${buildId}`
|
|
3449
|
+
];
|
|
3450
|
+
}
|
|
3451
|
+
if (status.status === "pending_approval") {
|
|
3452
|
+
return [
|
|
3453
|
+
`signaliz campaign-agent rows ${buildId} --limit 100`,
|
|
3454
|
+
`signaliz campaign-agent approve ${buildId} --destination-type json`
|
|
3455
|
+
];
|
|
3456
|
+
}
|
|
3457
|
+
if ((status.status === "queued" || status.status === "running") && status.triggerRunId) {
|
|
3458
|
+
return [`signaliz ops run-status ${status.triggerRunId} --watch`];
|
|
3459
|
+
}
|
|
3460
|
+
return [`signaliz campaign-agent status ${buildId}`];
|
|
3461
|
+
}
|
|
3462
|
+
function campaignReviewRowHasEmail(row) {
|
|
3463
|
+
const data = asRecord(row.data);
|
|
3464
|
+
return Boolean(
|
|
3465
|
+
stringValue(data.email) || stringValue(data.work_email) || stringValue(data.workEmail)
|
|
3466
|
+
);
|
|
3467
|
+
}
|
|
3468
|
+
function campaignReviewRowHasCopy(row) {
|
|
3469
|
+
const data = asRecord(row.data);
|
|
3470
|
+
const copy = asRecord(data.copy);
|
|
3471
|
+
const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
|
|
3472
|
+
return row.status === "copy_ready" || data.copy_ready === true || Boolean(
|
|
3473
|
+
stringValue(data.subject) || stringValue(data.subject_line) || stringValue(data.subjectLine) || stringValue(data.opener) || stringValue(data.body) || stringValue(data.cta) || stringValue(copy.subject) || stringValue(copy.body) || stringValue(rawCopy.subject) || stringValue(rawCopy.body)
|
|
3474
|
+
);
|
|
3475
|
+
}
|
|
3292
3476
|
function diagnosticMessages2(value) {
|
|
3293
3477
|
if (!Array.isArray(value)) return [];
|
|
3294
3478
|
return value.map((item) => {
|
package/dist/index.mjs
CHANGED