@signaliz/sdk 1.0.15 → 1.0.17

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.
@@ -243,25 +243,31 @@ var HttpClient = class {
243
243
  async getToken() {
244
244
  if (this.apiKey) return this.apiKey;
245
245
  if (this.accessToken) return this.accessToken;
246
- const res = await fetch("https://api.signaliz.com/token", {
247
- method: "POST",
248
- headers: { "Content-Type": "application/json" },
249
- body: JSON.stringify({
250
- grant_type: "client_credentials",
251
- client_id: this.clientId,
252
- client_secret: this.clientSecret
253
- })
254
- });
255
- if (!res.ok) {
256
- throw new SignalizError({
257
- code: "AUTH_FAILED",
258
- message: "Failed to obtain access token",
259
- errorType: "auth_expired"
246
+ if (this.accessTokenPromise) return this.accessTokenPromise;
247
+ this.accessTokenPromise = (async () => {
248
+ const res = await fetch("https://api.signaliz.com/token", {
249
+ method: "POST",
250
+ headers: { "Content-Type": "application/json" },
251
+ body: JSON.stringify({
252
+ grant_type: "client_credentials",
253
+ client_id: this.clientId,
254
+ client_secret: this.clientSecret
255
+ })
260
256
  });
261
- }
262
- const data = await res.json();
263
- this.accessToken = data.access_token;
264
- return this.accessToken;
257
+ if (!res.ok) {
258
+ throw new SignalizError({
259
+ code: "AUTH_FAILED",
260
+ message: "Failed to obtain access token",
261
+ errorType: "auth_expired"
262
+ });
263
+ }
264
+ const data = await res.json();
265
+ this.accessToken = data.access_token;
266
+ return this.accessToken;
267
+ })().finally(() => {
268
+ this.accessTokenPromise = void 0;
269
+ });
270
+ return this.accessTokenPromise;
265
271
  }
266
272
  };
267
273
  function sleep(ms) {
@@ -510,7 +516,6 @@ var Signals = class {
510
516
  if (params.online !== void 0) args.online = params.online;
511
517
  if (params.targetSignalCount) args.target_signal_count = params.targetSignalCount;
512
518
  if (params.lookbackDays) args.lookback_days = params.lookbackDays;
513
- if (params.model) args.model = params.model;
514
519
  if (params.enableDeepSearch) args.enable_deep_search = params.enableDeepSearch;
515
520
  if (params.enableOutreachIntelligence) args.enable_outreach_intelligence = params.enableOutreachIntelligence;
516
521
  if (params.enablePredictiveIntelligence) args.enable_predictive_intelligence = params.enablePredictiveIntelligence;
@@ -805,6 +810,10 @@ var Campaigns = class {
805
810
  async artifacts(campaignBuildId) {
806
811
  return this.listCampaignBuildArtifacts(campaignBuildId);
807
812
  }
813
+ /** Generate fresh signed URLs for a downloadable campaign artifact. */
814
+ async downloadArtifact(campaignBuildId, options) {
815
+ return this.downloadCampaignArtifact(campaignBuildId, options);
816
+ }
808
817
  /** Cancel a queued or running build. */
809
818
  async cancel(campaignBuildId, reason) {
810
819
  return this.cancelCampaignBuild(campaignBuildId, reason);
@@ -849,12 +858,16 @@ var Campaigns = class {
849
858
  dryRun: isDryRun,
850
859
  requestedTargetCount: data.requested_target_count,
851
860
  plannedTargetCount: data.planned_target_count,
861
+ acquisitionMode: data.acquisition_mode,
862
+ acquisitionSource: data.acquisition_source,
863
+ cacheReusePolicy: data.cache_reuse_policy,
852
864
  estimatedCredits: data.estimated_credits,
853
865
  estimatedDurationSeconds: data.estimated_duration_seconds,
854
866
  targetLimitApplied: data.target_limit_applied,
855
867
  targetLimitReason: data.target_limit_reason,
856
868
  maxSupportedTargetCount: data.max_supported_target_count,
857
869
  brainContext: data.brain_context ?? {},
870
+ learningHoldout: data.learning_holdout ?? {},
858
871
  providerRoute: mapProviderRoute(data)
859
872
  };
860
873
  }
@@ -870,14 +883,24 @@ var Campaigns = class {
870
883
  });
871
884
  return (data.artifacts ?? []).map(mapArtifact);
872
885
  }
886
+ async downloadCampaignArtifact(campaignBuildId, options) {
887
+ const args = { campaign_build_id: campaignBuildId };
888
+ if (options?.format) args.format = options.format;
889
+ const data = await this.callMcp("download_campaign_artifact", args);
890
+ return mapArtifactDownloadResult(data);
891
+ }
873
892
  async getCampaignBuildRows(campaignBuildId, options) {
874
893
  const args = { campaign_build_id: campaignBuildId };
875
894
  if (options?.limit) args.page_size = options.limit;
876
895
  if (options?.cursor) args.cursor = options.cursor;
896
+ if (options?.includeData !== void 0) args.include_data = options.includeData;
897
+ if (options?.includeRaw !== void 0) args.include_raw = options.includeRaw;
877
898
  const filters = {};
878
899
  if (options?.segment) filters.segment = options.segment;
879
900
  if (options?.rowStatus) filters.row_status = options.rowStatus;
880
901
  if (options?.qualified !== void 0) filters.qualified = options.qualified;
902
+ if (options?.cached !== void 0) filters.cached = options.cached;
903
+ if (options?.exportReady !== void 0) filters.export_ready = options.exportReady;
881
904
  if (Object.keys(filters).length > 0) args.filters = filters;
882
905
  const data = await this.callMcp("get_campaign_build_rows", args);
883
906
  return {
@@ -902,6 +925,7 @@ var Campaigns = class {
902
925
  };
903
926
  if (options?.destinationId) args.destination_id = options.destinationId;
904
927
  if (options?.destinationConfig) args.destination_config = options.destinationConfig;
928
+ if (options?.allowPartialDelivery === true) args.allow_partial_delivery = true;
905
929
  const data = await this.callMcp("approve_campaign_delivery", args);
906
930
  return {
907
931
  campaignBuildId: data.campaign_build_id,
@@ -910,7 +934,10 @@ var Campaigns = class {
910
934
  message: data.message ?? "",
911
935
  deliveryId: data.delivery_id,
912
936
  deliveryIds: data.delivery_ids,
913
- approvedCount: data.approved_count
937
+ approvedCount: data.approved_count,
938
+ partialDelivery: data.partial_delivery,
939
+ effectiveTargetCount: data.effective_target_count,
940
+ requestedTargetCount: data.requested_target_count
914
941
  };
915
942
  }
916
943
  async cancelCampaignBuild(campaignBuildId, reason) {
@@ -963,17 +990,50 @@ function mapStatus(data) {
963
990
  warnings: diagnosticMessages(data.warnings),
964
991
  errors: diagnosticMessages(data.errors),
965
992
  artifactCount: data.artifact_count ?? 0,
993
+ artifactDownloads: Array.isArray(data.artifact_downloads) ? data.artifact_downloads.map(mapArtifactDownload) : [],
994
+ customerRowCounts: mapCustomerRowCounts(data.customer_row_counts),
995
+ phaseAttemptTotals: recordOrNull(data.phase_attempt_totals) ?? void 0,
966
996
  providerRoute: mapProviderRoute(data),
967
997
  triggerRunId: typeof data.trigger_run_id === "string" ? data.trigger_run_id : null,
968
998
  staleRunningPhase: data.stale_running_phase === true,
969
999
  phaseAgeSeconds: numberOrNull(data.phase_age_seconds),
970
1000
  diagnostics: recordOrNull(data.diagnostics) ?? {},
971
1001
  nextAction: formatNextAction(data.next_action),
1002
+ approvalAction: formatNextAction(data.approval_action),
972
1003
  createdAt: data.created_at,
973
1004
  updatedAt: data.updated_at,
974
1005
  completedAt: data.completed_at
975
1006
  };
976
1007
  }
1008
+ function mapCustomerRowCounts(value) {
1009
+ const record = recordOrNull(value);
1010
+ if (!record) return void 0;
1011
+ return {
1012
+ requestedTarget: numberOrNull(record.requested_target),
1013
+ acquiredRows: numberOrNull(record.acquired_rows) ?? void 0,
1014
+ acceptedRows: numberOrNull(record.accepted_rows) ?? void 0,
1015
+ usableRows: numberOrNull(record.usable_rows) ?? void 0,
1016
+ copiedRows: numberOrNull(record.copied_rows) ?? void 0,
1017
+ approvalReadyRows: numberOrNull(record.approval_ready_rows) ?? void 0,
1018
+ qaReadyRows: numberOrNull(record.qa_ready_rows) ?? void 0,
1019
+ deliveredRows: numberOrNull(record.delivered_rows) ?? void 0,
1020
+ disqualifiedRows: numberOrNull(record.disqualified_rows) ?? void 0,
1021
+ reviewableRows: numberOrNull(record.reviewable_rows) ?? void 0,
1022
+ rowFailures: numberOrNull(record.row_failures) ?? void 0,
1023
+ acceptedShortfall: numberOrNull(record.accepted_shortfall),
1024
+ usableShortfall: numberOrNull(record.usable_shortfall),
1025
+ qaReadyShortfall: numberOrNull(record.qa_ready_shortfall),
1026
+ deliveryShortfall: numberOrNull(record.delivery_shortfall),
1027
+ fillRatio: numberOrNull(record.fill_ratio),
1028
+ qaReadyFillRatio: numberOrNull(record.qa_ready_fill_ratio),
1029
+ deliveredFillRatio: numberOrNull(record.delivered_fill_ratio),
1030
+ terminalReason: typeof record.terminal_reason === "string" ? record.terminal_reason : null,
1031
+ acceptedShortfallReason: typeof record.accepted_shortfall_reason === "string" ? record.accepted_shortfall_reason : null,
1032
+ usableShortfallReason: typeof record.usable_shortfall_reason === "string" ? record.usable_shortfall_reason : null,
1033
+ qaReadyShortfallReason: typeof record.qa_ready_shortfall_reason === "string" ? record.qa_ready_shortfall_reason : null,
1034
+ deliveryShortfallReason: typeof record.delivery_shortfall_reason === "string" ? record.delivery_shortfall_reason : null
1035
+ };
1036
+ }
977
1037
  function mapProviderRoute(data) {
978
1038
  const brainContext = recordOrNull(data?.brain_context);
979
1039
  const plan = recordOrNull(data?.provider_route_plan) ?? recordOrNull(brainContext?.provider_route_plan);
@@ -1051,13 +1111,56 @@ function mapArtifact(a) {
1051
1111
  artifactType: a.artifact_type,
1052
1112
  destination: a.destination,
1053
1113
  storagePath: a.storage_path,
1114
+ format: a.format ?? null,
1054
1115
  signedUrl: a.signed_url,
1116
+ downloadUrl: a.download_url ?? null,
1117
+ manifestUrl: a.manifest_url ?? null,
1118
+ expiresAt: a.expires_at ?? null,
1055
1119
  rowCount: a.row_count ?? 0,
1056
1120
  checksum: a.checksum,
1057
1121
  metadata: a.metadata ?? {},
1058
1122
  createdAt: a.created_at
1059
1123
  };
1060
1124
  }
1125
+ function mapArtifactDownload(data) {
1126
+ return {
1127
+ id: data.id,
1128
+ artifactType: data.artifact_type ?? null,
1129
+ format: data.format ?? null,
1130
+ rowCount: data.row_count ?? 0,
1131
+ signedUrl: data.signed_url ?? null,
1132
+ downloadUrl: data.download_url ?? null,
1133
+ manifestUrl: data.manifest_url ?? null,
1134
+ expiresAt: data.expires_at ?? null
1135
+ };
1136
+ }
1137
+ function mapArtifactDownloadResult(data) {
1138
+ return {
1139
+ campaignBuildId: data.campaign_build_id,
1140
+ artifactId: data.artifact_id,
1141
+ format: data.format,
1142
+ rowCount: data.row_count ?? 0,
1143
+ byteSize: numberOrNull(data.byte_size),
1144
+ partCount: data.part_count ?? 0,
1145
+ checksum: data.checksum ?? null,
1146
+ signedUrl: data.signed_url ?? null,
1147
+ downloadUrl: data.download_url ?? null,
1148
+ manifestUrl: data.manifest_url ?? null,
1149
+ expiresAt: data.expires_at ?? null,
1150
+ parts: Array.isArray(data.parts) ? data.parts.map(mapArtifactDownloadPart) : [],
1151
+ downloadCommands: recordOrNull(data.download_commands) ?? {},
1152
+ expiresInSeconds: numberOrNull(data.expires_in_seconds)
1153
+ };
1154
+ }
1155
+ function mapArtifactDownloadPart(data) {
1156
+ return {
1157
+ partIndex: data.part_index ?? 0,
1158
+ rowCount: data.row_count ?? 0,
1159
+ byteSize: numberOrNull(data.byte_size),
1160
+ checksum: data.checksum ?? null,
1161
+ signedUrl: data.signed_url ?? null
1162
+ };
1163
+ }
1061
1164
  function mapScope(data) {
1062
1165
  return {
1063
1166
  campaignScopeId: data.campaign_scope_id,
@@ -1111,8 +1214,29 @@ function buildArgs(request) {
1111
1214
  if (request.allowDownscale !== void 0) args.allow_downscale = request.allowDownscale;
1112
1215
  if (request.confirmSpend !== void 0) args.confirm_spend = request.confirmSpend;
1113
1216
  if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
1217
+ if (request.acquisitionMode) args.acquisition_mode = request.acquisitionMode;
1218
+ if (request.cacheReusePolicy) {
1219
+ args.cache_reuse_policy = {
1220
+ allow_verified_cache: request.cacheReusePolicy.allowVerifiedCache,
1221
+ suppress_prior_campaign_ids: request.cacheReusePolicy.suppressPriorCampaignIds,
1222
+ suppress_prior_list_ids: request.cacheReusePolicy.suppressPriorListIds,
1223
+ uniqueness: request.cacheReusePolicy.uniqueness,
1224
+ require_usage_metadata: request.cacheReusePolicy.requireUsageMetadata
1225
+ };
1226
+ }
1114
1227
  if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
1115
1228
  if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
1229
+ if (request.learningHoldout) {
1230
+ args.learning_holdout = {
1231
+ enabled: request.learningHoldout.enabled,
1232
+ control_percentage: request.learningHoldout.controlPercentage,
1233
+ min_control_size: request.learningHoldout.minControlSize,
1234
+ experiment_key: request.learningHoldout.experimentKey,
1235
+ source_campaign_id: request.learningHoldout.sourceCampaignId,
1236
+ primary_metric: request.learningHoldout.primaryMetric
1237
+ };
1238
+ }
1239
+ if (request.campaignStrategyContext) args.campaign_strategy_context = request.campaignStrategyContext;
1116
1240
  if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
1117
1241
  if (request.icp) {
1118
1242
  args.icp = {
@@ -1154,7 +1278,17 @@ function buildArgs(request) {
1154
1278
  max_body_words: request.copy.maxBodyWords,
1155
1279
  sender_context: request.copy.senderContext,
1156
1280
  offer_context: request.copy.offerContext,
1157
- model: request.copy.model
1281
+ model: request.copy.model,
1282
+ style_source: request.copy.styleSource ? {
1283
+ sample_text: request.copy.styleSource.sampleText,
1284
+ campaign_ids: request.copy.styleSource.campaignIds,
1285
+ artifact_ids: request.copy.styleSource.artifactIds
1286
+ } : void 0,
1287
+ sequence_steps: request.copy.sequenceSteps,
1288
+ copy_schema: request.copy.copySchema,
1289
+ banned_phrases: request.copy.bannedPhrases,
1290
+ approval_required: request.copy.approvalRequired,
1291
+ quality_tier: request.copy.qualityTier
1158
1292
  };
1159
1293
  }
1160
1294
  if (request.delivery) {
@@ -1217,6 +1351,8 @@ var DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS = {
1217
1351
  }
1218
1352
  };
1219
1353
  var DEFAULT_CAMPAIGN_BUILDER_BUILT_INS = [
1354
+ "company_discovery",
1355
+ "people_discovery",
1220
1356
  "lead_generation",
1221
1357
  "email_finding",
1222
1358
  "email_verification",
@@ -1225,6 +1361,8 @@ var DEFAULT_CAMPAIGN_BUILDER_BUILT_INS = [
1225
1361
  var CAMPAIGN_BUILDER_BUILT_IN_ROUTE_IDS = {
1226
1362
  lead_generation: "signaliz-lead-generation",
1227
1363
  local_leads: "signaliz-local-leads",
1364
+ company_discovery: "signaliz-company-discovery",
1365
+ people_discovery: "signaliz-people-discovery",
1228
1366
  email_finding: "signaliz-email-finding",
1229
1367
  email_verification: "signaliz-email-verification",
1230
1368
  signals: "signaliz-signals"
@@ -1242,8 +1380,8 @@ var CAMPAIGN_BUILDER_OPERATING_PLAYBOOKS = [
1242
1380
  slug: "cache-first-large-list",
1243
1381
  label: "Cache-First Large List",
1244
1382
  whenToUse: [
1245
- "The target count is high and reusable workspace lead or cache coverage may exist.",
1246
- "The deliverable is a verified list or top-up rather than a deeply custom one-off workflow."
1383
+ "The operator explicitly references a previous campaign, prior list, seed list, or suppression baseline.",
1384
+ "The deliverable is a top-up, continuation, or backfill where prior campaign context should guide reuse."
1247
1385
  ],
1248
1386
  sequence: [
1249
1387
  "Inventory reusable cache before paid sourcing.",
@@ -1449,7 +1587,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
1449
1587
  ],
1450
1588
  requireVerifiedEmail: true
1451
1589
  },
1452
- builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
1590
+ builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
1453
1591
  preferredProviders: ["signaliz_native"],
1454
1592
  memoryQueries: [{
1455
1593
  query: "industrial OT net-new prior email suppression verified manufacturing embedded systems field service cyber resilience business continuity",
@@ -1523,7 +1661,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
1523
1661
  ],
1524
1662
  requireVerifiedEmail: true
1525
1663
  },
1526
- builtIns: ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"],
1664
+ builtIns: ["company_discovery", "people_discovery", "lead_generation", "local_leads", "email_finding", "email_verification", "signals"],
1527
1665
  preferredProviders: ["signaliz_native", "octave", "clay_webhook", "apify"],
1528
1666
  memoryQueries: [{
1529
1667
  query: "mature non-medical home care agencies billable hours franchise caregiver recruiting proof gate qualification export approval",
@@ -1589,7 +1727,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
1589
1727
  exclusions: ["enterprise holding company", "staffing", "recruiting", "software-only vendor", "freelancer-only profile"],
1590
1728
  requireVerifiedEmail: true
1591
1729
  },
1592
- builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
1730
+ builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
1593
1731
  preferredProviders: ["signaliz_native", "octave"],
1594
1732
  memoryQueries: [{
1595
1733
  query: "agency founder owner CEO marketing services suppression domain pool email verification final approval gate",
@@ -1671,7 +1809,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
1671
1809
  ],
1672
1810
  requireVerifiedEmail: true
1673
1811
  },
1674
- builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
1812
+ builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
1675
1813
  preferredProviders: ["signaliz_native", "octave"],
1676
1814
  memoryQueries: [{
1677
1815
  query: "cloud hosting infrastructure VMware Broadcom qualification verified email persona trigger SKU mapping",
@@ -1704,25 +1842,21 @@ var CampaignBuilderAgent = class {
1704
1842
  async createPlan(request, options = {}) {
1705
1843
  const resolvedRequest = applyCampaignBuilderStrategyTemplate(request);
1706
1844
  const warnings = [];
1707
- const workspaceContext = resolvedRequest.workspaceContext ?? await this.getWorkspaceContext(warnings);
1708
- const scopeResult = options.scopeCampaign === false ? void 0 : await this.scopeCampaign(resolvedRequest, warnings);
1709
- if (options.discoverCapabilities !== false) {
1710
- await this.discoverPlannedRoutes(resolvedRequest, warnings);
1711
- }
1845
+ const [workspaceContext, scopeResult] = await Promise.all([
1846
+ resolvedRequest.workspaceContext ? Promise.resolve(resolvedRequest.workspaceContext) : this.getWorkspaceContext(warnings),
1847
+ options.scopeCampaign === false ? Promise.resolve(void 0) : this.scopeCampaign(resolvedRequest, warnings),
1848
+ options.discoverCapabilities === false ? Promise.resolve(void 0) : this.discoverPlannedRoutes(resolvedRequest, warnings)
1849
+ ]);
1712
1850
  const plan = createCampaignBuilderAgentPlan(resolvedRequest, {
1713
1851
  workspaceContext,
1714
1852
  scopeBuildArgs: asRecord(scopeResult?.build_campaign_args ?? scopeResult?.buildCampaignArgs),
1715
1853
  warnings
1716
1854
  });
1717
- if (options.includeStrategyMemoryStatus !== false) {
1718
- await this.attachStrategyMemoryStatus(plan, warnings);
1719
- }
1720
- if (options.includeKernelPlan !== false) {
1721
- await this.attachKernelCampaignBuildPlan(plan, warnings);
1722
- }
1723
- if (options.includeDeliveryRisk !== false) {
1724
- await this.attachDeliveryRiskPreflight(plan, warnings);
1725
- }
1855
+ await Promise.all([
1856
+ options.includeStrategyMemoryStatus === false ? Promise.resolve() : this.attachStrategyMemoryStatus(plan, warnings),
1857
+ options.includeKernelPlan === false ? Promise.resolve() : this.attachKernelCampaignBuildPlan(plan, warnings),
1858
+ options.includeDeliveryRisk === false ? Promise.resolve() : this.attachDeliveryRiskPreflight(plan, warnings)
1859
+ ]);
1726
1860
  return plan;
1727
1861
  }
1728
1862
  async readiness(request, options = {}) {
@@ -1739,6 +1873,9 @@ var CampaignBuilderAgent = class {
1739
1873
  buildKit(options = {}) {
1740
1874
  return createCampaignBuilderBuildKit(options);
1741
1875
  }
1876
+ memoryKit(options = {}) {
1877
+ return createCampaignBuilderMemoryKit(options);
1878
+ }
1742
1879
  async commitPlan(plan, options = {}) {
1743
1880
  const writeMode = options.confirm === true && options.dryRun === false;
1744
1881
  if (writeMode && !options.approvedBy) {
@@ -1767,6 +1904,7 @@ var CampaignBuilderAgent = class {
1767
1904
  },
1768
1905
  brain_defaults: plan.buildRequest.brainDefaults,
1769
1906
  brain_preflight: plan.buildRequest.brainPreflight,
1907
+ campaign_strategy_context: plan.buildRequest.campaignStrategyContext,
1770
1908
  delivery_risk_preflight: plan.buildRequest.deliveryRisk,
1771
1909
  delivery_risk: plan.buildRequest.deliveryRisk
1772
1910
  }),
@@ -1888,7 +2026,8 @@ var CampaignBuilderAgent = class {
1888
2026
  const destinationType = options.deliveryDestinationType ?? plan.buildRequest.delivery?.destinationType ?? "json";
1889
2027
  result.deliveryApproval = await this.approveCampaignDelivery(campaignBuildId, destinationType, {
1890
2028
  destinationId: options.deliveryDestinationId,
1891
- destinationConfig: options.deliveryDestinationConfig ?? plan.buildRequest.delivery?.destinationConfig
2029
+ destinationConfig: options.deliveryDestinationConfig ?? plan.buildRequest.delivery?.destinationConfig,
2030
+ allowPartialDelivery: options.allowPartialDelivery
1892
2031
  });
1893
2032
  finalStatus = await this.waitForCampaignBuildStatus(
1894
2033
  campaignBuildId,
@@ -1911,8 +2050,12 @@ var CampaignBuilderAgent = class {
1911
2050
  const args = compact({
1912
2051
  campaign_build_id: campaignBuildId,
1913
2052
  page_size: options.limit,
1914
- cursor: options.cursor
2053
+ cursor: options.cursor,
2054
+ include_data: options.includeData,
2055
+ include_raw: options.includeRaw
1915
2056
  });
2057
+ if (options.cached !== void 0) filters.cached = options.cached;
2058
+ if (options.exportReady !== void 0) filters.export_ready = options.exportReady;
1916
2059
  if (Object.keys(filters).length > 0) args.filters = filters;
1917
2060
  const data = await this.callMcp("get_campaign_build_rows", args);
1918
2061
  return mapAgentCampaignRowsResult(data);
@@ -1927,12 +2070,14 @@ var CampaignBuilderAgent = class {
1927
2070
  return this.approveCampaignDelivery(campaignBuildId, destinationType, options);
1928
2071
  }
1929
2072
  async reviewBuild(campaignBuildId, options = {}) {
1930
- const status = await this.getBuildStatus(campaignBuildId);
1931
- const rows = await this.getBuildRows(campaignBuildId, {
1932
- ...options,
1933
- limit: options.limit ?? 100
1934
- });
1935
- const artifacts = await this.listBuildArtifacts(campaignBuildId);
2073
+ const [status, rows, artifacts] = await Promise.all([
2074
+ this.getBuildStatus(campaignBuildId),
2075
+ this.getBuildRows(campaignBuildId, {
2076
+ ...options,
2077
+ limit: options.limit ?? 100
2078
+ }),
2079
+ this.listBuildArtifacts(campaignBuildId)
2080
+ ]);
1936
2081
  return createCampaignBuilderBuildReview(status, rows, artifacts);
1937
2082
  }
1938
2083
  async getCampaignBuildStatus(campaignBuildId) {
@@ -1960,7 +2105,8 @@ var CampaignBuilderAgent = class {
1960
2105
  campaign_build_id: campaignBuildId,
1961
2106
  destination_type: destinationType,
1962
2107
  destination_id: options?.destinationId,
1963
- destination_config: options?.destinationConfig
2108
+ destination_config: options?.destinationConfig,
2109
+ allow_partial_delivery: options?.allowPartialDelivery === true ? true : void 0
1964
2110
  });
1965
2111
  const data = await this.callMcp("approve_campaign_delivery", args);
1966
2112
  return {
@@ -1970,7 +2116,10 @@ var CampaignBuilderAgent = class {
1970
2116
  message: data.message ?? "",
1971
2117
  deliveryId: data.delivery_id,
1972
2118
  deliveryIds: data.delivery_ids,
1973
- approvedCount: data.approved_count
2119
+ approvedCount: data.approved_count,
2120
+ partialDelivery: data.partial_delivery,
2121
+ effectiveTargetCount: data.effective_target_count,
2122
+ requestedTargetCount: data.requested_target_count
1974
2123
  };
1975
2124
  }
1976
2125
  async getWorkspaceContext(warnings) {
@@ -2006,15 +2155,19 @@ var CampaignBuilderAgent = class {
2006
2155
  const providers = new Set(
2007
2156
  [...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])].filter((route) => route.provider !== "signaliz").map((route) => route.provider)
2008
2157
  );
2009
- for (const provider of providers) {
2158
+ const warningsByProvider = await Promise.all(Array.from(providers, async (provider) => {
2010
2159
  try {
2011
2160
  await this.callMcp("discover_capabilities", {
2012
2161
  query: `campaign builder ${provider} ${request.goal}`,
2013
2162
  category: "campaign"
2014
2163
  });
2164
+ return void 0;
2015
2165
  } catch (error) {
2016
- warnings.push(`Capability discovery for ${provider} failed: ${errorMessage(error)}`);
2166
+ return `Capability discovery for ${provider} failed: ${errorMessage(error)}`;
2017
2167
  }
2168
+ }));
2169
+ for (const warning of warningsByProvider) {
2170
+ if (warning) warnings.push(warning);
2018
2171
  }
2019
2172
  }
2020
2173
  async attachStrategyMemoryStatus(plan, warnings) {
@@ -2038,8 +2191,24 @@ var CampaignBuilderAgent = class {
2038
2191
  const kernelPlan = await this.callMcp("gtm_campaign_build_plan", asRecord(plannerStep.arguments));
2039
2192
  plan.kernelPlan = asRecord(kernelPlan);
2040
2193
  const brainDefaults = asRecord(plan.kernelPlan.brain_defaults ?? plan.kernelPlan.brainDefaults);
2194
+ const corpusContext = asRecord(plan.kernelPlan.corpus_context ?? plan.kernelPlan.corpusContext);
2195
+ const campaignStrategyContext = asRecord(plan.kernelPlan.campaign_strategy_context ?? plan.kernelPlan.campaignStrategyContext);
2196
+ const memoryExamples = Array.isArray(plan.kernelPlan.memory_examples) ? plan.kernelPlan.memory_examples.map((item) => asRecord(item)).filter((item) => Object.keys(item).length > 0).slice(0, 15) : [];
2041
2197
  if (Object.keys(brainDefaults).length > 0 && Object.keys(asRecord(plan.buildRequest.brainDefaults)).length === 0) {
2042
2198
  plan.buildRequest.brainDefaults = brainDefaults;
2199
+ }
2200
+ if (Object.keys(campaignStrategyContext).length > 0) {
2201
+ plan.buildRequest.campaignStrategyContext = campaignStrategyContext;
2202
+ }
2203
+ if (Object.keys(corpusContext).length > 0 || memoryExamples.length > 0 || Object.keys(brainDefaults).length > 0 || Object.keys(campaignStrategyContext).length > 0) {
2204
+ plan.buildRequest.brainPreflight = compact({
2205
+ ...asRecord(plan.buildRequest.brainPreflight),
2206
+ corpus_context: Object.keys(corpusContext).length > 0 ? corpusContext : void 0,
2207
+ memory_examples: memoryExamples.length > 0 ? memoryExamples : void 0,
2208
+ brain_defaults: Object.keys(brainDefaults).length > 0 ? brainDefaults : void 0,
2209
+ campaign_strategy_context: Object.keys(campaignStrategyContext).length > 0 ? campaignStrategyContext : void 0
2210
+ });
2211
+ plan.brainPreflight = asRecord(plan.buildRequest.brainPreflight);
2043
2212
  refreshBuildStepArguments(plan);
2044
2213
  }
2045
2214
  } catch (error) {
@@ -2220,6 +2389,9 @@ function createCampaignBuilderProofReceipt(plan, result) {
2220
2389
  campaign_build_id: dryRunResult.campaignBuildId ?? dryRunResult.campaign_build_id ?? null
2221
2390
  }
2222
2391
  ];
2392
+ const learnBackPlan = summarizeCampaignBuilderProofLearnBack(
2393
+ asRecord(asRecord(plan.buildRequest.brainPreflight).learn_back_plan ?? asRecord(plan.brainPreflight).learn_back_plan)
2394
+ );
2223
2395
  return {
2224
2396
  receipt_version: "campaign-agent-proof.v1",
2225
2397
  source: "signaliz.campaignBuilderAgent.proof",
@@ -2242,6 +2414,7 @@ function createCampaignBuilderProofReceipt(plan, result) {
2242
2414
  gates,
2243
2415
  strategy_memory_status: summarizeCampaignBuilderProofStrategyMemory(strategyMemory),
2244
2416
  dry_run_result: summarizeCampaignBuilderProofDryRun(dryRunResult),
2417
+ learn_back_plan: learnBackPlan,
2245
2418
  recommended_next_actions: [
2246
2419
  "Review the plan, approvals, and dry-run result.",
2247
2420
  "Use campaign-agent commit-plan --confirm-write only after review.",
@@ -2452,6 +2625,12 @@ function createCampaignBuilderBuildKit(input = {}) {
2452
2625
  command: `${cliBase} campaign-agent init${strategyFlag}${targetFlag}${localLeadsFlag} --output-file ${shellArg(requestFile)}`,
2453
2626
  safety: "local file only; no MCP calls, credits, provider writes, sender loads, exports, or sends"
2454
2627
  },
2628
+ {
2629
+ id: "memory_kit",
2630
+ label: "Inspect memory readiness and seed runner",
2631
+ command: `${sdkCliBase} campaign-agent memory-kit${strategyFlag}${targetFlag}${localLeadsFlag} --request-file ${shellArg(requestFile)} --json`,
2632
+ safety: "read-only memory readiness packet plus local seed dry-run commands"
2633
+ },
2455
2634
  {
2456
2635
  id: "proof_shortcut",
2457
2636
  label: "Run no-spend campaign-builder proof",
@@ -2546,6 +2725,147 @@ function createCampaignBuilderBuildKit(input = {}) {
2546
2725
  ]
2547
2726
  };
2548
2727
  }
2728
+ function createCampaignBuilderMemoryKit(input = {}) {
2729
+ const requestFile = input.requestFile || "campaign-request.json";
2730
+ const seedManifestFile = input.seedManifestFile || ".gtm-kernel-import-state/campaign-memory-dry-run.json";
2731
+ const cliPackage = input.cliPackage || "@signaliz/cli";
2732
+ const sdkPackage = input.sdkPackage || "@signaliz/sdk";
2733
+ const request = createCampaignBuilderAgentRequestTemplate(input);
2734
+ const strategyTemplate = stringValue(request.strategyTemplate) ?? null;
2735
+ const strategyFlag = strategyTemplate ? ` --strategy-template ${shellArg(strategyTemplate)}` : "";
2736
+ const targetFlag = request.targetCount ? ` --target-count ${request.targetCount}` : "";
2737
+ const localLeadsFlag = request.builtIns?.includes("local_leads") ? " --use-local-leads" : "";
2738
+ const cliBase = `npx ${cliPackage}`;
2739
+ const sdkCliBase = `npx ${sdkPackage}`;
2740
+ const source = campaignBuilderMemoryKitSource(input.source);
2741
+ const workspaceId = input.workspaceId || "your-workspace-id";
2742
+ const brief = request.goal || "Build a strategy-template campaign for the target ICP.";
2743
+ const statusArgs = compact({
2744
+ strategy_template: strategyTemplate,
2745
+ campaign_brief: brief,
2746
+ target_icp: request.icp,
2747
+ include_sources: true,
2748
+ include_samples: false,
2749
+ days: 90,
2750
+ limit: 25
2751
+ });
2752
+ const searchArgs = compact({
2753
+ query: request.memory?.queries?.[0]?.query || brief,
2754
+ layers: ["lead_generation", "email_finding", "email_verification", "company_enrichment", "copy_enrichment"],
2755
+ limit: 10
2756
+ });
2757
+ return {
2758
+ kit_version: "campaign-memory-kit.v1",
2759
+ source: "signaliz.campaignBuilderAgent.memoryKit",
2760
+ read_only: true,
2761
+ no_spend: true,
2762
+ no_provider_writes: true,
2763
+ client_names_allowed: false,
2764
+ request_file: requestFile,
2765
+ seed_manifest_file: seedManifestFile,
2766
+ request,
2767
+ strategy_template: strategyTemplate,
2768
+ operating_playbooks: getCampaignBuilderOperatingPlaybooksForRequest(request).map((playbook) => playbook.slug),
2769
+ memory_sources: source.memorySources,
2770
+ seed_runner: {
2771
+ local_script: "scripts/gtm-kernel/seed-import-runner.mjs",
2772
+ dry_run_command: [
2773
+ "node scripts/gtm-kernel/seed-import-runner.mjs",
2774
+ `--source ${source.seedSource}`,
2775
+ "--dry-run",
2776
+ `--workspace-id ${shellArg(input.workspaceId || "00000000-0000-4000-8000-000000000000")}`,
2777
+ `--manifest ${shellArg(seedManifestFile)}`,
2778
+ "--reset"
2779
+ ].join(" "),
2780
+ verify_manifest_command: source.verifyScript ? `node ${source.verifyScript} ${shellArg(seedManifestFile)}` : null,
2781
+ write_command: `GTM_KERNEL_WORKSPACE_ID=${shellArg(workspaceId)} node scripts/gtm-kernel/seed-import-runner.mjs --source ${source.seedSource} --write`,
2782
+ write_requires: ["SUPABASE_URL", "SUPABASE_SERVICE_ROLE_KEY", "GTM_KERNEL_WORKSPACE_ID", "explicit operator approval"]
2783
+ },
2784
+ cli_commands: [
2785
+ {
2786
+ id: "memory_status",
2787
+ label: "Check strategy memory readiness",
2788
+ command: `${sdkCliBase} gtm strategy-memory${strategyFlag} --brief ${shellArg(brief)} --json`,
2789
+ safety: "read-only MCP memory readiness; no credits, provider writes, sender loads, exports, or sends"
2790
+ },
2791
+ {
2792
+ id: "memory_search",
2793
+ label: "Search ranked campaign memory",
2794
+ command: `${sdkCliBase} gtm memory search --query ${shellArg(String(searchArgs.query || brief))} --limit 10 --json`,
2795
+ safety: "read-only ranked memory lookup"
2796
+ },
2797
+ {
2798
+ id: "seed_dry_run",
2799
+ label: "Dry-run private memory seed import",
2800
+ command: [
2801
+ "node scripts/gtm-kernel/seed-import-runner.mjs",
2802
+ `--source ${source.seedSource}`,
2803
+ "--dry-run",
2804
+ `--workspace-id ${shellArg(input.workspaceId || "00000000-0000-4000-8000-000000000000")}`,
2805
+ `--manifest ${shellArg(seedManifestFile)}`,
2806
+ "--reset"
2807
+ ].join(" "),
2808
+ safety: "local extraction and manifest only; no database writes"
2809
+ },
2810
+ {
2811
+ id: "write_request",
2812
+ label: "Write reusable campaign request JSON",
2813
+ command: `${cliBase} campaign-agent init${strategyFlag}${targetFlag}${localLeadsFlag} --output-file ${shellArg(requestFile)}`,
2814
+ safety: "local file only; no MCP calls, credits, provider writes, sender loads, exports, or sends"
2815
+ },
2816
+ {
2817
+ id: "proof",
2818
+ label: "Run campaign proof after memory check",
2819
+ command: `${cliBase} campaign-agent proof --request-file ${shellArg(requestFile)} --json`,
2820
+ safety: "read-only planning plus forced build_campaign dry-run with confirm_spend=false"
2821
+ }
2822
+ ],
2823
+ mcp_calls: [
2824
+ {
2825
+ id: "strategy_memory_status",
2826
+ tool: "gtm_campaign_strategy_memory_status",
2827
+ arguments: statusArgs,
2828
+ safety: "read-only strategy/workflow memory readiness with sources and no raw samples"
2829
+ },
2830
+ {
2831
+ id: "memory_search",
2832
+ tool: "gtm_memory_search",
2833
+ arguments: searchArgs,
2834
+ safety: "read-only ranked memory lookup"
2835
+ },
2836
+ {
2837
+ id: "campaign_agent_plan",
2838
+ tool: "gtm_campaign_agent_plan",
2839
+ arguments: campaignBuilderBuildKitMcpArgs(request),
2840
+ safety: "read-only campaign-agent plan using built-in Signaliz lanes, memory, Brain, Nango, and BYO routes"
2841
+ },
2842
+ {
2843
+ id: "campaign_agent_proof",
2844
+ tool: "gtm_campaign_agent_proof",
2845
+ arguments: { ...campaignBuilderBuildKitMcpArgs(request), idempotency_key: "campaign-agent-memory-proof-001" },
2846
+ safety: "forces build_campaign dry_run=true and confirm_spend=false after readiness"
2847
+ }
2848
+ ],
2849
+ sdk_example: {
2850
+ language: "typescript",
2851
+ code: campaignBuilderMemoryKitSdkExample(request, seedManifestFile)
2852
+ },
2853
+ privacy: {
2854
+ client_names_allowed: false,
2855
+ notes: [
2856
+ "Use strategy templates, operating playbooks, memory dimensions, and anonymized campaign patterns instead of client names.",
2857
+ "Do not expose raw leads, private replies, domains, secrets, provider payloads, or customer account labels in kit output.",
2858
+ "Seed writes are workspace-private and require explicit operator approval plus Supabase service credentials."
2859
+ ]
2860
+ },
2861
+ next_actions: [
2862
+ "Run memory_status before plan/proof so missing strategy coverage is visible.",
2863
+ `Run seed_dry_run and inspect ${seedManifestFile} before any memory write.`,
2864
+ "Use write_request to save the reusable campaign request, then run proof with no spend.",
2865
+ "Add BYO tools through campaign-agent --custom-tool only after route setup is reviewed."
2866
+ ]
2867
+ };
2868
+ }
2549
2869
  function createCampaignBuilderToolRoute(input) {
2550
2870
  return {
2551
2871
  provider: input.provider ?? "custom_mcp",
@@ -2615,6 +2935,96 @@ function campaignBuilderBuildKitSdkExample(request, requestFile) {
2615
2935
  "}"
2616
2936
  ].join("\n");
2617
2937
  }
2938
+ function campaignBuilderMemoryKitSdkExample(request, seedManifestFile) {
2939
+ const input = {
2940
+ goal: request.goal,
2941
+ strategyTemplate: request.strategyTemplate,
2942
+ targetCount: request.targetCount,
2943
+ builtIns: request.builtIns
2944
+ };
2945
+ return [
2946
+ "import { Signaliz, createCampaignBuilderMemoryKit } from '@signaliz/sdk';",
2947
+ "",
2948
+ `const kit = createCampaignBuilderMemoryKit({ seedManifestFile: ${JSON.stringify(seedManifestFile)}, ...${JSON.stringify(input, null, 2)} });`,
2949
+ "console.log(kit.cli_commands.find((command) => command.id === 'memory_status')?.command);",
2950
+ "",
2951
+ "const signaliz = new Signaliz({ apiKey: process.env.SIGNALIZ_API_KEY! });",
2952
+ "const status = await signaliz.gtm.campaignStrategyMemoryStatus({",
2953
+ " strategyTemplate: kit.request.strategyTemplate,",
2954
+ " campaignBrief: kit.request.goal,",
2955
+ " includeSources: true,",
2956
+ " includeSamples: false,",
2957
+ "});",
2958
+ "",
2959
+ "if (status?.ready === false) {",
2960
+ " throw new Error('Strategy memory is not ready for this campaign request');",
2961
+ "}"
2962
+ ].join("\n");
2963
+ }
2964
+ function campaignBuilderMemoryKitSource(source) {
2965
+ const normalized = normalizeTemplateKey(source || "agency");
2966
+ const catalog = {
2967
+ northStar: {
2968
+ id: "north_star_campaign_builder",
2969
+ label: "North Star campaign-builder acceptance patterns",
2970
+ seed_source: "north-star",
2971
+ scope: "redacted_acceptance_seed_packs",
2972
+ privacy: "redacted aggregate counts, QA gates, and fixture shape only"
2973
+ },
2974
+ agency: {
2975
+ id: "agency_campaign_builder",
2976
+ label: "Agency campaign-builder strategy patterns",
2977
+ seed_source: "agency",
2978
+ scope: "private_strategy_docs",
2979
+ privacy: "workspace-private sanitized docs and abstracted campaign summaries"
2980
+ },
2981
+ workflow: {
2982
+ id: "workflow_pattern_corpus",
2983
+ label: "Workflow and table-build pattern corpus",
2984
+ seed_source: "building-clay",
2985
+ scope: "read_only_workflow_docs",
2986
+ privacy: "sanitized operating model and workflow patterns"
2987
+ },
2988
+ feedback: {
2989
+ id: "campaign_feedback",
2990
+ label: "Campaign feedback and reply patterns",
2991
+ seed_source: "instantly",
2992
+ scope: "workspace_private_feedback",
2993
+ privacy: "aggregate feedback, reply, and sequence performance memory"
2994
+ }
2995
+ };
2996
+ const sourceMap = {
2997
+ agency: "agency",
2998
+ "campaign-builder": "agency",
2999
+ "north-star": "northStar",
3000
+ northstar: "northStar",
3001
+ "campaign-builder-north-star": "northStar",
3002
+ acceptance: "northStar",
3003
+ "strategy-memory": "agency",
3004
+ "workflow-patterns": "workflow",
3005
+ workflow: "workflow",
3006
+ "building-clay": "workflow",
3007
+ clay: "workflow",
3008
+ "instantly-feedback": "feedback",
3009
+ instantly: "feedback",
3010
+ feedback: "feedback",
3011
+ all: "all"
3012
+ };
3013
+ const selected = sourceMap[normalized] || "agency";
3014
+ if (selected === "all") {
3015
+ return {
3016
+ seedSource: "all",
3017
+ verifyScript: null,
3018
+ memorySources: [catalog.northStar, catalog.agency, catalog.workflow, catalog.feedback]
3019
+ };
3020
+ }
3021
+ const item = catalog[selected];
3022
+ return {
3023
+ seedSource: item.seed_source,
3024
+ verifyScript: item.seed_source === "north-star" ? "scripts/gtm-kernel/verify-north-star-import-manifest.mjs" : item.seed_source === "agency" ? "scripts/gtm-kernel/verify-agency-import-manifest.mjs" : item.seed_source === "building-clay" ? "scripts/gtm-kernel/verify-building-clay-import-manifest.mjs" : null,
3025
+ memorySources: [item]
3026
+ };
3027
+ }
2618
3028
  function shellArg(value) {
2619
3029
  return `'${value.replace(/'/g, "'\\''")}'`;
2620
3030
  }
@@ -2791,11 +3201,11 @@ function builtInRoutesFor(request) {
2791
3201
  routes.push({
2792
3202
  id: "signaliz-lead-generation",
2793
3203
  layer: "source",
2794
- gtmLayers: ["find_company", "find_people", "lead_generation"],
3204
+ gtmLayer: "lead_generation",
2795
3205
  provider: "signaliz",
2796
3206
  mode: "required",
2797
3207
  toolName: "generate_leads",
2798
- rationale: "Use Signaliz fresh workspace acquisition as the default source of truth."
3208
+ rationale: "Inventory verified cache first, then use Signaliz fresh workspace acquisition for the remaining approved gap."
2799
3209
  });
2800
3210
  }
2801
3211
  if (builtIns.has("local_leads")) {
@@ -2809,6 +3219,28 @@ function builtInRoutesFor(request) {
2809
3219
  rationale: "Use Signaliz local-leads sourcing for geography-bound local business campaigns."
2810
3220
  });
2811
3221
  }
3222
+ if (builtIns.has("company_discovery")) {
3223
+ routes.push({
3224
+ id: "signaliz-company-discovery",
3225
+ layer: "source",
3226
+ gtmLayer: "find_company",
3227
+ provider: "signaliz",
3228
+ mode: "if_available",
3229
+ toolName: "find_companies_signaliz",
3230
+ rationale: "Find and qualify company domains before people/email fill for account-led campaigns."
3231
+ });
3232
+ }
3233
+ if (builtIns.has("people_discovery")) {
3234
+ routes.push({
3235
+ id: "signaliz-people-discovery",
3236
+ layer: "source",
3237
+ gtmLayer: "find_people",
3238
+ provider: "signaliz",
3239
+ mode: "if_available",
3240
+ toolName: "find_people_signaliz",
3241
+ rationale: "Find people directly when the brief is contact research or LinkedIn-style prospecting."
3242
+ });
3243
+ }
2812
3244
  if (builtIns.has("email_finding")) {
2813
3245
  routes.push({
2814
3246
  id: "signaliz-email-finding",
@@ -2853,7 +3285,7 @@ function normalizeBuiltIns(request) {
2853
3285
  return [...builtIns].filter(isCampaignBuilderBuiltInTool);
2854
3286
  }
2855
3287
  function isCampaignBuilderBuiltInTool(value) {
2856
- return ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"].includes(String(value));
3288
+ return ["lead_generation", "local_leads", "company_discovery", "people_discovery", "email_finding", "email_verification", "signals"].includes(String(value));
2857
3289
  }
2858
3290
  function looksLikeLocalLeadCampaign(request) {
2859
3291
  const text = [
@@ -2908,7 +3340,11 @@ function createBuildRequest(request, defaults, targetCount, campaignName, scopeB
2908
3340
  qualification: defaults.qualification,
2909
3341
  copy: defaults.copy,
2910
3342
  delivery: defaults.delivery,
2911
- enhancers: enhancerConfig(request)
3343
+ enhancers: enhancerConfig(request),
3344
+ sourceRouting: request.sourceRouting ?? {
3345
+ mode: looksLikeLocalLeadCampaign(request) ? "local_leads" : "auto",
3346
+ fillPolicy: "aggressive"
3347
+ }
2912
3348
  };
2913
3349
  const scoped = asRecord(scopeBuildArgs);
2914
3350
  buildRequest.gtmCampaignId = request.gtmCampaignId ?? stringValue(scoped.gtm_campaign_id ?? scoped.gtmCampaignId);
@@ -2990,9 +3426,132 @@ function createBrainPreflight(request, buildRequest, routes, memory) {
2990
3426
  { tool: "gtm_brain_learning_cycle_plan", purpose: "Plan the Brain learning loop for this campaign.", arguments: learningArgs },
2991
3427
  { tool: "gtm_brain_seed_defaults", purpose: "Seed campaign defaults from workspace memory and safe aggregate patterns.", arguments: defaultsArgs },
2992
3428
  { tool: "gtm_brain_delivery_risk", purpose: "Check deliverability risk before launch or external writes.", arguments: riskArgs }
2993
- ]
3429
+ ],
3430
+ learn_back_plan: createCampaignBuilderLearnBackPlan(request, buildRequest)
3431
+ };
3432
+ }
3433
+ function createCampaignBuilderLearnBackPlan(request, buildRequest) {
3434
+ const instantlyFeedbackContext = campaignBuilderProviderFeedbackContext(request, buildRequest, "instantly");
3435
+ const postBuildSequence = [
3436
+ {
3437
+ tool: "get_campaign_build_status",
3438
+ approval_boundary: "read_only",
3439
+ arguments_template: { campaign_build_id: "<build_campaign.campaign_build_id>" },
3440
+ reason: "Wait for the Campaign Builder run to finish before deriving memory."
3441
+ },
3442
+ {
3443
+ tool: "gtm_campaign_build_backfill_preview",
3444
+ approval_boundary: "read_only",
3445
+ arguments_template: { campaign_build_id: "<build_campaign.campaign_build_id>", create_memory: true },
3446
+ reason: "Preview the provider-neutral Kernel import payload without writing rows."
3447
+ },
3448
+ {
3449
+ tool: "gtm_campaign_build_backfill_run",
3450
+ approval_boundary: "dry_run",
3451
+ arguments_template: { campaign_build_ids: ["<build_campaign.campaign_build_id>"], dry_run: true, create_memory: true, run_brain_cycle: false },
3452
+ reason: "Dry-run the Kernel history import before creating campaign memory."
3453
+ },
3454
+ {
3455
+ tool: "gtm_campaign_build_backfill_run",
3456
+ approval_boundary: "explicit_write_approval",
3457
+ arguments_template: { campaign_build_ids: ["<build_campaign.campaign_build_id>"], dry_run: false, create_memory: true, run_brain_cycle: true, brain_cycle_write_mode: "dry_run" },
3458
+ reason: "After review, queue the Kernel history import; Brain learning remains dry-run unless separately approved."
3459
+ }
3460
+ ];
3461
+ if (instantlyFeedbackContext) {
3462
+ postBuildSequence.push({
3463
+ tool: "gtm_instantly_feedback_pull",
3464
+ approval_boundary: "dry_run_first_explicit_write_approval",
3465
+ arguments_template: {
3466
+ campaign_id: buildRequest.gtmCampaignId || "<gtm_campaign_id_after_commit>",
3467
+ campaign_build_id: "<build_campaign.campaign_build_id>",
3468
+ source: "emails",
3469
+ email_type: "received",
3470
+ ...instantlyFeedbackContext,
3471
+ dry_run: true,
3472
+ create_memory: true,
3473
+ write_routine_outcomes: true,
3474
+ run_brain_cycle: true,
3475
+ brain_cycle_write_mode: "dry_run"
3476
+ },
3477
+ reason: "After Instantly delivery has live outcomes, pull reply and bounce history into private feedback memory before Brain learning."
3478
+ });
3479
+ }
3480
+ postBuildSequence.push(
3481
+ {
3482
+ tool: "gtm_campaign_learning_status",
3483
+ approval_boundary: "read_only",
3484
+ arguments_template: {
3485
+ campaign_id: buildRequest.gtmCampaignId || "<gtm_campaign_id_after_commit>",
3486
+ campaign_build_id: "<build_campaign.campaign_build_id>",
3487
+ write_mode: "dry_run"
3488
+ },
3489
+ reason: "Confirm feedback, memory, and Brain learning readiness after the import."
3490
+ },
3491
+ {
3492
+ tool: "gtm_memory_search",
3493
+ approval_boundary: "read_only",
3494
+ arguments_template: {
3495
+ query: request.goal,
3496
+ ...buildRequest.gtmCampaignId ? { campaign_id: buildRequest.gtmCampaignId } : {},
3497
+ limit: 10
3498
+ },
3499
+ reason: "Verify the new private memory is retrievable for future campaign planning."
3500
+ },
3501
+ {
3502
+ tool: "gtm_brain_learning_cycle_plan",
3503
+ approval_boundary: "read_only",
3504
+ arguments_template: {
3505
+ ...buildRequest.gtmCampaignId ? { campaign_id: buildRequest.gtmCampaignId } : {},
3506
+ include_memory: true,
3507
+ write_mode: "dry_run"
3508
+ },
3509
+ reason: "Plan the Brain phases from the imported outcomes before any pattern writes."
3510
+ }
3511
+ );
3512
+ return {
3513
+ source_tool: "campaign-builder-agent",
3514
+ gtm_campaign_id: buildRequest.gtmCampaignId ?? null,
3515
+ trigger: "After build_campaign returns a campaign_build_id and the build reaches a terminal reviewed state.",
3516
+ build_result_placeholders: {
3517
+ campaign_build_id: "<build_campaign.campaign_build_id>"
3518
+ },
3519
+ memory_write_policy: {
3520
+ target_tables: ["gtm_campaigns", "gtm_campaign_provider_links", "gtm_campaign_feedback_events", "gtm_memory_items", "gtm_brain_patterns"],
3521
+ gtm_memory_items: {
3522
+ shareable: false,
3523
+ allowed_redaction_states: ["redacted", "abstracted"],
3524
+ raw_private_fields_withheld: ["reply_text", "copy_body", "lead_email", "lead_domain", "company_domain", "provider_campaign_id", "provider_payload", "webhook_url", "secret"]
3525
+ },
3526
+ gtm_brain_patterns: "Workspace-scoped by default. Global promotion requires abstracted_only=true, shared opt-in, and privacy thresholds."
3527
+ },
3528
+ post_build_sequence: postBuildSequence.map((item, index) => ({ step: index + 1, ...item })),
3529
+ approval_policy: "This agent plan never writes learn-back rows. Backfill and provider-feedback writes require dry_run=false after review, and Brain writes require their own approved learning-cycle run.",
3530
+ privacy_policy: "Learn-back memory is workspace-private. Raw replies, copy bodies, leads, emails, domains, provider payloads, webhook URLs, secrets, private source paths, and raw client labels are withheld from memory rows and agent-visible outputs."
2994
3531
  };
2995
3532
  }
3533
+ function campaignBuilderProviderFeedbackContext(request, buildRequest, provider) {
3534
+ const normalizedProvider = String(provider).toLowerCase();
3535
+ const routes = [...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])];
3536
+ const providerRoute = routes.find((route) => String(route.provider).toLowerCase() === normalizedProvider);
3537
+ const routeConfig = asRecord(providerRoute?.config);
3538
+ const deliveryConfig = asRecord(buildRequest.delivery?.destinationConfig);
3539
+ const hasProviderContext = [
3540
+ ...request.preferredProviders ?? [],
3541
+ ...routes.map((route) => route.provider),
3542
+ stringValue(deliveryConfig.provider),
3543
+ stringValue(deliveryConfig.provider_id ?? deliveryConfig.providerId),
3544
+ stringValue(deliveryConfig.destination_provider ?? deliveryConfig.destinationProvider),
3545
+ stringValue(deliveryConfig.sink ?? deliveryConfig.sink_type ?? deliveryConfig.sinkType)
3546
+ ].some((value) => String(value).toLowerCase() === normalizedProvider);
3547
+ if (!hasProviderContext) return void 0;
3548
+ return compact({
3549
+ provider_link_id: stringValue(routeConfig.provider_link_id ?? routeConfig.providerLinkId ?? deliveryConfig.provider_link_id ?? deliveryConfig.providerLinkId),
3550
+ provider_campaign_id: stringValue(routeConfig.provider_campaign_id ?? routeConfig.providerCampaignId ?? routeConfig.instantly_campaign_id ?? routeConfig.instantlyCampaignId ?? deliveryConfig.provider_campaign_id ?? deliveryConfig.providerCampaignId ?? deliveryConfig.instantly_campaign_id ?? deliveryConfig.instantlyCampaignId),
3551
+ integration_id: stringValue(routeConfig.integration_id ?? routeConfig.integrationId ?? deliveryConfig.integration_id ?? deliveryConfig.integrationId),
3552
+ instantly_profile: stringValue(routeConfig.instantly_profile ?? routeConfig.instantlyProfile ?? routeConfig.profile ?? deliveryConfig.instantly_profile ?? deliveryConfig.instantlyProfile ?? deliveryConfig.profile)
3553
+ });
3554
+ }
2996
3555
  function gtmLayersForBuilderLayer(layer) {
2997
3556
  const map = {
2998
3557
  workspace_context: ["customer_data"],
@@ -3397,6 +3956,7 @@ function buildFallbackPlanSnapshot(plan) {
3397
3956
  target_count: plan.targetCount,
3398
3957
  approvals: plan.approvals,
3399
3958
  brain_preflight: plan.brainPreflight,
3959
+ campaign_strategy_context: plan.buildRequest.campaignStrategyContext,
3400
3960
  operating_playbooks: plan.operatingPlaybooks
3401
3961
  });
3402
3962
  }
@@ -3529,6 +4089,7 @@ function buildCampaignArgs(request) {
3529
4089
  if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
3530
4090
  if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
3531
4091
  if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
4092
+ if (request.campaignStrategyContext) args.campaign_strategy_context = request.campaignStrategyContext;
3532
4093
  if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
3533
4094
  if (request.icp) {
3534
4095
  args.icp = compact({
@@ -3548,6 +4109,15 @@ function buildCampaignArgs(request) {
3548
4109
  model: request.policy.model
3549
4110
  });
3550
4111
  }
4112
+ if (request.sourceRouting) {
4113
+ args.source_routing = compact({
4114
+ mode: request.sourceRouting.mode,
4115
+ fill_policy: request.sourceRouting.fillPolicy,
4116
+ shard_size: request.sourceRouting.shardSize,
4117
+ max_source_shard_size: request.sourceRouting.maxSourceShardSize,
4118
+ max_local_source_shard_size: request.sourceRouting.maxLocalSourceShardSize
4119
+ });
4120
+ }
3551
4121
  if (request.signals) {
3552
4122
  args.signals = compact({
3553
4123
  enabled: request.signals.enabled,
@@ -3619,7 +4189,8 @@ function buildExecutionPrepareArgs(request, dryRun, confirmSpend) {
3619
4189
  qualification: buildArgs2.qualification,
3620
4190
  copy: buildArgs2.copy,
3621
4191
  delivery: buildArgs2.delivery,
3622
- enhancers: buildArgs2.enhancers
4192
+ enhancers: buildArgs2.enhancers,
4193
+ source_routing: buildArgs2.source_routing
3623
4194
  });
3624
4195
  }
3625
4196
  function buildDeliveryApprovalArgs(request) {
@@ -3668,17 +4239,62 @@ function mapAgentCampaignBuildStatus(data) {
3668
4239
  warnings: diagnosticMessages2(data.warnings),
3669
4240
  errors: diagnosticMessages2(data.errors),
3670
4241
  artifactCount: numberOrUndefined2(data.artifact_count) ?? 0,
4242
+ artifactDownloads: Array.isArray(data.artifact_downloads) ? data.artifact_downloads.map(mapAgentCampaignArtifactDownload) : [],
4243
+ customerRowCounts: mapAgentCustomerRowCounts(data.customer_row_counts),
4244
+ phaseAttemptTotals: nullableRecord(data.phase_attempt_totals) ?? void 0,
3671
4245
  providerRoute: mapProviderRoute2(data),
3672
4246
  triggerRunId: stringValue(data.trigger_run_id) ?? null,
3673
4247
  staleRunningPhase: data.stale_running_phase === true,
3674
4248
  phaseAgeSeconds: numberOrNull2(data.phase_age_seconds),
3675
4249
  diagnostics: nullableRecord(data.diagnostics) ?? {},
3676
4250
  nextAction: formatAgentNextAction(data.next_action),
4251
+ approvalAction: formatAgentNextAction(data.approval_action),
3677
4252
  createdAt: stringValue(data.created_at) ?? "",
3678
4253
  updatedAt: stringValue(data.updated_at) ?? "",
3679
4254
  completedAt: stringValue(data.completed_at) ?? null
3680
4255
  };
3681
4256
  }
4257
+ function mapAgentCampaignArtifactDownload(data) {
4258
+ return {
4259
+ id: stringValue(data.id) ?? "",
4260
+ artifactType: stringValue(data.artifact_type) ?? null,
4261
+ format: stringValue(data.format) ?? null,
4262
+ rowCount: numberOrUndefined2(data.row_count) ?? 0,
4263
+ signedUrl: stringValue(data.signed_url) ?? null,
4264
+ downloadUrl: stringValue(data.download_url) ?? null,
4265
+ manifestUrl: stringValue(data.manifest_url) ?? null,
4266
+ expiresAt: stringValue(data.expires_at) ?? null
4267
+ };
4268
+ }
4269
+ function mapAgentCustomerRowCounts(value) {
4270
+ const record = nullableRecord(value);
4271
+ if (!record) return void 0;
4272
+ return {
4273
+ requestedTarget: numberOrNull2(record.requested_target),
4274
+ acquiredRows: numberOrUndefined2(record.acquired_rows),
4275
+ acceptedRows: numberOrUndefined2(record.accepted_rows),
4276
+ usableRows: numberOrUndefined2(record.usable_rows),
4277
+ copiedRows: numberOrUndefined2(record.copied_rows),
4278
+ approvalReadyRows: numberOrUndefined2(record.approval_ready_rows),
4279
+ qaReadyRows: numberOrUndefined2(record.qa_ready_rows),
4280
+ deliveredRows: numberOrUndefined2(record.delivered_rows),
4281
+ disqualifiedRows: numberOrUndefined2(record.disqualified_rows),
4282
+ reviewableRows: numberOrUndefined2(record.reviewable_rows),
4283
+ rowFailures: numberOrUndefined2(record.row_failures),
4284
+ acceptedShortfall: numberOrNull2(record.accepted_shortfall),
4285
+ usableShortfall: numberOrNull2(record.usable_shortfall),
4286
+ qaReadyShortfall: numberOrNull2(record.qa_ready_shortfall),
4287
+ deliveryShortfall: numberOrNull2(record.delivery_shortfall),
4288
+ fillRatio: numberOrNull2(record.fill_ratio),
4289
+ qaReadyFillRatio: numberOrNull2(record.qa_ready_fill_ratio),
4290
+ deliveredFillRatio: numberOrNull2(record.delivered_fill_ratio),
4291
+ terminalReason: stringValue(record.terminal_reason) ?? null,
4292
+ acceptedShortfallReason: stringValue(record.accepted_shortfall_reason) ?? null,
4293
+ usableShortfallReason: stringValue(record.usable_shortfall_reason) ?? null,
4294
+ qaReadyShortfallReason: stringValue(record.qa_ready_shortfall_reason) ?? null,
4295
+ deliveryShortfallReason: stringValue(record.delivery_shortfall_reason) ?? null
4296
+ };
4297
+ }
3682
4298
  function mapAgentCampaignRowsResult(data) {
3683
4299
  const rows = Array.isArray(data.rows) ? data.rows : [];
3684
4300
  return {
@@ -3706,7 +4322,11 @@ function mapAgentCampaignArtifact(data) {
3706
4322
  artifactType: stringValue(data.artifact_type) ?? "",
3707
4323
  destination: stringValue(data.destination) ?? "",
3708
4324
  storagePath: stringValue(data.storage_path) ?? "",
4325
+ format: stringValue(data.format) ?? null,
3709
4326
  signedUrl: stringValue(data.signed_url) ?? null,
4327
+ downloadUrl: stringValue(data.download_url) ?? null,
4328
+ manifestUrl: stringValue(data.manifest_url) ?? null,
4329
+ expiresAt: stringValue(data.expires_at) ?? null,
3710
4330
  rowCount: numberOrUndefined2(data.row_count) ?? 0,
3711
4331
  checksum: stringValue(data.checksum) ?? null,
3712
4332
  metadata: nullableRecord(data.metadata) ?? {},
@@ -3868,6 +4488,8 @@ function readinessLaneLabel(route, builtIn) {
3868
4488
  const labels = {
3869
4489
  lead_generation: "Signaliz lead generation",
3870
4490
  local_leads: "Signaliz local leads",
4491
+ company_discovery: "Signaliz company discovery",
4492
+ people_discovery: "Signaliz people discovery",
3871
4493
  email_finding: "Signaliz email finding",
3872
4494
  email_verification: "Signaliz email verification",
3873
4495
  signals: "Signaliz signals"
@@ -3952,6 +4574,35 @@ function summarizeCampaignBuilderProofDryRun(dryRunResult) {
3952
4574
  plannedTargetCount: dryRunResult.plannedTargetCount ?? dryRunResult.planned_target_count ?? null
3953
4575
  };
3954
4576
  }
4577
+ function summarizeCampaignBuilderProofLearnBack(plan) {
4578
+ if (Object.keys(plan).length === 0) return { ready: false };
4579
+ const memoryPolicy = asRecord(plan.memory_write_policy);
4580
+ const memoryItemsPolicy = asRecord(memoryPolicy.gtm_memory_items);
4581
+ const sequence = Array.isArray(plan.post_build_sequence) ? plan.post_build_sequence.map((step) => {
4582
+ const record = asRecord(step);
4583
+ return compact({
4584
+ step: record.step,
4585
+ tool: stringValue(record.tool),
4586
+ approval_boundary: stringValue(record.approval_boundary),
4587
+ reason: stringValue(record.reason)
4588
+ });
4589
+ }).filter((step) => typeof step.tool === "string") : [];
4590
+ return {
4591
+ ready: sequence.length > 0,
4592
+ source_tool: firstNonEmptyString(plan.source_tool, plan.sourceTool),
4593
+ post_build_sequence: sequence,
4594
+ memory_write_policy: {
4595
+ target_tables: Array.isArray(memoryPolicy.target_tables) ? memoryPolicy.target_tables : [],
4596
+ gtm_memory_items: {
4597
+ shareable: memoryItemsPolicy.shareable === false ? false : memoryItemsPolicy.shareable ?? null,
4598
+ allowed_redaction_states: Array.isArray(memoryItemsPolicy.allowed_redaction_states) ? memoryItemsPolicy.allowed_redaction_states : [],
4599
+ raw_private_fields_withheld: Array.isArray(memoryItemsPolicy.raw_private_fields_withheld) ? memoryItemsPolicy.raw_private_fields_withheld : []
4600
+ }
4601
+ },
4602
+ approval_policy: firstNonEmptyString(plan.approval_policy, plan.approvalPolicy),
4603
+ privacy_policy: firstNonEmptyString(plan.privacy_policy, plan.privacyPolicy)
4604
+ };
4605
+ }
3955
4606
  function firstNonEmptyString(...values) {
3956
4607
  for (const value of values) {
3957
4608
  if (typeof value === "string" && value.trim()) return value;
@@ -4434,14 +5085,87 @@ var Ops = class {
4434
5085
  const body = typeof params === "string" ? { prompt: params } : buildOpsCreateBody(params);
4435
5086
  return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_create", body)));
4436
5087
  }
5088
+ async schedule(params) {
5089
+ const createBody = typeof params === "string" ? { prompt: params, cadence: "daily" } : { ...buildOpsCreateBody(params), cadence: params.cadence ?? "daily" };
5090
+ const { activate: _activate, ...body } = createBody;
5091
+ return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_schedule", body)));
5092
+ }
5093
+ async scheduleAndWait(params) {
5094
+ const options = typeof params === "string" ? { schedule: { prompt: params, cadence: "daily" }, run: {}, wait: {} } : buildOpsScheduleAndWaitOptions(params);
5095
+ const raw = await this.call("ops_schedule_and_wait", buildOpsScheduleAndWaitBody(options));
5096
+ return normalizeOpsScheduleAndWaitCallResult(raw, options.wait, {
5097
+ approvalMessage: "ops.scheduleAndWait requires an approved schedulable Op. Retry with confirmSpend=true after reviewing approval details.",
5098
+ notCreatedMessage: "ops.scheduleAndWait requires ops_schedule_and_wait to create an op_id. Use ops.schedule for approval review flows."
5099
+ });
5100
+ }
5101
+ /** Schedule a recurring Op that delivers through a customer-owned Nango API connection. */
5102
+ async scheduleNangoAction(input) {
5103
+ return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_nango_schedule", buildOpsNangoScheduleBody(input))));
5104
+ }
5105
+ /** Schedule a recurring Nango-backed Op, run the first tick, and return result readback. */
5106
+ async scheduleNangoActionAndWait(input) {
5107
+ const options = buildOpsNangoScheduleAndWaitOptions(input);
5108
+ const raw = await this.call("ops_nango_schedule_and_wait", buildOpsNangoScheduleAndWaitBody(options));
5109
+ return normalizeOpsScheduleAndWaitCallResult(raw, options.wait, {
5110
+ approvalMessage: "ops.scheduleNangoActionAndWait requires an approved Nango-backed Op. Retry with confirmSpend=true after reviewing approval details.",
5111
+ notCreatedMessage: "ops.scheduleNangoActionAndWait requires ops_nango_schedule_and_wait to create an op_id. Use ops.scheduleNangoAction for approval review flows."
5112
+ });
5113
+ }
4437
5114
  async execute(params) {
4438
5115
  const body = typeof params === "string" ? { prompt: params } : buildOpsExecuteBody(params);
4439
5116
  return normalizeOpsExecuteResult(withExecutionRefs(await this.call("ops_execute", body)));
4440
5117
  }
5118
+ async executeAndWait(params) {
5119
+ const options = typeof params === "string" ? { execute: { prompt: params, auto_run: true }, wait: {} } : buildOpsExecuteAndWaitOptions(params);
5120
+ const execute = await this.execute(options.execute);
5121
+ if (execute.approval_required || execute.error_code === "APPROVAL_REQUIRED") {
5122
+ throw new SignalizError({
5123
+ code: "APPROVAL_REQUIRED",
5124
+ errorType: "validation",
5125
+ message: "ops.executeAndWait requires an approved executable Op. Retry with confirmSpend=true after reviewing approval details.",
5126
+ details: { execute }
5127
+ });
5128
+ }
5129
+ if (!execute.op_id) {
5130
+ throw new SignalizError({
5131
+ code: "OP_NOT_CREATED",
5132
+ errorType: "validation",
5133
+ message: "ops.executeAndWait requires ops_execute to create an op_id. Use ops.execute for dry runs or approval review flows.",
5134
+ details: { execute }
5135
+ });
5136
+ }
5137
+ const waited = await this.waitForResults({
5138
+ ...options.wait,
5139
+ op_id: execute.op_id
5140
+ });
5141
+ const runId = execute.run_id ?? execute.runId ?? waited.status.run_id ?? waited.status.runId ?? null;
5142
+ return {
5143
+ ...waited,
5144
+ execute,
5145
+ run_id: runId,
5146
+ runId,
5147
+ execution_refs: mergeExecutionRefsFrom([execute, waited])
5148
+ };
5149
+ }
4441
5150
  async run(params) {
4442
5151
  const body = typeof params === "string" ? { op_id: params } : buildOpsRunBody(params);
4443
5152
  return normalizeOpsRunResult(withExecutionRefs(await this.call("ops_run", body)));
4444
5153
  }
5154
+ async runAndWait(params) {
5155
+ const options = typeof params === "string" ? { op_id: params } : buildOpsRunAndWaitOptions(params);
5156
+ if (!options.op_id) throw new Error("ops.runAndWait requires op_id or opId");
5157
+ const run = await this.run({
5158
+ op_id: options.op_id,
5159
+ instruction: options.instruction,
5160
+ force: options.force
5161
+ });
5162
+ const waited = await this.waitForResults(options);
5163
+ return {
5164
+ ...waited,
5165
+ run,
5166
+ execution_refs: mergeExecutionRefsFrom([run, waited])
5167
+ };
5168
+ }
4445
5169
  async status(params) {
4446
5170
  const body = typeof params === "string" ? { op_id: params } : buildOpsStatusBody(params);
4447
5171
  return normalizeOpsStatusResult(withExecutionRefs(await this.call("ops_status", body)));
@@ -4450,77 +5174,250 @@ var Ops = class {
4450
5174
  const body = typeof params === "string" ? { op_id: params } : buildOpsResultsBody(params);
4451
5175
  return normalizeOpsResultsResult(withExecutionRefs(await this.call("ops_results", body)));
4452
5176
  }
4453
- async proof(params = {}) {
4454
- const data = await this.call("ops_proof", {
4455
- window_hours: params.windowHours,
4456
- output_format: "json"
5177
+ async waitForResults(params) {
5178
+ const options = typeof params === "string" ? { op_id: params } : buildOpsWaitForResultsOptions(params);
5179
+ if (!options.op_id) throw new Error("ops.waitForResults requires op_id or opId");
5180
+ const waitResult = await this.call("ops_wait", buildOpsWaitBody(options));
5181
+ return normalizeOpsWaitForResultsResult(waitResult, options);
5182
+ }
5183
+ /** Create a short-lived Nango Connect session from the Ops namespace. */
5184
+ async createNangoConnectSession(input) {
5185
+ return this.call("nango_connect_session_create", {
5186
+ provider_id: input.providerId,
5187
+ integration_id: input.integrationId,
5188
+ provider_display_name: input.providerDisplayName,
5189
+ integration_display_name: input.integrationDisplayName,
5190
+ allowed_integrations: input.allowedIntegrations,
5191
+ surface: input.surface,
5192
+ source: input.source,
5193
+ user_email: input.userEmail,
5194
+ user_display_name: input.userDisplayName
4457
5195
  });
4458
- return normalizeOpsProofResult(data);
4459
5196
  }
4460
- async debug(params) {
4461
- const options = typeof params === "string" ? { op_id: params } : buildOpsDebugOptions(params);
4462
- const diagnosticErrors = [];
4463
- const status = await this.status(options.op_id);
4464
- const refs = /* @__PURE__ */ new Map();
4465
- const addRefs = (items) => {
4466
- for (const ref of items ?? []) refs.set(`${ref.kind}:${ref.id}`, ref);
4467
- };
4468
- const recordError = (step, err) => {
4469
- diagnosticErrors.push({
4470
- step,
4471
- message: err instanceof Error ? err.message : String(err)
4472
- });
4473
- };
4474
- addRefs(status.execution_refs);
4475
- if (status.latest_run && typeof status.latest_run === "object") {
4476
- addRefs(collectExecutionReferences(status.latest_run));
4477
- }
4478
- const runRefs = Array.from(refs.values()).filter((ref) => ref.kind === "trigger_run" || ref.kind === "dataplane_run" || ref.kind === "replay_run");
4479
- const runStatuses = [];
4480
- for (const ref of runRefs) {
4481
- try {
4482
- const result = await this.getTriggerRunStatus(ref.id);
4483
- const runs = "runs" in result ? result.runs : [result];
4484
- runStatuses.push(...runs);
4485
- for (const run of runs) addRefs(run.execution_refs);
4486
- } catch (err) {
4487
- recordError(`run-status:${ref.id}`, err);
4488
- }
5197
+ /** Prepare the full Nango provider search, connect, pull/export, Ops, and route flow. */
5198
+ async prepareNangoIntegrationFlow(input = {}) {
5199
+ return this.call("nango_integration_flow_prepare", {
5200
+ query: input.query,
5201
+ search: input.search,
5202
+ provider_id: input.providerId,
5203
+ provider: input.provider,
5204
+ integration_id: input.integrationId,
5205
+ provider_config_key: input.providerConfigKey,
5206
+ workspace_connection_id: input.workspaceConnectionId,
5207
+ connection_id: input.connectionId,
5208
+ nango_connection_id: input.nangoConnectionId,
5209
+ intent: input.intent,
5210
+ action_name: input.actionName,
5211
+ tool_name: input.toolName,
5212
+ proxy_path: input.proxyPath,
5213
+ method: input.method,
5214
+ input: input.input,
5215
+ cadence: input.cadence,
5216
+ field_map: input.fieldMap,
5217
+ required_fields: input.requiredFields,
5218
+ confirm_spend: input.confirmSpend,
5219
+ write_confirmed: input.writeConfirmed,
5220
+ layer: input.layer,
5221
+ campaign_id: input.campaignId,
5222
+ limit: input.limit,
5223
+ include_provider_catalog: input.includeProviderCatalog
5224
+ });
5225
+ }
5226
+ /** List Nango-backed action tools for a workspace connection without executing them. */
5227
+ async listNangoTools(options = {}) {
5228
+ return this.call("nango_mcp_tools_list", {
5229
+ workspace_connection_id: options.workspaceConnectionId,
5230
+ connection_id: options.connectionId,
5231
+ provider_config_key: options.providerConfigKey,
5232
+ integration_id: options.integrationId,
5233
+ nango_connection_id: options.nangoConnectionId,
5234
+ format: options.format,
5235
+ include_raw: options.includeRaw
5236
+ });
5237
+ }
5238
+ /** Audit connected Nango rows, action/proxy readiness, and read/write proof gaps. */
5239
+ async proveNangoReadWrite(options = {}) {
5240
+ return this.call("nango_mcp_read_write_audit", {
5241
+ workspace_connection_id: options.workspaceConnectionId,
5242
+ connection_id: options.connectionId,
5243
+ provider_config_key: options.providerConfigKey,
5244
+ integration_id: options.integrationId,
5245
+ nango_connection_id: options.nangoConnectionId,
5246
+ limit: options.limit,
5247
+ include_raw: options.includeRaw,
5248
+ read_proxy_path: options.readProxyPath,
5249
+ write_proxy_path: options.writeProxyPath,
5250
+ method: options.method,
5251
+ execute_read_probe: options.executeReadProbe,
5252
+ execute_write_probe: options.executeWriteProbe,
5253
+ confirm: options.confirm,
5254
+ confirm_write: options.confirmWrite,
5255
+ input: options.input,
5256
+ write_input: options.writeInput
5257
+ });
5258
+ }
5259
+ /** Dry-run or execute a Nango-backed action tool through the approval-aware MCP bridge. */
5260
+ async callNangoTool(input) {
5261
+ return this.call("nango_mcp_tool_call", {
5262
+ workspace_connection_id: input.workspaceConnectionId,
5263
+ connection_id: input.connectionId,
5264
+ provider_config_key: input.providerConfigKey,
5265
+ integration_id: input.integrationId,
5266
+ nango_connection_id: input.nangoConnectionId,
5267
+ action_name: input.actionName,
5268
+ tool_name: input.toolName,
5269
+ delivery_mode: input.deliveryMode,
5270
+ proxy_path: input.proxyPath,
5271
+ nango_proxy_path: input.nangoProxyPath,
5272
+ method: input.method,
5273
+ http_method: input.httpMethod,
5274
+ proxy_headers: input.proxyHeaders,
5275
+ input: input.input,
5276
+ async: input.async,
5277
+ max_retries: input.maxRetries,
5278
+ dry_run: input.dryRun,
5279
+ confirm: input.confirm,
5280
+ confirm_write: input.confirmWrite
5281
+ });
5282
+ }
5283
+ /** Execute a Nango action and poll its async result when a status URL/action id is returned. */
5284
+ async callNangoToolAndWait(input) {
5285
+ const result = await this.call("nango_mcp_tool_call_and_wait", {
5286
+ workspace_connection_id: input.workspaceConnectionId,
5287
+ connection_id: input.connectionId,
5288
+ provider_config_key: input.providerConfigKey,
5289
+ integration_id: input.integrationId,
5290
+ nango_connection_id: input.nangoConnectionId,
5291
+ action_name: input.actionName,
5292
+ tool_name: input.toolName,
5293
+ delivery_mode: input.deliveryMode,
5294
+ proxy_path: input.proxyPath,
5295
+ nango_proxy_path: input.nangoProxyPath,
5296
+ method: input.method,
5297
+ http_method: input.httpMethod,
5298
+ proxy_headers: input.proxyHeaders,
5299
+ input: input.input,
5300
+ async: input.async ?? true,
5301
+ max_retries: input.maxRetries,
5302
+ dry_run: input.dryRun,
5303
+ confirm: input.confirm,
5304
+ confirm_write: input.confirmWrite,
5305
+ interval_ms: input.intervalMs,
5306
+ max_polls: input.maxPolls,
5307
+ timeout_ms: input.timeoutMs
5308
+ });
5309
+ const packet = asRecord2(result);
5310
+ const actionId = optionalString(packet.actionId) ?? optionalString(packet.action_id);
5311
+ const statusUrl = optionalString(packet.statusUrl) ?? optionalString(packet.status_url);
5312
+ const maxPolls = Number(packet.maxPolls ?? packet.max_polls ?? 0);
5313
+ const intervalMs = Number(packet.intervalMs ?? packet.interval_ms ?? 0);
5314
+ const timeoutMs = Number(packet.timeoutMs ?? packet.timeout_ms ?? 0);
5315
+ const timedOut = Boolean(packet.timedOut ?? packet.timed_out);
5316
+ return {
5317
+ ...packet,
5318
+ success: typeof packet.success === "boolean" ? packet.success : void 0,
5319
+ call: packet.call,
5320
+ result: packet.result,
5321
+ status: optionalString(packet.status),
5322
+ action_id: actionId,
5323
+ actionId,
5324
+ status_url: statusUrl,
5325
+ statusUrl,
5326
+ polls: Number(packet.polls ?? 0),
5327
+ max_polls: maxPolls,
5328
+ maxPolls,
5329
+ interval_ms: intervalMs,
5330
+ intervalMs,
5331
+ timeout_ms: timeoutMs,
5332
+ timeoutMs,
5333
+ timed_out: timedOut,
5334
+ timedOut
5335
+ };
5336
+ }
5337
+ /** Poll an async Nango action result by action id or status URL. */
5338
+ async getNangoActionResult(input) {
5339
+ return this.call("nango_mcp_action_result_get", {
5340
+ action_id: input.actionId,
5341
+ status_url: input.statusUrl
5342
+ });
5343
+ }
5344
+ async proof(params = {}) {
5345
+ const data = await this.call("ops_proof", {
5346
+ window_hours: params.windowHours,
5347
+ output_format: "json"
5348
+ });
5349
+ return normalizeOpsProofResult(data);
5350
+ }
5351
+ async debug(params) {
5352
+ const options = typeof params === "string" ? { op_id: params } : buildOpsDebugOptions(params);
5353
+ const diagnosticErrors = [];
5354
+ const status = await this.status(options.op_id);
5355
+ const refs = /* @__PURE__ */ new Map();
5356
+ const addRefs = (items) => {
5357
+ for (const ref of items ?? []) refs.set(`${ref.kind}:${ref.id}`, ref);
5358
+ };
5359
+ const recordError = (step, err) => {
5360
+ diagnosticErrors.push({
5361
+ step,
5362
+ message: err instanceof Error ? err.message : String(err)
5363
+ });
5364
+ };
5365
+ addRefs(status.execution_refs);
5366
+ if (status.latest_run && typeof status.latest_run === "object") {
5367
+ addRefs(collectExecutionReferences(status.latest_run));
4489
5368
  }
5369
+ const runRefs = Array.from(refs.values()).filter((ref) => ref.kind === "trigger_run" || ref.kind === "dataplane_run" || ref.kind === "replay_run");
5370
+ let runStatuses = [];
4490
5371
  let queue;
4491
- if (options.include_queue !== false) {
4492
- try {
4493
- queue = await this.getQueueStatus({ summary: true });
4494
- addRefs(queue.execution_refs);
4495
- } catch (err) {
4496
- recordError("queue", err);
4497
- }
4498
- }
4499
5372
  let dashboardRecent;
4500
- if (options.include_dashboard !== false) {
4501
- try {
4502
- dashboardRecent = await this.getDashboard({
4503
- section: "recent",
4504
- limit: options.dashboard_limit ?? 10,
4505
- timeRangeDays: options.time_range_days
4506
- });
4507
- } catch (err) {
4508
- recordError("dashboard:recent", err);
4509
- }
4510
- }
4511
5373
  let results;
4512
- if (options.include_results) {
4513
- try {
4514
- results = await this.results({
4515
- op_id: options.op_id,
4516
- limit: options.results_limit ?? 25,
4517
- include_failed_runs: true
4518
- });
4519
- addRefs(results.execution_refs);
4520
- } catch (err) {
4521
- recordError("results", err);
4522
- }
4523
- }
5374
+ await Promise.all([
5375
+ (async () => {
5376
+ if (runRefs.length === 0) return;
5377
+ try {
5378
+ const result = await this.getTriggerRunStatus({ run_ids: runRefs.map((ref) => ref.id) });
5379
+ const runs = "runs" in result ? result.runs : [result];
5380
+ runStatuses = runs;
5381
+ for (const run of runs) addRefs(run.execution_refs);
5382
+ } catch (err) {
5383
+ recordError(runRefs.length === 1 ? `run-status:${runRefs[0].id}` : "run-status:batch", err);
5384
+ }
5385
+ })(),
5386
+ (async () => {
5387
+ if (options.include_queue === false) return;
5388
+ try {
5389
+ queue = await this.getQueueStatus({ summary: true });
5390
+ addRefs(queue.execution_refs);
5391
+ } catch (err) {
5392
+ recordError("queue", err);
5393
+ }
5394
+ })(),
5395
+ (async () => {
5396
+ if (options.include_dashboard === false) return;
5397
+ try {
5398
+ dashboardRecent = await this.getDashboard({
5399
+ section: "recent",
5400
+ limit: options.dashboard_limit ?? 10,
5401
+ timeRangeDays: options.time_range_days
5402
+ });
5403
+ } catch (err) {
5404
+ recordError("dashboard:recent", err);
5405
+ }
5406
+ })(),
5407
+ (async () => {
5408
+ if (!options.include_results) return;
5409
+ try {
5410
+ results = await this.results({
5411
+ op_id: options.op_id,
5412
+ limit: options.results_limit ?? 25,
5413
+ include_failed_runs: true
5414
+ });
5415
+ addRefs(results.execution_refs);
5416
+ } catch (err) {
5417
+ recordError("results", err);
5418
+ }
5419
+ })()
5420
+ ]);
4524
5421
  const executionRefs = Array.from(refs.values());
4525
5422
  const replayCandidates = executionRefs.filter((ref) => ref.kind === "execution_event");
4526
5423
  const nextActions = buildDebugNextActions(status, executionRefs, diagnosticErrors);
@@ -4722,6 +5619,69 @@ function mergeExecutionRefs(result) {
4722
5619
  for (const ref of collectExecutionReferences(result)) add(ref);
4723
5620
  return Array.from(refs.values());
4724
5621
  }
5622
+ function mergeExecutionRefsFrom(results) {
5623
+ const refs = /* @__PURE__ */ new Map();
5624
+ for (const result of results) {
5625
+ if (!result) continue;
5626
+ for (const ref of mergeExecutionRefs(result)) refs.set(`${ref.kind}:${ref.id}`, ref);
5627
+ }
5628
+ return Array.from(refs.values());
5629
+ }
5630
+ function normalizeOpsScheduleAndWaitCallResult(raw, waitOptions, messages) {
5631
+ if (raw.approval_required || raw.approvalRequired || raw.error_code === "APPROVAL_REQUIRED" || raw.errorCode === "APPROVAL_REQUIRED") {
5632
+ throw new SignalizError({
5633
+ code: "APPROVAL_REQUIRED",
5634
+ errorType: "validation",
5635
+ message: messages.approvalMessage,
5636
+ details: { schedule: raw }
5637
+ });
5638
+ }
5639
+ const opId = stringValue2(raw.op_id ?? raw.opId);
5640
+ if (!opId) {
5641
+ throw new SignalizError({
5642
+ code: "OP_NOT_CREATED",
5643
+ errorType: "validation",
5644
+ message: messages.notCreatedMessage,
5645
+ details: { schedule: raw }
5646
+ });
5647
+ }
5648
+ const scheduleRaw = asRecord2(raw.schedule ?? raw.schedule_result ?? raw.scheduleResult);
5649
+ const runRaw = asRecord2(raw.run ?? raw.run_result ?? raw.runResult);
5650
+ const schedule = normalizeOpsCreateResult(withExecutionRefs(
5651
+ Object.keys(scheduleRaw).length > 0 ? scheduleRaw : {
5652
+ ...raw,
5653
+ op_id: opId,
5654
+ routine_id: raw.routine_id ?? raw.routineId ?? opId,
5655
+ status: "ready",
5656
+ phase: "scheduled",
5657
+ next_action: raw.next_action ?? raw.nextAction
5658
+ }
5659
+ ));
5660
+ const run = normalizeOpsRunResult(withExecutionRefs(
5661
+ Object.keys(runRaw).length > 0 ? runRaw : {
5662
+ success: raw.success !== false,
5663
+ op_id: opId,
5664
+ routine_id: raw.routine_id ?? raw.routineId ?? opId,
5665
+ run_id: raw.run_id ?? raw.runId ?? null,
5666
+ status: "running",
5667
+ phase: "queued",
5668
+ next_action: raw.next_action ?? raw.nextAction,
5669
+ results_count: 0,
5670
+ results_url: raw.results_url ?? raw.resultsUrl,
5671
+ delivery_status: raw.delivery_status ?? raw.deliveryStatus
5672
+ }
5673
+ ));
5674
+ const waited = normalizeOpsWaitForResultsResult(raw, { ...waitOptions, op_id: opId });
5675
+ const runId = run.run_id ?? run.runId ?? waited.run_id ?? waited.runId ?? waited.status.run_id ?? waited.status.runId ?? null;
5676
+ return {
5677
+ ...waited,
5678
+ schedule,
5679
+ run,
5680
+ run_id: runId,
5681
+ runId,
5682
+ execution_refs: mergeExecutionRefsFrom([schedule, run, waited])
5683
+ };
5684
+ }
4725
5685
  function normalizeOpsPrimitiveRetryPolicy(policy = {}) {
4726
5686
  return {
4727
5687
  ...policy,
@@ -4797,8 +5757,122 @@ function normalizeOpsPrimitive(primitive) {
4797
5757
  observability: normalizeOpsPrimitiveObservabilityPolicy(primitive.observability)
4798
5758
  };
4799
5759
  }
5760
+ function normalizeOpsExecutionToolCall(rawCall) {
5761
+ const call = asRecord2(rawCall);
5762
+ return {
5763
+ ...call,
5764
+ tool: stringValue2(call.tool),
5765
+ arguments: asRecord2(call.arguments),
5766
+ purpose: stringValue2(call.purpose)
5767
+ };
5768
+ }
5769
+ function normalizeOpsExecutionScheduleContract(rawSchedule) {
5770
+ const schedule = asRecord2(rawSchedule);
5771
+ const wakeOnEvents = Array.isArray(schedule.wake_on_events) ? schedule.wake_on_events.map(String) : Array.isArray(schedule.wakeOnEvents) ? schedule.wakeOnEvents.map(String) : [];
5772
+ return {
5773
+ ...schedule,
5774
+ create_tool: stringValue2(schedule.create_tool ?? schedule.createTool),
5775
+ createTool: stringValue2(schedule.createTool ?? schedule.create_tool),
5776
+ activate_tool: stringValue2(schedule.activate_tool ?? schedule.activateTool),
5777
+ activateTool: stringValue2(schedule.activateTool ?? schedule.activate_tool),
5778
+ cadence: stringValue2(schedule.cadence, "manual"),
5779
+ recurrence: stringValue2(schedule.recurrence),
5780
+ wake_on_events: wakeOnEvents,
5781
+ wakeOnEvents
5782
+ };
5783
+ }
5784
+ function normalizeOpsExecutionApprovalContract(rawApproval) {
5785
+ const approval = asRecord2(rawApproval);
5786
+ return {
5787
+ ...approval,
5788
+ required: Boolean(approval.required),
5789
+ tool: stringValue2(approval.tool),
5790
+ reason: stringValue2(approval.reason)
5791
+ };
5792
+ }
5793
+ function normalizeOpsExecutionMonitorContract(rawMonitor) {
5794
+ const monitor = asRecord2(rawMonitor);
5795
+ const pollAfterMs = numberValue(monitor.poll_after_ms ?? monitor.pollAfterMs);
5796
+ return {
5797
+ ...monitor,
5798
+ status_tool: stringValue2(monitor.status_tool ?? monitor.statusTool),
5799
+ statusTool: stringValue2(monitor.statusTool ?? monitor.status_tool),
5800
+ wait_tool: stringValue2(monitor.wait_tool ?? monitor.waitTool),
5801
+ waitTool: stringValue2(monitor.waitTool ?? monitor.wait_tool),
5802
+ results_tool: stringValue2(monitor.results_tool ?? monitor.resultsTool),
5803
+ resultsTool: stringValue2(monitor.resultsTool ?? monitor.results_tool),
5804
+ poll_after_ms: pollAfterMs,
5805
+ pollAfterMs
5806
+ };
5807
+ }
5808
+ function normalizeOpsExecutionResultContract(rawResult) {
5809
+ const result = asRecord2(rawResult);
5810
+ const shape = Array.isArray(result.shape) ? result.shape.map(String) : [];
5811
+ return {
5812
+ ...result,
5813
+ tool: stringValue2(result.tool),
5814
+ wait_tool: stringValue2(result.wait_tool ?? result.waitTool),
5815
+ waitTool: stringValue2(result.waitTool ?? result.wait_tool),
5816
+ shape,
5817
+ empty_result_recovery: stringValue2(result.empty_result_recovery ?? result.emptyResultRecovery),
5818
+ emptyResultRecovery: stringValue2(result.emptyResultRecovery ?? result.empty_result_recovery)
5819
+ };
5820
+ }
5821
+ function normalizeOpsExecutionNangoRouteContract(rawRoute) {
5822
+ if (!rawRoute || typeof rawRoute !== "object" || Array.isArray(rawRoute)) return void 0;
5823
+ const route = asRecord2(rawRoute);
5824
+ const requiredFields = Array.isArray(route.required_fields) ? route.required_fields.map(String) : Array.isArray(route.requiredFields) ? route.requiredFields.map(String) : [];
5825
+ return {
5826
+ ...route,
5827
+ enabled: route.enabled !== false,
5828
+ connect_tool: stringValue2(route.connect_tool ?? route.connectTool),
5829
+ connectTool: stringValue2(route.connectTool ?? route.connect_tool),
5830
+ discover_tool: stringValue2(route.discover_tool ?? route.discoverTool),
5831
+ discoverTool: stringValue2(route.discoverTool ?? route.discover_tool),
5832
+ dry_run_tool: stringValue2(route.dry_run_tool ?? route.dryRunTool),
5833
+ dryRunTool: stringValue2(route.dryRunTool ?? route.dry_run_tool),
5834
+ execute_tool: stringValue2(route.execute_tool ?? route.executeTool),
5835
+ executeTool: stringValue2(route.executeTool ?? route.execute_tool),
5836
+ execute_and_wait_tool: stringValue2(route.execute_and_wait_tool ?? route.executeAndWaitTool),
5837
+ executeAndWaitTool: stringValue2(route.executeAndWaitTool ?? route.execute_and_wait_tool),
5838
+ schedule_tool: stringValue2(route.schedule_tool ?? route.scheduleTool),
5839
+ scheduleTool: stringValue2(route.scheduleTool ?? route.schedule_tool),
5840
+ schedule_and_wait_tool: stringValue2(route.schedule_and_wait_tool ?? route.scheduleAndWaitTool),
5841
+ scheduleAndWaitTool: stringValue2(route.scheduleAndWaitTool ?? route.schedule_and_wait_tool),
5842
+ result_tool: stringValue2(route.result_tool ?? route.resultTool),
5843
+ resultTool: stringValue2(route.resultTool ?? route.result_tool),
5844
+ write_gate: stringValue2(route.write_gate ?? route.writeGate),
5845
+ writeGate: stringValue2(route.writeGate ?? route.write_gate),
5846
+ required_fields: requiredFields,
5847
+ requiredFields,
5848
+ schedule_arguments: asRecord2(route.schedule_arguments ?? route.scheduleArguments),
5849
+ scheduleArguments: asRecord2(route.scheduleArguments ?? route.schedule_arguments),
5850
+ schedule_and_wait_arguments: asRecord2(route.schedule_and_wait_arguments ?? route.scheduleAndWaitArguments),
5851
+ scheduleAndWaitArguments: asRecord2(route.scheduleAndWaitArguments ?? route.schedule_and_wait_arguments)
5852
+ };
5853
+ }
5854
+ function normalizeOpsExecutionContract(rawContract) {
5855
+ if (!rawContract || typeof rawContract !== "object" || Array.isArray(rawContract)) return void 0;
5856
+ const contract = asRecord2(rawContract);
5857
+ const nangoRoute = normalizeOpsExecutionNangoRouteContract(contract.nango_route ?? contract.nangoRoute);
5858
+ const sequence = Array.isArray(contract.sequence) ? contract.sequence.map(normalizeOpsExecutionToolCall) : [];
5859
+ return {
5860
+ ...contract,
5861
+ mode: stringValue2(contract.mode, "run_once"),
5862
+ run_now: normalizeOpsExecutionToolCall(contract.run_now ?? contract.runNow),
5863
+ runNow: normalizeOpsExecutionToolCall(contract.runNow ?? contract.run_now),
5864
+ schedule: normalizeOpsExecutionScheduleContract(contract.schedule),
5865
+ approval: normalizeOpsExecutionApprovalContract(contract.approval),
5866
+ monitor: normalizeOpsExecutionMonitorContract(contract.monitor),
5867
+ result_contract: normalizeOpsExecutionResultContract(contract.result_contract ?? contract.resultContract),
5868
+ resultContract: normalizeOpsExecutionResultContract(contract.resultContract ?? contract.result_contract),
5869
+ ...nangoRoute ? { nango_route: nangoRoute, nangoRoute } : {},
5870
+ sequence
5871
+ };
5872
+ }
4800
5873
  function normalizeOpsPlanResult(result) {
4801
5874
  const primitiveGraph = result.primitive_graph ?? result.primitiveGraph;
5875
+ const executionContract = normalizeOpsExecutionContract(result.execution_contract ?? result.executionContract);
4802
5876
  return {
4803
5877
  ...result,
4804
5878
  plan_id: result.plan_id ?? result.planId,
@@ -4822,7 +5896,8 @@ function normalizeOpsPlanResult(result) {
4822
5896
  destination_status: result.destination_status ?? result.destinationStatus,
4823
5897
  destinationStatus: result.destinationStatus ?? result.destination_status,
4824
5898
  primitive_graph: primitiveGraph?.map(normalizeOpsPrimitive),
4825
- primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive)
5899
+ primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive),
5900
+ ...executionContract ? { execution_contract: executionContract, executionContract } : {}
4826
5901
  };
4827
5902
  }
4828
5903
  function normalizeOpsCreateResult(result) {
@@ -4844,7 +5919,18 @@ function normalizeOpsCreateResult(result) {
4844
5919
  deliveryStatus: result.deliveryStatus ?? result.delivery_status,
4845
5920
  estimated_credits: result.estimated_credits ?? result.estimatedCredits,
4846
5921
  estimatedCredits: result.estimatedCredits ?? result.estimated_credits,
4847
- plan: result.plan ? normalizeOpsPlanResult(result.plan) : result.plan
5922
+ error_code: result.error_code ?? result.errorCode,
5923
+ errorCode: result.errorCode ?? result.error_code,
5924
+ approval_required: result.approval_required ?? result.approvalRequired,
5925
+ approvalRequired: result.approvalRequired ?? result.approval_required,
5926
+ retry_arguments: result.retry_arguments ?? result.retryArguments,
5927
+ retryArguments: result.retryArguments ?? result.retry_arguments,
5928
+ blockers: result.blockers,
5929
+ plan: result.plan ? normalizeOpsPlanResult(result.plan) : result.plan,
5930
+ next_step: result.next_step ?? result.nextStep,
5931
+ nextStep: result.nextStep ?? result.next_step,
5932
+ next_steps: result.next_steps ?? result.nextSteps,
5933
+ nextSteps: result.nextSteps ?? result.next_steps
4848
5934
  };
4849
5935
  }
4850
5936
  function normalizeOpsExecuteResult(result) {
@@ -4972,6 +6058,40 @@ function normalizeOpsStatusResult(result) {
4972
6058
  diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
4973
6059
  };
4974
6060
  }
6061
+ function normalizeOpsResultsSummary(value) {
6062
+ const summary = asRecord2(value);
6063
+ if (Object.keys(summary).length === 0) return void 0;
6064
+ const resultsTotal = summary.results_total ?? summary.resultsTotal;
6065
+ const nextCursor = summary.next_cursor ?? summary.nextCursor ?? null;
6066
+ const resultsUrl = summary.results_url ?? summary.resultsUrl;
6067
+ const nextAction = summary.next_action ?? summary.nextAction;
6068
+ const runId = summary.run_id ?? summary.runId ?? null;
6069
+ const creditsUsed = summary.credits_used ?? summary.creditsUsed;
6070
+ return {
6071
+ ...summary,
6072
+ label: optionalString(summary.label),
6073
+ status: optionalString(summary.status),
6074
+ phase: optionalString(summary.phase),
6075
+ results_count: numberValue(summary.results_count ?? summary.resultsCount),
6076
+ resultsCount: numberValue(summary.results_count ?? summary.resultsCount),
6077
+ results_total: resultsTotal === null || resultsTotal === void 0 ? resultsTotal : numberValue(resultsTotal),
6078
+ resultsTotal: resultsTotal === null || resultsTotal === void 0 ? resultsTotal : numberValue(resultsTotal),
6079
+ delivery_status: optionalString(summary.delivery_status ?? summary.deliveryStatus),
6080
+ deliveryStatus: optionalString(summary.delivery_status ?? summary.deliveryStatus),
6081
+ has_more: Boolean(summary.has_more ?? summary.hasMore),
6082
+ hasMore: Boolean(summary.has_more ?? summary.hasMore),
6083
+ next_cursor: nextCursor === null ? null : optionalString(nextCursor),
6084
+ nextCursor: nextCursor === null ? null : optionalString(nextCursor),
6085
+ results_url: optionalString(resultsUrl),
6086
+ resultsUrl: optionalString(resultsUrl),
6087
+ next_action: optionalString(nextAction),
6088
+ nextAction: optionalString(nextAction),
6089
+ run_id: runId === null ? null : optionalString(runId),
6090
+ runId: runId === null ? null : optionalString(runId),
6091
+ credits_used: creditsUsed === void 0 ? void 0 : numberValue(creditsUsed),
6092
+ creditsUsed: creditsUsed === void 0 ? void 0 : numberValue(creditsUsed)
6093
+ };
6094
+ }
4975
6095
  function normalizeOpsResultsResult(result) {
4976
6096
  const nextCursor = result.next_cursor ?? result.nextCursor ?? null;
4977
6097
  const hasMore = result.has_more ?? result.hasMore ?? false;
@@ -4996,7 +6116,104 @@ function normalizeOpsResultsResult(result) {
4996
6116
  results_url: result.results_url ?? result.resultsUrl,
4997
6117
  resultsUrl: result.resultsUrl ?? result.results_url,
4998
6118
  delivery_status: result.delivery_status ?? result.deliveryStatus,
4999
- deliveryStatus: result.deliveryStatus ?? result.delivery_status
6119
+ deliveryStatus: result.deliveryStatus ?? result.delivery_status,
6120
+ summary: normalizeOpsResultsSummary(result.summary)
6121
+ };
6122
+ }
6123
+ function normalizeOpsWaitForResultsPoll(value, fallbackPoll) {
6124
+ const raw = asRecord2(value);
6125
+ const checkedAt = stringValue2(raw.checked_at ?? raw.checkedAt);
6126
+ const resultsCount = raw.results_count ?? raw.resultsCount;
6127
+ const runId = raw.run_id ?? raw.runId ?? null;
6128
+ const nextAction = raw.next_action ?? raw.nextAction;
6129
+ return {
6130
+ ...raw,
6131
+ poll: numberValue(raw.poll) || fallbackPoll,
6132
+ checked_at: checkedAt,
6133
+ checkedAt,
6134
+ status: stringValue2(raw.status, "unknown"),
6135
+ phase: optionalString(raw.phase),
6136
+ results_count: resultsCount === void 0 ? void 0 : numberValue(resultsCount),
6137
+ resultsCount: resultsCount === void 0 ? void 0 : numberValue(resultsCount),
6138
+ run_id: runId === null ? null : optionalString(runId),
6139
+ runId: runId === null ? null : optionalString(runId),
6140
+ next_action: optionalString(nextAction),
6141
+ nextAction: optionalString(nextAction)
6142
+ };
6143
+ }
6144
+ function normalizeOpsWaitForResultsResult(result, options) {
6145
+ const opId = stringValue2(result.op_id ?? result.opId ?? options.op_id);
6146
+ const routineId = stringValue2(result.routine_id ?? result.routineId ?? opId);
6147
+ const runId = result.run_id ?? result.runId ?? null;
6148
+ const timedOut = Boolean(result.timed_out ?? result.timedOut);
6149
+ const statusRaw = asRecord2(result.status_result ?? result.statusResult);
6150
+ const resultsRaw = asRecord2(result.results_result ?? result.resultsResult);
6151
+ const historySource = Array.isArray(result.poll_history) ? result.poll_history : Array.isArray(result.history) ? result.history : [];
6152
+ const history = historySource.map((item, index) => normalizeOpsWaitForResultsPoll(item, index + 1));
6153
+ const status = normalizeOpsStatusResult(withExecutionRefs({
6154
+ success: result.success !== false,
6155
+ op_id: opId,
6156
+ routine_id: routineId,
6157
+ run_id: runId,
6158
+ status: stringValue2(result.status, "unknown"),
6159
+ phase: stringValue2(result.phase, "unknown"),
6160
+ next_action: stringValue2(result.next_action ?? result.nextAction),
6161
+ results_count: numberValue(result.results_count ?? result.resultsCount),
6162
+ results_url: optionalString(result.results_url ?? result.resultsUrl),
6163
+ delivery_status: optionalString(result.delivery_status ?? result.deliveryStatus),
6164
+ ...statusRaw
6165
+ }));
6166
+ const includeResults = options.include_results !== false && options.includeResults !== false;
6167
+ const hasResultsPacket = Object.keys(resultsRaw).length > 0 || Array.isArray(result.results);
6168
+ const results = includeResults && hasResultsPacket ? normalizeOpsResultsResult(withExecutionRefs({
6169
+ success: result.success !== false,
6170
+ op_id: opId,
6171
+ routine_id: routineId,
6172
+ run_id: runId,
6173
+ status: stringValue2(result.status, status.status),
6174
+ phase: stringValue2(result.phase, status.phase),
6175
+ results_count: numberValue(result.results_count ?? result.resultsCount),
6176
+ results_total: result.results_total ?? result.resultsTotal ?? null,
6177
+ results: Array.isArray(result.results) ? result.results : [],
6178
+ next_cursor: result.next_cursor ?? result.nextCursor ?? null,
6179
+ has_more: Boolean(result.has_more ?? result.hasMore),
6180
+ next_action: stringValue2(result.next_action ?? result.nextAction),
6181
+ results_url: optionalString(result.results_url ?? result.resultsUrl),
6182
+ delivery_status: optionalString(result.delivery_status ?? result.deliveryStatus),
6183
+ ...resultsRaw
6184
+ })) : void 0;
6185
+ const polls = numberValue(result.polls) || history.length;
6186
+ const maxPolls = result.max_polls ?? result.maxPolls;
6187
+ const intervalMs = result.interval_ms ?? result.intervalMs;
6188
+ const timeoutMs = result.timeout_ms ?? result.timeoutMs;
6189
+ const stopReason = result.stop_reason ?? result.stopReason;
6190
+ const nextAction = result.next_action ?? result.nextAction ?? results?.next_action ?? status.next_action;
6191
+ return {
6192
+ ...result,
6193
+ success: result.success !== false && !timedOut,
6194
+ op_id: opId,
6195
+ opId,
6196
+ routine_id: routineId,
6197
+ routineId,
6198
+ run_id: runId === null ? null : optionalString(runId),
6199
+ runId: runId === null ? null : optionalString(runId),
6200
+ status,
6201
+ results,
6202
+ timed_out: timedOut,
6203
+ timedOut,
6204
+ polls,
6205
+ max_polls: maxPolls === void 0 ? void 0 : numberValue(maxPolls),
6206
+ maxPolls: maxPolls === void 0 ? void 0 : numberValue(maxPolls),
6207
+ interval_ms: intervalMs === void 0 ? void 0 : numberValue(intervalMs),
6208
+ intervalMs: intervalMs === void 0 ? void 0 : numberValue(intervalMs),
6209
+ timeout_ms: timeoutMs === void 0 ? void 0 : numberValue(timeoutMs),
6210
+ timeoutMs: timeoutMs === void 0 ? void 0 : numberValue(timeoutMs),
6211
+ stop_reason: optionalString(stopReason),
6212
+ stopReason: optionalString(stopReason),
6213
+ history,
6214
+ next_action: optionalString(nextAction),
6215
+ nextAction: optionalString(nextAction),
6216
+ execution_refs: mergeExecutionRefsFrom([result, status, results, { history }])
5000
6217
  };
5001
6218
  }
5002
6219
  function normalizeOpsProofResult(data) {
@@ -5076,11 +6293,107 @@ function normalizeOpsProofResult(data) {
5076
6293
  raw: data
5077
6294
  };
5078
6295
  }
6296
+ function normalizeOpsAutopilotSchedulePacket(rawPacket) {
6297
+ const packet = asRecord2(rawPacket);
6298
+ return {
6299
+ ...packet,
6300
+ cadence: stringValue2(packet.cadence, "manual"),
6301
+ recurrence: stringValue2(packet.recurrence),
6302
+ activate_with: stringValue2(packet.activate_with ?? packet.activateWith),
6303
+ activateWith: stringValue2(packet.activate_with ?? packet.activateWith),
6304
+ run_now_with: stringValue2(packet.run_now_with ?? packet.runNowWith),
6305
+ runNowWith: stringValue2(packet.run_now_with ?? packet.runNowWith),
6306
+ monitor_with: stringValue2(packet.monitor_with ?? packet.monitorWith),
6307
+ monitorWith: stringValue2(packet.monitor_with ?? packet.monitorWith),
6308
+ retrieve_with: stringValue2(packet.retrieve_with ?? packet.retrieveWith),
6309
+ retrieveWith: stringValue2(packet.retrieve_with ?? packet.retrieveWith)
6310
+ };
6311
+ }
6312
+ function normalizeOpsAutopilotNangoRoutePacket(rawPacket) {
6313
+ if (!rawPacket || typeof rawPacket !== "object" || Array.isArray(rawPacket)) return void 0;
6314
+ const packet = asRecord2(rawPacket);
6315
+ const requiredFields = Array.isArray(packet.required_fields) ? packet.required_fields.map(String) : Array.isArray(packet.requiredFields) ? packet.requiredFields.map(String) : [];
6316
+ return {
6317
+ ...packet,
6318
+ enabled: packet.enabled !== false,
6319
+ route_label: stringValue2(packet.route_label ?? packet.routeLabel),
6320
+ routeLabel: stringValue2(packet.route_label ?? packet.routeLabel),
6321
+ connect_tool: stringValue2(packet.connect_tool ?? packet.connectTool),
6322
+ connectTool: stringValue2(packet.connect_tool ?? packet.connectTool),
6323
+ discover_tool: stringValue2(packet.discover_tool ?? packet.discoverTool),
6324
+ discoverTool: stringValue2(packet.discover_tool ?? packet.discoverTool),
6325
+ dry_run_tool: stringValue2(packet.dry_run_tool ?? packet.dryRunTool),
6326
+ dryRunTool: stringValue2(packet.dry_run_tool ?? packet.dryRunTool),
6327
+ execute_tool: stringValue2(packet.execute_tool ?? packet.executeTool),
6328
+ executeTool: stringValue2(packet.execute_tool ?? packet.executeTool),
6329
+ execute_and_wait_tool: stringValue2(packet.execute_and_wait_tool ?? packet.executeAndWaitTool),
6330
+ executeAndWaitTool: stringValue2(packet.execute_and_wait_tool ?? packet.executeAndWaitTool),
6331
+ schedule_tool: stringValue2(packet.schedule_tool ?? packet.scheduleTool),
6332
+ scheduleTool: stringValue2(packet.schedule_tool ?? packet.scheduleTool),
6333
+ schedule_and_wait_tool: stringValue2(packet.schedule_and_wait_tool ?? packet.scheduleAndWaitTool),
6334
+ scheduleAndWaitTool: stringValue2(packet.schedule_and_wait_tool ?? packet.scheduleAndWaitTool),
6335
+ result_tool: stringValue2(packet.result_tool ?? packet.resultTool),
6336
+ resultTool: stringValue2(packet.result_tool ?? packet.resultTool),
6337
+ write_gate: stringValue2(packet.write_gate ?? packet.writeGate),
6338
+ writeGate: stringValue2(packet.write_gate ?? packet.writeGate),
6339
+ required_fields: requiredFields,
6340
+ requiredFields,
6341
+ placeholders: asRecord2(packet.placeholders),
6342
+ dry_run_arguments: asRecord2(packet.dry_run_arguments ?? packet.dryRunArguments),
6343
+ dryRunArguments: asRecord2(packet.dry_run_arguments ?? packet.dryRunArguments),
6344
+ execute_arguments: asRecord2(packet.execute_arguments ?? packet.executeArguments),
6345
+ executeArguments: asRecord2(packet.execute_arguments ?? packet.executeArguments),
6346
+ execute_and_wait_arguments: asRecord2(packet.execute_and_wait_arguments ?? packet.executeAndWaitArguments),
6347
+ executeAndWaitArguments: asRecord2(packet.execute_and_wait_arguments ?? packet.executeAndWaitArguments),
6348
+ schedule_arguments: asRecord2(packet.schedule_arguments ?? packet.scheduleArguments),
6349
+ scheduleArguments: asRecord2(packet.schedule_arguments ?? packet.scheduleArguments),
6350
+ schedule_and_wait_arguments: asRecord2(packet.schedule_and_wait_arguments ?? packet.scheduleAndWaitArguments),
6351
+ scheduleAndWaitArguments: asRecord2(packet.schedule_and_wait_arguments ?? packet.scheduleAndWaitArguments),
6352
+ result_arguments: asRecord2(packet.result_arguments ?? packet.resultArguments),
6353
+ resultArguments: asRecord2(packet.result_arguments ?? packet.resultArguments)
6354
+ };
6355
+ }
6356
+ function normalizeOpsAutopilotResultPacket(rawPacket) {
6357
+ const packet = asRecord2(rawPacket);
6358
+ const resultShape = Array.isArray(packet.result_shape) ? packet.result_shape.map(String) : Array.isArray(packet.resultShape) ? packet.resultShape.map(String) : [];
6359
+ const deliveryReceipts = Array.isArray(packet.delivery_receipts) ? packet.delivery_receipts.map(String) : Array.isArray(packet.deliveryReceipts) ? packet.deliveryReceipts.map(String) : [];
6360
+ return {
6361
+ ...packet,
6362
+ retrieve_tool: stringValue2(packet.retrieve_tool ?? packet.retrieveTool),
6363
+ retrieveTool: stringValue2(packet.retrieve_tool ?? packet.retrieveTool),
6364
+ result_shape: resultShape,
6365
+ resultShape,
6366
+ delivery_receipts: deliveryReceipts,
6367
+ deliveryReceipts,
6368
+ empty_result_recovery: stringValue2(packet.empty_result_recovery ?? packet.emptyResultRecovery),
6369
+ emptyResultRecovery: stringValue2(packet.empty_result_recovery ?? packet.emptyResultRecovery)
6370
+ };
6371
+ }
6372
+ function normalizeOpsAutopilotOperatingPacket(rawPacket) {
6373
+ if (!rawPacket || typeof rawPacket !== "object" || Array.isArray(rawPacket)) return void 0;
6374
+ const packet = asRecord2(rawPacket);
6375
+ const nangoRoute = normalizeOpsAutopilotNangoRoutePacket(packet.nango_route ?? packet.nangoRoute);
6376
+ const approvalBoundaries = Array.isArray(packet.approval_boundaries) ? packet.approval_boundaries.map(String) : Array.isArray(packet.approvalBoundaries) ? packet.approvalBoundaries.map(String) : [];
6377
+ return {
6378
+ ...packet,
6379
+ north_star: stringValue2(packet.north_star ?? packet.northStar),
6380
+ northStar: stringValue2(packet.north_star ?? packet.northStar),
6381
+ schedule: normalizeOpsAutopilotSchedulePacket(packet.schedule),
6382
+ ...nangoRoute ? { nango_route: nangoRoute, nangoRoute } : {},
6383
+ result_contract: normalizeOpsAutopilotResultPacket(packet.result_contract ?? packet.resultContract),
6384
+ resultContract: normalizeOpsAutopilotResultPacket(packet.result_contract ?? packet.resultContract),
6385
+ approval_boundaries: approvalBoundaries,
6386
+ approvalBoundaries,
6387
+ saved_command_hint: stringValue2(packet.saved_command_hint ?? packet.savedCommandHint),
6388
+ savedCommandHint: stringValue2(packet.saved_command_hint ?? packet.savedCommandHint)
6389
+ };
6390
+ }
5079
6391
  function normalizeOpsAutopilotMotion(rawMotion) {
5080
6392
  const motion = asRecord2(rawMotion);
5081
6393
  const targetCount = numberValue(motion.target_count ?? motion.targetCount);
5082
6394
  const estimatedCredits = numberValue(motion.estimated_credits ?? motion.estimatedCredits);
5083
6395
  const mcpSequence = Array.isArray(motion.mcp_sequence) ? motion.mcp_sequence : Array.isArray(motion.mcpSequence) ? motion.mcpSequence : [];
6396
+ const operatingPacket = normalizeOpsAutopilotOperatingPacket(motion.operating_packet ?? motion.operatingPacket);
5084
6397
  return {
5085
6398
  ...motion,
5086
6399
  id: stringValue2(motion.id),
@@ -5103,12 +6416,16 @@ function normalizeOpsAutopilotMotion(rawMotion) {
5103
6416
  cli_command: optionalString(motion.cli_command ?? motion.cliCommand),
5104
6417
  cliCommand: optionalString(motion.cli_command ?? motion.cliCommand),
5105
6418
  mcp_sequence: mcpSequence,
5106
- mcpSequence
6419
+ mcpSequence,
6420
+ ...operatingPacket ? { operating_packet: operatingPacket, operatingPacket } : {}
5107
6421
  };
5108
6422
  }
5109
6423
  function normalizeOpsAutopilotResult(result) {
5110
6424
  const primary = normalizeOpsAutopilotMotion(result.primary_motion ?? result.primaryMotion);
5111
6425
  const motions = Array.isArray(result.motions) ? result.motions.map(normalizeOpsAutopilotMotion) : [];
6426
+ const operatingPacket = normalizeOpsAutopilotOperatingPacket(
6427
+ result.operating_packet ?? result.operatingPacket ?? primary.operating_packet ?? primary.operatingPacket
6428
+ );
5112
6429
  const queryErrors = Array.isArray(result.query_errors) ? result.query_errors.map(String) : Array.isArray(result.queryErrors) ? result.queryErrors.map(String) : [];
5113
6430
  return {
5114
6431
  ...result,
@@ -5124,6 +6441,7 @@ function normalizeOpsAutopilotResult(result) {
5124
6441
  scaleRule: optionalString(result.scale_rule ?? result.scaleRule),
5125
6442
  agent_handoff: optionalString(result.agent_handoff ?? result.agentHandoff),
5126
6443
  agentHandoff: optionalString(result.agent_handoff ?? result.agentHandoff),
6444
+ ...operatingPacket ? { operating_packet: operatingPacket, operatingPacket } : {},
5127
6445
  proof_state: optionalString(result.proof_state ?? result.proofState),
5128
6446
  proofState: optionalString(result.proof_state ?? result.proofState),
5129
6447
  proof_summary: result.proof_summary ?? result.proofSummary,
@@ -5388,11 +6706,125 @@ function normalizeOpsRoutineTickItemsResult(result) {
5388
6706
  hasMore
5389
6707
  };
5390
6708
  }
6709
+ function buildOpsNangoScheduleBody(input) {
6710
+ const {
6711
+ workspaceConnectionId,
6712
+ workspace_connection_id,
6713
+ connectionId,
6714
+ connection_id,
6715
+ providerConfigKey,
6716
+ provider_config_key,
6717
+ integrationId,
6718
+ integration_id,
6719
+ nangoConnectionId,
6720
+ nango_connection_id,
6721
+ actionName,
6722
+ action_name,
6723
+ toolName,
6724
+ tool_name,
6725
+ proxyPath,
6726
+ proxy_path,
6727
+ nangoProxyPath,
6728
+ nango_proxy_path,
6729
+ method,
6730
+ httpMethod,
6731
+ http_method,
6732
+ input: nangoInput,
6733
+ arguments: nangoArguments,
6734
+ fieldMap,
6735
+ field_map,
6736
+ requiredFields,
6737
+ required_fields,
6738
+ writeConfirmed,
6739
+ write_confirmed,
6740
+ agentWriteConfirmed,
6741
+ agent_write_confirmed,
6742
+ config,
6743
+ destinations: _destinations,
6744
+ ...schedule
6745
+ } = input;
6746
+ return {
6747
+ ...buildOpsCreateBody({
6748
+ ...schedule,
6749
+ cadence: schedule.cadence ?? "daily"
6750
+ }),
6751
+ workspace_connection_id: workspace_connection_id ?? workspaceConnectionId,
6752
+ connection_id: connection_id ?? connectionId,
6753
+ provider_config_key: provider_config_key ?? providerConfigKey,
6754
+ integration_id: integration_id ?? integrationId,
6755
+ nango_connection_id: nango_connection_id ?? nangoConnectionId,
6756
+ action_name: action_name ?? actionName,
6757
+ tool_name: tool_name ?? toolName,
6758
+ proxy_path: proxy_path ?? proxyPath ?? nango_proxy_path ?? nangoProxyPath,
6759
+ nango_proxy_path: nango_proxy_path ?? nangoProxyPath,
6760
+ method: method ?? http_method ?? httpMethod,
6761
+ input: nangoInput ?? nangoArguments,
6762
+ field_map: field_map ?? fieldMap,
6763
+ required_fields: required_fields ?? requiredFields,
6764
+ write_confirmed: write_confirmed ?? writeConfirmed,
6765
+ agent_write_confirmed: agent_write_confirmed ?? agentWriteConfirmed,
6766
+ config
6767
+ };
6768
+ }
6769
+ function buildOpsNangoScheduleAndWaitOptions(params) {
6770
+ const {
6771
+ force,
6772
+ instruction,
6773
+ nextCursor,
6774
+ includeFailedRuns,
6775
+ intervalMs,
6776
+ maxPolls,
6777
+ timeoutMs,
6778
+ includeResults,
6779
+ cursor,
6780
+ state,
6781
+ limit,
6782
+ include_failed_runs,
6783
+ interval_ms,
6784
+ max_polls,
6785
+ timeout_ms,
6786
+ include_results,
6787
+ ...schedule
6788
+ } = params;
6789
+ return {
6790
+ schedule: {
6791
+ ...schedule,
6792
+ cadence: schedule.cadence ?? "daily"
6793
+ },
6794
+ run: {
6795
+ force,
6796
+ instruction
6797
+ },
6798
+ wait: {
6799
+ cursor: cursor ?? nextCursor,
6800
+ state,
6801
+ limit,
6802
+ include_failed_runs: include_failed_runs ?? includeFailedRuns,
6803
+ interval_ms: interval_ms ?? intervalMs,
6804
+ max_polls: max_polls ?? maxPolls,
6805
+ timeout_ms: timeout_ms ?? timeoutMs,
6806
+ include_results: include_results ?? includeResults
6807
+ }
6808
+ };
6809
+ }
6810
+ function buildOpsNangoScheduleAndWaitBody(options) {
6811
+ const waitBody = buildOpsWaitBody(options.wait);
6812
+ const { op_id: _opId, ...waitWithoutOp } = waitBody;
6813
+ return {
6814
+ ...buildOpsNangoScheduleBody(options.schedule),
6815
+ ...waitWithoutOp,
6816
+ instruction: options.run.instruction,
6817
+ force: options.run.force
6818
+ };
6819
+ }
5391
6820
  function buildOpsPlanBody(params) {
5392
- const { targetCount, companyDomains, customAiPrompt, signalPrompt, outputPrompt, ...rest } = params;
6821
+ const { targetCount, wakeOnEvents, companyDomains, customAiPrompt, signalPrompt, outputPrompt, ...rest } = params;
6822
+ const destinations = Array.isArray(rest.destinations) ? rest.destinations.map(normalizeOpsDestinationRequest) : rest.destinations;
5393
6823
  return {
5394
6824
  ...rest,
6825
+ destinations,
5395
6826
  target_count: rest.target_count ?? targetCount,
6827
+ wake_on_events: rest.wake_on_events ?? wakeOnEvents,
5396
6828
  company_domains: rest.company_domains ?? companyDomains,
5397
6829
  custom_ai_prompt: rest.custom_ai_prompt ?? customAiPrompt,
5398
6830
  signal_prompt: rest.signal_prompt ?? signalPrompt,
@@ -5415,6 +6847,95 @@ function buildOpsExecuteBody(params) {
5415
6847
  output_format: rest.output_format ?? outputFormat
5416
6848
  };
5417
6849
  }
6850
+ function buildOpsExecuteAndWaitOptions(params) {
6851
+ const {
6852
+ nextCursor,
6853
+ includeFailedRuns,
6854
+ intervalMs,
6855
+ maxPolls,
6856
+ timeoutMs,
6857
+ includeResults,
6858
+ cursor,
6859
+ state,
6860
+ limit,
6861
+ include_failed_runs,
6862
+ interval_ms,
6863
+ max_polls,
6864
+ timeout_ms,
6865
+ include_results,
6866
+ ...execute
6867
+ } = params;
6868
+ return {
6869
+ execute: {
6870
+ ...execute,
6871
+ auto_run: execute.auto_run ?? execute.autoRun ?? true
6872
+ },
6873
+ wait: {
6874
+ cursor: cursor ?? nextCursor,
6875
+ state,
6876
+ limit,
6877
+ include_failed_runs: include_failed_runs ?? includeFailedRuns,
6878
+ interval_ms: interval_ms ?? intervalMs,
6879
+ max_polls: max_polls ?? maxPolls,
6880
+ timeout_ms: timeout_ms ?? timeoutMs,
6881
+ include_results: include_results ?? includeResults
6882
+ }
6883
+ };
6884
+ }
6885
+ function buildOpsScheduleAndWaitOptions(params) {
6886
+ const {
6887
+ force,
6888
+ instruction,
6889
+ nextCursor,
6890
+ includeFailedRuns,
6891
+ intervalMs,
6892
+ maxPolls,
6893
+ timeoutMs,
6894
+ includeResults,
6895
+ cursor,
6896
+ state,
6897
+ limit,
6898
+ include_failed_runs,
6899
+ interval_ms,
6900
+ max_polls,
6901
+ timeout_ms,
6902
+ include_results,
6903
+ ...schedule
6904
+ } = params;
6905
+ return {
6906
+ schedule: {
6907
+ ...schedule,
6908
+ cadence: schedule.cadence ?? "daily"
6909
+ },
6910
+ run: {
6911
+ force,
6912
+ instruction
6913
+ },
6914
+ wait: {
6915
+ cursor: cursor ?? nextCursor,
6916
+ state,
6917
+ limit,
6918
+ include_failed_runs: include_failed_runs ?? includeFailedRuns,
6919
+ interval_ms: interval_ms ?? intervalMs,
6920
+ max_polls: max_polls ?? maxPolls,
6921
+ timeout_ms: timeout_ms ?? timeoutMs,
6922
+ include_results: include_results ?? includeResults
6923
+ }
6924
+ };
6925
+ }
6926
+ function buildOpsScheduleAndWaitBody(options) {
6927
+ const waitBody = buildOpsWaitBody(options.wait);
6928
+ const { op_id: _opId, ...waitWithoutOp } = waitBody;
6929
+ return {
6930
+ ...buildOpsCreateBody({
6931
+ ...options.schedule,
6932
+ cadence: options.schedule.cadence ?? "daily"
6933
+ }),
6934
+ ...waitWithoutOp,
6935
+ instruction: options.run.instruction,
6936
+ force: options.run.force
6937
+ };
6938
+ }
5418
6939
  function buildOpsRunBody(params) {
5419
6940
  const { opId, ...rest } = params;
5420
6941
  return {
@@ -5422,6 +6943,28 @@ function buildOpsRunBody(params) {
5422
6943
  op_id: rest.op_id ?? opId
5423
6944
  };
5424
6945
  }
6946
+ function buildOpsRunAndWaitOptions(params) {
6947
+ const {
6948
+ opId,
6949
+ nextCursor,
6950
+ includeFailedRuns,
6951
+ intervalMs,
6952
+ maxPolls,
6953
+ timeoutMs,
6954
+ includeResults,
6955
+ ...rest
6956
+ } = params;
6957
+ return {
6958
+ ...rest,
6959
+ op_id: rest.op_id ?? opId,
6960
+ cursor: rest.cursor ?? nextCursor,
6961
+ include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
6962
+ interval_ms: rest.interval_ms ?? intervalMs,
6963
+ max_polls: rest.max_polls ?? maxPolls,
6964
+ timeout_ms: rest.timeout_ms ?? timeoutMs,
6965
+ include_results: rest.include_results ?? includeResults
6966
+ };
6967
+ }
5425
6968
  function buildOpsStatusBody(params) {
5426
6969
  const { opId, ...rest } = params;
5427
6970
  return {
@@ -5438,6 +6981,50 @@ function buildOpsResultsBody(params) {
5438
6981
  include_failed_runs: rest.include_failed_runs ?? includeFailedRuns
5439
6982
  };
5440
6983
  }
6984
+ function buildOpsWaitForResultsOptions(params) {
6985
+ const {
6986
+ opId,
6987
+ nextCursor,
6988
+ includeFailedRuns,
6989
+ intervalMs,
6990
+ maxPolls,
6991
+ timeoutMs,
6992
+ includeResults,
6993
+ ...rest
6994
+ } = params;
6995
+ return {
6996
+ ...rest,
6997
+ op_id: rest.op_id ?? opId,
6998
+ cursor: rest.cursor ?? nextCursor,
6999
+ include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
7000
+ interval_ms: rest.interval_ms ?? intervalMs,
7001
+ max_polls: rest.max_polls ?? maxPolls,
7002
+ timeout_ms: rest.timeout_ms ?? timeoutMs,
7003
+ include_results: rest.include_results ?? includeResults
7004
+ };
7005
+ }
7006
+ function buildOpsWaitBody(params) {
7007
+ const {
7008
+ opId,
7009
+ nextCursor,
7010
+ includeFailedRuns,
7011
+ intervalMs,
7012
+ maxPolls,
7013
+ timeoutMs,
7014
+ includeResults,
7015
+ ...rest
7016
+ } = params;
7017
+ return {
7018
+ ...rest,
7019
+ op_id: rest.op_id ?? opId,
7020
+ cursor: rest.cursor ?? nextCursor,
7021
+ include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
7022
+ interval_ms: rest.interval_ms ?? intervalMs,
7023
+ max_polls: rest.max_polls ?? maxPolls,
7024
+ timeout_ms: rest.timeout_ms ?? timeoutMs,
7025
+ include_results: rest.include_results ?? includeResults
7026
+ };
7027
+ }
5441
7028
  function buildOpsDebugOptions(params) {
5442
7029
  const {
5443
7030
  opId,
@@ -5515,6 +7102,8 @@ function normalizeOpsSinkRequest(sink) {
5515
7102
  nangoAction,
5516
7103
  proxyPath,
5517
7104
  nangoProxyPath,
7105
+ method,
7106
+ httpMethod,
5518
7107
  fieldMap,
5519
7108
  requiredFields,
5520
7109
  writeConfirmed,
@@ -5533,6 +7122,7 @@ function normalizeOpsSinkRequest(sink) {
5533
7122
  const nango_action = rest.nango_action ?? nangoAction;
5534
7123
  const proxy_path = rest.proxy_path ?? proxyPath;
5535
7124
  const nango_proxy_path = rest.nango_proxy_path ?? nangoProxyPath;
7125
+ const http_method = rest.http_method ?? httpMethod;
5536
7126
  const field_map = rest.field_map ?? fieldMap;
5537
7127
  const required_fields = rest.required_fields ?? requiredFields;
5538
7128
  const write_confirmed = rest.write_confirmed ?? writeConfirmed;
@@ -5547,6 +7137,9 @@ function normalizeOpsSinkRequest(sink) {
5547
7137
  if (nango_action !== void 0 && normalizedConfig.nango_action === void 0) normalizedConfig.nango_action = nango_action;
5548
7138
  if (proxy_path !== void 0 && normalizedConfig.proxy_path === void 0) normalizedConfig.proxy_path = proxy_path;
5549
7139
  if (nango_proxy_path !== void 0 && normalizedConfig.nango_proxy_path === void 0) normalizedConfig.nango_proxy_path = nango_proxy_path;
7140
+ if (method !== void 0 && normalizedConfig.method === void 0) normalizedConfig.method = method;
7141
+ if (http_method !== void 0 && normalizedConfig.http_method === void 0) normalizedConfig.http_method = http_method;
7142
+ if (normalizedConfig.method === void 0 && http_method !== void 0) normalizedConfig.method = http_method;
5550
7143
  if (field_map !== void 0 && normalizedConfig.field_map === void 0) normalizedConfig.field_map = field_map;
5551
7144
  if (required_fields !== void 0 && normalizedConfig.required_fields === void 0) normalizedConfig.required_fields = required_fields;
5552
7145
  if (write_confirmed !== void 0 && normalizedConfig.write_confirmed === void 0) normalizedConfig.write_confirmed = write_confirmed;
@@ -5566,6 +7159,8 @@ function normalizeOpsSinkRequest(sink) {
5566
7159
  nango_action,
5567
7160
  proxy_path,
5568
7161
  nango_proxy_path,
7162
+ method,
7163
+ http_method,
5569
7164
  field_map,
5570
7165
  required_fields,
5571
7166
  write_confirmed,
@@ -5573,6 +7168,10 @@ function normalizeOpsSinkRequest(sink) {
5573
7168
  config: normalizedConfig
5574
7169
  };
5575
7170
  }
7171
+ function normalizeOpsDestinationRequest(destination) {
7172
+ if (!destination || typeof destination !== "object" || Array.isArray(destination)) return destination;
7173
+ return normalizeOpsSinkRequest(destination);
7174
+ }
5576
7175
  function normalizeOpsSinkConfigRequest(config) {
5577
7176
  const out = { ...config ?? {} };
5578
7177
  if (out.connection_id === void 0 && out.connectionId !== void 0) out.connection_id = out.connectionId;
@@ -5586,6 +7185,8 @@ function normalizeOpsSinkConfigRequest(config) {
5586
7185
  if (out.nango_action === void 0 && out.nangoAction !== void 0) out.nango_action = out.nangoAction;
5587
7186
  if (out.proxy_path === void 0 && out.proxyPath !== void 0) out.proxy_path = out.proxyPath;
5588
7187
  if (out.nango_proxy_path === void 0 && out.nangoProxyPath !== void 0) out.nango_proxy_path = out.nangoProxyPath;
7188
+ if (out.http_method === void 0 && out.httpMethod !== void 0) out.http_method = out.httpMethod;
7189
+ if (out.method === void 0 && out.http_method !== void 0) out.method = out.http_method;
5589
7190
  if (out.field_map === void 0 && out.fieldMap !== void 0) out.field_map = out.fieldMap;
5590
7191
  if (out.required_fields === void 0 && out.requiredFields !== void 0) out.required_fields = out.requiredFields;
5591
7192
  if (out.write_confirmed === void 0 && out.writeConfirmed !== void 0) out.write_confirmed = out.writeConfirmed;
@@ -5659,7 +7260,6 @@ function toSnakeConfig(params) {
5659
7260
  return {
5660
7261
  system_prompt: params.systemPrompt || params.system_prompt || "You are a senior business research analyst. Use multi-model evidence carefully and return concise structured enrichment.",
5661
7262
  user_template: params.userTemplate || params.user_template || params.prompt,
5662
- model: params.model,
5663
7263
  temperature: params.temperature,
5664
7264
  max_concurrency: params.maxConcurrency || params.max_concurrency,
5665
7265
  max_tokens: params.maxTokens || params.max_tokens,
@@ -5683,13 +7283,10 @@ var Ai = class {
5683
7283
  /**
5684
7284
  * Run Custom AI Enrichment - Multi Model.
5685
7285
  *
5686
- * Uses OpenRouter Fusion for multi-model analysis with web search/fetch enabled
5687
- * inside Fusion, then synthesizes the requested structured output fields.
7286
+ * Uses the hosted default model with bounded synthesis, then returns the
7287
+ * requested structured output fields.
5688
7288
  */
5689
7289
  async multiModel(params) {
5690
- if (!params.model) {
5691
- throw new Error('model is required. Use an OpenRouter id such as "anthropic/claude-sonnet-4" or "google/gemini-2.5-flash".');
5692
- }
5693
7290
  if (!params.prompt && !params.userTemplate && !params.user_template) {
5694
7291
  throw new Error("prompt or userTemplate is required.");
5695
7292
  }
@@ -5906,6 +7503,10 @@ var GtmKernel = class {
5906
7503
  days: options.days,
5907
7504
  network_days: options.networkDays,
5908
7505
  min_sample_size: options.minSampleSize,
7506
+ holdout_min_sample_size: options.holdoutMinSampleSize,
7507
+ predictive_min_labeled_outcomes: options.predictiveMinLabeledOutcomes,
7508
+ predictive_min_positive_outcomes: options.predictiveMinPositiveOutcomes,
7509
+ predictive_min_memory_sample_size: options.predictiveMinMemorySampleSize,
5909
7510
  min_workspace_count: options.minWorkspaceCount,
5910
7511
  min_privacy_k: options.minPrivacyK,
5911
7512
  include_memory: options.includeMemory,
@@ -5972,9 +7573,11 @@ var GtmKernel = class {
5972
7573
  write_routine_outcomes: input.writeRoutineOutcomes
5973
7574
  });
5974
7575
  }
5975
- /** Start a background Instantly webhook-events pull and route results into the GTM feedback loop. */
7576
+ /** Start a background Instantly webhook-events or email-history pull and route results into the GTM feedback loop. */
5976
7577
  async pullInstantlyFeedback(input) {
5977
7578
  return this.callMcp("gtm_instantly_feedback_pull", {
7579
+ source: input.source,
7580
+ instantly_profile: input.instantlyProfile,
5978
7581
  campaign_id: input.campaignId,
5979
7582
  campaign_build_id: input.campaignBuildId,
5980
7583
  provider_link_id: input.providerLinkId,
@@ -5986,6 +7589,9 @@ var GtmKernel = class {
5986
7589
  to: input.to,
5987
7590
  limit: input.limit,
5988
7591
  max_pages: input.maxPages,
7592
+ email_type: input.emailType,
7593
+ mode: input.mode,
7594
+ sort_order: input.sortOrder,
5989
7595
  create_memory: input.createMemory,
5990
7596
  write_routine_outcomes: input.writeRoutineOutcomes,
5991
7597
  dry_run: input.dryRun,
@@ -6115,6 +7721,7 @@ var GtmKernel = class {
6115
7721
  days: input.days,
6116
7722
  network_days: input.networkDays,
6117
7723
  min_sample_size: input.minSampleSize,
7724
+ holdout_min_sample_size: input.holdoutMinSampleSize,
6118
7725
  min_workspace_count: input.minWorkspaceCount,
6119
7726
  min_privacy_k: input.minPrivacyK,
6120
7727
  include_memory: input.includeMemory,
@@ -6135,6 +7742,7 @@ var GtmKernel = class {
6135
7742
  days: input.days,
6136
7743
  network_days: input.networkDays,
6137
7744
  min_sample_size: input.minSampleSize,
7745
+ holdout_min_sample_size: input.holdoutMinSampleSize,
6138
7746
  min_workspace_count: input.minWorkspaceCount,
6139
7747
  min_privacy_k: input.minPrivacyK,
6140
7748
  include_memory: input.includeMemory,
@@ -6259,6 +7867,29 @@ var GtmKernel = class {
6259
7867
  include_details: options.includeDetails
6260
7868
  });
6261
7869
  }
7870
+ /** Search the Agency Autopilot safe-action catalog for agency-style lead lists, Clay tables, and GTM motions. */
7871
+ async agencyAutopilotCapabilityCatalog(options = {}) {
7872
+ return this.callMcp("gtm_agency_autopilot_capability_catalog", {
7873
+ query: options.query,
7874
+ family: options.family,
7875
+ phase: options.phase,
7876
+ account_label: options.accountLabel,
7877
+ workspace_label: options.workspaceLabel,
7878
+ target_count: options.targetCount,
7879
+ limit: options.limit,
7880
+ include_agent_prompts: options.includeAgentPrompts
7881
+ });
7882
+ }
7883
+ /** Search agency operating playbooks Agency Autopilot can use for lead lists, Clay tables, GTM motions, and proof gates. */
7884
+ async agencyAutopilotPlaybookCatalog(options = {}) {
7885
+ return this.callMcp("gtm_agency_autopilot_playbook_catalog", {
7886
+ query: options.query,
7887
+ playbook_slug: options.playbookSlug,
7888
+ outcome_type: options.outcomeType,
7889
+ limit: options.limit,
7890
+ include_required_fields: options.includeRequiredFields
7891
+ });
7892
+ }
6262
7893
  /** Build the read-only Memory, Brain, risk, and provider-route runbook needed before planning a campaign. */
6263
7894
  async campaignStartContext(input = {}) {
6264
7895
  return this.callMcp("gtm_campaign_start_context", {
@@ -6617,6 +8248,35 @@ var GtmKernel = class {
6617
8248
  user_display_name: input.userDisplayName
6618
8249
  });
6619
8250
  }
8251
+ /** Prepare the full Nango provider search, connect, pull/export, Ops, and campaign-route flow. */
8252
+ async prepareNangoIntegrationFlow(input = {}) {
8253
+ return this.callMcp("nango_integration_flow_prepare", {
8254
+ query: input.query,
8255
+ search: input.search,
8256
+ provider_id: input.providerId,
8257
+ provider: input.provider,
8258
+ integration_id: input.integrationId,
8259
+ provider_config_key: input.providerConfigKey,
8260
+ workspace_connection_id: input.workspaceConnectionId,
8261
+ connection_id: input.connectionId,
8262
+ nango_connection_id: input.nangoConnectionId,
8263
+ intent: input.intent,
8264
+ action_name: input.actionName,
8265
+ tool_name: input.toolName,
8266
+ proxy_path: input.proxyPath,
8267
+ method: input.method,
8268
+ input: input.input,
8269
+ cadence: input.cadence,
8270
+ field_map: input.fieldMap,
8271
+ required_fields: input.requiredFields,
8272
+ confirm_spend: input.confirmSpend,
8273
+ write_confirmed: input.writeConfirmed,
8274
+ layer: input.layer,
8275
+ campaign_id: input.campaignId,
8276
+ limit: input.limit,
8277
+ include_provider_catalog: input.includeProviderCatalog
8278
+ });
8279
+ }
6620
8280
  /** List Nango-backed action tools for a workspace connection without executing them. */
6621
8281
  async listNangoTools(options = {}) {
6622
8282
  return this.callMcp("nango_mcp_tools_list", {
@@ -6639,6 +8299,12 @@ var GtmKernel = class {
6639
8299
  nango_connection_id: input.nangoConnectionId,
6640
8300
  action_name: input.actionName,
6641
8301
  tool_name: input.toolName,
8302
+ delivery_mode: input.deliveryMode,
8303
+ proxy_path: input.proxyPath,
8304
+ nango_proxy_path: input.nangoProxyPath,
8305
+ method: input.method,
8306
+ http_method: input.httpMethod,
8307
+ proxy_headers: input.proxyHeaders,
6642
8308
  input: input.input,
6643
8309
  async: input.async,
6644
8310
  max_retries: input.maxRetries,
@@ -6788,6 +8454,7 @@ function compact2(value) {
6788
8454
  }
6789
8455
 
6790
8456
  // src/index.ts
8457
+ var MCP_TOOL_CACHE_TTL_MS = 3e4;
6791
8458
  function inferMcpToolCategory(toolName) {
6792
8459
  if (typeof toolName !== "string" || !toolName) return void 0;
6793
8460
  if (toolName.startsWith("ops_") || toolName === "get_ops_readiness" || toolName === "get_gtm_ops_readiness" || toolName.startsWith("gtm_") || [
@@ -6919,6 +8586,21 @@ var Signaliz = class {
6919
8586
  }
6920
8587
  /** List all available MCP tools */
6921
8588
  async listTools() {
8589
+ const now = Date.now();
8590
+ if (this.toolListCache && this.toolListCache.expiresAt > now) {
8591
+ return this.toolListCache.promise;
8592
+ }
8593
+ const promise = this.fetchTools().catch((error) => {
8594
+ if (this.toolListCache?.promise === promise) this.toolListCache = void 0;
8595
+ throw error;
8596
+ });
8597
+ this.toolListCache = {
8598
+ expiresAt: now + MCP_TOOL_CACHE_TTL_MS,
8599
+ promise
8600
+ };
8601
+ return promise;
8602
+ }
8603
+ async fetchTools() {
6922
8604
  try {
6923
8605
  const manifest = await this.client.mcp("tools/call", {
6924
8606
  name: "get_tool_manifest",