@signaliz/sdk 1.0.6 → 1.0.8
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 +100 -8
- package/dist/{chunk-GRVV37LD.mjs → chunk-KL6KNOP6.mjs} +1432 -55
- package/dist/cli.js +2390 -62
- package/dist/cli.mjs +963 -9
- package/dist/index.d.mts +245 -10
- package/dist/index.d.ts +245 -10
- package/dist/index.js +1442 -55
- package/dist/index.mjs +21 -1
- package/dist/mcp-config.js +1320 -55
- package/dist/mcp-config.mjs +1 -1
- package/package.json +2 -2
package/dist/mcp-config.js
CHANGED
|
@@ -782,7 +782,7 @@ var Campaigns = class {
|
|
|
782
782
|
async build(request, options) {
|
|
783
783
|
return this.buildCampaign(request, options);
|
|
784
784
|
}
|
|
785
|
-
/** Scope an agency/
|
|
785
|
+
/** Scope an agency/customer campaign into a markdown brief plus build_campaign dry-run args. */
|
|
786
786
|
async scope(request) {
|
|
787
787
|
return this.scopeCampaign(request);
|
|
788
788
|
}
|
|
@@ -964,6 +964,10 @@ function mapStatus(data) {
|
|
|
964
964
|
errors: diagnosticMessages(data.errors),
|
|
965
965
|
artifactCount: data.artifact_count ?? 0,
|
|
966
966
|
providerRoute: mapProviderRoute(data),
|
|
967
|
+
triggerRunId: typeof data.trigger_run_id === "string" ? data.trigger_run_id : null,
|
|
968
|
+
staleRunningPhase: data.stale_running_phase === true,
|
|
969
|
+
phaseAgeSeconds: numberOrNull(data.phase_age_seconds),
|
|
970
|
+
diagnostics: recordOrNull(data.diagnostics) ?? {},
|
|
967
971
|
nextAction: formatNextAction(data.next_action),
|
|
968
972
|
createdAt: data.created_at,
|
|
969
973
|
updatedAt: data.updated_at,
|
|
@@ -1057,7 +1061,7 @@ function mapArtifact(a) {
|
|
|
1057
1061
|
function mapScope(data) {
|
|
1058
1062
|
return {
|
|
1059
1063
|
campaignScopeId: data.campaign_scope_id,
|
|
1060
|
-
|
|
1064
|
+
accountLabel: data.account_label,
|
|
1061
1065
|
campaignName: data.campaign_name,
|
|
1062
1066
|
approach: data.approach,
|
|
1063
1067
|
approachLabel: data.approach_label,
|
|
@@ -1083,8 +1087,8 @@ function scopeArgs(request) {
|
|
|
1083
1087
|
const args = {
|
|
1084
1088
|
prompt: request.prompt
|
|
1085
1089
|
};
|
|
1086
|
-
if (request.
|
|
1087
|
-
if (request.
|
|
1090
|
+
if (request.accountLabel) args.account_label = request.accountLabel;
|
|
1091
|
+
if (request.accountContext) args.account_context = request.accountContext;
|
|
1088
1092
|
if (request.campaignGoal) args.campaign_goal = request.campaignGoal;
|
|
1089
1093
|
if (request.targetCount) args.target_count = request.targetCount;
|
|
1090
1094
|
if (request.destinations) args.destinations = request.destinations;
|
|
@@ -1212,22 +1216,557 @@ var DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS = {
|
|
|
1212
1216
|
approvalRequired: true
|
|
1213
1217
|
}
|
|
1214
1218
|
};
|
|
1219
|
+
var DEFAULT_CAMPAIGN_BUILDER_BUILT_INS = [
|
|
1220
|
+
"lead_generation",
|
|
1221
|
+
"email_finding",
|
|
1222
|
+
"email_verification",
|
|
1223
|
+
"signals"
|
|
1224
|
+
];
|
|
1225
|
+
var CAMPAIGN_BUILDER_OPERATING_PLAYBOOKS = [
|
|
1226
|
+
{
|
|
1227
|
+
slug: "cache-first-large-list",
|
|
1228
|
+
label: "Cache-First Large List",
|
|
1229
|
+
whenToUse: [
|
|
1230
|
+
"The target count is high and reusable workspace lead or cache coverage may exist.",
|
|
1231
|
+
"The deliverable is a verified list or top-up rather than a deeply custom one-off workflow."
|
|
1232
|
+
],
|
|
1233
|
+
sequence: [
|
|
1234
|
+
"Inventory reusable cache before paid sourcing.",
|
|
1235
|
+
"Report unique emails, role buckets, exclusions, and missing-field counts.",
|
|
1236
|
+
"Use fresh sourcing only for the approved gap.",
|
|
1237
|
+
"Write newly approved source metadata back to memory or cache after review."
|
|
1238
|
+
],
|
|
1239
|
+
requiredFields: {
|
|
1240
|
+
inventory: ["matching_cached_rows", "unique_cached_emails", "persona_bucket_counts", "exclusions_applied", "missing_field_counts"],
|
|
1241
|
+
finalRows: ["first_name", "last_name", "company_name", "company_domain", "work_email", "email_status", "source_type"]
|
|
1242
|
+
},
|
|
1243
|
+
qualityGates: [
|
|
1244
|
+
"Deduplicate by normalized email before counting final rows.",
|
|
1245
|
+
"Separate cache reuse from fresh sourcing in the build receipt.",
|
|
1246
|
+
"Block export when required identity, company, or email fields are missing."
|
|
1247
|
+
],
|
|
1248
|
+
activationBoundary: "Cache inventory is read-only. Fresh sourcing, cache writes, export, and sender loading require explicit approval.",
|
|
1249
|
+
memoryKeywords: ["cache inventory", "large list", "unique emails", "top-up sourcing", "source metadata"]
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
slug: "net-new-suppressed-list",
|
|
1253
|
+
label: "Net-New Suppressed List",
|
|
1254
|
+
whenToUse: [
|
|
1255
|
+
"A prior campaign, seed list, or exclusion list must be suppressed.",
|
|
1256
|
+
"The operator needs both outreach-facing rows and provenance-rich QA evidence."
|
|
1257
|
+
],
|
|
1258
|
+
sequence: [
|
|
1259
|
+
"Load suppression baselines before source selection.",
|
|
1260
|
+
"Apply email suppression as a hard gate and domain suppression as required by the brief.",
|
|
1261
|
+
"Keep provenance, source, and validation fields outside the outreach-facing export when needed.",
|
|
1262
|
+
"Run final overlap checks before any delivery action."
|
|
1263
|
+
],
|
|
1264
|
+
requiredFields: {
|
|
1265
|
+
suppression: ["suppression_source", "prior_email_overlap", "prior_domain_match", "suppression_decision"],
|
|
1266
|
+
finalRows: ["first_name", "last_name", "company_name", "company_domain", "work_email", "email_status", "provenance_id"]
|
|
1267
|
+
},
|
|
1268
|
+
qualityGates: [
|
|
1269
|
+
"Prior email overlap must be zero for rows marked export ready.",
|
|
1270
|
+
"Prior-domain matches must be flagged or blocked according to the approved campaign promise.",
|
|
1271
|
+
"Do not describe rows as fully qualified when the approved path only proves net-new email status."
|
|
1272
|
+
],
|
|
1273
|
+
activationBoundary: "Suppression review must pass before export, upload, CRM sync, sender load, or sequence launch.",
|
|
1274
|
+
memoryKeywords: ["suppression", "net-new", "prior email overlap", "domain review", "provenance-rich QA"]
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
slug: "proof-first-vertical-gate",
|
|
1278
|
+
label: "Proof-First Vertical Gate",
|
|
1279
|
+
whenToUse: [
|
|
1280
|
+
"Wrong-account risk is high or the target category has close lookalike exclusions.",
|
|
1281
|
+
"Account proof is more important than raw lead volume."
|
|
1282
|
+
],
|
|
1283
|
+
sequence: [
|
|
1284
|
+
"Define positive and negative proof fields before sourcing at scale.",
|
|
1285
|
+
"Qualify companies before contact discovery.",
|
|
1286
|
+
"Qualify contacts before email finding.",
|
|
1287
|
+
"Keep pass, review, and fail rows distinct through delivery review."
|
|
1288
|
+
],
|
|
1289
|
+
requiredFields: {
|
|
1290
|
+
account: ["company_name", "company_domain", "source_url", "positive_proof", "negative_proof", "fit_score", "account_qualified"],
|
|
1291
|
+
contact: ["person_name", "person_title", "persona_match", "contact_fit_score", "contact_qualified"]
|
|
1292
|
+
},
|
|
1293
|
+
qualityGates: [
|
|
1294
|
+
"Do not spend on contact or email enrichment until the account passes the proof gate.",
|
|
1295
|
+
"Adjacent excluded categories must stay exclusions, not synonyms.",
|
|
1296
|
+
"Contact fit should meet the configured threshold before email finding or copy generation."
|
|
1297
|
+
],
|
|
1298
|
+
activationBoundary: "Proof gates are required before contact spend, copy, export, or external writes.",
|
|
1299
|
+
memoryKeywords: ["proof gate", "vertical exclusion", "company before contact", "pass review fail", "fit threshold"]
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
slug: "signal-led-copy-approval",
|
|
1303
|
+
label: "Signal-Led Copy With Approval",
|
|
1304
|
+
whenToUse: [
|
|
1305
|
+
"Outbound copy should be grounded in company signals, proof fields, or row context.",
|
|
1306
|
+
"Delivery destinations must remain locked after copy generation until review."
|
|
1307
|
+
],
|
|
1308
|
+
sequence: [
|
|
1309
|
+
"Validate list quality before copy.",
|
|
1310
|
+
"Attach the strongest supported signal and source evidence.",
|
|
1311
|
+
"Generate copy only for fit-qualified and contactable rows.",
|
|
1312
|
+
"Hold every destination behind explicit approval."
|
|
1313
|
+
],
|
|
1314
|
+
requiredFields: {
|
|
1315
|
+
evidence: ["strongest_signal", "signal_source_url", "why_now", "personalization_basis"],
|
|
1316
|
+
copy: ["subject_line", "opening_line", "email_copy", "copy_ready", "copy_blocker"]
|
|
1317
|
+
},
|
|
1318
|
+
qualityGates: [
|
|
1319
|
+
"Copy cannot invent unsupported pain, claims, numbers, or recent events.",
|
|
1320
|
+
"Weak evidence should route the row to review instead of send-ready copy.",
|
|
1321
|
+
"Destination fields must remain blocked until approval metadata is present."
|
|
1322
|
+
],
|
|
1323
|
+
activationBoundary: "Copy readiness is not delivery approval. Export, sync, sender load, and launch require a separate human-approved gate.",
|
|
1324
|
+
memoryKeywords: ["company signals", "evidence-fed copy", "why now", "copy blocker", "approval gate"]
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
slug: "domain-first-recovery",
|
|
1328
|
+
label: "Domain-First Recovery",
|
|
1329
|
+
whenToUse: [
|
|
1330
|
+
"Strict yield is low and broad people sourcing creates noisy, duplicated, or off-fit rows.",
|
|
1331
|
+
"The account universe should be recovered or expanded before more contact spend."
|
|
1332
|
+
],
|
|
1333
|
+
sequence: [
|
|
1334
|
+
"Model attrition after an initial sample.",
|
|
1335
|
+
"Source or recover account domains in tight slices.",
|
|
1336
|
+
"Filter domains locally before contact discovery.",
|
|
1337
|
+
"Use accepted domains as the seed for person and email work."
|
|
1338
|
+
],
|
|
1339
|
+
requiredFields: {
|
|
1340
|
+
domainReview: ["company_domain", "source_slice", "domain_fit_score", "domain_rejection_reason", "accepted_domain"],
|
|
1341
|
+
recovery: ["target_gap", "expected_yield", "accepted_domain_count", "contact_pull_limit"]
|
|
1342
|
+
},
|
|
1343
|
+
qualityGates: [
|
|
1344
|
+
"Do not repeat broad people-with-email sourcing after strict yield proves low.",
|
|
1345
|
+
"Rejected domains should stay suppressed unless the operator changes the ICP.",
|
|
1346
|
+
"Target count means final held rows, not raw sourced rows."
|
|
1347
|
+
],
|
|
1348
|
+
activationBoundary: "Domain recovery informs sourcing. Contact enrichment, paid qualification, and export still require approved gates.",
|
|
1349
|
+
memoryKeywords: ["domain-first", "yield modeling", "attrition", "accepted domains", "gap fill"]
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
slug: "table-workflow-handoff",
|
|
1353
|
+
label: "Table Workflow Handoff",
|
|
1354
|
+
whenToUse: [
|
|
1355
|
+
"The campaign needs connected source, account, people, enrichment, copy, and destination tables.",
|
|
1356
|
+
"A workspace or partner tool owns part of the workflow through MCP, webhook, API, or managed integration."
|
|
1357
|
+
],
|
|
1358
|
+
sequence: [
|
|
1359
|
+
"Create source/account context before child people rows.",
|
|
1360
|
+
"Carry source context into enrichment, copy, and destination mapping.",
|
|
1361
|
+
"Expose request-ready, result, error, blocker, and export-ready fields for every action.",
|
|
1362
|
+
"Dry-run provider routes and destination writes before activation."
|
|
1363
|
+
],
|
|
1364
|
+
requiredFields: {
|
|
1365
|
+
workflow: ["source_record_id", "company_context", "request_ready", "provider_status", "error", "export_ready", "export_blocker"],
|
|
1366
|
+
destination: ["destination_type", "destination_status", "approval_status", "approved_by", "approved_at"]
|
|
1367
|
+
},
|
|
1368
|
+
qualityGates: [
|
|
1369
|
+
"Every paid/API action needs visible request readiness and parsed output fields.",
|
|
1370
|
+
"Child people rows must preserve the account context that justified the search.",
|
|
1371
|
+
"Provider route activation must dry-run before any external write."
|
|
1372
|
+
],
|
|
1373
|
+
activationBoundary: "MCP, webhook, managed integration, and destination routes remain dry-run until the reviewed route and campaign are approved.",
|
|
1374
|
+
memoryKeywords: ["table workflow", "request ready", "provider status", "export blocker", "BYO integration"]
|
|
1375
|
+
}
|
|
1376
|
+
];
|
|
1377
|
+
var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
|
|
1378
|
+
{
|
|
1379
|
+
slug: "industrial-ot-resilience",
|
|
1380
|
+
label: "Industrial OT Resilience",
|
|
1381
|
+
aliases: ["industrial ot", "ot resilience", "industrial continuity", "industrial-ot-resilience"],
|
|
1382
|
+
defaultTargetCount: 3e3,
|
|
1383
|
+
campaignName: "Industrial OT Resilience Net-New",
|
|
1384
|
+
accountContext: [
|
|
1385
|
+
"Strategy template: Signaliz-only OT, industrial, manufacturing, embedded systems, field service, cyber resilience, and business continuity sourcing.",
|
|
1386
|
+
"Use prior approved campaign output as the email suppression baseline; final files must have zero prior-used email overlap.",
|
|
1387
|
+
"Keep external qualification providers disabled unless the operator explicitly changes the requirement."
|
|
1388
|
+
].join(" "),
|
|
1389
|
+
icp: {
|
|
1390
|
+
personas: [
|
|
1391
|
+
"OT leader",
|
|
1392
|
+
"Industrial automation leader",
|
|
1393
|
+
"Engineering leader",
|
|
1394
|
+
"IT infrastructure leader",
|
|
1395
|
+
"Reliability or maintenance leader",
|
|
1396
|
+
"Operations leader"
|
|
1397
|
+
],
|
|
1398
|
+
industries: [
|
|
1399
|
+
"Machinery",
|
|
1400
|
+
"Electrical and electronic manufacturing",
|
|
1401
|
+
"Mechanical or industrial engineering",
|
|
1402
|
+
"Industrial automation",
|
|
1403
|
+
"Semiconductors",
|
|
1404
|
+
"Medical devices",
|
|
1405
|
+
"Oil and energy",
|
|
1406
|
+
"Automotive"
|
|
1407
|
+
],
|
|
1408
|
+
geographies: ["United States", "United Kingdom", "Canada", "Nordics", "Netherlands"],
|
|
1409
|
+
keywords: [
|
|
1410
|
+
"OT",
|
|
1411
|
+
"ICS",
|
|
1412
|
+
"SCADA",
|
|
1413
|
+
"control systems",
|
|
1414
|
+
"industrial automation",
|
|
1415
|
+
"manufacturing",
|
|
1416
|
+
"plant operations",
|
|
1417
|
+
"reliability",
|
|
1418
|
+
"maintenance",
|
|
1419
|
+
"PLC",
|
|
1420
|
+
"business continuity"
|
|
1421
|
+
],
|
|
1422
|
+
exclusions: [
|
|
1423
|
+
"sales",
|
|
1424
|
+
"marketing",
|
|
1425
|
+
"recruiting",
|
|
1426
|
+
"HR",
|
|
1427
|
+
"finance",
|
|
1428
|
+
"legal",
|
|
1429
|
+
"customer success",
|
|
1430
|
+
"retail",
|
|
1431
|
+
"restaurants",
|
|
1432
|
+
"staffing",
|
|
1433
|
+
"real estate"
|
|
1434
|
+
],
|
|
1435
|
+
requireVerifiedEmail: true
|
|
1436
|
+
},
|
|
1437
|
+
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1438
|
+
preferredProviders: ["signaliz_native"],
|
|
1439
|
+
memoryQueries: [{
|
|
1440
|
+
query: "industrial OT net-new prior email suppression verified manufacturing embedded systems field service cyber resilience business continuity",
|
|
1441
|
+
scopes: ["workspace", "operator_notes"],
|
|
1442
|
+
topK: 10,
|
|
1443
|
+
required: true,
|
|
1444
|
+
rationale: "Load OT sourcing, dedupe, cache metadata, and approval gates before planning net-new work."
|
|
1445
|
+
}],
|
|
1446
|
+
constraints: {
|
|
1447
|
+
deliverabilityNotes: [
|
|
1448
|
+
"Require verified email, valid syntax, first name, last name, company name, and normalized company domain.",
|
|
1449
|
+
"Keep export, upload, sync, send, and replacement actions blocked until explicit approval.",
|
|
1450
|
+
"Treat prior-domain matches as flagged review evidence unless strict domain suppression is explicitly requested."
|
|
1451
|
+
]
|
|
1452
|
+
},
|
|
1453
|
+
signalizDefaults: {
|
|
1454
|
+
copy: {
|
|
1455
|
+
offerContext: "Do not invent product claims. Anchor messaging only in row-supported OT, industrial, cyber resilience, backup/recovery, or business-continuity context."
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
agencyContext: {
|
|
1459
|
+
partnerEcosystem: ["signaliz", "instantly", "nango"]
|
|
1460
|
+
},
|
|
1461
|
+
operatingPlaybookSlugs: ["net-new-suppressed-list", "proof-first-vertical-gate", "signal-led-copy-approval"]
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
slug: "non-medical-home-care",
|
|
1465
|
+
label: "Non-Medical Home Care Operations",
|
|
1466
|
+
aliases: ["home care", "non-medical home care", "home-care-operations", "non-medical-home-care"],
|
|
1467
|
+
defaultTargetCount: 3e3,
|
|
1468
|
+
campaignName: "Mature Home Care Agency Operators",
|
|
1469
|
+
accountContext: [
|
|
1470
|
+
"Strategy template: mature US non-medical home care agencies with scale signals, proof fields, strict home-care vs home-health separation, and approval-gated export.",
|
|
1471
|
+
"Use proof before paid enrichment or copy. Preserve pass vs review ICP status because healthcare language often blurs home care and home health."
|
|
1472
|
+
].join(" "),
|
|
1473
|
+
icp: {
|
|
1474
|
+
personas: [
|
|
1475
|
+
"Owner",
|
|
1476
|
+
"CEO",
|
|
1477
|
+
"COO",
|
|
1478
|
+
"Administrator",
|
|
1479
|
+
"Operations Director",
|
|
1480
|
+
"Scheduler",
|
|
1481
|
+
"Care coordinator leader"
|
|
1482
|
+
],
|
|
1483
|
+
industries: ["Non-medical home care", "Senior care", "Private duty care", "Home services"],
|
|
1484
|
+
companySizes: ["20+ employees", "600+ billable care hours/week", "1000+ billable care hours/week ideal"],
|
|
1485
|
+
geographies: ["United States"],
|
|
1486
|
+
keywords: [
|
|
1487
|
+
"non-medical home care",
|
|
1488
|
+
"private duty",
|
|
1489
|
+
"caregiver recruiting",
|
|
1490
|
+
"multi-location",
|
|
1491
|
+
"franchise",
|
|
1492
|
+
"scheduler",
|
|
1493
|
+
"billing",
|
|
1494
|
+
"payroll",
|
|
1495
|
+
"EVV",
|
|
1496
|
+
"WellSky",
|
|
1497
|
+
"AxisCare",
|
|
1498
|
+
"CareSmartz360"
|
|
1499
|
+
],
|
|
1500
|
+
exclusions: [
|
|
1501
|
+
"home health",
|
|
1502
|
+
"skilled nursing",
|
|
1503
|
+
"hospice",
|
|
1504
|
+
"hospital",
|
|
1505
|
+
"clinic",
|
|
1506
|
+
"therapy practice",
|
|
1507
|
+
"very small owner-only shop"
|
|
1508
|
+
],
|
|
1509
|
+
requireVerifiedEmail: true
|
|
1510
|
+
},
|
|
1511
|
+
builtIns: ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"],
|
|
1512
|
+
preferredProviders: ["signaliz_native", "octave", "clay_webhook", "apify"],
|
|
1513
|
+
memoryQueries: [{
|
|
1514
|
+
query: "mature non-medical home care agencies billable hours franchise caregiver recruiting proof gate qualification export approval",
|
|
1515
|
+
scopes: ["workspace", "operator_notes"],
|
|
1516
|
+
topK: 10,
|
|
1517
|
+
required: true,
|
|
1518
|
+
rationale: "Load home-care ICP gates, source lanes, qualification thresholds, and home-care exclusion logic."
|
|
1519
|
+
}],
|
|
1520
|
+
constraints: {
|
|
1521
|
+
deliverabilityNotes: [
|
|
1522
|
+
"Company proof and strict ICP gate must pass before contact search, email finding, Signaliz signals, or export.",
|
|
1523
|
+
"Home health is an exclusion signal, not a synonym for home care."
|
|
1524
|
+
]
|
|
1525
|
+
},
|
|
1526
|
+
signalizDefaults: {
|
|
1527
|
+
copy: {
|
|
1528
|
+
offerContext: "Use angles around after-hours shift recovery, billing/payroll exceptions, multi-location consistency, and caregiver retention only when supported by evidence."
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
agencyContext: {
|
|
1532
|
+
partnerEcosystem: ["clay", "octave", "signaliz", "instantly", "nango"]
|
|
1533
|
+
},
|
|
1534
|
+
operatingPlaybookSlugs: ["proof-first-vertical-gate", "domain-first-recovery", "table-workflow-handoff"]
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
slug: "agency-founder-led",
|
|
1538
|
+
label: "Founder-Led Agency Services",
|
|
1539
|
+
aliases: ["agency founder", "founder-led agency", "agency-founder-led"],
|
|
1540
|
+
defaultTargetCount: 3e3,
|
|
1541
|
+
campaignName: "Founder-Led Agency Executive Campaign",
|
|
1542
|
+
accountContext: [
|
|
1543
|
+
"Strategy template: agency founder, owner, CEO, and executive sourcing across marketing services, creative, web, PR, ecommerce, paid media, SEO, content, and specialist digital agencies.",
|
|
1544
|
+
"Use suppression files, company-domain pool review, people/email verification queues, and final approval gates before any delivery action."
|
|
1545
|
+
].join(" "),
|
|
1546
|
+
icp: {
|
|
1547
|
+
personas: ["Founder", "Owner", "CEO", "Managing Partner", "President", "Agency Executive"],
|
|
1548
|
+
industries: [
|
|
1549
|
+
"Marketing services",
|
|
1550
|
+
"Advertising services",
|
|
1551
|
+
"Digital marketing agency",
|
|
1552
|
+
"Creative agency",
|
|
1553
|
+
"PR and communications",
|
|
1554
|
+
"Ecommerce agency",
|
|
1555
|
+
"Paid media agency",
|
|
1556
|
+
"SEO agency",
|
|
1557
|
+
"Content agency"
|
|
1558
|
+
],
|
|
1559
|
+
companySizes: ["11-50", "25-150", "51-200"],
|
|
1560
|
+
geographies: ["United States"],
|
|
1561
|
+
keywords: [
|
|
1562
|
+
"agency founder",
|
|
1563
|
+
"performance marketing",
|
|
1564
|
+
"paid media",
|
|
1565
|
+
"SEO",
|
|
1566
|
+
"content",
|
|
1567
|
+
"creative",
|
|
1568
|
+
"web design",
|
|
1569
|
+
"brand agency",
|
|
1570
|
+
"PR communications",
|
|
1571
|
+
"Shopify",
|
|
1572
|
+
"Klaviyo"
|
|
1573
|
+
],
|
|
1574
|
+
exclusions: ["enterprise holding company", "staffing", "recruiting", "software-only vendor", "freelancer-only profile"],
|
|
1575
|
+
requireVerifiedEmail: true
|
|
1576
|
+
},
|
|
1577
|
+
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1578
|
+
preferredProviders: ["signaliz_native", "octave"],
|
|
1579
|
+
memoryQueries: [{
|
|
1580
|
+
query: "agency founder owner CEO marketing services suppression domain pool email verification final approval gate",
|
|
1581
|
+
scopes: ["workspace", "operator_notes"],
|
|
1582
|
+
topK: 10,
|
|
1583
|
+
required: true,
|
|
1584
|
+
rationale: "Load agency-segment sourcing lanes, suppression rules, and verification workflow lessons."
|
|
1585
|
+
}],
|
|
1586
|
+
constraints: {
|
|
1587
|
+
deliverabilityNotes: [
|
|
1588
|
+
"Keep email and domain suppression visible in the plan.",
|
|
1589
|
+
"Do not export or send until the final verified file and suppression checks are approved."
|
|
1590
|
+
]
|
|
1591
|
+
},
|
|
1592
|
+
agencyContext: {
|
|
1593
|
+
partnerEcosystem: ["signaliz", "octave", "instantly", "nango"]
|
|
1594
|
+
},
|
|
1595
|
+
operatingPlaybookSlugs: ["net-new-suppressed-list", "signal-led-copy-approval", "table-workflow-handoff"]
|
|
1596
|
+
},
|
|
1597
|
+
{
|
|
1598
|
+
slug: "cloud-infrastructure-displacement",
|
|
1599
|
+
label: "Cloud Infrastructure Displacement",
|
|
1600
|
+
aliases: ["cloud displacement", "private cloud displacement", "cloud infrastructure", "cloud-infrastructure-displacement"],
|
|
1601
|
+
defaultTargetCount: 3e3,
|
|
1602
|
+
campaignName: "Cloud Infrastructure Displacement Campaign",
|
|
1603
|
+
accountContext: [
|
|
1604
|
+
"Strategy template: managed infrastructure, private cloud, disaster recovery, colocation, and VMware/Broadcom displacement motions.",
|
|
1605
|
+
"The spend-efficient ladder is Signaliz company search, Octave company qualification, Signaliz people search, Octave person qualification, then Signaliz email finding and verification."
|
|
1606
|
+
].join(" "),
|
|
1607
|
+
icp: {
|
|
1608
|
+
personas: [
|
|
1609
|
+
"CTO",
|
|
1610
|
+
"CIO",
|
|
1611
|
+
"CISO",
|
|
1612
|
+
"CFO tied to cloud spend",
|
|
1613
|
+
"VP Engineering",
|
|
1614
|
+
"VP Infrastructure",
|
|
1615
|
+
"VP Cloud",
|
|
1616
|
+
"Head of Platform",
|
|
1617
|
+
"Director IT",
|
|
1618
|
+
"Cloud Architect",
|
|
1619
|
+
"Infrastructure Architect"
|
|
1620
|
+
],
|
|
1621
|
+
industries: [
|
|
1622
|
+
"SaaS",
|
|
1623
|
+
"Software",
|
|
1624
|
+
"Cybersecurity",
|
|
1625
|
+
"Fintech",
|
|
1626
|
+
"Healthcare technology",
|
|
1627
|
+
"Compliance and GRC",
|
|
1628
|
+
"DevOps",
|
|
1629
|
+
"Infrastructure",
|
|
1630
|
+
"Observability"
|
|
1631
|
+
],
|
|
1632
|
+
companySizes: ["$10M-$500M revenue", "50-1500 employees"],
|
|
1633
|
+
geographies: ["United States"],
|
|
1634
|
+
keywords: [
|
|
1635
|
+
"VMware Broadcom",
|
|
1636
|
+
"VxRail",
|
|
1637
|
+
"cloud cost pressure",
|
|
1638
|
+
"private cloud",
|
|
1639
|
+
"Proxmox",
|
|
1640
|
+
"Hyper-V",
|
|
1641
|
+
"managed infrastructure",
|
|
1642
|
+
"DRaaS",
|
|
1643
|
+
"colocation",
|
|
1644
|
+
"uptime",
|
|
1645
|
+
"reliability"
|
|
1646
|
+
],
|
|
1647
|
+
exclusions: [
|
|
1648
|
+
"MSP competitor",
|
|
1649
|
+
"hosting provider",
|
|
1650
|
+
"data center competitor",
|
|
1651
|
+
"staffing",
|
|
1652
|
+
"recruiting",
|
|
1653
|
+
"international-only",
|
|
1654
|
+
"procurement-only",
|
|
1655
|
+
"AI GPU-heavy infrastructure"
|
|
1656
|
+
],
|
|
1657
|
+
requireVerifiedEmail: true
|
|
1658
|
+
},
|
|
1659
|
+
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1660
|
+
preferredProviders: ["signaliz_native", "octave"],
|
|
1661
|
+
memoryQueries: [{
|
|
1662
|
+
query: "cloud hosting infrastructure VMware Broadcom qualification verified email persona trigger SKU mapping",
|
|
1663
|
+
scopes: ["workspace", "operator_notes"],
|
|
1664
|
+
topK: 10,
|
|
1665
|
+
required: true,
|
|
1666
|
+
rationale: "Load cloud-infrastructure qualification order, persona clusters, trigger/SKU mapping, and verified-list QA rules."
|
|
1667
|
+
}],
|
|
1668
|
+
constraints: {
|
|
1669
|
+
deliverabilityNotes: [
|
|
1670
|
+
"Qualify accounts and people before email verification.",
|
|
1671
|
+
"If signal enrichment is deferred or unavailable, state it plainly instead of inventing evidence."
|
|
1672
|
+
]
|
|
1673
|
+
},
|
|
1674
|
+
signalizDefaults: {
|
|
1675
|
+
copy: {
|
|
1676
|
+
offerContext: "Map pain to routes such as VMware/Broadcom exit, cloud cost reduction, infrastructure modernization, compliance gap, managed infrastructure, private cloud, Proxmox/Hyper-V, colocation, or DRaaS."
|
|
1677
|
+
}
|
|
1678
|
+
},
|
|
1679
|
+
agencyContext: {
|
|
1680
|
+
partnerEcosystem: ["signaliz", "octave", "instantly", "nango"]
|
|
1681
|
+
},
|
|
1682
|
+
operatingPlaybookSlugs: ["proof-first-vertical-gate", "domain-first-recovery", "signal-led-copy-approval"]
|
|
1683
|
+
}
|
|
1684
|
+
];
|
|
1215
1685
|
var CampaignBuilderAgent = class {
|
|
1216
1686
|
constructor(client) {
|
|
1217
1687
|
this.client = client;
|
|
1218
1688
|
}
|
|
1219
1689
|
async createPlan(request, options = {}) {
|
|
1690
|
+
const resolvedRequest = applyCampaignBuilderStrategyTemplate(request);
|
|
1220
1691
|
const warnings = [];
|
|
1221
|
-
const workspaceContext =
|
|
1222
|
-
const scopeResult = options.scopeCampaign === false ? void 0 : await this.scopeCampaign(
|
|
1692
|
+
const workspaceContext = resolvedRequest.workspaceContext ?? await this.getWorkspaceContext(warnings);
|
|
1693
|
+
const scopeResult = options.scopeCampaign === false ? void 0 : await this.scopeCampaign(resolvedRequest, warnings);
|
|
1223
1694
|
if (options.discoverCapabilities !== false) {
|
|
1224
|
-
await this.discoverPlannedRoutes(
|
|
1695
|
+
await this.discoverPlannedRoutes(resolvedRequest, warnings);
|
|
1225
1696
|
}
|
|
1226
|
-
|
|
1697
|
+
const plan = createCampaignBuilderAgentPlan(resolvedRequest, {
|
|
1227
1698
|
workspaceContext,
|
|
1228
1699
|
scopeBuildArgs: asRecord(scopeResult?.build_campaign_args ?? scopeResult?.buildCampaignArgs),
|
|
1229
1700
|
warnings
|
|
1230
1701
|
});
|
|
1702
|
+
if (options.includeStrategyMemoryStatus !== false) {
|
|
1703
|
+
await this.attachStrategyMemoryStatus(plan, warnings);
|
|
1704
|
+
}
|
|
1705
|
+
if (options.includeKernelPlan !== false) {
|
|
1706
|
+
await this.attachKernelCampaignBuildPlan(plan, warnings);
|
|
1707
|
+
}
|
|
1708
|
+
if (options.includeDeliveryRisk !== false) {
|
|
1709
|
+
await this.attachDeliveryRiskPreflight(plan, warnings);
|
|
1710
|
+
}
|
|
1711
|
+
return plan;
|
|
1712
|
+
}
|
|
1713
|
+
async commitPlan(plan, options = {}) {
|
|
1714
|
+
const writeMode = options.confirm === true && options.dryRun === false;
|
|
1715
|
+
if (writeMode && !options.approvedBy) {
|
|
1716
|
+
throw new Error("Campaign builder plan commit requires approvedBy before writing state");
|
|
1717
|
+
}
|
|
1718
|
+
const plannerStep = plan.mcpFlow.find((step) => step.id === "agency-campaign-build-plan");
|
|
1719
|
+
const plannerArgs = asRecord(plannerStep?.arguments);
|
|
1720
|
+
const commitArgs = compact({
|
|
1721
|
+
campaign_id: plan.buildRequest.gtmCampaignId,
|
|
1722
|
+
name: plan.campaignName,
|
|
1723
|
+
campaign_brief: plan.buildRequest.prompt || plan.goal,
|
|
1724
|
+
target_icp: plan.buildRequest.icp ? buildGtmTargetIcpContext(plan.buildRequest.icp) : void 0,
|
|
1725
|
+
lead_count: plan.targetCount,
|
|
1726
|
+
layers: plannerArgs.layers,
|
|
1727
|
+
preferred_providers: plannerArgs.preferred_providers,
|
|
1728
|
+
plan_snapshot: Object.keys(asRecord(plan.kernelPlan)).length > 0 ? plan.kernelPlan : buildFallbackPlanSnapshot(plan),
|
|
1729
|
+
send_config: plan.buildRequest.delivery ? {
|
|
1730
|
+
delivery: plan.buildRequest.delivery,
|
|
1731
|
+
approval_required: true
|
|
1732
|
+
} : void 0,
|
|
1733
|
+
brain_config: compact({
|
|
1734
|
+
campaign_builder_agent_v1: {
|
|
1735
|
+
plan_id: plan.planId,
|
|
1736
|
+
kernel_plan_attached: Object.keys(asRecord(plan.kernelPlan)).length > 0,
|
|
1737
|
+
approval_ids: plan.approvals.map((approval) => approval.id)
|
|
1738
|
+
},
|
|
1739
|
+
brain_defaults: plan.buildRequest.brainDefaults,
|
|
1740
|
+
brain_preflight: plan.buildRequest.brainPreflight,
|
|
1741
|
+
delivery_risk_preflight: plan.buildRequest.deliveryRisk,
|
|
1742
|
+
delivery_risk: plan.buildRequest.deliveryRisk
|
|
1743
|
+
}),
|
|
1744
|
+
metadata: {
|
|
1745
|
+
campaign_builder_agent_v1: {
|
|
1746
|
+
plan_id: plan.planId,
|
|
1747
|
+
source: "campaign-builder-agent",
|
|
1748
|
+
approval_required: plan.approvals.some((approval) => approval.blocking),
|
|
1749
|
+
approval_ids: plan.approvals.map((approval) => approval.id),
|
|
1750
|
+
estimated_credits: plan.estimatedCredits
|
|
1751
|
+
},
|
|
1752
|
+
brain_delivery_risk_preflight: plan.buildRequest.deliveryRisk,
|
|
1753
|
+
delivery_risk: plan.buildRequest.deliveryRisk
|
|
1754
|
+
},
|
|
1755
|
+
approval_required: plan.approvals.some((approval) => approval.blocking),
|
|
1756
|
+
actor_type: "agent",
|
|
1757
|
+
actor_id: options.approvedBy,
|
|
1758
|
+
rationale: options.rationale || "Committed a reviewed strategy-template campaign-builder plan before execution.",
|
|
1759
|
+
idempotency_key: options.idempotencyKey,
|
|
1760
|
+
dry_run: !writeMode,
|
|
1761
|
+
confirm: writeMode
|
|
1762
|
+
});
|
|
1763
|
+
const data = asRecord(await this.callMcp("gtm_campaign_build_plan_commit", commitArgs));
|
|
1764
|
+
const result = mapPlanCommitResult(data);
|
|
1765
|
+
if (result.wroteState && result.campaignId) {
|
|
1766
|
+
plan.buildRequest.gtmCampaignId = result.campaignId;
|
|
1767
|
+
refreshBuildStepArguments(plan);
|
|
1768
|
+
}
|
|
1769
|
+
return result;
|
|
1231
1770
|
}
|
|
1232
1771
|
async dryRunPlan(plan, options) {
|
|
1233
1772
|
let args = buildCampaignArgs({
|
|
@@ -1262,6 +1801,15 @@ var CampaignBuilderAgent = class {
|
|
|
1262
1801
|
if (missing.length > 0) {
|
|
1263
1802
|
throw new Error(`Campaign builder approval is incomplete: ${missing.map((a) => a.label).join(", ")}`);
|
|
1264
1803
|
}
|
|
1804
|
+
if (options?.commitBeforeLaunch && !plan.buildRequest.gtmCampaignId) {
|
|
1805
|
+
await this.commitPlan(plan, {
|
|
1806
|
+
confirm: true,
|
|
1807
|
+
dryRun: false,
|
|
1808
|
+
approvedBy: approval.approvedBy,
|
|
1809
|
+
idempotencyKey: options.idempotencyKey ? `${options.idempotencyKey}:plan-commit` : void 0,
|
|
1810
|
+
rationale: "Committed reviewed campaign-builder plan immediately before approved launch."
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1265
1813
|
let args = buildCampaignArgs({
|
|
1266
1814
|
...plan.buildRequest,
|
|
1267
1815
|
dryRun: false,
|
|
@@ -1308,8 +1856,8 @@ var CampaignBuilderAgent = class {
|
|
|
1308
1856
|
try {
|
|
1309
1857
|
return await this.callMcp("scope_campaign", {
|
|
1310
1858
|
prompt: request.goal,
|
|
1311
|
-
|
|
1312
|
-
|
|
1859
|
+
account_label: campaignBuilderAccountLabel(request),
|
|
1860
|
+
account_context: campaignBuilderAccountContext(request),
|
|
1313
1861
|
campaign_goal: request.goal,
|
|
1314
1862
|
target_count: request.targetCount,
|
|
1315
1863
|
approval_policy: request.approvalPolicy?.requireHumanApproval ? "human_required" : "standard"
|
|
@@ -1334,25 +1882,70 @@ var CampaignBuilderAgent = class {
|
|
|
1334
1882
|
}
|
|
1335
1883
|
}
|
|
1336
1884
|
}
|
|
1885
|
+
async attachStrategyMemoryStatus(plan, warnings) {
|
|
1886
|
+
const statusStep = plan.mcpFlow.find((step) => step.id === "strategy-memory-status");
|
|
1887
|
+
if (!statusStep) return;
|
|
1888
|
+
try {
|
|
1889
|
+
const status = asRecord(await this.callMcp("gtm_campaign_strategy_memory_status", asRecord(statusStep.arguments)));
|
|
1890
|
+
plan.strategyMemoryStatus = status;
|
|
1891
|
+
const blockers = arrayOfStrings(status.blockers) ?? [];
|
|
1892
|
+
if (status.ready === false || blockers.length > 0) {
|
|
1893
|
+
warnings.push(`Strategy memory readiness is incomplete: ${blockers.join("; ") || "missing required strategy or workflow memory"}`);
|
|
1894
|
+
}
|
|
1895
|
+
} catch (error) {
|
|
1896
|
+
warnings.push(`Strategy memory readiness check failed: ${errorMessage(error)}`);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
async attachKernelCampaignBuildPlan(plan, warnings) {
|
|
1900
|
+
const plannerStep = plan.mcpFlow.find((step) => step.id === "agency-campaign-build-plan");
|
|
1901
|
+
if (!plannerStep) return;
|
|
1902
|
+
try {
|
|
1903
|
+
const kernelPlan = await this.callMcp("gtm_campaign_build_plan", asRecord(plannerStep.arguments));
|
|
1904
|
+
plan.kernelPlan = asRecord(kernelPlan);
|
|
1905
|
+
const brainDefaults = asRecord(plan.kernelPlan.brain_defaults ?? plan.kernelPlan.brainDefaults);
|
|
1906
|
+
if (Object.keys(brainDefaults).length > 0 && Object.keys(asRecord(plan.buildRequest.brainDefaults)).length === 0) {
|
|
1907
|
+
plan.buildRequest.brainDefaults = brainDefaults;
|
|
1908
|
+
refreshBuildStepArguments(plan);
|
|
1909
|
+
}
|
|
1910
|
+
} catch (error) {
|
|
1911
|
+
warnings.push(`GTM Kernel campaign build plan failed: ${errorMessage(error)}`);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
async attachDeliveryRiskPreflight(plan, warnings) {
|
|
1915
|
+
if (Object.keys(asRecord(plan.buildRequest.deliveryRisk)).length > 0) return;
|
|
1916
|
+
const riskStep = plan.mcpFlow.find((step) => step.tool === "gtm_brain_delivery_risk");
|
|
1917
|
+
if (!riskStep) return;
|
|
1918
|
+
try {
|
|
1919
|
+
const deliveryRisk = asRecord(await this.callMcp("gtm_brain_delivery_risk", asRecord(riskStep.arguments)));
|
|
1920
|
+
if (Object.keys(deliveryRisk).length > 0) {
|
|
1921
|
+
plan.buildRequest.deliveryRisk = deliveryRisk;
|
|
1922
|
+
refreshBuildStepArguments(plan);
|
|
1923
|
+
}
|
|
1924
|
+
} catch (error) {
|
|
1925
|
+
warnings.push(`GTM Brain delivery risk preflight failed: ${errorMessage(error)}`);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1337
1928
|
async callMcp(tool, args) {
|
|
1338
1929
|
return this.client.mcp("tools/call", { name: tool, arguments: compact(args) });
|
|
1339
1930
|
}
|
|
1340
1931
|
};
|
|
1341
1932
|
function createCampaignBuilderAgentPlan(request, context = {}) {
|
|
1342
|
-
const
|
|
1343
|
-
const
|
|
1344
|
-
const
|
|
1345
|
-
const
|
|
1346
|
-
const
|
|
1347
|
-
const
|
|
1348
|
-
const
|
|
1349
|
-
const
|
|
1933
|
+
const resolvedRequest = applyCampaignBuilderStrategyTemplate(request);
|
|
1934
|
+
const defaults = mergeDefaults(resolvedRequest.signalizDefaults);
|
|
1935
|
+
const targetCount = resolvedRequest.targetCount ?? numberOrUndefined2(context.scopeBuildArgs?.target_count) ?? 100;
|
|
1936
|
+
const campaignName = resolvedRequest.campaignName ?? stringValue(context.scopeBuildArgs?.name) ?? titleFromGoal(resolvedRequest.goal);
|
|
1937
|
+
const workspaceContext = context.workspaceContext ?? resolvedRequest.workspaceContext ?? {};
|
|
1938
|
+
const memory = normalizeMemory(resolvedRequest);
|
|
1939
|
+
const routes = normalizeRoutes(resolvedRequest);
|
|
1940
|
+
const operatingPlaybooks = getCampaignBuilderOperatingPlaybooksForRequest(resolvedRequest);
|
|
1941
|
+
const estimatedCredits = estimateCredits(resolvedRequest, defaults, targetCount);
|
|
1942
|
+
const buildRequest = createBuildRequest(resolvedRequest, defaults, targetCount, campaignName, context.scopeBuildArgs, routes, memory, context.scopeBrainPreflight);
|
|
1350
1943
|
const brainPreflight = asRecord(buildRequest.brainPreflight);
|
|
1351
|
-
const approvals = deriveApprovals(
|
|
1944
|
+
const approvals = deriveApprovals(resolvedRequest, routes, memory, estimatedCredits, defaults.delivery?.approvalRequired !== false);
|
|
1352
1945
|
return {
|
|
1353
|
-
planId: `cbp_${hashString(JSON.stringify({ goal:
|
|
1946
|
+
planId: `cbp_${hashString(JSON.stringify({ goal: resolvedRequest.goal, campaignName, targetCount, routes }))}`,
|
|
1354
1947
|
campaignName,
|
|
1355
|
-
goal:
|
|
1948
|
+
goal: resolvedRequest.goal,
|
|
1356
1949
|
targetCount,
|
|
1357
1950
|
workspaceContext,
|
|
1358
1951
|
memory,
|
|
@@ -1365,7 +1958,8 @@ function createCampaignBuilderAgentPlan(request, context = {}) {
|
|
|
1365
1958
|
approvals,
|
|
1366
1959
|
buildRequest,
|
|
1367
1960
|
brainPreflight,
|
|
1368
|
-
|
|
1961
|
+
operatingPlaybooks,
|
|
1962
|
+
mcpFlow: createMcpFlow(resolvedRequest, buildRequest, routes, memory, approvals),
|
|
1369
1963
|
estimatedCredits,
|
|
1370
1964
|
warnings: context.warnings ?? []
|
|
1371
1965
|
};
|
|
@@ -1386,6 +1980,155 @@ function getMissingCampaignBuilderApprovals(plan, approval) {
|
|
|
1386
1980
|
return false;
|
|
1387
1981
|
});
|
|
1388
1982
|
}
|
|
1983
|
+
function getCampaignBuilderStrategyTemplate(value) {
|
|
1984
|
+
const normalized = normalizeTemplateKey(value);
|
|
1985
|
+
if (!normalized) return void 0;
|
|
1986
|
+
return CAMPAIGN_BUILDER_STRATEGY_TEMPLATES.find(
|
|
1987
|
+
(template) => template.slug === normalized || template.aliases.some((alias) => normalizeTemplateKey(alias) === normalized)
|
|
1988
|
+
);
|
|
1989
|
+
}
|
|
1990
|
+
function getCampaignBuilderOperatingPlaybook(value) {
|
|
1991
|
+
const normalized = normalizeTemplateKey(value);
|
|
1992
|
+
if (!normalized) return void 0;
|
|
1993
|
+
return CAMPAIGN_BUILDER_OPERATING_PLAYBOOKS.find((playbook) => playbook.slug === normalized);
|
|
1994
|
+
}
|
|
1995
|
+
function getCampaignBuilderOperatingPlaybooksForRequest(request) {
|
|
1996
|
+
const template = getCampaignBuilderStrategyTemplate(request.strategyTemplate);
|
|
1997
|
+
const slugs = uniqueStrings([
|
|
1998
|
+
...template?.operatingPlaybookSlugs ?? [],
|
|
1999
|
+
...request.operatingPlaybooks ?? []
|
|
2000
|
+
]);
|
|
2001
|
+
return slugs.map(getCampaignBuilderOperatingPlaybook).filter((playbook) => Boolean(playbook));
|
|
2002
|
+
}
|
|
2003
|
+
function applyCampaignBuilderStrategyTemplate(request) {
|
|
2004
|
+
const template = getCampaignBuilderStrategyTemplate(request.strategyTemplate);
|
|
2005
|
+
if (!template) return request;
|
|
2006
|
+
return {
|
|
2007
|
+
...request,
|
|
2008
|
+
strategyTemplate: template.slug,
|
|
2009
|
+
campaignName: request.campaignName ?? template.campaignName,
|
|
2010
|
+
accountContext: mergeText(template.accountContext, campaignBuilderAccountContext(request)),
|
|
2011
|
+
targetCount: request.targetCount ?? template.defaultTargetCount,
|
|
2012
|
+
icp: mergeIcp(template.icp, request.icp),
|
|
2013
|
+
builtIns: request.builtIns ?? template.builtIns,
|
|
2014
|
+
operatingPlaybooks: uniqueStrings([
|
|
2015
|
+
...template.operatingPlaybookSlugs,
|
|
2016
|
+
...request.operatingPlaybooks ?? []
|
|
2017
|
+
]),
|
|
2018
|
+
preferredProviders: uniqueStrings([
|
|
2019
|
+
...template.preferredProviders,
|
|
2020
|
+
...request.preferredProviders ?? []
|
|
2021
|
+
]),
|
|
2022
|
+
memory: mergeMemoryPlan({
|
|
2023
|
+
enabled: true,
|
|
2024
|
+
useWorkspaceHistory: true,
|
|
2025
|
+
useNetworkPatterns: request.memory?.useNetworkPatterns,
|
|
2026
|
+
privacyMode: request.memory?.privacyMode,
|
|
2027
|
+
queries: template.memoryQueries
|
|
2028
|
+
}, request.memory),
|
|
2029
|
+
constraints: mergeConstraints(template.constraints, request.constraints),
|
|
2030
|
+
signalizDefaults: mergeSignalizDefaultOverrides(template.signalizDefaults, request.signalizDefaults),
|
|
2031
|
+
agencyContext: mergeAgencyContext(template.agencyContext, request.agencyContext)
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
function normalizeTemplateKey(value) {
|
|
2035
|
+
return String(value || "").trim().toLowerCase().replace(/[_\s]+/g, "-");
|
|
2036
|
+
}
|
|
2037
|
+
function mergeText(base, override) {
|
|
2038
|
+
if (base && override && !base.includes(override)) return `${base}
|
|
2039
|
+
${override}`;
|
|
2040
|
+
return override ?? base;
|
|
2041
|
+
}
|
|
2042
|
+
function mergeIcp(base, override) {
|
|
2043
|
+
if (!base) return override;
|
|
2044
|
+
if (!override) return base;
|
|
2045
|
+
return {
|
|
2046
|
+
...base,
|
|
2047
|
+
...override,
|
|
2048
|
+
personas: uniqueStrings([...base.personas ?? [], ...override.personas ?? []]),
|
|
2049
|
+
industries: uniqueStrings([...base.industries ?? [], ...override.industries ?? []]),
|
|
2050
|
+
companySizes: uniqueStrings([...base.companySizes ?? [], ...override.companySizes ?? []]),
|
|
2051
|
+
geographies: uniqueStrings([...base.geographies ?? [], ...override.geographies ?? []]),
|
|
2052
|
+
keywords: uniqueStrings([...base.keywords ?? [], ...override.keywords ?? []]),
|
|
2053
|
+
exclusions: uniqueStrings([...base.exclusions ?? [], ...override.exclusions ?? []]),
|
|
2054
|
+
requireVerifiedEmail: override.requireVerifiedEmail ?? base.requireVerifiedEmail
|
|
2055
|
+
};
|
|
2056
|
+
}
|
|
2057
|
+
function mergeMemoryPlan(base, override) {
|
|
2058
|
+
const queries = dedupeMemoryQueries([...base.queries ?? [], ...override?.queries ?? []]);
|
|
2059
|
+
return {
|
|
2060
|
+
...base,
|
|
2061
|
+
...override,
|
|
2062
|
+
queries: queries.length > 0 ? queries : void 0,
|
|
2063
|
+
enabled: override?.enabled ?? base.enabled,
|
|
2064
|
+
useWorkspaceHistory: override?.useWorkspaceHistory ?? base.useWorkspaceHistory,
|
|
2065
|
+
useNetworkPatterns: override?.useNetworkPatterns ?? base.useNetworkPatterns,
|
|
2066
|
+
privacyMode: override?.privacyMode ?? base.privacyMode
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
function dedupeMemoryQueries(queries) {
|
|
2070
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2071
|
+
return queries.filter((query) => {
|
|
2072
|
+
const key = query.query.trim().toLowerCase();
|
|
2073
|
+
if (!key || seen.has(key)) return false;
|
|
2074
|
+
seen.add(key);
|
|
2075
|
+
return true;
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
function mergeConstraints(base, override) {
|
|
2079
|
+
if (!base) return override;
|
|
2080
|
+
if (!override) return base;
|
|
2081
|
+
return {
|
|
2082
|
+
...base,
|
|
2083
|
+
...override,
|
|
2084
|
+
geographies: uniqueStrings([...base.geographies ?? [], ...override.geographies ?? []]),
|
|
2085
|
+
exclusions: uniqueStrings([...base.exclusions ?? [], ...override.exclusions ?? []]),
|
|
2086
|
+
deliverabilityNotes: uniqueStrings([...base.deliverabilityNotes ?? [], ...override.deliverabilityNotes ?? []]),
|
|
2087
|
+
maxDailySends: override.maxDailySends ?? base.maxDailySends
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
function mergeSignalizDefaultOverrides(base, override) {
|
|
2091
|
+
if (!base) return override;
|
|
2092
|
+
if (!override) return base;
|
|
2093
|
+
return {
|
|
2094
|
+
...base,
|
|
2095
|
+
...override,
|
|
2096
|
+
signals: { ...base.signals, ...override.signals },
|
|
2097
|
+
qualification: { ...base.qualification, ...override.qualification },
|
|
2098
|
+
copy: { ...base.copy, ...override.copy },
|
|
2099
|
+
delivery: { ...base.delivery, ...override.delivery }
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
function mergeAgencyContext(base, override) {
|
|
2103
|
+
if (!base) return override;
|
|
2104
|
+
if (!override) return base;
|
|
2105
|
+
return {
|
|
2106
|
+
...base,
|
|
2107
|
+
...override,
|
|
2108
|
+
partnerEcosystem: uniqueStrings([...base.partnerEcosystem ?? [], ...override.partnerEcosystem ?? []]),
|
|
2109
|
+
strategyModel: override.strategyModel ?? base.strategyModel,
|
|
2110
|
+
includeStrategyPatterns: override.includeStrategyPatterns ?? base.includeStrategyPatterns,
|
|
2111
|
+
includeWorkflowPatterns: override.includeWorkflowPatterns ?? base.includeWorkflowPatterns,
|
|
2112
|
+
includeClayPatterns: override.includeClayPatterns ?? base.includeClayPatterns,
|
|
2113
|
+
includeNangoCatalog: override.includeNangoCatalog ?? base.includeNangoCatalog,
|
|
2114
|
+
revenueMotion: override.revenueMotion ?? base.revenueMotion
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
2117
|
+
function campaignBuilderStrategyModel(agencyContext) {
|
|
2118
|
+
return agencyContext?.strategyModel ?? "strategy_template";
|
|
2119
|
+
}
|
|
2120
|
+
function campaignBuilderStrategyPatternsEnabled(agencyContext) {
|
|
2121
|
+
return agencyContext?.includeStrategyPatterns ?? true;
|
|
2122
|
+
}
|
|
2123
|
+
function campaignBuilderWorkflowPatternsEnabled(agencyContext) {
|
|
2124
|
+
return agencyContext?.includeWorkflowPatterns ?? agencyContext?.includeClayPatterns ?? true;
|
|
2125
|
+
}
|
|
2126
|
+
function campaignBuilderAccountLabel(request) {
|
|
2127
|
+
return request.accountLabel;
|
|
2128
|
+
}
|
|
2129
|
+
function campaignBuilderAccountContext(request) {
|
|
2130
|
+
return request.accountContext;
|
|
2131
|
+
}
|
|
1389
2132
|
function mergeDefaults(overrides) {
|
|
1390
2133
|
return {
|
|
1391
2134
|
...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS,
|
|
@@ -1398,12 +2141,9 @@ function mergeDefaults(overrides) {
|
|
|
1398
2141
|
}
|
|
1399
2142
|
function normalizeMemory(request) {
|
|
1400
2143
|
const configured = request.memory ?? {};
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
topK: 8,
|
|
1405
|
-
rationale: "Seed the campaign plan with prior ICP, angle, source, and reply-performance patterns."
|
|
1406
|
-
}];
|
|
2144
|
+
const defaultQueries = defaultAgencyMemoryQueries(request, configured);
|
|
2145
|
+
const configuredQueries = configured.queries ?? [];
|
|
2146
|
+
const queries = configuredQueries.length > 0 ? request.strategyTemplate ? dedupeMemoryQueries([...configuredQueries, ...defaultQueries]) : configuredQueries : defaultQueries;
|
|
1407
2147
|
return {
|
|
1408
2148
|
enabled: configured.enabled !== false,
|
|
1409
2149
|
queries,
|
|
@@ -1412,40 +2152,130 @@ function normalizeMemory(request) {
|
|
|
1412
2152
|
privacyMode: configured.privacyMode ?? (configured.useNetworkPatterns ? "anonymized_patterns" : "workspace_only")
|
|
1413
2153
|
};
|
|
1414
2154
|
}
|
|
2155
|
+
function defaultAgencyMemoryQueries(request, configured) {
|
|
2156
|
+
const operatingPlaybookTerms = getCampaignBuilderOperatingPlaybooksForRequest(request).flatMap((playbook) => [playbook.label, ...playbook.memoryKeywords]).join(" ");
|
|
2157
|
+
const queries = [{
|
|
2158
|
+
query: request.goal,
|
|
2159
|
+
scopes: ["workspace", configured.useNetworkPatterns ? "network_patterns" : "operator_notes"],
|
|
2160
|
+
topK: 8,
|
|
2161
|
+
rationale: "Seed the campaign plan with prior ICP, angle, source, and reply-performance patterns."
|
|
2162
|
+
}];
|
|
2163
|
+
if (campaignBuilderStrategyModel(request.agencyContext) !== "custom" && campaignBuilderStrategyPatternsEnabled(request.agencyContext)) {
|
|
2164
|
+
queries.push({
|
|
2165
|
+
query: [
|
|
2166
|
+
"Private campaign strategy pattern library prior campaign casebook",
|
|
2167
|
+
campaignBuilderAccountLabel(request),
|
|
2168
|
+
operatingPlaybookTerms,
|
|
2169
|
+
request.goal
|
|
2170
|
+
].filter(Boolean).join(" "),
|
|
2171
|
+
scopes: ["workspace", "operator_notes"],
|
|
2172
|
+
topK: 8,
|
|
2173
|
+
required: true,
|
|
2174
|
+
rationale: "Anchor the plan in private strategy learnings from prior industrial, healthcare, agency-services, infrastructure, recruiting, media, and integration builds."
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
if (campaignBuilderWorkflowPatternsEnabled(request.agencyContext)) {
|
|
2178
|
+
queries.push({
|
|
2179
|
+
query: [
|
|
2180
|
+
"Workflow table architecture enrichment qualification copy export gates",
|
|
2181
|
+
request.goal
|
|
2182
|
+
].filter(Boolean).join(" "),
|
|
2183
|
+
scopes: ["workspace", "operator_notes"],
|
|
2184
|
+
topK: 6,
|
|
2185
|
+
rationale: "Pull workflow patterns for source tables, enrichment order, qualification gates, and handoff controls."
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
return queries;
|
|
2189
|
+
}
|
|
1415
2190
|
function normalizeRoutes(request) {
|
|
1416
|
-
const routes =
|
|
1417
|
-
|
|
1418
|
-
|
|
2191
|
+
const routes = builtInRoutesFor(request);
|
|
2192
|
+
routes.push(...routesFromCustomerTools(request.customerTools ?? []));
|
|
2193
|
+
routes.push(...request.integrations ?? []);
|
|
2194
|
+
return routes.map((route, index) => ({
|
|
2195
|
+
...route,
|
|
2196
|
+
id: route.id ?? `${route.provider}-${route.layer}-${index + 1}`,
|
|
2197
|
+
mode: route.mode ?? "if_available"
|
|
2198
|
+
}));
|
|
2199
|
+
}
|
|
2200
|
+
function builtInRoutesFor(request) {
|
|
2201
|
+
const builtIns = new Set(normalizeBuiltIns(request));
|
|
2202
|
+
const routes = [];
|
|
2203
|
+
if (builtIns.has("lead_generation")) {
|
|
2204
|
+
routes.push({
|
|
2205
|
+
id: "signaliz-lead-generation",
|
|
1419
2206
|
layer: "source",
|
|
2207
|
+
gtmLayers: ["find_company", "find_people", "lead_generation"],
|
|
1420
2208
|
provider: "signaliz",
|
|
1421
2209
|
mode: "required",
|
|
1422
2210
|
toolName: "generate_leads",
|
|
1423
2211
|
rationale: "Use Signaliz fresh workspace acquisition as the default source of truth."
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2214
|
+
if (builtIns.has("local_leads")) {
|
|
2215
|
+
routes.push({
|
|
2216
|
+
id: "signaliz-local-leads",
|
|
2217
|
+
layer: "source",
|
|
2218
|
+
gtmLayer: "local_leads",
|
|
2219
|
+
provider: "signaliz",
|
|
2220
|
+
mode: "if_available",
|
|
2221
|
+
toolName: "generate_local_leads",
|
|
2222
|
+
rationale: "Use Signaliz local-leads sourcing for geography-bound local business campaigns."
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
if (builtIns.has("email_finding")) {
|
|
2226
|
+
routes.push({
|
|
2227
|
+
id: "signaliz-email-finding",
|
|
2228
|
+
layer: "enrichment",
|
|
2229
|
+
gtmLayer: "email_finding",
|
|
1428
2230
|
provider: "signaliz",
|
|
1429
2231
|
mode: "required",
|
|
1430
2232
|
toolName: "find_and_verify_emails",
|
|
2233
|
+
rationale: "Find contact emails before verification and campaign handoff."
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
if (builtIns.has("email_verification")) {
|
|
2237
|
+
routes.push({
|
|
2238
|
+
id: "signaliz-email-verification",
|
|
2239
|
+
layer: "qualification",
|
|
2240
|
+
gtmLayer: "email_verification",
|
|
2241
|
+
provider: "signaliz",
|
|
2242
|
+
mode: "required",
|
|
2243
|
+
toolName: "verify_emails",
|
|
1431
2244
|
rationale: "Require verified contactability before sequence delivery."
|
|
1432
|
-
}
|
|
1433
|
-
|
|
2245
|
+
});
|
|
2246
|
+
}
|
|
2247
|
+
if (builtIns.has("signals")) {
|
|
2248
|
+
routes.push({
|
|
1434
2249
|
id: "signaliz-signals",
|
|
1435
2250
|
layer: "enrichment",
|
|
2251
|
+
gtmLayer: "company_enrichment",
|
|
1436
2252
|
provider: "signaliz",
|
|
1437
2253
|
mode: "if_available",
|
|
1438
2254
|
toolName: "enrich_company_signals",
|
|
1439
2255
|
rationale: "Attach current buying signals and evidence for qualification and copy."
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
routes
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
return routes;
|
|
2259
|
+
}
|
|
2260
|
+
function normalizeBuiltIns(request) {
|
|
2261
|
+
const configured = request.builtIns !== void 0 ? request.builtIns : DEFAULT_CAMPAIGN_BUILDER_BUILT_INS;
|
|
2262
|
+
const builtIns = new Set(configured);
|
|
2263
|
+
if (request.builtIns === void 0 && looksLikeLocalLeadCampaign(request)) {
|
|
2264
|
+
builtIns.add("local_leads");
|
|
2265
|
+
}
|
|
2266
|
+
return [...builtIns].filter(isCampaignBuilderBuiltInTool);
|
|
2267
|
+
}
|
|
2268
|
+
function isCampaignBuilderBuiltInTool(value) {
|
|
2269
|
+
return ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"].includes(String(value));
|
|
2270
|
+
}
|
|
2271
|
+
function looksLikeLocalLeadCampaign(request) {
|
|
2272
|
+
const text = [
|
|
2273
|
+
request.goal,
|
|
2274
|
+
campaignBuilderAccountContext(request),
|
|
2275
|
+
...request.icp?.industries ?? [],
|
|
2276
|
+
...request.icp?.keywords ?? []
|
|
2277
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
2278
|
+
return /\b(local|google maps|near me|nearby|city|cities|location|locations|home services?|clinics?|restaurants?|contractors?)\b/.test(text);
|
|
1449
2279
|
}
|
|
1450
2280
|
function routesFromCustomerTools(tools) {
|
|
1451
2281
|
return tools.flatMap(
|
|
@@ -1463,7 +2293,7 @@ function routesFromCustomerTools(tools) {
|
|
|
1463
2293
|
...tool.config,
|
|
1464
2294
|
available_tools: tool.availableTools
|
|
1465
2295
|
},
|
|
1466
|
-
rationale: `${tool.label ?? tool.provider} is
|
|
2296
|
+
rationale: `${tool.label ?? tool.provider} is operator-provided for ${layer}.`
|
|
1467
2297
|
}))
|
|
1468
2298
|
);
|
|
1469
2299
|
}
|
|
@@ -1508,6 +2338,7 @@ function createBuildRequest(request, defaults, targetCount, campaignName, scopeB
|
|
|
1508
2338
|
return buildRequest;
|
|
1509
2339
|
}
|
|
1510
2340
|
function createBrainPreflight(request, buildRequest, routes, memory) {
|
|
2341
|
+
const operatingPlaybooks = getCampaignBuilderOperatingPlaybooksForRequest(request);
|
|
1511
2342
|
const layers = uniqueStrings([
|
|
1512
2343
|
"icp",
|
|
1513
2344
|
"email_finding",
|
|
@@ -1517,7 +2348,7 @@ function createBrainPreflight(request, buildRequest, routes, memory) {
|
|
|
1517
2348
|
["instantly", "smartlead", "heyreach"].some((provider) => routes.some((route) => route.provider === provider)) ? "sender" : void 0,
|
|
1518
2349
|
memory.enabled ? "feedback" : void 0
|
|
1519
2350
|
]);
|
|
1520
|
-
const providerChain = uniqueStrings(["signaliz", ...routes.map((route) => route.provider)]);
|
|
2351
|
+
const providerChain = uniqueStrings(["signaliz", ...request.preferredProviders ?? [], ...routes.map((route) => route.provider)]);
|
|
1521
2352
|
const targetIcp = compact({
|
|
1522
2353
|
personas: buildRequest.icp?.personas,
|
|
1523
2354
|
industries: buildRequest.icp?.industries,
|
|
@@ -1558,6 +2389,13 @@ function createBrainPreflight(request, buildRequest, routes, memory) {
|
|
|
1558
2389
|
required: true,
|
|
1559
2390
|
policy: "Run read-only GTM Brain preflight before build_campaign so learned defaults, memory, and deliverability risk stay attached to the build.",
|
|
1560
2391
|
layers,
|
|
2392
|
+
operating_playbooks: operatingPlaybooks.map((playbook) => ({
|
|
2393
|
+
slug: playbook.slug,
|
|
2394
|
+
label: playbook.label,
|
|
2395
|
+
quality_gates: playbook.qualityGates,
|
|
2396
|
+
required_fields: playbook.requiredFields,
|
|
2397
|
+
activation_boundary: playbook.activationBoundary
|
|
2398
|
+
})),
|
|
1561
2399
|
target_icp: targetIcp,
|
|
1562
2400
|
provider_chain: providerChain,
|
|
1563
2401
|
lead_source: providerChain[0] ?? "signaliz",
|
|
@@ -1690,6 +2528,47 @@ function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
|
1690
2528
|
approvalRequired: false
|
|
1691
2529
|
}
|
|
1692
2530
|
];
|
|
2531
|
+
steps.push({
|
|
2532
|
+
id: "gtm-provider-catalog",
|
|
2533
|
+
phase: "plan",
|
|
2534
|
+
tool: "gtm_provider_catalog",
|
|
2535
|
+
arguments: {
|
|
2536
|
+
include_layer_catalog: true,
|
|
2537
|
+
include_planned: true
|
|
2538
|
+
},
|
|
2539
|
+
readOnly: true,
|
|
2540
|
+
approvalRequired: false
|
|
2541
|
+
});
|
|
2542
|
+
if (request.agencyContext?.includeNangoCatalog !== false) {
|
|
2543
|
+
steps.push({
|
|
2544
|
+
id: "nango-tool-catalog",
|
|
2545
|
+
phase: "plan",
|
|
2546
|
+
tool: "nango_mcp_tools_list",
|
|
2547
|
+
arguments: {
|
|
2548
|
+
format: "mcp"
|
|
2549
|
+
},
|
|
2550
|
+
readOnly: true,
|
|
2551
|
+
approvalRequired: false
|
|
2552
|
+
});
|
|
2553
|
+
}
|
|
2554
|
+
if (memory.enabled) {
|
|
2555
|
+
steps.push({
|
|
2556
|
+
id: "strategy-memory-status",
|
|
2557
|
+
phase: "memory",
|
|
2558
|
+
tool: "gtm_campaign_strategy_memory_status",
|
|
2559
|
+
arguments: buildGtmCampaignStrategyMemoryStatusArgs(request, buildRequest),
|
|
2560
|
+
readOnly: true,
|
|
2561
|
+
approvalRequired: false
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
steps.push({
|
|
2565
|
+
id: "agency-campaign-build-plan",
|
|
2566
|
+
phase: "plan",
|
|
2567
|
+
tool: "gtm_campaign_build_plan",
|
|
2568
|
+
arguments: buildGtmCampaignBuildPlanArgs(request, buildRequest, routes, memory),
|
|
2569
|
+
readOnly: true,
|
|
2570
|
+
approvalRequired: memory.useNetworkPatterns === true
|
|
2571
|
+
});
|
|
1693
2572
|
if (memory.enabled) {
|
|
1694
2573
|
for (const [index, query] of memory.queries.entries()) {
|
|
1695
2574
|
steps.push({
|
|
@@ -1703,6 +2582,25 @@ function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
|
1703
2582
|
}
|
|
1704
2583
|
}
|
|
1705
2584
|
for (const route of routes) {
|
|
2585
|
+
if (shouldPrepareProviderRoute(route)) {
|
|
2586
|
+
steps.push({
|
|
2587
|
+
id: `prepare-${route.id}`,
|
|
2588
|
+
phase: "plan",
|
|
2589
|
+
tool: "gtm_provider_recipe_prepare",
|
|
2590
|
+
arguments: buildProviderRecipePrepareArgs(route, buildRequest),
|
|
2591
|
+
readOnly: true,
|
|
2592
|
+
approvalRequired: false
|
|
2593
|
+
});
|
|
2594
|
+
steps.push({
|
|
2595
|
+
id: `activate-${route.id}-dry-run`,
|
|
2596
|
+
phase: "plan",
|
|
2597
|
+
tool: "gtm_provider_route_activate",
|
|
2598
|
+
arguments: buildProviderRouteActivateArgs(route, buildRequest),
|
|
2599
|
+
readOnly: true,
|
|
2600
|
+
approvalRequired: false
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
const routeApprovalRequired = route.approvalRequired === true || route.provider !== "signaliz" && route.approvalRequired !== false && route.mode === "required" || route.layer === "delivery" || route.layer === "feedback";
|
|
1706
2604
|
steps.push({
|
|
1707
2605
|
id: `route-${route.id}`,
|
|
1708
2606
|
phase: route.layer,
|
|
@@ -1714,7 +2612,7 @@ function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
|
1714
2612
|
config: route.config
|
|
1715
2613
|
},
|
|
1716
2614
|
readOnly: !["delivery", "feedback"].includes(route.layer),
|
|
1717
|
-
approvalRequired:
|
|
2615
|
+
approvalRequired: routeApprovalRequired
|
|
1718
2616
|
});
|
|
1719
2617
|
}
|
|
1720
2618
|
steps.push({
|
|
@@ -1723,8 +2621,8 @@ function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
|
1723
2621
|
tool: "scope_campaign",
|
|
1724
2622
|
arguments: {
|
|
1725
2623
|
prompt: request.goal,
|
|
1726
|
-
|
|
1727
|
-
|
|
2624
|
+
account_label: campaignBuilderAccountLabel(request),
|
|
2625
|
+
account_context: campaignBuilderAccountContext(request),
|
|
1728
2626
|
target_count: request.targetCount
|
|
1729
2627
|
},
|
|
1730
2628
|
readOnly: true,
|
|
@@ -1784,11 +2682,212 @@ function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
|
1784
2682
|
readOnly: false,
|
|
1785
2683
|
approvalRequired: approvals.some((approval) => approval.blocking)
|
|
1786
2684
|
});
|
|
2685
|
+
const deliveryApprovalArgs = buildDeliveryApprovalArgs(buildRequest);
|
|
2686
|
+
if (deliveryApprovalArgs) {
|
|
2687
|
+
steps.push({
|
|
2688
|
+
id: "delivery-approval",
|
|
2689
|
+
phase: "delivery",
|
|
2690
|
+
tool: "approve_campaign_delivery",
|
|
2691
|
+
arguments: deliveryApprovalArgs,
|
|
2692
|
+
readOnly: false,
|
|
2693
|
+
approvalRequired: true
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
1787
2696
|
return steps.map((step) => ({ ...step, arguments: compact(step.arguments) }));
|
|
1788
2697
|
}
|
|
2698
|
+
function shouldPrepareProviderRoute(route) {
|
|
2699
|
+
return !["signaliz", "csv"].includes(route.provider);
|
|
2700
|
+
}
|
|
2701
|
+
function buildProviderRecipePrepareArgs(route, buildRequest) {
|
|
2702
|
+
const layerCapabilities = uniqueStrings(gtmLayersForRoute(route));
|
|
2703
|
+
const layer = layerCapabilities[0] ?? mapCampaignBuilderLayerToGtmLayer(route.layer) ?? "custom";
|
|
2704
|
+
const config = asRecord(route.config);
|
|
2705
|
+
return compact({
|
|
2706
|
+
provider_id: route.provider,
|
|
2707
|
+
provider_name: route.label,
|
|
2708
|
+
layer,
|
|
2709
|
+
layer_capabilities: layerCapabilities.length > 0 ? layerCapabilities : void 0,
|
|
2710
|
+
invocation_type: route.providerCapability?.invocationType ?? inferProviderInvocationType(route),
|
|
2711
|
+
auth_strategy: inferProviderAuthStrategy(route),
|
|
2712
|
+
workspace_mcp_server_id: stringValue(config.workspace_mcp_server_id ?? config.workspaceMcpServerId ?? route.mcpServerName),
|
|
2713
|
+
workspace_integration_id: stringValue(config.workspace_integration_id ?? config.workspaceIntegrationId),
|
|
2714
|
+
workspace_connection_id: stringValue(config.workspace_connection_id ?? config.workspaceConnectionId),
|
|
2715
|
+
endpoint_url: stringValue(config.endpoint_url ?? config.endpointUrl ?? config.webhook_url ?? config.webhookUrl),
|
|
2716
|
+
request_template: asOptionalRecord(config.request_template ?? config.requestTemplate),
|
|
2717
|
+
response_mapping: asOptionalRecord(config.response_mapping ?? config.responseMapping),
|
|
2718
|
+
input_schema: asOptionalRecord(config.input_schema ?? config.inputSchema ?? route.providerCapability?.exampleInputSchema),
|
|
2719
|
+
output_schema: asOptionalRecord(config.output_schema ?? config.outputSchema ?? route.providerCapability?.exampleOutputSchema),
|
|
2720
|
+
readiness: asOptionalRecord(config.readiness),
|
|
2721
|
+
metadata: compact({
|
|
2722
|
+
source: "campaign-builder-agent",
|
|
2723
|
+
route_id: route.id,
|
|
2724
|
+
campaign_name: buildRequest.name,
|
|
2725
|
+
tool_name: route.toolName,
|
|
2726
|
+
mcp_server_name: route.mcpServerName,
|
|
2727
|
+
dry_run_only: true
|
|
2728
|
+
}),
|
|
2729
|
+
context: compact({
|
|
2730
|
+
source: "campaign-builder-agent",
|
|
2731
|
+
route_id: route.id,
|
|
2732
|
+
gtm_campaign_id: buildRequest.gtmCampaignId
|
|
2733
|
+
}),
|
|
2734
|
+
use_signaliz_fallback: route.routingPolicy?.useSignalizFallback ?? true,
|
|
2735
|
+
priority: numberOrUndefined2(config.priority),
|
|
2736
|
+
status: stringValue(config.status) ?? "needs_setup"
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2739
|
+
function buildProviderRouteActivateArgs(route, buildRequest) {
|
|
2740
|
+
const layerCapabilities = uniqueStrings(gtmLayersForRoute(route));
|
|
2741
|
+
const config = asRecord(route.config);
|
|
2742
|
+
return compact({
|
|
2743
|
+
provider_id: route.provider,
|
|
2744
|
+
provider_name: route.label,
|
|
2745
|
+
campaign_id: buildRequest.gtmCampaignId,
|
|
2746
|
+
layer: layerCapabilities[0] ?? mapCampaignBuilderLayerToGtmLayer(route.layer) ?? "custom",
|
|
2747
|
+
layers: layerCapabilities.length > 0 ? layerCapabilities : void 0,
|
|
2748
|
+
invocation_type: route.providerCapability?.invocationType ?? inferProviderInvocationType(route),
|
|
2749
|
+
auth_strategy: inferProviderAuthStrategy(route),
|
|
2750
|
+
workspace_mcp_server_id: stringValue(config.workspace_mcp_server_id ?? config.workspaceMcpServerId ?? route.mcpServerName),
|
|
2751
|
+
workspace_integration_id: stringValue(config.workspace_integration_id ?? config.workspaceIntegrationId),
|
|
2752
|
+
workspace_connection_id: stringValue(config.workspace_connection_id ?? config.workspaceConnectionId),
|
|
2753
|
+
endpoint_url: stringValue(config.endpoint_url ?? config.endpointUrl ?? config.webhook_url ?? config.webhookUrl),
|
|
2754
|
+
route_config: compact({
|
|
2755
|
+
...asRecord(config.route_config ?? config.routeConfig),
|
|
2756
|
+
source: "campaign-builder-agent",
|
|
2757
|
+
route_id: route.id,
|
|
2758
|
+
tool_name: route.toolName,
|
|
2759
|
+
mcp_server_name: route.mcpServerName
|
|
2760
|
+
}),
|
|
2761
|
+
use_signaliz_fallback: route.routingPolicy?.useSignalizFallback ?? true,
|
|
2762
|
+
priority: numberOrUndefined2(config.priority),
|
|
2763
|
+
dry_run: true,
|
|
2764
|
+
confirm: false
|
|
2765
|
+
});
|
|
2766
|
+
}
|
|
2767
|
+
function inferProviderInvocationType(route) {
|
|
2768
|
+
if (route.provider === "airbyte") return "airbyte";
|
|
2769
|
+
if (route.provider === "nango") return "managed_integration";
|
|
2770
|
+
if (["custom_webhook", "webhook", "clay_webhook"].includes(route.provider)) return "webhook";
|
|
2771
|
+
if (["custom_api", "apollo", "ai_ark", "apify"].includes(route.provider)) return "api";
|
|
2772
|
+
if (route.mcpServerName || route.toolName || ["custom_mcp", "octave"].includes(route.provider)) return "mcp_tool";
|
|
2773
|
+
return "manual";
|
|
2774
|
+
}
|
|
2775
|
+
function inferProviderAuthStrategy(route) {
|
|
2776
|
+
const config = asRecord(route.config);
|
|
2777
|
+
const configured = stringValue(config.auth_strategy ?? config.authStrategy);
|
|
2778
|
+
if (configured) return configured;
|
|
2779
|
+
const invocationType = route.providerCapability?.invocationType ?? inferProviderInvocationType(route);
|
|
2780
|
+
if (invocationType === "webhook") return "webhook_secret";
|
|
2781
|
+
if (invocationType === "mcp_tool") return "mcp_auth";
|
|
2782
|
+
if (invocationType === "managed_integration") return "byo_runtime";
|
|
2783
|
+
if (invocationType === "api" || invocationType === "airbyte") return "integration_key";
|
|
2784
|
+
return void 0;
|
|
2785
|
+
}
|
|
2786
|
+
function refreshBuildStepArguments(plan) {
|
|
2787
|
+
for (const step of plan.mcpFlow) {
|
|
2788
|
+
if (step.id === "dry-run-build") {
|
|
2789
|
+
step.arguments = compact({
|
|
2790
|
+
...buildCampaignArgs({ ...plan.buildRequest, dryRun: true, confirmSpend: false }),
|
|
2791
|
+
dry_run: true
|
|
2792
|
+
});
|
|
2793
|
+
}
|
|
2794
|
+
if (step.id === "approved-build") {
|
|
2795
|
+
step.arguments = compact({
|
|
2796
|
+
...buildCampaignArgs({ ...plan.buildRequest, dryRun: false, confirmSpend: true }),
|
|
2797
|
+
required_approvals: plan.approvals.map((approval) => approval.id)
|
|
2798
|
+
});
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
function buildFallbackPlanSnapshot(plan) {
|
|
2803
|
+
const plannerStep = plan.mcpFlow.find((step) => step.id === "agency-campaign-build-plan");
|
|
2804
|
+
return compact({
|
|
2805
|
+
source_tool: "campaign-builder-agent",
|
|
2806
|
+
plan_id: plan.planId,
|
|
2807
|
+
query: asRecord(plannerStep?.arguments),
|
|
2808
|
+
campaign_name: plan.campaignName,
|
|
2809
|
+
goal: plan.goal,
|
|
2810
|
+
target_count: plan.targetCount,
|
|
2811
|
+
approvals: plan.approvals,
|
|
2812
|
+
brain_preflight: plan.brainPreflight,
|
|
2813
|
+
operating_playbooks: plan.operatingPlaybooks
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2816
|
+
function mapPlanCommitResult(data) {
|
|
2817
|
+
const campaign = asRecord(data.campaign);
|
|
2818
|
+
const campaignBuild = asRecord(data.campaign_build ?? data.campaignBuild);
|
|
2819
|
+
const committedPlan = asRecord(data.committed_plan ?? data.committedPlan);
|
|
2820
|
+
const commitPlan = asRecord(data.commit_plan ?? data.commitPlan);
|
|
2821
|
+
const campaignArgs = asRecord(commitPlan.campaign_arguments ?? commitPlan.campaignArguments);
|
|
2822
|
+
return {
|
|
2823
|
+
dryRun: data.dry_run === true || data.dryRun === true,
|
|
2824
|
+
wroteState: data.wrote_state === true || data.wroteState === true,
|
|
2825
|
+
campaignId: stringValue(campaign.id ?? committedPlan.campaign_id ?? committedPlan.campaignId ?? commitPlan.campaign_id ?? commitPlan.campaignId ?? campaignArgs.id),
|
|
2826
|
+
campaignBuildId: stringValue(campaignBuild.id ?? committedPlan.campaign_build_id ?? committedPlan.campaignBuildId ?? campaignArgs.campaign_build_id ?? campaignArgs.campaignBuildId),
|
|
2827
|
+
raw: data
|
|
2828
|
+
};
|
|
2829
|
+
}
|
|
2830
|
+
function buildGtmCampaignBuildPlanArgs(request, buildRequest, routes, memory) {
|
|
2831
|
+
const agencyContext = request.agencyContext ?? {};
|
|
2832
|
+
const strategyModel = campaignBuilderStrategyModel(agencyContext);
|
|
2833
|
+
const partnerEcosystem = agencyContext.partnerEcosystem ?? (strategyModel === "custom" ? void 0 : ["clay", "instantly", "nango"]);
|
|
2834
|
+
const layers = uniqueStrings([
|
|
2835
|
+
"icp",
|
|
2836
|
+
buildRequest.icp?.requireVerifiedEmail !== false ? "email_finding" : void 0,
|
|
2837
|
+
buildRequest.icp?.requireVerifiedEmail !== false ? "email_verification" : void 0,
|
|
2838
|
+
...routes.flatMap(gtmLayersForRoute),
|
|
2839
|
+
buildRequest.delivery?.destinationType === "webhook" ? "destination_export" : void 0,
|
|
2840
|
+
memory.enabled ? "feedback" : void 0
|
|
2841
|
+
]);
|
|
2842
|
+
const preferredProviders = uniqueStrings([
|
|
2843
|
+
...request.preferredProviders ?? [],
|
|
2844
|
+
...routes.map((route) => route.provider).filter((provider) => provider !== "signaliz")
|
|
2845
|
+
]);
|
|
2846
|
+
const operatingPlaybooks = getCampaignBuilderOperatingPlaybooksForRequest(request);
|
|
2847
|
+
return compact({
|
|
2848
|
+
campaign_id: buildRequest.gtmCampaignId,
|
|
2849
|
+
campaign_brief: buildRequest.prompt || request.goal,
|
|
2850
|
+
strategy_template: request.strategyTemplate,
|
|
2851
|
+
target_icp: buildRequest.icp ? buildGtmTargetIcpContext(buildRequest.icp) : void 0,
|
|
2852
|
+
lead_count: buildRequest.targetCount,
|
|
2853
|
+
layers: layers.length > 0 ? layers : void 0,
|
|
2854
|
+
preferred_providers: preferredProviders.length > 0 ? preferredProviders : void 0,
|
|
2855
|
+
strategy_model: strategyModel,
|
|
2856
|
+
include_strategy_patterns: campaignBuilderStrategyPatternsEnabled(agencyContext),
|
|
2857
|
+
include_workflow_patterns: campaignBuilderWorkflowPatternsEnabled(agencyContext),
|
|
2858
|
+
include_nango_catalog: agencyContext.includeNangoCatalog !== false,
|
|
2859
|
+
partner_ecosystem: partnerEcosystem,
|
|
2860
|
+
operating_playbooks: operatingPlaybooks.map((playbook) => ({
|
|
2861
|
+
slug: playbook.slug,
|
|
2862
|
+
label: playbook.label,
|
|
2863
|
+
quality_gates: playbook.qualityGates,
|
|
2864
|
+
activation_boundary: playbook.activationBoundary
|
|
2865
|
+
})),
|
|
2866
|
+
include_memory: memory.enabled,
|
|
2867
|
+
include_brain: true,
|
|
2868
|
+
include_provider_routes: true,
|
|
2869
|
+
include_failure_patterns: true,
|
|
2870
|
+
include_planned_providers: true,
|
|
2871
|
+
limit: 25
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
function buildGtmCampaignStrategyMemoryStatusArgs(request, buildRequest) {
|
|
2875
|
+
return compact({
|
|
2876
|
+
query: request.goal,
|
|
2877
|
+
campaign_brief: buildRequest.prompt || request.goal,
|
|
2878
|
+
strategy_template: request.strategyTemplate,
|
|
2879
|
+
target_icp: buildRequest.icp ? buildGtmTargetIcpContext(buildRequest.icp) : void 0,
|
|
2880
|
+
memory_dimension_filters: request.strategyTemplate ? { strategy_template: request.strategyTemplate } : void 0,
|
|
2881
|
+
require_memory_dimension_match: false,
|
|
2882
|
+
include_samples: false,
|
|
2883
|
+
include_sources: true,
|
|
2884
|
+
days: 3650,
|
|
2885
|
+
limit: 25
|
|
2886
|
+
});
|
|
2887
|
+
}
|
|
1789
2888
|
function buildGtmMemorySearchArgs(request, routes, query) {
|
|
1790
2889
|
const layers = uniqueStrings(routes.flatMap(gtmLayersForRoute));
|
|
1791
|
-
const providerChain = uniqueStrings(routes.map((route) => route.provider));
|
|
2890
|
+
const providerChain = uniqueStrings([...request.preferredProviders ?? [], ...routes.map((route) => route.provider)]);
|
|
1792
2891
|
return compact({
|
|
1793
2892
|
query: query.query,
|
|
1794
2893
|
limit: query.topK,
|
|
@@ -1810,6 +2909,26 @@ function buildGtmTargetIcpContext(icp) {
|
|
|
1810
2909
|
require_verified_email: icp.requireVerifiedEmail
|
|
1811
2910
|
});
|
|
1812
2911
|
}
|
|
2912
|
+
function mapCampaignBuilderLayerToGtmLayer(layer) {
|
|
2913
|
+
switch (layer) {
|
|
2914
|
+
case "source":
|
|
2915
|
+
return "lead_generation";
|
|
2916
|
+
case "enrichment":
|
|
2917
|
+
return "company_enrichment";
|
|
2918
|
+
case "qualification":
|
|
2919
|
+
return "qualification";
|
|
2920
|
+
case "copy":
|
|
2921
|
+
return "copy_enrichment";
|
|
2922
|
+
case "delivery":
|
|
2923
|
+
return "destination_export";
|
|
2924
|
+
case "feedback":
|
|
2925
|
+
return "feedback";
|
|
2926
|
+
case "approval":
|
|
2927
|
+
return "approval";
|
|
2928
|
+
default:
|
|
2929
|
+
return void 0;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
1813
2932
|
function buildCampaignArgs(request) {
|
|
1814
2933
|
const args = {
|
|
1815
2934
|
name: request.name,
|
|
@@ -1916,6 +3035,14 @@ function buildExecutionPrepareArgs(request, dryRun, confirmSpend) {
|
|
|
1916
3035
|
enhancers: buildArgs2.enhancers
|
|
1917
3036
|
});
|
|
1918
3037
|
}
|
|
3038
|
+
function buildDeliveryApprovalArgs(request) {
|
|
3039
|
+
if (request.delivery?.enabled === false || request.delivery?.approvalRequired === false) return void 0;
|
|
3040
|
+
return compact({
|
|
3041
|
+
campaign_build_id: "<campaign_build_id_from_approved_build>",
|
|
3042
|
+
destination_type: request.delivery?.destinationType ?? "json",
|
|
3043
|
+
destination_config: request.delivery?.destinationConfig
|
|
3044
|
+
});
|
|
3045
|
+
}
|
|
1919
3046
|
function mapBuildResult(data, dryRun) {
|
|
1920
3047
|
return {
|
|
1921
3048
|
campaignBuildId: data.campaign_build_id ?? null,
|
|
@@ -1990,8 +3117,8 @@ function estimateCredits(request, defaults, targetCount) {
|
|
|
1990
3117
|
}
|
|
1991
3118
|
function buildDescription(request) {
|
|
1992
3119
|
const parts = [
|
|
1993
|
-
request
|
|
1994
|
-
request
|
|
3120
|
+
campaignBuilderAccountLabel(request) ? `Account label: ${campaignBuilderAccountLabel(request)}` : void 0,
|
|
3121
|
+
campaignBuilderAccountContext(request) ? `Context: ${campaignBuilderAccountContext(request)}` : void 0,
|
|
1995
3122
|
request.constraints?.deliverabilityNotes?.length ? `Deliverability: ${request.constraints.deliverabilityNotes.join("; ")}` : void 0,
|
|
1996
3123
|
"Agent-built campaign plan layered on Signaliz kernel and existing MCP tools."
|
|
1997
3124
|
];
|
|
@@ -2014,6 +3141,10 @@ function compact(record) {
|
|
|
2014
3141
|
function asRecord(value) {
|
|
2015
3142
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2016
3143
|
}
|
|
3144
|
+
function asOptionalRecord(value) {
|
|
3145
|
+
const record = asRecord(value);
|
|
3146
|
+
return Object.keys(record).length > 0 ? record : void 0;
|
|
3147
|
+
}
|
|
2017
3148
|
function stringValue(value) {
|
|
2018
3149
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2019
3150
|
}
|
|
@@ -3758,7 +4889,7 @@ var GtmKernel = class {
|
|
|
3758
4889
|
campaigns: input.campaigns.map(campaignHistoryImportCampaignArgs)
|
|
3759
4890
|
});
|
|
3760
4891
|
}
|
|
3761
|
-
/** Queue a Trigger-backed campaign history import for larger
|
|
4892
|
+
/** Queue a Trigger-backed campaign history import for larger private campaign backfills. */
|
|
3762
4893
|
async importCampaignHistoryRun(input) {
|
|
3763
4894
|
return this.callMcp("gtm_campaign_history_import_run", {
|
|
3764
4895
|
source: input.source,
|
|
@@ -4205,6 +5336,40 @@ var GtmKernel = class {
|
|
|
4205
5336
|
include_layer_catalog: options.includeLayerCatalog
|
|
4206
5337
|
});
|
|
4207
5338
|
}
|
|
5339
|
+
/** List private-safe campaign strategy templates agents can merge into campaign build plans. */
|
|
5340
|
+
async campaignStrategyTemplates(options = {}) {
|
|
5341
|
+
return this.callMcp("gtm_campaign_strategy_templates", {
|
|
5342
|
+
strategy_template: options.strategyTemplate,
|
|
5343
|
+
query: options.query,
|
|
5344
|
+
include_details: options.includeDetails
|
|
5345
|
+
});
|
|
5346
|
+
}
|
|
5347
|
+
/** Build the read-only Memory, Brain, risk, and provider-route runbook needed before planning a campaign. */
|
|
5348
|
+
async campaignStartContext(input = {}) {
|
|
5349
|
+
return this.callMcp("gtm_campaign_start_context", {
|
|
5350
|
+
campaign_id: input.campaignId,
|
|
5351
|
+
campaign_build_id: input.campaignBuildId,
|
|
5352
|
+
campaign_brief: input.campaignBrief,
|
|
5353
|
+
strategy_template: input.strategyTemplate,
|
|
5354
|
+
target_icp: input.targetIcp,
|
|
5355
|
+
lead_count: input.leadCount,
|
|
5356
|
+
layers: input.layers,
|
|
5357
|
+
preferred_providers: input.preferredProviders,
|
|
5358
|
+
memory_dimension_filters: input.memoryDimensionFilters,
|
|
5359
|
+
require_memory_dimension_match: input.requireMemoryDimensionMatch,
|
|
5360
|
+
include_memory: input.includeMemory,
|
|
5361
|
+
include_brain: input.includeBrain,
|
|
5362
|
+
include_provider_routes: input.includeProviderRoutes,
|
|
5363
|
+
include_failure_patterns: input.includeFailurePatterns,
|
|
5364
|
+
include_delivery_risk: input.includeDeliveryRisk,
|
|
5365
|
+
include_global_brain: input.includeGlobalBrain,
|
|
5366
|
+
include_planned_providers: input.includePlannedProviders,
|
|
5367
|
+
days: input.days,
|
|
5368
|
+
min_confidence: input.minConfidence,
|
|
5369
|
+
min_sample_size: input.minSampleSize,
|
|
5370
|
+
limit: input.limit
|
|
5371
|
+
});
|
|
5372
|
+
}
|
|
4208
5373
|
/** Inspect GTM integration activation cards for UI and agent routing without writing state. */
|
|
4209
5374
|
async integrationsActivationStatus(options = {}) {
|
|
4210
5375
|
return this.callMcp("gtm_integrations_activation_status", {
|
|
@@ -4220,21 +5385,100 @@ var GtmKernel = class {
|
|
|
4220
5385
|
campaign_id: input.campaignId,
|
|
4221
5386
|
campaign_build_id: input.campaignBuildId,
|
|
4222
5387
|
campaign_brief: input.campaignBrief,
|
|
5388
|
+
strategy_template: input.strategyTemplate,
|
|
5389
|
+
target_icp: input.targetIcp,
|
|
5390
|
+
lead_count: input.leadCount,
|
|
5391
|
+
layers: input.layers,
|
|
5392
|
+
preferred_providers: input.preferredProviders,
|
|
5393
|
+
strategy_model: input.strategyModel,
|
|
5394
|
+
include_strategy_patterns: input.includeStrategyPatterns,
|
|
5395
|
+
include_workflow_patterns: input.includeWorkflowPatterns ?? input.includeClayPatterns,
|
|
5396
|
+
include_nango_catalog: input.includeNangoCatalog,
|
|
5397
|
+
partner_ecosystem: input.partnerEcosystem,
|
|
5398
|
+
memory_dimension_filters: input.memoryDimensionFilters,
|
|
5399
|
+
require_memory_dimension_match: input.requireMemoryDimensionMatch,
|
|
5400
|
+
include_memory: input.includeMemory,
|
|
5401
|
+
include_brain: input.includeBrain,
|
|
5402
|
+
include_provider_routes: input.includeProviderRoutes,
|
|
5403
|
+
include_failure_patterns: input.includeFailurePatterns,
|
|
5404
|
+
include_planned_providers: input.includePlannedProviders,
|
|
5405
|
+
days: input.days,
|
|
5406
|
+
limit: input.limit
|
|
5407
|
+
});
|
|
5408
|
+
}
|
|
5409
|
+
/** Emit reusable CampaignBuilderAgentRequest JSON from hosted MCP strategy-template defaults without spending credits. */
|
|
5410
|
+
async campaignAgentRequestTemplate(input = {}) {
|
|
5411
|
+
return this.callMcp("gtm_campaign_agent_request_template", {
|
|
5412
|
+
goal: input.goal,
|
|
5413
|
+
campaign_brief: input.campaignBrief,
|
|
5414
|
+
campaign_name: input.campaignName,
|
|
5415
|
+
account_label: input.accountLabel,
|
|
5416
|
+
account_context: input.accountContext,
|
|
5417
|
+
strategy_template: input.strategyTemplate,
|
|
5418
|
+
operating_playbooks: input.operatingPlaybooks,
|
|
4223
5419
|
target_icp: input.targetIcp,
|
|
5420
|
+
target_count: input.targetCount,
|
|
5421
|
+
builtins: input.builtIns,
|
|
5422
|
+
include_local_leads: input.includeLocalLeads,
|
|
5423
|
+
include_byo_placeholder: input.includeByoPlaceholder,
|
|
5424
|
+
include_nango_catalog: input.includeNangoCatalog,
|
|
5425
|
+
preferred_providers: input.preferredProviders,
|
|
5426
|
+
privacy_mode: input.privacyMode,
|
|
5427
|
+
destination_type: input.destinationType
|
|
5428
|
+
});
|
|
5429
|
+
}
|
|
5430
|
+
/** Compose a one-call read-only strategy-template campaign-agent runbook across built-ins, Memory, Brain, Nango, and BYO routes. */
|
|
5431
|
+
async campaignAgentPlan(input = {}) {
|
|
5432
|
+
return this.callMcp("gtm_campaign_agent_plan", {
|
|
5433
|
+
goal: input.goal,
|
|
5434
|
+
campaign_brief: input.campaignBrief,
|
|
5435
|
+
campaign_name: input.campaignName,
|
|
5436
|
+
campaign_id: input.campaignId,
|
|
5437
|
+
campaign_build_id: input.campaignBuildId,
|
|
5438
|
+
strategy_template: input.strategyTemplate,
|
|
5439
|
+
operating_playbooks: input.operatingPlaybooks,
|
|
5440
|
+
account_context: input.accountContext,
|
|
5441
|
+
target_icp: input.targetIcp,
|
|
5442
|
+
target_count: input.targetCount,
|
|
4224
5443
|
lead_count: input.leadCount,
|
|
5444
|
+
builtins: input.builtIns,
|
|
5445
|
+
use_local_leads: input.useLocalLeads,
|
|
4225
5446
|
layers: input.layers,
|
|
4226
5447
|
preferred_providers: input.preferredProviders,
|
|
5448
|
+
custom_tools: input.customTools,
|
|
5449
|
+
integrations: input.integrations,
|
|
5450
|
+
strategy_model: input.strategyModel,
|
|
5451
|
+
include_strategy_patterns: input.includeStrategyPatterns,
|
|
5452
|
+
include_workflow_patterns: input.includeWorkflowPatterns,
|
|
5453
|
+
include_nango_catalog: input.includeNangoCatalog,
|
|
5454
|
+
partner_ecosystem: input.partnerEcosystem,
|
|
4227
5455
|
memory_dimension_filters: input.memoryDimensionFilters,
|
|
4228
5456
|
require_memory_dimension_match: input.requireMemoryDimensionMatch,
|
|
4229
5457
|
include_memory: input.includeMemory,
|
|
4230
5458
|
include_brain: input.includeBrain,
|
|
4231
5459
|
include_provider_routes: input.includeProviderRoutes,
|
|
4232
5460
|
include_failure_patterns: input.includeFailurePatterns,
|
|
5461
|
+
include_delivery_risk: input.includeDeliveryRisk,
|
|
4233
5462
|
include_planned_providers: input.includePlannedProviders,
|
|
4234
5463
|
days: input.days,
|
|
4235
5464
|
limit: input.limit
|
|
4236
5465
|
});
|
|
4237
5466
|
}
|
|
5467
|
+
/** Inspect private-safe strategy-template/workflow memory readiness before campaign planning. */
|
|
5468
|
+
async campaignStrategyMemoryStatus(input = {}) {
|
|
5469
|
+
return this.callMcp("gtm_campaign_strategy_memory_status", {
|
|
5470
|
+
strategy_template: input.strategyTemplate,
|
|
5471
|
+
query: input.query,
|
|
5472
|
+
campaign_brief: input.campaignBrief,
|
|
5473
|
+
target_icp: input.targetIcp,
|
|
5474
|
+
memory_dimension_filters: input.memoryDimensionFilters,
|
|
5475
|
+
require_memory_dimension_match: input.requireMemoryDimensionMatch,
|
|
5476
|
+
include_samples: input.includeSamples,
|
|
5477
|
+
include_sources: input.includeSources,
|
|
5478
|
+
days: input.days,
|
|
5479
|
+
limit: input.limit
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
4238
5482
|
/** Persist a reviewed campaign build plan into a campaign object and audit log. Dry-run first by default. */
|
|
4239
5483
|
async commitCampaignBuildPlan(input = {}) {
|
|
4240
5484
|
return this.callMcp("gtm_campaign_build_plan_commit", {
|
|
@@ -4381,6 +5625,13 @@ var GtmKernel = class {
|
|
|
4381
5625
|
vendor_id: input.vendorId,
|
|
4382
5626
|
service_category: input.serviceCategory,
|
|
4383
5627
|
connection_type: input.connectionType,
|
|
5628
|
+
integration_id: input.integrationId,
|
|
5629
|
+
provider_config_key: input.providerConfigKey,
|
|
5630
|
+
allowed_integrations: input.allowedIntegrations,
|
|
5631
|
+
surface: input.surface,
|
|
5632
|
+
source: input.source,
|
|
5633
|
+
user_email: input.userEmail,
|
|
5634
|
+
user_display_name: input.userDisplayName,
|
|
4384
5635
|
status: input.status,
|
|
4385
5636
|
metadata: input.metadata
|
|
4386
5637
|
});
|
|
@@ -4437,6 +5688,20 @@ var GtmKernel = class {
|
|
|
4437
5688
|
context: input.context
|
|
4438
5689
|
});
|
|
4439
5690
|
}
|
|
5691
|
+
/** Create a short-lived Nango Connect session so a user can authorize a vendor API. */
|
|
5692
|
+
async createNangoConnectSession(input) {
|
|
5693
|
+
return this.callMcp("nango_connect_session_create", {
|
|
5694
|
+
provider_id: input.providerId,
|
|
5695
|
+
integration_id: input.integrationId,
|
|
5696
|
+
provider_display_name: input.providerDisplayName,
|
|
5697
|
+
integration_display_name: input.integrationDisplayName,
|
|
5698
|
+
allowed_integrations: input.allowedIntegrations,
|
|
5699
|
+
surface: input.surface,
|
|
5700
|
+
source: input.source,
|
|
5701
|
+
user_email: input.userEmail,
|
|
5702
|
+
user_display_name: input.userDisplayName
|
|
5703
|
+
});
|
|
5704
|
+
}
|
|
4440
5705
|
/** List Nango-backed action tools for a workspace connection without executing them. */
|
|
4441
5706
|
async listNangoTools(options = {}) {
|
|
4442
5707
|
return this.callMcp("nango_mcp_tools_list", {
|