@signaliz/sdk 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -12
- package/dist/{chunk-5JNKSMNW.mjs → chunk-VFBQCWOM.mjs} +2211 -169
- package/dist/cli.js +5700 -3280
- package/dist/cli.mjs +237 -24
- package/dist/index.d.mts +2634 -1939
- package/dist/index.d.ts +2634 -1939
- package/dist/index.js +2211 -169
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +2211 -169
- package/dist/mcp-config.mjs +1 -1
- package/package.json +1 -1
|
@@ -212,25 +212,31 @@ var HttpClient = class {
|
|
|
212
212
|
async getToken() {
|
|
213
213
|
if (this.apiKey) return this.apiKey;
|
|
214
214
|
if (this.accessToken) return this.accessToken;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
throw new SignalizError({
|
|
226
|
-
code: "AUTH_FAILED",
|
|
227
|
-
message: "Failed to obtain access token",
|
|
228
|
-
errorType: "auth_expired"
|
|
215
|
+
if (this.accessTokenPromise) return this.accessTokenPromise;
|
|
216
|
+
this.accessTokenPromise = (async () => {
|
|
217
|
+
const res = await fetch("https://api.signaliz.com/token", {
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers: { "Content-Type": "application/json" },
|
|
220
|
+
body: JSON.stringify({
|
|
221
|
+
grant_type: "client_credentials",
|
|
222
|
+
client_id: this.clientId,
|
|
223
|
+
client_secret: this.clientSecret
|
|
224
|
+
})
|
|
229
225
|
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
226
|
+
if (!res.ok) {
|
|
227
|
+
throw new SignalizError({
|
|
228
|
+
code: "AUTH_FAILED",
|
|
229
|
+
message: "Failed to obtain access token",
|
|
230
|
+
errorType: "auth_expired"
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
const data = await res.json();
|
|
234
|
+
this.accessToken = data.access_token;
|
|
235
|
+
return this.accessToken;
|
|
236
|
+
})().finally(() => {
|
|
237
|
+
this.accessTokenPromise = void 0;
|
|
238
|
+
});
|
|
239
|
+
return this.accessTokenPromise;
|
|
234
240
|
}
|
|
235
241
|
};
|
|
236
242
|
function sleep(ms) {
|
|
@@ -479,7 +485,6 @@ var Signals = class {
|
|
|
479
485
|
if (params.online !== void 0) args.online = params.online;
|
|
480
486
|
if (params.targetSignalCount) args.target_signal_count = params.targetSignalCount;
|
|
481
487
|
if (params.lookbackDays) args.lookback_days = params.lookbackDays;
|
|
482
|
-
if (params.model) args.model = params.model;
|
|
483
488
|
if (params.enableDeepSearch) args.enable_deep_search = params.enableDeepSearch;
|
|
484
489
|
if (params.enableOutreachIntelligence) args.enable_outreach_intelligence = params.enableOutreachIntelligence;
|
|
485
490
|
if (params.enablePredictiveIntelligence) args.enable_predictive_intelligence = params.enablePredictiveIntelligence;
|
|
@@ -774,6 +779,10 @@ var Campaigns = class {
|
|
|
774
779
|
async artifacts(campaignBuildId) {
|
|
775
780
|
return this.listCampaignBuildArtifacts(campaignBuildId);
|
|
776
781
|
}
|
|
782
|
+
/** Generate fresh signed URLs for a downloadable campaign artifact. */
|
|
783
|
+
async downloadArtifact(campaignBuildId, options) {
|
|
784
|
+
return this.downloadCampaignArtifact(campaignBuildId, options);
|
|
785
|
+
}
|
|
777
786
|
/** Cancel a queued or running build. */
|
|
778
787
|
async cancel(campaignBuildId, reason) {
|
|
779
788
|
return this.cancelCampaignBuild(campaignBuildId, reason);
|
|
@@ -818,13 +827,21 @@ var Campaigns = class {
|
|
|
818
827
|
dryRun: isDryRun,
|
|
819
828
|
requestedTargetCount: data.requested_target_count,
|
|
820
829
|
plannedTargetCount: data.planned_target_count,
|
|
830
|
+
acquisitionMode: data.acquisition_mode,
|
|
831
|
+
acquisitionSource: data.acquisition_source,
|
|
832
|
+
cacheReusePolicy: data.cache_reuse_policy,
|
|
821
833
|
estimatedCredits: data.estimated_credits,
|
|
822
834
|
estimatedDurationSeconds: data.estimated_duration_seconds,
|
|
823
835
|
targetLimitApplied: data.target_limit_applied,
|
|
824
836
|
targetLimitReason: data.target_limit_reason,
|
|
825
837
|
maxSupportedTargetCount: data.max_supported_target_count,
|
|
826
838
|
brainContext: data.brain_context ?? {},
|
|
827
|
-
|
|
839
|
+
learningHoldout: data.learning_holdout ?? {},
|
|
840
|
+
providerRoute: mapProviderRoute(data),
|
|
841
|
+
effectiveSourceRouting: recordOrNull(data.effective_source_routing ?? data.source_routing),
|
|
842
|
+
sourcePlan: recordOrNull(data.source_plan ?? data.plan?.source_plan),
|
|
843
|
+
sourceRoutes: recordArray(data.source_routes ?? data.source_plan?.routes ?? data.plan?.source_plan?.routes),
|
|
844
|
+
sourceShards: recordArray(data.source_shards ?? data.source_plan?.shards ?? data.plan?.source_plan?.shards)
|
|
828
845
|
};
|
|
829
846
|
}
|
|
830
847
|
async getCampaignBuildStatus(campaignBuildId) {
|
|
@@ -839,14 +856,24 @@ var Campaigns = class {
|
|
|
839
856
|
});
|
|
840
857
|
return (data.artifacts ?? []).map(mapArtifact);
|
|
841
858
|
}
|
|
859
|
+
async downloadCampaignArtifact(campaignBuildId, options) {
|
|
860
|
+
const args = { campaign_build_id: campaignBuildId };
|
|
861
|
+
if (options?.format) args.format = options.format;
|
|
862
|
+
const data = await this.callMcp("download_campaign_artifact", args);
|
|
863
|
+
return mapArtifactDownloadResult(data);
|
|
864
|
+
}
|
|
842
865
|
async getCampaignBuildRows(campaignBuildId, options) {
|
|
843
866
|
const args = { campaign_build_id: campaignBuildId };
|
|
844
867
|
if (options?.limit) args.page_size = options.limit;
|
|
845
868
|
if (options?.cursor) args.cursor = options.cursor;
|
|
869
|
+
if (options?.includeData !== void 0) args.include_data = options.includeData;
|
|
870
|
+
if (options?.includeRaw !== void 0) args.include_raw = options.includeRaw;
|
|
846
871
|
const filters = {};
|
|
847
872
|
if (options?.segment) filters.segment = options.segment;
|
|
848
873
|
if (options?.rowStatus) filters.row_status = options.rowStatus;
|
|
849
874
|
if (options?.qualified !== void 0) filters.qualified = options.qualified;
|
|
875
|
+
if (options?.cached !== void 0) filters.cached = options.cached;
|
|
876
|
+
if (options?.exportReady !== void 0) filters.export_ready = options.exportReady;
|
|
850
877
|
if (Object.keys(filters).length > 0) args.filters = filters;
|
|
851
878
|
const data = await this.callMcp("get_campaign_build_rows", args);
|
|
852
879
|
return {
|
|
@@ -871,6 +898,7 @@ var Campaigns = class {
|
|
|
871
898
|
};
|
|
872
899
|
if (options?.destinationId) args.destination_id = options.destinationId;
|
|
873
900
|
if (options?.destinationConfig) args.destination_config = options.destinationConfig;
|
|
901
|
+
if (options?.allowPartialDelivery === true) args.allow_partial_delivery = true;
|
|
874
902
|
const data = await this.callMcp("approve_campaign_delivery", args);
|
|
875
903
|
return {
|
|
876
904
|
campaignBuildId: data.campaign_build_id,
|
|
@@ -879,7 +907,10 @@ var Campaigns = class {
|
|
|
879
907
|
message: data.message ?? "",
|
|
880
908
|
deliveryId: data.delivery_id,
|
|
881
909
|
deliveryIds: data.delivery_ids,
|
|
882
|
-
approvedCount: data.approved_count
|
|
910
|
+
approvedCount: data.approved_count,
|
|
911
|
+
partialDelivery: data.partial_delivery,
|
|
912
|
+
effectiveTargetCount: data.effective_target_count,
|
|
913
|
+
requestedTargetCount: data.requested_target_count
|
|
883
914
|
};
|
|
884
915
|
}
|
|
885
916
|
async cancelCampaignBuild(campaignBuildId, reason) {
|
|
@@ -932,17 +963,50 @@ function mapStatus(data) {
|
|
|
932
963
|
warnings: diagnosticMessages(data.warnings),
|
|
933
964
|
errors: diagnosticMessages(data.errors),
|
|
934
965
|
artifactCount: data.artifact_count ?? 0,
|
|
966
|
+
artifactDownloads: Array.isArray(data.artifact_downloads) ? data.artifact_downloads.map(mapArtifactDownload) : [],
|
|
967
|
+
customerRowCounts: mapCustomerRowCounts(data.customer_row_counts),
|
|
968
|
+
phaseAttemptTotals: recordOrNull(data.phase_attempt_totals) ?? void 0,
|
|
935
969
|
providerRoute: mapProviderRoute(data),
|
|
936
970
|
triggerRunId: typeof data.trigger_run_id === "string" ? data.trigger_run_id : null,
|
|
937
971
|
staleRunningPhase: data.stale_running_phase === true,
|
|
938
972
|
phaseAgeSeconds: numberOrNull(data.phase_age_seconds),
|
|
939
973
|
diagnostics: recordOrNull(data.diagnostics) ?? {},
|
|
940
974
|
nextAction: formatNextAction(data.next_action),
|
|
975
|
+
approvalAction: formatNextAction(data.approval_action),
|
|
941
976
|
createdAt: data.created_at,
|
|
942
977
|
updatedAt: data.updated_at,
|
|
943
978
|
completedAt: data.completed_at
|
|
944
979
|
};
|
|
945
980
|
}
|
|
981
|
+
function mapCustomerRowCounts(value) {
|
|
982
|
+
const record = recordOrNull(value);
|
|
983
|
+
if (!record) return void 0;
|
|
984
|
+
return {
|
|
985
|
+
requestedTarget: numberOrNull(record.requested_target),
|
|
986
|
+
acquiredRows: numberOrNull(record.acquired_rows) ?? void 0,
|
|
987
|
+
acceptedRows: numberOrNull(record.accepted_rows) ?? void 0,
|
|
988
|
+
usableRows: numberOrNull(record.usable_rows) ?? void 0,
|
|
989
|
+
copiedRows: numberOrNull(record.copied_rows) ?? void 0,
|
|
990
|
+
approvalReadyRows: numberOrNull(record.approval_ready_rows) ?? void 0,
|
|
991
|
+
qaReadyRows: numberOrNull(record.qa_ready_rows) ?? void 0,
|
|
992
|
+
deliveredRows: numberOrNull(record.delivered_rows) ?? void 0,
|
|
993
|
+
disqualifiedRows: numberOrNull(record.disqualified_rows) ?? void 0,
|
|
994
|
+
reviewableRows: numberOrNull(record.reviewable_rows) ?? void 0,
|
|
995
|
+
rowFailures: numberOrNull(record.row_failures) ?? void 0,
|
|
996
|
+
acceptedShortfall: numberOrNull(record.accepted_shortfall),
|
|
997
|
+
usableShortfall: numberOrNull(record.usable_shortfall),
|
|
998
|
+
qaReadyShortfall: numberOrNull(record.qa_ready_shortfall),
|
|
999
|
+
deliveryShortfall: numberOrNull(record.delivery_shortfall),
|
|
1000
|
+
fillRatio: numberOrNull(record.fill_ratio),
|
|
1001
|
+
qaReadyFillRatio: numberOrNull(record.qa_ready_fill_ratio),
|
|
1002
|
+
deliveredFillRatio: numberOrNull(record.delivered_fill_ratio),
|
|
1003
|
+
terminalReason: typeof record.terminal_reason === "string" ? record.terminal_reason : null,
|
|
1004
|
+
acceptedShortfallReason: typeof record.accepted_shortfall_reason === "string" ? record.accepted_shortfall_reason : null,
|
|
1005
|
+
usableShortfallReason: typeof record.usable_shortfall_reason === "string" ? record.usable_shortfall_reason : null,
|
|
1006
|
+
qaReadyShortfallReason: typeof record.qa_ready_shortfall_reason === "string" ? record.qa_ready_shortfall_reason : null,
|
|
1007
|
+
deliveryShortfallReason: typeof record.delivery_shortfall_reason === "string" ? record.delivery_shortfall_reason : null
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
946
1010
|
function mapProviderRoute(data) {
|
|
947
1011
|
const brainContext = recordOrNull(data?.brain_context);
|
|
948
1012
|
const plan = recordOrNull(data?.provider_route_plan) ?? recordOrNull(brainContext?.provider_route_plan);
|
|
@@ -969,6 +1033,9 @@ function recordOrNull(value) {
|
|
|
969
1033
|
function stringArray(value) {
|
|
970
1034
|
return Array.isArray(value) ? value.map((item) => String(item || "").trim()).filter(Boolean) : [];
|
|
971
1035
|
}
|
|
1036
|
+
function recordArray(value) {
|
|
1037
|
+
return Array.isArray(value) ? value.map(recordOrNull).filter((item) => Boolean(item)) : [];
|
|
1038
|
+
}
|
|
972
1039
|
function diagnosticMessages(value) {
|
|
973
1040
|
if (!Array.isArray(value)) return [];
|
|
974
1041
|
return value.map((item) => {
|
|
@@ -1020,13 +1087,56 @@ function mapArtifact(a) {
|
|
|
1020
1087
|
artifactType: a.artifact_type,
|
|
1021
1088
|
destination: a.destination,
|
|
1022
1089
|
storagePath: a.storage_path,
|
|
1090
|
+
format: a.format ?? null,
|
|
1023
1091
|
signedUrl: a.signed_url,
|
|
1092
|
+
downloadUrl: a.download_url ?? null,
|
|
1093
|
+
manifestUrl: a.manifest_url ?? null,
|
|
1094
|
+
expiresAt: a.expires_at ?? null,
|
|
1024
1095
|
rowCount: a.row_count ?? 0,
|
|
1025
1096
|
checksum: a.checksum,
|
|
1026
1097
|
metadata: a.metadata ?? {},
|
|
1027
1098
|
createdAt: a.created_at
|
|
1028
1099
|
};
|
|
1029
1100
|
}
|
|
1101
|
+
function mapArtifactDownload(data) {
|
|
1102
|
+
return {
|
|
1103
|
+
id: data.id,
|
|
1104
|
+
artifactType: data.artifact_type ?? null,
|
|
1105
|
+
format: data.format ?? null,
|
|
1106
|
+
rowCount: data.row_count ?? 0,
|
|
1107
|
+
signedUrl: data.signed_url ?? null,
|
|
1108
|
+
downloadUrl: data.download_url ?? null,
|
|
1109
|
+
manifestUrl: data.manifest_url ?? null,
|
|
1110
|
+
expiresAt: data.expires_at ?? null
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
function mapArtifactDownloadResult(data) {
|
|
1114
|
+
return {
|
|
1115
|
+
campaignBuildId: data.campaign_build_id,
|
|
1116
|
+
artifactId: data.artifact_id,
|
|
1117
|
+
format: data.format,
|
|
1118
|
+
rowCount: data.row_count ?? 0,
|
|
1119
|
+
byteSize: numberOrNull(data.byte_size),
|
|
1120
|
+
partCount: data.part_count ?? 0,
|
|
1121
|
+
checksum: data.checksum ?? null,
|
|
1122
|
+
signedUrl: data.signed_url ?? null,
|
|
1123
|
+
downloadUrl: data.download_url ?? null,
|
|
1124
|
+
manifestUrl: data.manifest_url ?? null,
|
|
1125
|
+
expiresAt: data.expires_at ?? null,
|
|
1126
|
+
parts: Array.isArray(data.parts) ? data.parts.map(mapArtifactDownloadPart) : [],
|
|
1127
|
+
downloadCommands: recordOrNull(data.download_commands) ?? {},
|
|
1128
|
+
expiresInSeconds: numberOrNull(data.expires_in_seconds)
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
function mapArtifactDownloadPart(data) {
|
|
1132
|
+
return {
|
|
1133
|
+
partIndex: data.part_index ?? 0,
|
|
1134
|
+
rowCount: data.row_count ?? 0,
|
|
1135
|
+
byteSize: numberOrNull(data.byte_size),
|
|
1136
|
+
checksum: data.checksum ?? null,
|
|
1137
|
+
signedUrl: data.signed_url ?? null
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1030
1140
|
function mapScope(data) {
|
|
1031
1141
|
return {
|
|
1032
1142
|
campaignScopeId: data.campaign_scope_id,
|
|
@@ -1080,8 +1190,30 @@ function buildArgs(request) {
|
|
|
1080
1190
|
if (request.allowDownscale !== void 0) args.allow_downscale = request.allowDownscale;
|
|
1081
1191
|
if (request.confirmSpend !== void 0) args.confirm_spend = request.confirmSpend;
|
|
1082
1192
|
if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
|
|
1193
|
+
if (request.acquisitionMode) args.acquisition_mode = request.acquisitionMode;
|
|
1194
|
+
if (request.cacheReusePolicy) {
|
|
1195
|
+
args.cache_reuse_policy = {
|
|
1196
|
+
allow_verified_cache: request.cacheReusePolicy.allowVerifiedCache,
|
|
1197
|
+
suppress_prior_campaign_ids: request.cacheReusePolicy.suppressPriorCampaignIds,
|
|
1198
|
+
suppress_prior_list_ids: request.cacheReusePolicy.suppressPriorListIds,
|
|
1199
|
+
uniqueness: request.cacheReusePolicy.uniqueness,
|
|
1200
|
+
require_usage_metadata: request.cacheReusePolicy.requireUsageMetadata,
|
|
1201
|
+
verified_cache_ttl_days: request.cacheReusePolicy.verifiedCacheTtlDays
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1083
1204
|
if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
|
|
1084
1205
|
if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
|
|
1206
|
+
if (request.learningHoldout) {
|
|
1207
|
+
args.learning_holdout = {
|
|
1208
|
+
enabled: request.learningHoldout.enabled,
|
|
1209
|
+
control_percentage: request.learningHoldout.controlPercentage,
|
|
1210
|
+
min_control_size: request.learningHoldout.minControlSize,
|
|
1211
|
+
experiment_key: request.learningHoldout.experimentKey,
|
|
1212
|
+
source_campaign_id: request.learningHoldout.sourceCampaignId,
|
|
1213
|
+
primary_metric: request.learningHoldout.primaryMetric
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
if (request.campaignStrategyContext) args.campaign_strategy_context = request.campaignStrategyContext;
|
|
1085
1217
|
if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
|
|
1086
1218
|
if (request.icp) {
|
|
1087
1219
|
args.icp = {
|
|
@@ -1123,7 +1255,17 @@ function buildArgs(request) {
|
|
|
1123
1255
|
max_body_words: request.copy.maxBodyWords,
|
|
1124
1256
|
sender_context: request.copy.senderContext,
|
|
1125
1257
|
offer_context: request.copy.offerContext,
|
|
1126
|
-
model: request.copy.model
|
|
1258
|
+
model: request.copy.model,
|
|
1259
|
+
style_source: request.copy.styleSource ? {
|
|
1260
|
+
sample_text: request.copy.styleSource.sampleText,
|
|
1261
|
+
campaign_ids: request.copy.styleSource.campaignIds,
|
|
1262
|
+
artifact_ids: request.copy.styleSource.artifactIds
|
|
1263
|
+
} : void 0,
|
|
1264
|
+
sequence_steps: request.copy.sequenceSteps,
|
|
1265
|
+
copy_schema: request.copy.copySchema,
|
|
1266
|
+
banned_phrases: request.copy.bannedPhrases,
|
|
1267
|
+
approval_required: request.copy.approvalRequired,
|
|
1268
|
+
quality_tier: request.copy.qualityTier
|
|
1127
1269
|
};
|
|
1128
1270
|
}
|
|
1129
1271
|
if (request.delivery) {
|
|
@@ -1186,6 +1328,8 @@ var DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS = {
|
|
|
1186
1328
|
}
|
|
1187
1329
|
};
|
|
1188
1330
|
var DEFAULT_CAMPAIGN_BUILDER_BUILT_INS = [
|
|
1331
|
+
"company_discovery",
|
|
1332
|
+
"people_discovery",
|
|
1189
1333
|
"lead_generation",
|
|
1190
1334
|
"email_finding",
|
|
1191
1335
|
"email_verification",
|
|
@@ -1194,6 +1338,8 @@ var DEFAULT_CAMPAIGN_BUILDER_BUILT_INS = [
|
|
|
1194
1338
|
var CAMPAIGN_BUILDER_BUILT_IN_ROUTE_IDS = {
|
|
1195
1339
|
lead_generation: "signaliz-lead-generation",
|
|
1196
1340
|
local_leads: "signaliz-local-leads",
|
|
1341
|
+
company_discovery: "signaliz-company-discovery",
|
|
1342
|
+
people_discovery: "signaliz-people-discovery",
|
|
1197
1343
|
email_finding: "signaliz-email-finding",
|
|
1198
1344
|
email_verification: "signaliz-email-verification",
|
|
1199
1345
|
signals: "signaliz-signals"
|
|
@@ -1211,8 +1357,8 @@ var CAMPAIGN_BUILDER_OPERATING_PLAYBOOKS = [
|
|
|
1211
1357
|
slug: "cache-first-large-list",
|
|
1212
1358
|
label: "Cache-First Large List",
|
|
1213
1359
|
whenToUse: [
|
|
1214
|
-
"The
|
|
1215
|
-
"The deliverable is a
|
|
1360
|
+
"The operator explicitly references a previous campaign, prior list, seed list, or suppression baseline.",
|
|
1361
|
+
"The deliverable is a top-up, continuation, or backfill where prior campaign context should guide reuse."
|
|
1216
1362
|
],
|
|
1217
1363
|
sequence: [
|
|
1218
1364
|
"Inventory reusable cache before paid sourcing.",
|
|
@@ -1418,7 +1564,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
|
|
|
1418
1564
|
],
|
|
1419
1565
|
requireVerifiedEmail: true
|
|
1420
1566
|
},
|
|
1421
|
-
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1567
|
+
builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
|
|
1422
1568
|
preferredProviders: ["signaliz_native"],
|
|
1423
1569
|
memoryQueries: [{
|
|
1424
1570
|
query: "industrial OT net-new prior email suppression verified manufacturing embedded systems field service cyber resilience business continuity",
|
|
@@ -1492,7 +1638,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
|
|
|
1492
1638
|
],
|
|
1493
1639
|
requireVerifiedEmail: true
|
|
1494
1640
|
},
|
|
1495
|
-
builtIns: ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"],
|
|
1641
|
+
builtIns: ["company_discovery", "people_discovery", "lead_generation", "local_leads", "email_finding", "email_verification", "signals"],
|
|
1496
1642
|
preferredProviders: ["signaliz_native", "octave", "clay_webhook", "apify"],
|
|
1497
1643
|
memoryQueries: [{
|
|
1498
1644
|
query: "mature non-medical home care agencies billable hours franchise caregiver recruiting proof gate qualification export approval",
|
|
@@ -1558,7 +1704,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
|
|
|
1558
1704
|
exclusions: ["enterprise holding company", "staffing", "recruiting", "software-only vendor", "freelancer-only profile"],
|
|
1559
1705
|
requireVerifiedEmail: true
|
|
1560
1706
|
},
|
|
1561
|
-
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1707
|
+
builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
|
|
1562
1708
|
preferredProviders: ["signaliz_native", "octave"],
|
|
1563
1709
|
memoryQueries: [{
|
|
1564
1710
|
query: "agency founder owner CEO marketing services suppression domain pool email verification final approval gate",
|
|
@@ -1640,7 +1786,7 @@ var CAMPAIGN_BUILDER_STRATEGY_TEMPLATES = [
|
|
|
1640
1786
|
],
|
|
1641
1787
|
requireVerifiedEmail: true
|
|
1642
1788
|
},
|
|
1643
|
-
builtIns: ["lead_generation", "email_finding", "email_verification", "signals"],
|
|
1789
|
+
builtIns: ["company_discovery", "people_discovery", "lead_generation", "email_finding", "email_verification", "signals"],
|
|
1644
1790
|
preferredProviders: ["signaliz_native", "octave"],
|
|
1645
1791
|
memoryQueries: [{
|
|
1646
1792
|
query: "cloud hosting infrastructure VMware Broadcom qualification verified email persona trigger SKU mapping",
|
|
@@ -1673,25 +1819,21 @@ var CampaignBuilderAgent = class {
|
|
|
1673
1819
|
async createPlan(request, options = {}) {
|
|
1674
1820
|
const resolvedRequest = applyCampaignBuilderStrategyTemplate(request);
|
|
1675
1821
|
const warnings = [];
|
|
1676
|
-
const workspaceContext =
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1822
|
+
const [workspaceContext, scopeResult] = await Promise.all([
|
|
1823
|
+
resolvedRequest.workspaceContext ? Promise.resolve(resolvedRequest.workspaceContext) : this.getWorkspaceContext(warnings),
|
|
1824
|
+
options.scopeCampaign === false ? Promise.resolve(void 0) : this.scopeCampaign(resolvedRequest, warnings),
|
|
1825
|
+
options.discoverCapabilities === false ? Promise.resolve(void 0) : this.discoverPlannedRoutes(resolvedRequest, warnings)
|
|
1826
|
+
]);
|
|
1681
1827
|
const plan = createCampaignBuilderAgentPlan(resolvedRequest, {
|
|
1682
1828
|
workspaceContext,
|
|
1683
1829
|
scopeBuildArgs: asRecord(scopeResult?.build_campaign_args ?? scopeResult?.buildCampaignArgs),
|
|
1684
1830
|
warnings
|
|
1685
1831
|
});
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
}
|
|
1692
|
-
if (options.includeDeliveryRisk !== false) {
|
|
1693
|
-
await this.attachDeliveryRiskPreflight(plan, warnings);
|
|
1694
|
-
}
|
|
1832
|
+
await Promise.all([
|
|
1833
|
+
options.includeStrategyMemoryStatus === false ? Promise.resolve() : this.attachStrategyMemoryStatus(plan, warnings),
|
|
1834
|
+
options.includeKernelPlan === false ? Promise.resolve() : this.attachKernelCampaignBuildPlan(plan, warnings),
|
|
1835
|
+
options.includeDeliveryRisk === false ? Promise.resolve() : this.attachDeliveryRiskPreflight(plan, warnings)
|
|
1836
|
+
]);
|
|
1695
1837
|
return plan;
|
|
1696
1838
|
}
|
|
1697
1839
|
async readiness(request, options = {}) {
|
|
@@ -1739,6 +1881,8 @@ var CampaignBuilderAgent = class {
|
|
|
1739
1881
|
},
|
|
1740
1882
|
brain_defaults: plan.buildRequest.brainDefaults,
|
|
1741
1883
|
brain_preflight: plan.buildRequest.brainPreflight,
|
|
1884
|
+
learning_holdout: plan.buildRequest.learningHoldout,
|
|
1885
|
+
campaign_strategy_context: plan.buildRequest.campaignStrategyContext,
|
|
1742
1886
|
delivery_risk_preflight: plan.buildRequest.deliveryRisk,
|
|
1743
1887
|
delivery_risk: plan.buildRequest.deliveryRisk
|
|
1744
1888
|
}),
|
|
@@ -1751,7 +1895,8 @@ var CampaignBuilderAgent = class {
|
|
|
1751
1895
|
estimated_credits: plan.estimatedCredits
|
|
1752
1896
|
},
|
|
1753
1897
|
brain_delivery_risk_preflight: plan.buildRequest.deliveryRisk,
|
|
1754
|
-
delivery_risk: plan.buildRequest.deliveryRisk
|
|
1898
|
+
delivery_risk: plan.buildRequest.deliveryRisk,
|
|
1899
|
+
learning_holdout: plan.buildRequest.learningHoldout
|
|
1755
1900
|
},
|
|
1756
1901
|
approval_required: plan.approvals.some((approval) => approval.blocking),
|
|
1757
1902
|
actor_type: "agent",
|
|
@@ -1860,7 +2005,8 @@ var CampaignBuilderAgent = class {
|
|
|
1860
2005
|
const destinationType = options.deliveryDestinationType ?? plan.buildRequest.delivery?.destinationType ?? "json";
|
|
1861
2006
|
result.deliveryApproval = await this.approveCampaignDelivery(campaignBuildId, destinationType, {
|
|
1862
2007
|
destinationId: options.deliveryDestinationId,
|
|
1863
|
-
destinationConfig: options.deliveryDestinationConfig ?? plan.buildRequest.delivery?.destinationConfig
|
|
2008
|
+
destinationConfig: options.deliveryDestinationConfig ?? plan.buildRequest.delivery?.destinationConfig,
|
|
2009
|
+
allowPartialDelivery: options.allowPartialDelivery
|
|
1864
2010
|
});
|
|
1865
2011
|
finalStatus = await this.waitForCampaignBuildStatus(
|
|
1866
2012
|
campaignBuildId,
|
|
@@ -1883,8 +2029,12 @@ var CampaignBuilderAgent = class {
|
|
|
1883
2029
|
const args = compact({
|
|
1884
2030
|
campaign_build_id: campaignBuildId,
|
|
1885
2031
|
page_size: options.limit,
|
|
1886
|
-
cursor: options.cursor
|
|
2032
|
+
cursor: options.cursor,
|
|
2033
|
+
include_data: options.includeData,
|
|
2034
|
+
include_raw: options.includeRaw
|
|
1887
2035
|
});
|
|
2036
|
+
if (options.cached !== void 0) filters.cached = options.cached;
|
|
2037
|
+
if (options.exportReady !== void 0) filters.export_ready = options.exportReady;
|
|
1888
2038
|
if (Object.keys(filters).length > 0) args.filters = filters;
|
|
1889
2039
|
const data = await this.callMcp("get_campaign_build_rows", args);
|
|
1890
2040
|
return mapAgentCampaignRowsResult(data);
|
|
@@ -1899,12 +2049,14 @@ var CampaignBuilderAgent = class {
|
|
|
1899
2049
|
return this.approveCampaignDelivery(campaignBuildId, destinationType, options);
|
|
1900
2050
|
}
|
|
1901
2051
|
async reviewBuild(campaignBuildId, options = {}) {
|
|
1902
|
-
const status = await
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
2052
|
+
const [status, rows, artifacts] = await Promise.all([
|
|
2053
|
+
this.getBuildStatus(campaignBuildId),
|
|
2054
|
+
this.getBuildRows(campaignBuildId, {
|
|
2055
|
+
...options,
|
|
2056
|
+
limit: options.limit ?? 100
|
|
2057
|
+
}),
|
|
2058
|
+
this.listBuildArtifacts(campaignBuildId)
|
|
2059
|
+
]);
|
|
1908
2060
|
return createCampaignBuilderBuildReview(status, rows, artifacts);
|
|
1909
2061
|
}
|
|
1910
2062
|
async getCampaignBuildStatus(campaignBuildId) {
|
|
@@ -1932,7 +2084,8 @@ var CampaignBuilderAgent = class {
|
|
|
1932
2084
|
campaign_build_id: campaignBuildId,
|
|
1933
2085
|
destination_type: destinationType,
|
|
1934
2086
|
destination_id: options?.destinationId,
|
|
1935
|
-
destination_config: options?.destinationConfig
|
|
2087
|
+
destination_config: options?.destinationConfig,
|
|
2088
|
+
allow_partial_delivery: options?.allowPartialDelivery === true ? true : void 0
|
|
1936
2089
|
});
|
|
1937
2090
|
const data = await this.callMcp("approve_campaign_delivery", args);
|
|
1938
2091
|
return {
|
|
@@ -1942,7 +2095,10 @@ var CampaignBuilderAgent = class {
|
|
|
1942
2095
|
message: data.message ?? "",
|
|
1943
2096
|
deliveryId: data.delivery_id,
|
|
1944
2097
|
deliveryIds: data.delivery_ids,
|
|
1945
|
-
approvedCount: data.approved_count
|
|
2098
|
+
approvedCount: data.approved_count,
|
|
2099
|
+
partialDelivery: data.partial_delivery,
|
|
2100
|
+
effectiveTargetCount: data.effective_target_count,
|
|
2101
|
+
requestedTargetCount: data.requested_target_count
|
|
1946
2102
|
};
|
|
1947
2103
|
}
|
|
1948
2104
|
async getWorkspaceContext(warnings) {
|
|
@@ -1978,15 +2134,19 @@ var CampaignBuilderAgent = class {
|
|
|
1978
2134
|
const providers = new Set(
|
|
1979
2135
|
[...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])].filter((route) => route.provider !== "signaliz").map((route) => route.provider)
|
|
1980
2136
|
);
|
|
1981
|
-
|
|
2137
|
+
const warningsByProvider = await Promise.all(Array.from(providers, async (provider) => {
|
|
1982
2138
|
try {
|
|
1983
2139
|
await this.callMcp("discover_capabilities", {
|
|
1984
2140
|
query: `campaign builder ${provider} ${request.goal}`,
|
|
1985
2141
|
category: "campaign"
|
|
1986
2142
|
});
|
|
2143
|
+
return void 0;
|
|
1987
2144
|
} catch (error) {
|
|
1988
|
-
|
|
2145
|
+
return `Capability discovery for ${provider} failed: ${errorMessage(error)}`;
|
|
1989
2146
|
}
|
|
2147
|
+
}));
|
|
2148
|
+
for (const warning of warningsByProvider) {
|
|
2149
|
+
if (warning) warnings.push(warning);
|
|
1990
2150
|
}
|
|
1991
2151
|
}
|
|
1992
2152
|
async attachStrategyMemoryStatus(plan, warnings) {
|
|
@@ -2010,8 +2170,24 @@ var CampaignBuilderAgent = class {
|
|
|
2010
2170
|
const kernelPlan = await this.callMcp("gtm_campaign_build_plan", asRecord(plannerStep.arguments));
|
|
2011
2171
|
plan.kernelPlan = asRecord(kernelPlan);
|
|
2012
2172
|
const brainDefaults = asRecord(plan.kernelPlan.brain_defaults ?? plan.kernelPlan.brainDefaults);
|
|
2173
|
+
const corpusContext = asRecord(plan.kernelPlan.corpus_context ?? plan.kernelPlan.corpusContext);
|
|
2174
|
+
const campaignStrategyContext = asRecord(plan.kernelPlan.campaign_strategy_context ?? plan.kernelPlan.campaignStrategyContext);
|
|
2175
|
+
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) : [];
|
|
2013
2176
|
if (Object.keys(brainDefaults).length > 0 && Object.keys(asRecord(plan.buildRequest.brainDefaults)).length === 0) {
|
|
2014
2177
|
plan.buildRequest.brainDefaults = brainDefaults;
|
|
2178
|
+
}
|
|
2179
|
+
if (Object.keys(campaignStrategyContext).length > 0) {
|
|
2180
|
+
plan.buildRequest.campaignStrategyContext = campaignStrategyContext;
|
|
2181
|
+
}
|
|
2182
|
+
if (Object.keys(corpusContext).length > 0 || memoryExamples.length > 0 || Object.keys(brainDefaults).length > 0 || Object.keys(campaignStrategyContext).length > 0) {
|
|
2183
|
+
plan.buildRequest.brainPreflight = compact({
|
|
2184
|
+
...asRecord(plan.buildRequest.brainPreflight),
|
|
2185
|
+
corpus_context: Object.keys(corpusContext).length > 0 ? corpusContext : void 0,
|
|
2186
|
+
memory_examples: memoryExamples.length > 0 ? memoryExamples : void 0,
|
|
2187
|
+
brain_defaults: Object.keys(brainDefaults).length > 0 ? brainDefaults : void 0,
|
|
2188
|
+
campaign_strategy_context: Object.keys(campaignStrategyContext).length > 0 ? campaignStrategyContext : void 0
|
|
2189
|
+
});
|
|
2190
|
+
plan.brainPreflight = asRecord(plan.buildRequest.brainPreflight);
|
|
2015
2191
|
refreshBuildStepArguments(plan);
|
|
2016
2192
|
}
|
|
2017
2193
|
} catch (error) {
|
|
@@ -2192,6 +2368,9 @@ function createCampaignBuilderProofReceipt(plan, result) {
|
|
|
2192
2368
|
campaign_build_id: dryRunResult.campaignBuildId ?? dryRunResult.campaign_build_id ?? null
|
|
2193
2369
|
}
|
|
2194
2370
|
];
|
|
2371
|
+
const learnBackPlan = summarizeCampaignBuilderProofLearnBack(
|
|
2372
|
+
asRecord(asRecord(plan.buildRequest.brainPreflight).learn_back_plan ?? asRecord(plan.brainPreflight).learn_back_plan)
|
|
2373
|
+
);
|
|
2195
2374
|
return {
|
|
2196
2375
|
receipt_version: "campaign-agent-proof.v1",
|
|
2197
2376
|
source: "signaliz.campaignBuilderAgent.proof",
|
|
@@ -2214,6 +2393,7 @@ function createCampaignBuilderProofReceipt(plan, result) {
|
|
|
2214
2393
|
gates,
|
|
2215
2394
|
strategy_memory_status: summarizeCampaignBuilderProofStrategyMemory(strategyMemory),
|
|
2216
2395
|
dry_run_result: summarizeCampaignBuilderProofDryRun(dryRunResult),
|
|
2396
|
+
learn_back_plan: learnBackPlan,
|
|
2217
2397
|
recommended_next_actions: [
|
|
2218
2398
|
"Review the plan, approvals, and dry-run result.",
|
|
2219
2399
|
"Use campaign-agent commit-plan --confirm-write only after review.",
|
|
@@ -2770,6 +2950,13 @@ function campaignBuilderMemoryKitSdkExample(request, seedManifestFile) {
|
|
|
2770
2950
|
function campaignBuilderMemoryKitSource(source) {
|
|
2771
2951
|
const normalized = normalizeTemplateKey(source || "agency");
|
|
2772
2952
|
const catalog = {
|
|
2953
|
+
northStar: {
|
|
2954
|
+
id: "north_star_campaign_builder",
|
|
2955
|
+
label: "North Star campaign-builder acceptance patterns",
|
|
2956
|
+
seed_source: "north-star",
|
|
2957
|
+
scope: "redacted_acceptance_seed_packs",
|
|
2958
|
+
privacy: "redacted aggregate counts, QA gates, and fixture shape only"
|
|
2959
|
+
},
|
|
2773
2960
|
agency: {
|
|
2774
2961
|
id: "agency_campaign_builder",
|
|
2775
2962
|
label: "Agency campaign-builder strategy patterns",
|
|
@@ -2795,6 +2982,10 @@ function campaignBuilderMemoryKitSource(source) {
|
|
|
2795
2982
|
const sourceMap = {
|
|
2796
2983
|
agency: "agency",
|
|
2797
2984
|
"campaign-builder": "agency",
|
|
2985
|
+
"north-star": "northStar",
|
|
2986
|
+
northstar: "northStar",
|
|
2987
|
+
"campaign-builder-north-star": "northStar",
|
|
2988
|
+
acceptance: "northStar",
|
|
2798
2989
|
"strategy-memory": "agency",
|
|
2799
2990
|
"workflow-patterns": "workflow",
|
|
2800
2991
|
workflow: "workflow",
|
|
@@ -2810,13 +3001,13 @@ function campaignBuilderMemoryKitSource(source) {
|
|
|
2810
3001
|
return {
|
|
2811
3002
|
seedSource: "all",
|
|
2812
3003
|
verifyScript: null,
|
|
2813
|
-
memorySources: [catalog.agency, catalog.workflow, catalog.feedback]
|
|
3004
|
+
memorySources: [catalog.northStar, catalog.agency, catalog.workflow, catalog.feedback]
|
|
2814
3005
|
};
|
|
2815
3006
|
}
|
|
2816
3007
|
const item = catalog[selected];
|
|
2817
3008
|
return {
|
|
2818
3009
|
seedSource: item.seed_source,
|
|
2819
|
-
verifyScript: 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,
|
|
3010
|
+
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,
|
|
2820
3011
|
memorySources: [item]
|
|
2821
3012
|
};
|
|
2822
3013
|
}
|
|
@@ -2996,11 +3187,11 @@ function builtInRoutesFor(request) {
|
|
|
2996
3187
|
routes.push({
|
|
2997
3188
|
id: "signaliz-lead-generation",
|
|
2998
3189
|
layer: "source",
|
|
2999
|
-
|
|
3190
|
+
gtmLayer: "lead_generation",
|
|
3000
3191
|
provider: "signaliz",
|
|
3001
3192
|
mode: "required",
|
|
3002
3193
|
toolName: "generate_leads",
|
|
3003
|
-
rationale: "
|
|
3194
|
+
rationale: "Inventory verified cache first, then use Signaliz fresh workspace acquisition for the remaining approved gap."
|
|
3004
3195
|
});
|
|
3005
3196
|
}
|
|
3006
3197
|
if (builtIns.has("local_leads")) {
|
|
@@ -3014,6 +3205,28 @@ function builtInRoutesFor(request) {
|
|
|
3014
3205
|
rationale: "Use Signaliz local-leads sourcing for geography-bound local business campaigns."
|
|
3015
3206
|
});
|
|
3016
3207
|
}
|
|
3208
|
+
if (builtIns.has("company_discovery")) {
|
|
3209
|
+
routes.push({
|
|
3210
|
+
id: "signaliz-company-discovery",
|
|
3211
|
+
layer: "source",
|
|
3212
|
+
gtmLayer: "find_company",
|
|
3213
|
+
provider: "signaliz",
|
|
3214
|
+
mode: "if_available",
|
|
3215
|
+
toolName: "find_companies_signaliz",
|
|
3216
|
+
rationale: "Find and qualify company domains before people/email fill for account-led campaigns."
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
if (builtIns.has("people_discovery")) {
|
|
3220
|
+
routes.push({
|
|
3221
|
+
id: "signaliz-people-discovery",
|
|
3222
|
+
layer: "source",
|
|
3223
|
+
gtmLayer: "find_people",
|
|
3224
|
+
provider: "signaliz",
|
|
3225
|
+
mode: "if_available",
|
|
3226
|
+
toolName: "find_people_signaliz",
|
|
3227
|
+
rationale: "Find people directly when the brief is contact research or LinkedIn-style prospecting."
|
|
3228
|
+
});
|
|
3229
|
+
}
|
|
3017
3230
|
if (builtIns.has("email_finding")) {
|
|
3018
3231
|
routes.push({
|
|
3019
3232
|
id: "signaliz-email-finding",
|
|
@@ -3058,7 +3271,7 @@ function normalizeBuiltIns(request) {
|
|
|
3058
3271
|
return [...builtIns].filter(isCampaignBuilderBuiltInTool);
|
|
3059
3272
|
}
|
|
3060
3273
|
function isCampaignBuilderBuiltInTool(value) {
|
|
3061
|
-
return ["lead_generation", "local_leads", "email_finding", "email_verification", "signals"].includes(String(value));
|
|
3274
|
+
return ["lead_generation", "local_leads", "company_discovery", "people_discovery", "email_finding", "email_verification", "signals"].includes(String(value));
|
|
3062
3275
|
}
|
|
3063
3276
|
function looksLikeLocalLeadCampaign(request) {
|
|
3064
3277
|
const text = [
|
|
@@ -3089,6 +3302,21 @@ function routesFromCustomerTools(tools) {
|
|
|
3089
3302
|
}))
|
|
3090
3303
|
);
|
|
3091
3304
|
}
|
|
3305
|
+
function normalizeCampaignBuilderLearningHoldout(input, gtmCampaignId, campaignName) {
|
|
3306
|
+
const source = asRecord(input);
|
|
3307
|
+
if (source.enabled === false) return { enabled: false };
|
|
3308
|
+
const controlPercentage = numberOrUndefined2(source.control_percentage ?? source.controlPercentage);
|
|
3309
|
+
const minControlSize = numberOrUndefined2(source.min_control_size ?? source.minControlSize);
|
|
3310
|
+
const experimentKey = stringValue(source.experiment_key ?? source.experimentKey) ?? (gtmCampaignId ? `gtm_campaign:${gtmCampaignId}:learning_holdout` : `campaign_builder_agent:${hashString(campaignName)}:learning_holdout`);
|
|
3311
|
+
return {
|
|
3312
|
+
enabled: true,
|
|
3313
|
+
controlPercentage: controlPercentage ?? 0.2,
|
|
3314
|
+
minControlSize: minControlSize ?? 50,
|
|
3315
|
+
experimentKey,
|
|
3316
|
+
sourceCampaignId: stringValue(source.source_campaign_id ?? source.sourceCampaignId) ?? gtmCampaignId,
|
|
3317
|
+
primaryMetric: stringValue(source.primary_metric ?? source.primaryMetric) ?? "positive_reply_rate"
|
|
3318
|
+
};
|
|
3319
|
+
}
|
|
3092
3320
|
function createBuildRequest(request, defaults, targetCount, campaignName, scopeBuildArgs, routes = [], memory, scopeBrainPreflight) {
|
|
3093
3321
|
const buildRequest = {
|
|
3094
3322
|
name: campaignName,
|
|
@@ -3113,10 +3341,19 @@ function createBuildRequest(request, defaults, targetCount, campaignName, scopeB
|
|
|
3113
3341
|
qualification: defaults.qualification,
|
|
3114
3342
|
copy: defaults.copy,
|
|
3115
3343
|
delivery: defaults.delivery,
|
|
3116
|
-
enhancers: enhancerConfig(request)
|
|
3344
|
+
enhancers: enhancerConfig(request),
|
|
3345
|
+
sourceRouting: request.sourceRouting ?? {
|
|
3346
|
+
mode: looksLikeLocalLeadCampaign(request) ? "local_leads" : "auto",
|
|
3347
|
+
fillPolicy: "aggressive"
|
|
3348
|
+
}
|
|
3117
3349
|
};
|
|
3118
3350
|
const scoped = asRecord(scopeBuildArgs);
|
|
3119
3351
|
buildRequest.gtmCampaignId = request.gtmCampaignId ?? stringValue(scoped.gtm_campaign_id ?? scoped.gtmCampaignId);
|
|
3352
|
+
buildRequest.learningHoldout = normalizeCampaignBuilderLearningHoldout(
|
|
3353
|
+
request.learningHoldout ?? scoped.learning_holdout ?? scoped.learningHoldout,
|
|
3354
|
+
buildRequest.gtmCampaignId,
|
|
3355
|
+
campaignName
|
|
3356
|
+
);
|
|
3120
3357
|
if (typeof scoped.name === "string") buildRequest.name = scoped.name;
|
|
3121
3358
|
if (typeof scoped.prompt === "string") buildRequest.prompt = scoped.prompt;
|
|
3122
3359
|
if (typeof scoped.target_count === "number") buildRequest.targetCount = scoped.target_count;
|
|
@@ -3191,13 +3428,137 @@ function createBrainPreflight(request, buildRequest, routes, memory) {
|
|
|
3191
3428
|
target_icp: targetIcp,
|
|
3192
3429
|
provider_chain: providerChain,
|
|
3193
3430
|
lead_source: providerChain[0] ?? "signaliz",
|
|
3431
|
+
learning_holdout: buildRequest.learningHoldout,
|
|
3194
3432
|
tool_sequence: [
|
|
3195
3433
|
{ tool: "gtm_brain_learning_cycle_plan", purpose: "Plan the Brain learning loop for this campaign.", arguments: learningArgs },
|
|
3196
3434
|
{ tool: "gtm_brain_seed_defaults", purpose: "Seed campaign defaults from workspace memory and safe aggregate patterns.", arguments: defaultsArgs },
|
|
3197
3435
|
{ tool: "gtm_brain_delivery_risk", purpose: "Check deliverability risk before launch or external writes.", arguments: riskArgs }
|
|
3198
|
-
]
|
|
3436
|
+
],
|
|
3437
|
+
learn_back_plan: createCampaignBuilderLearnBackPlan(request, buildRequest)
|
|
3438
|
+
};
|
|
3439
|
+
}
|
|
3440
|
+
function createCampaignBuilderLearnBackPlan(request, buildRequest) {
|
|
3441
|
+
const instantlyFeedbackContext = campaignBuilderProviderFeedbackContext(request, buildRequest, "instantly");
|
|
3442
|
+
const postBuildSequence = [
|
|
3443
|
+
{
|
|
3444
|
+
tool: "get_campaign_build_status",
|
|
3445
|
+
approval_boundary: "read_only",
|
|
3446
|
+
arguments_template: { campaign_build_id: "<build_campaign.campaign_build_id>" },
|
|
3447
|
+
reason: "Wait for the Campaign Builder run to finish before deriving memory."
|
|
3448
|
+
},
|
|
3449
|
+
{
|
|
3450
|
+
tool: "gtm_campaign_build_backfill_preview",
|
|
3451
|
+
approval_boundary: "read_only",
|
|
3452
|
+
arguments_template: { campaign_build_id: "<build_campaign.campaign_build_id>", create_memory: true },
|
|
3453
|
+
reason: "Preview the provider-neutral Kernel import payload without writing rows."
|
|
3454
|
+
},
|
|
3455
|
+
{
|
|
3456
|
+
tool: "gtm_campaign_build_backfill_run",
|
|
3457
|
+
approval_boundary: "dry_run",
|
|
3458
|
+
arguments_template: { campaign_build_ids: ["<build_campaign.campaign_build_id>"], dry_run: true, create_memory: true, run_brain_cycle: false },
|
|
3459
|
+
reason: "Dry-run the Kernel history import before creating campaign memory."
|
|
3460
|
+
},
|
|
3461
|
+
{
|
|
3462
|
+
tool: "gtm_campaign_build_backfill_run",
|
|
3463
|
+
approval_boundary: "explicit_write_approval",
|
|
3464
|
+
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" },
|
|
3465
|
+
reason: "After review, queue the Kernel history import; Brain learning remains dry-run unless separately approved."
|
|
3466
|
+
}
|
|
3467
|
+
];
|
|
3468
|
+
if (instantlyFeedbackContext) {
|
|
3469
|
+
postBuildSequence.push({
|
|
3470
|
+
tool: "gtm_instantly_feedback_pull",
|
|
3471
|
+
approval_boundary: "dry_run_first_explicit_write_approval",
|
|
3472
|
+
arguments_template: {
|
|
3473
|
+
campaign_id: buildRequest.gtmCampaignId || "<gtm_campaign_id_after_commit>",
|
|
3474
|
+
campaign_build_id: "<build_campaign.campaign_build_id>",
|
|
3475
|
+
source: "emails",
|
|
3476
|
+
email_type: "received",
|
|
3477
|
+
...instantlyFeedbackContext,
|
|
3478
|
+
dry_run: true,
|
|
3479
|
+
create_memory: true,
|
|
3480
|
+
write_routine_outcomes: true,
|
|
3481
|
+
run_brain_cycle: true,
|
|
3482
|
+
brain_cycle_write_mode: "dry_run"
|
|
3483
|
+
},
|
|
3484
|
+
reason: "After Instantly delivery has live outcomes, pull reply and bounce history into private feedback memory before Brain learning."
|
|
3485
|
+
});
|
|
3486
|
+
}
|
|
3487
|
+
postBuildSequence.push(
|
|
3488
|
+
{
|
|
3489
|
+
tool: "gtm_campaign_learning_status",
|
|
3490
|
+
approval_boundary: "read_only",
|
|
3491
|
+
arguments_template: {
|
|
3492
|
+
campaign_id: buildRequest.gtmCampaignId || "<gtm_campaign_id_after_commit>",
|
|
3493
|
+
campaign_build_id: "<build_campaign.campaign_build_id>",
|
|
3494
|
+
write_mode: "dry_run"
|
|
3495
|
+
},
|
|
3496
|
+
reason: "Confirm feedback, memory, and Brain learning readiness after the import."
|
|
3497
|
+
},
|
|
3498
|
+
{
|
|
3499
|
+
tool: "gtm_memory_search",
|
|
3500
|
+
approval_boundary: "read_only",
|
|
3501
|
+
arguments_template: {
|
|
3502
|
+
query: request.goal,
|
|
3503
|
+
...buildRequest.gtmCampaignId ? { campaign_id: buildRequest.gtmCampaignId } : {},
|
|
3504
|
+
limit: 10
|
|
3505
|
+
},
|
|
3506
|
+
reason: "Verify the new private memory is retrievable for future campaign planning."
|
|
3507
|
+
},
|
|
3508
|
+
{
|
|
3509
|
+
tool: "gtm_brain_learning_cycle_plan",
|
|
3510
|
+
approval_boundary: "read_only",
|
|
3511
|
+
arguments_template: {
|
|
3512
|
+
...buildRequest.gtmCampaignId ? { campaign_id: buildRequest.gtmCampaignId } : {},
|
|
3513
|
+
include_memory: true,
|
|
3514
|
+
write_mode: "dry_run"
|
|
3515
|
+
},
|
|
3516
|
+
reason: "Plan the Brain phases from the imported outcomes before any pattern writes."
|
|
3517
|
+
}
|
|
3518
|
+
);
|
|
3519
|
+
return {
|
|
3520
|
+
source_tool: "campaign-builder-agent",
|
|
3521
|
+
gtm_campaign_id: buildRequest.gtmCampaignId ?? null,
|
|
3522
|
+
trigger: "After build_campaign returns a campaign_build_id and the build reaches a terminal reviewed state.",
|
|
3523
|
+
build_result_placeholders: {
|
|
3524
|
+
campaign_build_id: "<build_campaign.campaign_build_id>"
|
|
3525
|
+
},
|
|
3526
|
+
memory_write_policy: {
|
|
3527
|
+
target_tables: ["gtm_campaigns", "gtm_campaign_provider_links", "gtm_campaign_feedback_events", "gtm_memory_items", "gtm_brain_patterns"],
|
|
3528
|
+
gtm_memory_items: {
|
|
3529
|
+
shareable: false,
|
|
3530
|
+
allowed_redaction_states: ["redacted", "abstracted"],
|
|
3531
|
+
raw_private_fields_withheld: ["reply_text", "copy_body", "lead_email", "lead_domain", "company_domain", "provider_campaign_id", "provider_payload", "webhook_url", "secret"]
|
|
3532
|
+
},
|
|
3533
|
+
gtm_brain_patterns: "Workspace-scoped by default. Global promotion requires abstracted_only=true, shared opt-in, and privacy thresholds."
|
|
3534
|
+
},
|
|
3535
|
+
post_build_sequence: postBuildSequence.map((item, index) => ({ step: index + 1, ...item })),
|
|
3536
|
+
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.",
|
|
3537
|
+
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."
|
|
3199
3538
|
};
|
|
3200
3539
|
}
|
|
3540
|
+
function campaignBuilderProviderFeedbackContext(request, buildRequest, provider) {
|
|
3541
|
+
const normalizedProvider = String(provider).toLowerCase();
|
|
3542
|
+
const routes = [...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])];
|
|
3543
|
+
const providerRoute = routes.find((route) => String(route.provider).toLowerCase() === normalizedProvider);
|
|
3544
|
+
const routeConfig = asRecord(providerRoute?.config);
|
|
3545
|
+
const deliveryConfig = asRecord(buildRequest.delivery?.destinationConfig);
|
|
3546
|
+
const hasProviderContext = [
|
|
3547
|
+
...request.preferredProviders ?? [],
|
|
3548
|
+
...routes.map((route) => route.provider),
|
|
3549
|
+
stringValue(deliveryConfig.provider),
|
|
3550
|
+
stringValue(deliveryConfig.provider_id ?? deliveryConfig.providerId),
|
|
3551
|
+
stringValue(deliveryConfig.destination_provider ?? deliveryConfig.destinationProvider),
|
|
3552
|
+
stringValue(deliveryConfig.sink ?? deliveryConfig.sink_type ?? deliveryConfig.sinkType)
|
|
3553
|
+
].some((value) => String(value).toLowerCase() === normalizedProvider);
|
|
3554
|
+
if (!hasProviderContext) return void 0;
|
|
3555
|
+
return compact({
|
|
3556
|
+
provider_link_id: stringValue(routeConfig.provider_link_id ?? routeConfig.providerLinkId ?? deliveryConfig.provider_link_id ?? deliveryConfig.providerLinkId),
|
|
3557
|
+
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),
|
|
3558
|
+
integration_id: stringValue(routeConfig.integration_id ?? routeConfig.integrationId ?? deliveryConfig.integration_id ?? deliveryConfig.integrationId),
|
|
3559
|
+
instantly_profile: stringValue(routeConfig.instantly_profile ?? routeConfig.instantlyProfile ?? routeConfig.profile ?? deliveryConfig.instantly_profile ?? deliveryConfig.instantlyProfile ?? deliveryConfig.profile)
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3201
3562
|
function gtmLayersForBuilderLayer(layer) {
|
|
3202
3563
|
const map = {
|
|
3203
3564
|
workspace_context: ["customer_data"],
|
|
@@ -3602,6 +3963,7 @@ function buildFallbackPlanSnapshot(plan) {
|
|
|
3602
3963
|
target_count: plan.targetCount,
|
|
3603
3964
|
approvals: plan.approvals,
|
|
3604
3965
|
brain_preflight: plan.brainPreflight,
|
|
3966
|
+
campaign_strategy_context: plan.buildRequest.campaignStrategyContext,
|
|
3605
3967
|
operating_playbooks: plan.operatingPlaybooks
|
|
3606
3968
|
});
|
|
3607
3969
|
}
|
|
@@ -3734,6 +4096,17 @@ function buildCampaignArgs(request) {
|
|
|
3734
4096
|
if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
|
|
3735
4097
|
if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
|
|
3736
4098
|
if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
|
|
4099
|
+
if (request.learningHoldout) {
|
|
4100
|
+
args.learning_holdout = compact({
|
|
4101
|
+
enabled: request.learningHoldout.enabled,
|
|
4102
|
+
control_percentage: request.learningHoldout.controlPercentage,
|
|
4103
|
+
min_control_size: request.learningHoldout.minControlSize,
|
|
4104
|
+
experiment_key: request.learningHoldout.experimentKey,
|
|
4105
|
+
source_campaign_id: request.learningHoldout.sourceCampaignId,
|
|
4106
|
+
primary_metric: request.learningHoldout.primaryMetric
|
|
4107
|
+
});
|
|
4108
|
+
}
|
|
4109
|
+
if (request.campaignStrategyContext) args.campaign_strategy_context = request.campaignStrategyContext;
|
|
3737
4110
|
if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
|
|
3738
4111
|
if (request.icp) {
|
|
3739
4112
|
args.icp = compact({
|
|
@@ -3753,6 +4126,15 @@ function buildCampaignArgs(request) {
|
|
|
3753
4126
|
model: request.policy.model
|
|
3754
4127
|
});
|
|
3755
4128
|
}
|
|
4129
|
+
if (request.sourceRouting) {
|
|
4130
|
+
args.source_routing = compact({
|
|
4131
|
+
mode: request.sourceRouting.mode,
|
|
4132
|
+
fill_policy: request.sourceRouting.fillPolicy,
|
|
4133
|
+
shard_size: request.sourceRouting.shardSize,
|
|
4134
|
+
max_source_shard_size: request.sourceRouting.maxSourceShardSize,
|
|
4135
|
+
max_local_source_shard_size: request.sourceRouting.maxLocalSourceShardSize
|
|
4136
|
+
});
|
|
4137
|
+
}
|
|
3756
4138
|
if (request.signals) {
|
|
3757
4139
|
args.signals = compact({
|
|
3758
4140
|
enabled: request.signals.enabled,
|
|
@@ -3820,11 +4202,13 @@ function buildExecutionPrepareArgs(request, dryRun, confirmSpend) {
|
|
|
3820
4202
|
delivery_risk: buildArgs2.delivery_risk,
|
|
3821
4203
|
dedup_keys: buildArgs2.dedup_keys,
|
|
3822
4204
|
policy: buildArgs2.policy,
|
|
4205
|
+
learning_holdout: buildArgs2.learning_holdout,
|
|
3823
4206
|
signals: buildArgs2.signals,
|
|
3824
4207
|
qualification: buildArgs2.qualification,
|
|
3825
4208
|
copy: buildArgs2.copy,
|
|
3826
4209
|
delivery: buildArgs2.delivery,
|
|
3827
|
-
enhancers: buildArgs2.enhancers
|
|
4210
|
+
enhancers: buildArgs2.enhancers,
|
|
4211
|
+
source_routing: buildArgs2.source_routing
|
|
3828
4212
|
});
|
|
3829
4213
|
}
|
|
3830
4214
|
function buildDeliveryApprovalArgs(request) {
|
|
@@ -3853,10 +4237,145 @@ function mapBuildResult(data, dryRun) {
|
|
|
3853
4237
|
targetLimitReason: data.target_limit_reason,
|
|
3854
4238
|
maxSupportedTargetCount: data.max_supported_target_count,
|
|
3855
4239
|
brainContext: data.brain_context ?? {},
|
|
4240
|
+
learningHoldout: data.learning_holdout ?? {},
|
|
3856
4241
|
providerRoute: mapProviderRoute2(data)
|
|
3857
4242
|
};
|
|
3858
4243
|
}
|
|
4244
|
+
var CAMPAIGN_BUILDER_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "canceled", "cancelled"]);
|
|
4245
|
+
var CAMPAIGN_BUILDER_BLOCKED_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["failed", "canceled", "cancelled"]);
|
|
4246
|
+
function mapAgentCampaignPhaseHealth(value) {
|
|
4247
|
+
if (!Array.isArray(value)) return [];
|
|
4248
|
+
return value.map((phase) => {
|
|
4249
|
+
const record = asRecord(phase);
|
|
4250
|
+
return {
|
|
4251
|
+
phase: stringValue(record.phase) ?? "unknown",
|
|
4252
|
+
status: stringValue(record.status) ?? "unknown",
|
|
4253
|
+
recordsProcessed: numberOrNull2(record.records_processed ?? record.recordsProcessed),
|
|
4254
|
+
recordsSucceeded: numberOrNull2(record.records_succeeded ?? record.recordsSucceeded),
|
|
4255
|
+
recordsFailed: numberOrNull2(record.records_failed ?? record.recordsFailed),
|
|
4256
|
+
heartbeatAgeSeconds: numberOrNull2(record.heartbeat_age_seconds ?? record.heartbeatAgeSeconds ?? record.phase_age_seconds)
|
|
4257
|
+
};
|
|
4258
|
+
});
|
|
4259
|
+
}
|
|
4260
|
+
function deriveCampaignBuildTerminalState(input) {
|
|
4261
|
+
const status = input.status.toLowerCase();
|
|
4262
|
+
const heartbeatAgeSeconds = input.phaseAgeSeconds;
|
|
4263
|
+
const stale = input.staleRunningPhase === true;
|
|
4264
|
+
const safeWatchAction = input.triggerRunId ? `signaliz ops run-status ${input.triggerRunId} --watch` : "signaliz campaign-agent status <campaign_build_id>";
|
|
4265
|
+
if (CAMPAIGN_BUILDER_BLOCKED_TERMINAL_STATUSES.has(status)) {
|
|
4266
|
+
return {
|
|
4267
|
+
kind: "blocked",
|
|
4268
|
+
label: "Blocked terminal state",
|
|
4269
|
+
reviewable: true,
|
|
4270
|
+
terminal: true,
|
|
4271
|
+
stale: false,
|
|
4272
|
+
phase: input.phase,
|
|
4273
|
+
phaseStatus: input.phaseStatus,
|
|
4274
|
+
heartbeatAgeSeconds,
|
|
4275
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4276
|
+
terminalReason: input.terminalReason,
|
|
4277
|
+
staleReason: null,
|
|
4278
|
+
safeNextAction: input.nextAction || "Review errors and rerun only after the blocker is resolved."
|
|
4279
|
+
};
|
|
4280
|
+
}
|
|
4281
|
+
if (status === "pending_approval") {
|
|
4282
|
+
return {
|
|
4283
|
+
kind: "pending_approval",
|
|
4284
|
+
label: "Pending delivery approval",
|
|
4285
|
+
reviewable: true,
|
|
4286
|
+
terminal: false,
|
|
4287
|
+
stale: false,
|
|
4288
|
+
phase: input.phase,
|
|
4289
|
+
phaseStatus: input.phaseStatus,
|
|
4290
|
+
heartbeatAgeSeconds,
|
|
4291
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4292
|
+
terminalReason: input.terminalReason,
|
|
4293
|
+
staleReason: null,
|
|
4294
|
+
safeNextAction: input.approvalAction || input.nextAction || "Review rows and approve delivery only after the approval packet passes."
|
|
4295
|
+
};
|
|
4296
|
+
}
|
|
4297
|
+
if (CAMPAIGN_BUILDER_TERMINAL_STATUSES.has(status)) {
|
|
4298
|
+
return {
|
|
4299
|
+
kind: "terminal",
|
|
4300
|
+
label: "Terminal and reviewable",
|
|
4301
|
+
reviewable: true,
|
|
4302
|
+
terminal: true,
|
|
4303
|
+
stale: false,
|
|
4304
|
+
phase: input.phase,
|
|
4305
|
+
phaseStatus: input.phaseStatus,
|
|
4306
|
+
heartbeatAgeSeconds,
|
|
4307
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4308
|
+
terminalReason: input.terminalReason,
|
|
4309
|
+
staleReason: null,
|
|
4310
|
+
safeNextAction: input.nextAction || "Review rows, artifacts, scorecard, and approval locks before delivery."
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
if (status === "running" || status === "queued" || status === "processing") {
|
|
4314
|
+
if (stale) {
|
|
4315
|
+
return {
|
|
4316
|
+
kind: "running_stale",
|
|
4317
|
+
label: "Running but stale",
|
|
4318
|
+
reviewable: false,
|
|
4319
|
+
terminal: false,
|
|
4320
|
+
stale: true,
|
|
4321
|
+
phase: input.phase,
|
|
4322
|
+
phaseStatus: input.phaseStatus,
|
|
4323
|
+
heartbeatAgeSeconds,
|
|
4324
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4325
|
+
terminalReason: null,
|
|
4326
|
+
staleReason: input.staleReason || "The active phase heartbeat is stale.",
|
|
4327
|
+
safeNextAction: input.nextAction || safeWatchAction
|
|
4328
|
+
};
|
|
4329
|
+
}
|
|
4330
|
+
return {
|
|
4331
|
+
kind: "running_healthy",
|
|
4332
|
+
label: "Running and healthy",
|
|
4333
|
+
reviewable: false,
|
|
4334
|
+
terminal: false,
|
|
4335
|
+
stale: false,
|
|
4336
|
+
phase: input.phase,
|
|
4337
|
+
phaseStatus: input.phaseStatus,
|
|
4338
|
+
heartbeatAgeSeconds,
|
|
4339
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4340
|
+
terminalReason: null,
|
|
4341
|
+
staleReason: null,
|
|
4342
|
+
safeNextAction: input.nextAction || safeWatchAction
|
|
4343
|
+
};
|
|
4344
|
+
}
|
|
4345
|
+
return {
|
|
4346
|
+
kind: "unknown",
|
|
4347
|
+
label: "Unknown build state",
|
|
4348
|
+
reviewable: false,
|
|
4349
|
+
terminal: false,
|
|
4350
|
+
stale,
|
|
4351
|
+
phase: input.phase,
|
|
4352
|
+
phaseStatus: input.phaseStatus,
|
|
4353
|
+
heartbeatAgeSeconds,
|
|
4354
|
+
nextPollAfterSeconds: input.nextPollAfterSeconds,
|
|
4355
|
+
terminalReason: input.terminalReason,
|
|
4356
|
+
staleReason: input.staleReason,
|
|
4357
|
+
safeNextAction: input.nextAction || "Read campaign build status again before making a launch or delivery decision."
|
|
4358
|
+
};
|
|
4359
|
+
}
|
|
3859
4360
|
function mapAgentCampaignBuildStatus(data) {
|
|
4361
|
+
const customerRowCounts = mapAgentCustomerRowCounts(data.customer_row_counts);
|
|
4362
|
+
const phaseHealth = mapAgentCampaignPhaseHealth(data.phases);
|
|
4363
|
+
const terminalReason = stringValue(data.terminal_reason) ?? customerRowCounts?.terminalReason ?? null;
|
|
4364
|
+
const staleReason = stringValue(data.stale_reason) ?? stringValue(asRecord(data.diagnostics).stale_reason) ?? null;
|
|
4365
|
+
const nextPollAfterSeconds = numberOrNull2(data.next_poll_after_seconds ?? data.nextPollAfterSeconds);
|
|
4366
|
+
const terminalState = deriveCampaignBuildTerminalState({
|
|
4367
|
+
status: stringValue(data.status) ?? "unknown",
|
|
4368
|
+
phase: stringValue(data.current_phase) ?? null,
|
|
4369
|
+
phaseStatus: stringValue(data.current_phase_status) ?? null,
|
|
4370
|
+
staleRunningPhase: data.stale_running_phase === true,
|
|
4371
|
+
phaseAgeSeconds: numberOrNull2(data.phase_age_seconds),
|
|
4372
|
+
nextPollAfterSeconds,
|
|
4373
|
+
terminalReason,
|
|
4374
|
+
staleReason,
|
|
4375
|
+
nextAction: formatAgentNextAction(data.next_action),
|
|
4376
|
+
approvalAction: formatAgentNextAction(data.approval_action),
|
|
4377
|
+
triggerRunId: stringValue(data.trigger_run_id) ?? null
|
|
4378
|
+
});
|
|
3860
4379
|
return {
|
|
3861
4380
|
campaignBuildId: stringValue(data.campaign_build_id) ?? "",
|
|
3862
4381
|
campaignId: stringValue(data.campaign_id) ?? null,
|
|
@@ -3873,17 +4392,68 @@ function mapAgentCampaignBuildStatus(data) {
|
|
|
3873
4392
|
warnings: diagnosticMessages2(data.warnings),
|
|
3874
4393
|
errors: diagnosticMessages2(data.errors),
|
|
3875
4394
|
artifactCount: numberOrUndefined2(data.artifact_count) ?? 0,
|
|
4395
|
+
artifactDownloads: Array.isArray(data.artifact_downloads) ? data.artifact_downloads.map(mapAgentCampaignArtifactDownload) : [],
|
|
4396
|
+
customerRowCounts,
|
|
4397
|
+
phaseAttemptTotals: nullableRecord(data.phase_attempt_totals) ?? void 0,
|
|
3876
4398
|
providerRoute: mapProviderRoute2(data),
|
|
3877
4399
|
triggerRunId: stringValue(data.trigger_run_id) ?? null,
|
|
3878
4400
|
staleRunningPhase: data.stale_running_phase === true,
|
|
3879
4401
|
phaseAgeSeconds: numberOrNull2(data.phase_age_seconds),
|
|
4402
|
+
nextPollAfterSeconds,
|
|
4403
|
+
terminalReason,
|
|
4404
|
+
staleReason,
|
|
4405
|
+
safeNextAction: terminalState.safeNextAction,
|
|
4406
|
+
terminalState,
|
|
4407
|
+
phaseHealth,
|
|
3880
4408
|
diagnostics: nullableRecord(data.diagnostics) ?? {},
|
|
3881
4409
|
nextAction: formatAgentNextAction(data.next_action),
|
|
4410
|
+
approvalAction: formatAgentNextAction(data.approval_action),
|
|
3882
4411
|
createdAt: stringValue(data.created_at) ?? "",
|
|
3883
4412
|
updatedAt: stringValue(data.updated_at) ?? "",
|
|
3884
4413
|
completedAt: stringValue(data.completed_at) ?? null
|
|
3885
4414
|
};
|
|
3886
4415
|
}
|
|
4416
|
+
function mapAgentCampaignArtifactDownload(data) {
|
|
4417
|
+
return {
|
|
4418
|
+
id: stringValue(data.id) ?? "",
|
|
4419
|
+
artifactType: stringValue(data.artifact_type) ?? null,
|
|
4420
|
+
format: stringValue(data.format) ?? null,
|
|
4421
|
+
rowCount: numberOrUndefined2(data.row_count) ?? 0,
|
|
4422
|
+
signedUrl: stringValue(data.signed_url) ?? null,
|
|
4423
|
+
downloadUrl: stringValue(data.download_url) ?? null,
|
|
4424
|
+
manifestUrl: stringValue(data.manifest_url) ?? null,
|
|
4425
|
+
expiresAt: stringValue(data.expires_at) ?? null
|
|
4426
|
+
};
|
|
4427
|
+
}
|
|
4428
|
+
function mapAgentCustomerRowCounts(value) {
|
|
4429
|
+
const record = nullableRecord(value);
|
|
4430
|
+
if (!record) return void 0;
|
|
4431
|
+
return {
|
|
4432
|
+
requestedTarget: numberOrNull2(record.requested_target),
|
|
4433
|
+
acquiredRows: numberOrUndefined2(record.acquired_rows),
|
|
4434
|
+
acceptedRows: numberOrUndefined2(record.accepted_rows),
|
|
4435
|
+
usableRows: numberOrUndefined2(record.usable_rows),
|
|
4436
|
+
copiedRows: numberOrUndefined2(record.copied_rows),
|
|
4437
|
+
approvalReadyRows: numberOrUndefined2(record.approval_ready_rows),
|
|
4438
|
+
qaReadyRows: numberOrUndefined2(record.qa_ready_rows),
|
|
4439
|
+
deliveredRows: numberOrUndefined2(record.delivered_rows),
|
|
4440
|
+
disqualifiedRows: numberOrUndefined2(record.disqualified_rows),
|
|
4441
|
+
reviewableRows: numberOrUndefined2(record.reviewable_rows),
|
|
4442
|
+
rowFailures: numberOrUndefined2(record.row_failures),
|
|
4443
|
+
acceptedShortfall: numberOrNull2(record.accepted_shortfall),
|
|
4444
|
+
usableShortfall: numberOrNull2(record.usable_shortfall),
|
|
4445
|
+
qaReadyShortfall: numberOrNull2(record.qa_ready_shortfall),
|
|
4446
|
+
deliveryShortfall: numberOrNull2(record.delivery_shortfall),
|
|
4447
|
+
fillRatio: numberOrNull2(record.fill_ratio),
|
|
4448
|
+
qaReadyFillRatio: numberOrNull2(record.qa_ready_fill_ratio),
|
|
4449
|
+
deliveredFillRatio: numberOrNull2(record.delivered_fill_ratio),
|
|
4450
|
+
terminalReason: stringValue(record.terminal_reason) ?? null,
|
|
4451
|
+
acceptedShortfallReason: stringValue(record.accepted_shortfall_reason) ?? null,
|
|
4452
|
+
usableShortfallReason: stringValue(record.usable_shortfall_reason) ?? null,
|
|
4453
|
+
qaReadyShortfallReason: stringValue(record.qa_ready_shortfall_reason) ?? null,
|
|
4454
|
+
deliveryShortfallReason: stringValue(record.delivery_shortfall_reason) ?? null
|
|
4455
|
+
};
|
|
4456
|
+
}
|
|
3887
4457
|
function mapAgentCampaignRowsResult(data) {
|
|
3888
4458
|
const rows = Array.isArray(data.rows) ? data.rows : [];
|
|
3889
4459
|
return {
|
|
@@ -3911,74 +4481,296 @@ function mapAgentCampaignArtifact(data) {
|
|
|
3911
4481
|
artifactType: stringValue(data.artifact_type) ?? "",
|
|
3912
4482
|
destination: stringValue(data.destination) ?? "",
|
|
3913
4483
|
storagePath: stringValue(data.storage_path) ?? "",
|
|
4484
|
+
format: stringValue(data.format) ?? null,
|
|
3914
4485
|
signedUrl: stringValue(data.signed_url) ?? null,
|
|
4486
|
+
downloadUrl: stringValue(data.download_url) ?? null,
|
|
4487
|
+
manifestUrl: stringValue(data.manifest_url) ?? null,
|
|
4488
|
+
expiresAt: stringValue(data.expires_at) ?? null,
|
|
3915
4489
|
rowCount: numberOrUndefined2(data.row_count) ?? 0,
|
|
3916
4490
|
checksum: stringValue(data.checksum) ?? null,
|
|
3917
4491
|
metadata: nullableRecord(data.metadata) ?? {},
|
|
3918
4492
|
createdAt: stringValue(data.created_at) ?? ""
|
|
3919
4493
|
};
|
|
3920
4494
|
}
|
|
4495
|
+
var NORTH_STAR_BANNED_COPY_PHRASES = [
|
|
4496
|
+
"i have been following",
|
|
4497
|
+
"i saw that",
|
|
4498
|
+
"would you be opposed",
|
|
4499
|
+
"unlock new opportunities",
|
|
4500
|
+
"significant success",
|
|
4501
|
+
"we understand",
|
|
4502
|
+
"hope this finds you well"
|
|
4503
|
+
];
|
|
4504
|
+
function campaignReviewGate(id, label, status, detail) {
|
|
4505
|
+
return {
|
|
4506
|
+
id,
|
|
4507
|
+
label,
|
|
4508
|
+
status,
|
|
4509
|
+
passed: status !== "blocked",
|
|
4510
|
+
detail
|
|
4511
|
+
};
|
|
4512
|
+
}
|
|
4513
|
+
function northStarMetric(id, label, status, detail, value, target) {
|
|
4514
|
+
return {
|
|
4515
|
+
id,
|
|
4516
|
+
label,
|
|
4517
|
+
status,
|
|
4518
|
+
detail,
|
|
4519
|
+
...value !== void 0 ? { value } : {},
|
|
4520
|
+
...target !== void 0 ? { target } : {}
|
|
4521
|
+
};
|
|
4522
|
+
}
|
|
4523
|
+
function createCampaignBuilderNorthStarScorecard(status, rows, artifacts, terminalState) {
|
|
4524
|
+
if (!terminalState.reviewable) {
|
|
4525
|
+
const pendingMetric = northStarMetric(
|
|
4526
|
+
"terminal_state",
|
|
4527
|
+
"Terminal-state contract",
|
|
4528
|
+
terminalState.kind === "running_stale" ? "blocked" : "pending",
|
|
4529
|
+
terminalState.kind === "running_stale" ? `Build is stale in ${terminalState.phase || "unknown phase"}; do not grade output yet.` : `Build is ${terminalState.label.toLowerCase()}; wait for terminal or approval state before grading.`,
|
|
4530
|
+
terminalState.kind,
|
|
4531
|
+
"terminal or pending_approval"
|
|
4532
|
+
);
|
|
4533
|
+
return {
|
|
4534
|
+
version: "campaign-builder-north-star.v1",
|
|
4535
|
+
status: pendingMetric.status,
|
|
4536
|
+
score: null,
|
|
4537
|
+
moatState: "scaffolding_ready",
|
|
4538
|
+
metrics: [pendingMetric],
|
|
4539
|
+
blockers: pendingMetric.status === "blocked" ? [pendingMetric.detail] : [],
|
|
4540
|
+
warnings: pendingMetric.status === "pending" ? [pendingMetric.detail] : [],
|
|
4541
|
+
nextAction: terminalState.safeNextAction
|
|
4542
|
+
};
|
|
4543
|
+
}
|
|
4544
|
+
const sampledRows = rows.rows.length;
|
|
4545
|
+
const rowData = rows.rows.map((row) => asRecord(row.data));
|
|
4546
|
+
const requestedTarget = status.customerRowCounts?.requestedTarget ?? status.recordsTotal ?? rows.count;
|
|
4547
|
+
const finalRows = status.customerRowCounts?.deliveredRows ?? status.customerRowCounts?.qaReadyRows ?? status.customerRowCounts?.copiedRows ?? status.customerRowCounts?.acceptedRows ?? rows.count;
|
|
4548
|
+
const rowsWithEmail = rows.rows.filter(campaignReviewRowHasEmail).length;
|
|
4549
|
+
const verifiedEmailRows = rowData.filter(campaignReviewDataHasVerifiedEmail).length;
|
|
4550
|
+
const uniqueEmails = new Set(rowData.map(campaignReviewDataEmail).filter(Boolean)).size;
|
|
4551
|
+
const uniqueDomains = new Set(rowData.map(campaignReviewDataDomain).filter(Boolean)).size;
|
|
4552
|
+
const copyReadyRows = rows.rows.filter(campaignReviewRowHasCopy).length;
|
|
4553
|
+
const copyQaIssuesByRow = rowData.map(campaignReviewDataCopyQaIssues).filter((issues) => issues.length > 0);
|
|
4554
|
+
const copyQaIssueCounts = countCampaignReviewIssues(copyQaIssuesByRow);
|
|
4555
|
+
const signalBackedRows = rowData.filter(campaignReviewDataHasSignalBasis).length;
|
|
4556
|
+
const noSupportedSignalRows = rowData.filter(campaignReviewDataHasNoSupportedSignal).length;
|
|
4557
|
+
const unsupportedSignalClaims = rowData.filter(campaignReviewDataHasUnsupportedSignalClaim).length;
|
|
4558
|
+
const approvalLockedRows = rowData.filter(campaignReviewDataHasApprovalLock).length;
|
|
4559
|
+
const holdoutRows = rowData.filter(campaignReviewDataHasHoldoutAttribution).length;
|
|
4560
|
+
const artifactCount = artifacts.length || status.artifactCount || 0;
|
|
4561
|
+
const deliveredRows = status.customerRowCounts?.deliveredRows ?? 0;
|
|
4562
|
+
const feedbackReady = campaignReviewStatusHasFeedbackReadiness(status);
|
|
4563
|
+
const feedbackRequiredForApproval = terminalState.kind === "pending_approval";
|
|
4564
|
+
const moat = campaignReviewMoatState(status, holdoutRows);
|
|
4565
|
+
const metrics = [
|
|
4566
|
+
northStarMetric(
|
|
4567
|
+
"terminal_state",
|
|
4568
|
+
"Terminal-state contract",
|
|
4569
|
+
terminalState.kind === "blocked" ? "blocked" : "pass",
|
|
4570
|
+
terminalState.label,
|
|
4571
|
+
terminalState.kind,
|
|
4572
|
+
"terminal or pending_approval"
|
|
4573
|
+
),
|
|
4574
|
+
northStarMetric(
|
|
4575
|
+
"target_fill",
|
|
4576
|
+
"Target fill",
|
|
4577
|
+
requestedTarget && finalRows < requestedTarget ? "review" : "pass",
|
|
4578
|
+
requestedTarget ? `${finalRows || 0}/${requestedTarget} final or reviewable row(s) are accounted for.` : "No requested target was reported; using sampled rows for review.",
|
|
4579
|
+
finalRows || sampledRows,
|
|
4580
|
+
requestedTarget || sampledRows
|
|
4581
|
+
),
|
|
4582
|
+
northStarMetric(
|
|
4583
|
+
"unique_emails",
|
|
4584
|
+
"Unique emails",
|
|
4585
|
+
sampledRows === 0 ? "blocked" : uniqueEmails === rowsWithEmail ? "pass" : "blocked",
|
|
4586
|
+
sampledRows === 0 ? "No sampled rows were available for email uniqueness review." : `${uniqueEmails}/${rowsWithEmail} sampled email(s) are unique.`,
|
|
4587
|
+
uniqueEmails,
|
|
4588
|
+
rowsWithEmail
|
|
4589
|
+
),
|
|
4590
|
+
northStarMetric(
|
|
4591
|
+
"unique_domains",
|
|
4592
|
+
"Unique domains",
|
|
4593
|
+
sampledRows === 0 ? "blocked" : uniqueDomains === sampledRows ? "pass" : "review",
|
|
4594
|
+
sampledRows === 0 ? "No sampled rows were available for domain uniqueness review." : `${uniqueDomains}/${sampledRows} sampled company domain(s) are unique.`,
|
|
4595
|
+
uniqueDomains,
|
|
4596
|
+
sampledRows
|
|
4597
|
+
),
|
|
4598
|
+
northStarMetric(
|
|
4599
|
+
"verified_email_rows",
|
|
4600
|
+
"Verified email rows",
|
|
4601
|
+
sampledRows === 0 ? "blocked" : verifiedEmailRows === sampledRows ? "pass" : rowsWithEmail === sampledRows ? "review" : "blocked",
|
|
4602
|
+
sampledRows === 0 ? "No sampled rows were available for email verification review." : `${verifiedEmailRows}/${sampledRows} sampled row(s) carry verified-email evidence.`,
|
|
4603
|
+
verifiedEmailRows,
|
|
4604
|
+
sampledRows
|
|
4605
|
+
),
|
|
4606
|
+
northStarMetric(
|
|
4607
|
+
"copy_completeness",
|
|
4608
|
+
"Copy completeness",
|
|
4609
|
+
sampledRows === 0 ? "blocked" : copyReadyRows === sampledRows ? "pass" : "blocked",
|
|
4610
|
+
sampledRows === 0 ? "No sampled rows were available for copy review." : `${copyReadyRows}/${sampledRows} sampled row(s) include generated copy.`,
|
|
4611
|
+
copyReadyRows,
|
|
4612
|
+
sampledRows
|
|
4613
|
+
),
|
|
4614
|
+
northStarMetric(
|
|
4615
|
+
"copy_quality",
|
|
4616
|
+
"Copy QA",
|
|
4617
|
+
copyQaIssuesByRow.length === 0 ? "pass" : "blocked",
|
|
4618
|
+
copyQaIssuesByRow.length === 0 ? "No sampled copy QA blockers were detected." : `${copyQaIssuesByRow.length}/${sampledRows} sampled row(s) have copy QA issue(s): ${formatCampaignReviewIssueCounts(copyQaIssueCounts)}.`,
|
|
4619
|
+
copyQaIssuesByRow.length,
|
|
4620
|
+
0
|
|
4621
|
+
),
|
|
4622
|
+
northStarMetric(
|
|
4623
|
+
"signal_grounding",
|
|
4624
|
+
"Signal grounding",
|
|
4625
|
+
unsupportedSignalClaims > 0 ? "blocked" : signalBackedRows > 0 ? "pass" : "review",
|
|
4626
|
+
unsupportedSignalClaims > 0 ? `${unsupportedSignalClaims} sampled row(s) make unsupported signal claims.` : signalBackedRows > 0 ? `${signalBackedRows}/${sampledRows} sampled row(s) include supported signal or personalization basis.` : noSupportedSignalRows > 0 ? `${noSupportedSignalRows}/${sampledRows} sampled row(s) are explicitly marked no_supported_signal; copy should stay conservative.` : "No sampled rows include supported signal evidence; copy should stay conservative.",
|
|
4627
|
+
signalBackedRows,
|
|
4628
|
+
sampledRows
|
|
4629
|
+
),
|
|
4630
|
+
northStarMetric(
|
|
4631
|
+
"approval_locks",
|
|
4632
|
+
"Approval locks",
|
|
4633
|
+
approvalLockedRows > 0 || deliveredRows === 0 ? "pass" : "review",
|
|
4634
|
+
approvalLockedRows > 0 ? `${approvalLockedRows}/${sampledRows} sampled row(s) show approval/export lock metadata.` : "Approval-lock metadata was not visible in sampled rows; preserve delivery approval gates.",
|
|
4635
|
+
approvalLockedRows,
|
|
4636
|
+
sampledRows
|
|
4637
|
+
),
|
|
4638
|
+
northStarMetric(
|
|
4639
|
+
"export_send_safety",
|
|
4640
|
+
"Export/send safety",
|
|
4641
|
+
deliveredRows > 0 && status.status !== "completed" ? "blocked" : "pass",
|
|
4642
|
+
deliveredRows > 0 ? `${deliveredRows} row(s) are delivered; status is ${status.status}.` : "No delivered rows are reported before approval.",
|
|
4643
|
+
deliveredRows,
|
|
4644
|
+
0
|
|
4645
|
+
),
|
|
4646
|
+
northStarMetric(
|
|
4647
|
+
"holdout_attribution",
|
|
4648
|
+
"Holdout attribution",
|
|
4649
|
+
holdoutRows > 0 ? "pass" : "review",
|
|
4650
|
+
holdoutRows > 0 ? `${holdoutRows}/${sampledRows} sampled row(s) preserve holdout attribution.` : "No holdout attribution was visible in the sampled rows.",
|
|
4651
|
+
holdoutRows,
|
|
4652
|
+
sampledRows
|
|
4653
|
+
),
|
|
4654
|
+
northStarMetric(
|
|
4655
|
+
"feedback_readiness",
|
|
4656
|
+
"Feedback readiness",
|
|
4657
|
+
feedbackReady ? "pass" : feedbackRequiredForApproval ? "blocked" : "review",
|
|
4658
|
+
feedbackReady ? "Feedback readiness is visible in status diagnostics." : feedbackRequiredForApproval ? "Feedback webhook or approved pull readiness is required before delivery approval." : "Feedback webhook or approved pull readiness was not visible; require it before real send approval.",
|
|
4659
|
+
feedbackReady,
|
|
4660
|
+
true
|
|
4661
|
+
),
|
|
4662
|
+
northStarMetric(
|
|
4663
|
+
"causal_moat",
|
|
4664
|
+
"Causal moat",
|
|
4665
|
+
moat.state === "proved" ? "pass" : "review",
|
|
4666
|
+
moat.detail,
|
|
4667
|
+
moat.state,
|
|
4668
|
+
"proved"
|
|
4669
|
+
),
|
|
4670
|
+
northStarMetric(
|
|
4671
|
+
"artifact_readback",
|
|
4672
|
+
"Artifact readback",
|
|
4673
|
+
artifactCount > 0 ? "pass" : "review",
|
|
4674
|
+
artifactCount > 0 ? `${artifactCount} artifact(s) are available for review.` : "No review artifact is available yet.",
|
|
4675
|
+
artifactCount,
|
|
4676
|
+
1
|
|
4677
|
+
)
|
|
4678
|
+
];
|
|
4679
|
+
const gradedMetrics = metrics.filter((metric) => metric.status !== "pending");
|
|
4680
|
+
const score = gradedMetrics.length === 0 ? null : Math.round(gradedMetrics.filter((metric) => metric.status === "pass").length / gradedMetrics.length * 100);
|
|
4681
|
+
const blockers = metrics.filter((metric) => metric.status === "blocked").map((metric) => metric.detail);
|
|
4682
|
+
const warnings = metrics.filter((metric) => metric.status === "review").map((metric) => metric.detail);
|
|
4683
|
+
const scorecardStatus = blockers.length > 0 ? "blocked" : warnings.length > 0 ? "review" : "pass";
|
|
4684
|
+
return {
|
|
4685
|
+
version: "campaign-builder-north-star.v1",
|
|
4686
|
+
status: scorecardStatus,
|
|
4687
|
+
score,
|
|
4688
|
+
moatState: moat.state,
|
|
4689
|
+
metrics,
|
|
4690
|
+
blockers,
|
|
4691
|
+
warnings,
|
|
4692
|
+
nextAction: scorecardStatus === "blocked" ? "Fix blocked North Star gates before approval or delivery." : terminalState.safeNextAction
|
|
4693
|
+
};
|
|
4694
|
+
}
|
|
3921
4695
|
function createCampaignBuilderBuildReview(status, rows, artifacts) {
|
|
4696
|
+
const terminalState = status.terminalState ?? deriveCampaignBuildTerminalState({
|
|
4697
|
+
status: status.status,
|
|
4698
|
+
phase: status.currentPhase,
|
|
4699
|
+
phaseStatus: status.currentPhaseStatus,
|
|
4700
|
+
staleRunningPhase: status.staleRunningPhase === true,
|
|
4701
|
+
phaseAgeSeconds: status.phaseAgeSeconds ?? null,
|
|
4702
|
+
nextPollAfterSeconds: status.nextPollAfterSeconds ?? null,
|
|
4703
|
+
terminalReason: status.terminalReason ?? status.customerRowCounts?.terminalReason ?? null,
|
|
4704
|
+
staleReason: status.staleReason ?? null,
|
|
4705
|
+
nextAction: status.nextAction,
|
|
4706
|
+
approvalAction: status.approvalAction,
|
|
4707
|
+
triggerRunId: status.triggerRunId ?? null
|
|
4708
|
+
});
|
|
3922
4709
|
const sampledRows = rows.rows.length;
|
|
3923
4710
|
const availableRows = rows.count || sampledRows;
|
|
3924
4711
|
const qualifiedRows = rows.rows.filter((row) => row.qualified !== false).length;
|
|
3925
4712
|
const rowsWithEmail = rows.rows.filter(campaignReviewRowHasEmail).length;
|
|
3926
4713
|
const copyReadyRows = rows.rows.filter(campaignReviewRowHasCopy).length;
|
|
3927
4714
|
const artifactCount = artifacts.length || status.artifactCount || 0;
|
|
4715
|
+
const northStarScorecard = createCampaignBuilderNorthStarScorecard(status, rows, artifacts, terminalState);
|
|
3928
4716
|
const gates = [
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
4717
|
+
campaignReviewGate(
|
|
4718
|
+
"build_reviewable",
|
|
4719
|
+
"Build reviewable",
|
|
4720
|
+
terminalState.kind === "running_healthy" ? "pending" : terminalState.kind === "running_stale" || terminalState.kind === "blocked" ? "blocked" : "pass",
|
|
4721
|
+
terminalState.label
|
|
4722
|
+
),
|
|
4723
|
+
campaignReviewGate(
|
|
4724
|
+
"rows_available",
|
|
4725
|
+
"Rows available",
|
|
4726
|
+
sampledRows > 0 ? "pass" : terminalState.reviewable ? "blocked" : "pending",
|
|
4727
|
+
sampledRows > 0 ? `${sampledRows} sampled row(s) are available for review.` : terminalState.reviewable ? "No rows were returned for review." : "Rows are not graded until the build is reviewable."
|
|
4728
|
+
),
|
|
4729
|
+
campaignReviewGate(
|
|
4730
|
+
"qualified_sample",
|
|
4731
|
+
"Sample rows qualified",
|
|
4732
|
+
sampledRows === 0 ? terminalState.reviewable ? "blocked" : "pending" : qualifiedRows === sampledRows ? "pass" : "blocked",
|
|
4733
|
+
sampledRows > 0 ? `${qualifiedRows}/${sampledRows} sampled row(s) are marked qualified.` : "Qualification could not be checked without sampled rows."
|
|
4734
|
+
),
|
|
4735
|
+
campaignReviewGate(
|
|
4736
|
+
"email_coverage",
|
|
4737
|
+
"Email coverage",
|
|
4738
|
+
sampledRows === 0 ? terminalState.reviewable ? "blocked" : "pending" : rowsWithEmail === sampledRows ? "pass" : "blocked",
|
|
4739
|
+
sampledRows > 0 ? `${rowsWithEmail}/${sampledRows} sampled row(s) include an email.` : "Email coverage could not be checked without sampled rows."
|
|
4740
|
+
),
|
|
4741
|
+
campaignReviewGate(
|
|
4742
|
+
"artifact_available",
|
|
4743
|
+
"Artifact available",
|
|
4744
|
+
artifactCount > 0 ? "pass" : terminalState.reviewable ? "review" : "pending",
|
|
4745
|
+
artifactCount > 0 ? `${artifactCount} artifact(s) are available.` : "No delivery artifact is available yet."
|
|
4746
|
+
),
|
|
4747
|
+
campaignReviewGate(
|
|
4748
|
+
"no_failed_rows",
|
|
4749
|
+
"No failed rows",
|
|
4750
|
+
status.recordsFailed === 0 ? "pass" : "blocked",
|
|
4751
|
+
status.recordsFailed === 0 ? "The build reports zero failed rows." : `${status.recordsFailed} row(s) failed during the build.`
|
|
4752
|
+
)
|
|
3965
4753
|
];
|
|
3966
|
-
const blockedReasons = gates.filter((gate) => !gate.passed).map((gate) => gate.detail);
|
|
4754
|
+
const blockedReasons = gates.filter((gate) => gate.status === "blocked" || !gate.passed).map((gate) => gate.detail);
|
|
3967
4755
|
const warnings = [
|
|
3968
4756
|
rows.hasMore ? "This review is based on a row sample; page through remaining rows before final approval." : void 0,
|
|
3969
4757
|
sampledRows > 0 && copyReadyRows < sampledRows ? `${copyReadyRows}/${sampledRows} sampled row(s) include generated copy.` : void 0,
|
|
3970
4758
|
...status.warnings
|
|
3971
4759
|
].filter((item) => Boolean(item));
|
|
3972
|
-
const readyForDeliveryApproval = blockedReasons.length === 0;
|
|
4760
|
+
const readyForDeliveryApproval = terminalState.reviewable && blockedReasons.length === 0 && northStarScorecard.status !== "blocked";
|
|
3973
4761
|
return {
|
|
3974
4762
|
campaignBuildId: status.campaignBuildId || rows.campaignBuildId,
|
|
3975
4763
|
status,
|
|
3976
4764
|
rows,
|
|
3977
4765
|
artifacts,
|
|
3978
4766
|
gates,
|
|
4767
|
+
northStarScorecard,
|
|
3979
4768
|
summary: {
|
|
3980
4769
|
status: status.status,
|
|
3981
4770
|
phase: status.currentPhase,
|
|
4771
|
+
terminalState: terminalState.kind,
|
|
4772
|
+
scorecardStatus: northStarScorecard.status,
|
|
4773
|
+
scorecardScore: northStarScorecard.score,
|
|
3982
4774
|
sampledRows,
|
|
3983
4775
|
availableRows,
|
|
3984
4776
|
qualifiedRows,
|
|
@@ -4032,6 +4824,184 @@ function campaignReviewRowHasCopy(row) {
|
|
|
4032
4824
|
stringValue(data.subject) || stringValue(data.subject_line) || stringValue(data.subjectLine) || stringValue(data.opener) || stringValue(data.body) || stringValue(data.cta) || stringValue(copy.subject) || stringValue(copy.body) || stringValue(rawCopy.subject) || stringValue(rawCopy.body)
|
|
4033
4825
|
);
|
|
4034
4826
|
}
|
|
4827
|
+
function campaignReviewDataEmail(data) {
|
|
4828
|
+
return stringValue(data.email) || stringValue(data.work_email) || stringValue(data.workEmail) || stringValue(asRecord(data.contact).email);
|
|
4829
|
+
}
|
|
4830
|
+
function campaignReviewDataDomain(data) {
|
|
4831
|
+
const domain = stringValue(data.company_domain) || stringValue(data.companyDomain) || stringValue(asRecord(data.company).domain);
|
|
4832
|
+
return domain?.toLowerCase();
|
|
4833
|
+
}
|
|
4834
|
+
function campaignReviewDataHasVerifiedEmail(data) {
|
|
4835
|
+
const status = String(data.email_status ?? data.emailStatus ?? asRecord(data.contact).email_status ?? "").toLowerCase();
|
|
4836
|
+
return data.email_verified === true || data.emailVerified === true || asRecord(data.contact).email_verified === true || ["valid", "validated", "verified"].includes(status);
|
|
4837
|
+
}
|
|
4838
|
+
function campaignReviewDataCopyParts(data) {
|
|
4839
|
+
const copy = asRecord(data.copy);
|
|
4840
|
+
const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
|
|
4841
|
+
return [
|
|
4842
|
+
stringValue(data.subject),
|
|
4843
|
+
stringValue(data.subject_line),
|
|
4844
|
+
stringValue(data.opener),
|
|
4845
|
+
stringValue(data.body),
|
|
4846
|
+
stringValue(data.cta),
|
|
4847
|
+
stringValue(copy.subject),
|
|
4848
|
+
stringValue(copy.opener),
|
|
4849
|
+
stringValue(copy.body),
|
|
4850
|
+
stringValue(copy.cta),
|
|
4851
|
+
stringValue(rawCopy.subject),
|
|
4852
|
+
stringValue(rawCopy.opener),
|
|
4853
|
+
stringValue(rawCopy.body),
|
|
4854
|
+
stringValue(rawCopy.cta)
|
|
4855
|
+
].filter((part) => Boolean(part));
|
|
4856
|
+
}
|
|
4857
|
+
function campaignReviewDataHasBadGreeting(data) {
|
|
4858
|
+
return campaignReviewDataCopyParts(data).some(
|
|
4859
|
+
(part) => /\bhi\s*(?:,|\{\{|\[)|\bhello\s*(?:,|\{\{|\[)/i.test(part) || /\b(first_name|firstname|name)\b/i.test(part)
|
|
4860
|
+
);
|
|
4861
|
+
}
|
|
4862
|
+
function campaignReviewDataHasBannedPhrase(data) {
|
|
4863
|
+
const text = campaignReviewDataCopyParts(data).join(" ").toLowerCase();
|
|
4864
|
+
return NORTH_STAR_BANNED_COPY_PHRASES.some((phrase) => text.includes(phrase));
|
|
4865
|
+
}
|
|
4866
|
+
function campaignReviewDataSubject(data) {
|
|
4867
|
+
const copy = asRecord(data.copy);
|
|
4868
|
+
const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
|
|
4869
|
+
return stringValue(data.subject) || stringValue(data.subject_line) || stringValue(data.subjectLine) || stringValue(copy.subject) || stringValue(rawCopy.subject);
|
|
4870
|
+
}
|
|
4871
|
+
function campaignReviewDataCta(data) {
|
|
4872
|
+
const copy = asRecord(data.copy);
|
|
4873
|
+
const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
|
|
4874
|
+
return stringValue(data.cta) || stringValue(copy.cta) || stringValue(rawCopy.cta);
|
|
4875
|
+
}
|
|
4876
|
+
function countCampaignReviewIssues(issueRows) {
|
|
4877
|
+
return issueRows.flat().reduce((acc, issue) => {
|
|
4878
|
+
acc[issue] = (acc[issue] || 0) + 1;
|
|
4879
|
+
return acc;
|
|
4880
|
+
}, {});
|
|
4881
|
+
}
|
|
4882
|
+
function formatCampaignReviewIssueCounts(counts) {
|
|
4883
|
+
const entries = Object.entries(counts);
|
|
4884
|
+
return entries.length > 0 ? entries.map(([issue, count]) => `${issue}=${count}`).join(", ") : "none";
|
|
4885
|
+
}
|
|
4886
|
+
function campaignReviewDataCopyQaIssues(data) {
|
|
4887
|
+
const issues = /* @__PURE__ */ new Set();
|
|
4888
|
+
const copyParts = campaignReviewDataCopyParts(data);
|
|
4889
|
+
if (copyParts.length === 0) return [];
|
|
4890
|
+
if (campaignReviewDataHasBadGreeting(data)) issues.add("bad_greeting");
|
|
4891
|
+
if (campaignReviewDataHasBannedPhrase(data)) issues.add("banned_or_vague_phrase");
|
|
4892
|
+
if (campaignReviewDataHasUnsupportedSignalClaim(data)) issues.add("unsupported_signal_claim");
|
|
4893
|
+
if (campaignReviewDataPersonalizationBasis(data).length === 0) issues.add("missing_personalization_basis");
|
|
4894
|
+
if (!campaignReviewDataCta(data)) issues.add("missing_cta");
|
|
4895
|
+
const subject = campaignReviewDataSubject(data);
|
|
4896
|
+
if (subject && subject.length > 70) issues.add("overlong_subject");
|
|
4897
|
+
return [...issues];
|
|
4898
|
+
}
|
|
4899
|
+
function campaignReviewDataPersonalizationBasis(data) {
|
|
4900
|
+
const rawCopy = asRecord(data.raw_copy ?? data.rawCopy);
|
|
4901
|
+
const copy = asRecord(data.copy);
|
|
4902
|
+
const metadata = asRecord(data.metadata);
|
|
4903
|
+
const signalEvidence = asRecord(data.signal_evidence ?? metadata.signal_evidence ?? metadata.signalEvidence);
|
|
4904
|
+
return [
|
|
4905
|
+
...arrayOfStrings(data.personalization_basis) ?? [],
|
|
4906
|
+
...arrayOfStrings(data.personalizationBasis) ?? [],
|
|
4907
|
+
...arrayOfStrings(copy.personalization_basis) ?? [],
|
|
4908
|
+
...arrayOfStrings(rawCopy.personalization_basis) ?? [],
|
|
4909
|
+
...arrayOfStrings(metadata.personalization_basis) ?? [],
|
|
4910
|
+
...arrayOfStrings(metadata.personalizationBasis) ?? [],
|
|
4911
|
+
...arrayOfStrings(signalEvidence.personalization_basis) ?? []
|
|
4912
|
+
];
|
|
4913
|
+
}
|
|
4914
|
+
function campaignReviewDataHasNoSupportedSignal(data) {
|
|
4915
|
+
const metadata = asRecord(data.metadata);
|
|
4916
|
+
const copy = asRecord(data.copy);
|
|
4917
|
+
const state = [
|
|
4918
|
+
data.copy_signal_state,
|
|
4919
|
+
data.signal_basis,
|
|
4920
|
+
data.signal_type,
|
|
4921
|
+
metadata.copy_signal_state,
|
|
4922
|
+
metadata.signal_basis,
|
|
4923
|
+
metadata.signal_type,
|
|
4924
|
+
copy.copy_signal_state
|
|
4925
|
+
].map((value) => stringValue(value)?.toLowerCase()).filter(Boolean);
|
|
4926
|
+
return data.no_supported_signal === true || metadata.no_supported_signal === true || state.includes("no_supported_signal");
|
|
4927
|
+
}
|
|
4928
|
+
function campaignReviewDataHasSignalBasis(data) {
|
|
4929
|
+
if (campaignReviewDataHasNoSupportedSignal(data)) return false;
|
|
4930
|
+
const metadata = asRecord(data.metadata);
|
|
4931
|
+
const signal = asRecord(data.signal);
|
|
4932
|
+
const signalEvidence = asRecord(data.signal_evidence ?? metadata.signal_evidence ?? metadata.signalEvidence);
|
|
4933
|
+
const basis = campaignReviewDataPersonalizationBasis(data);
|
|
4934
|
+
return Boolean(
|
|
4935
|
+
stringValue(data.signal_type) || stringValue(data.signalType) || stringValue(data.signal_summary) || stringValue(data.signalSummary) || stringValue(data.signal_source_url) || stringValue(data.signalSourceUrl) || stringValue(metadata.signal_type) || stringValue(metadata.signal_summary) || stringValue(metadata.signal_source_url) || stringValue(signal.type) || stringValue(signal.summary) || stringValue(signal.source_url) || stringValue(signalEvidence.signal_type) || stringValue(signalEvidence.summary) || stringValue(signalEvidence.source_url) || basis.some((item) => /\bsignal|hiring|funding|leadership|growth|launch|news|technology\b/i.test(item))
|
|
4936
|
+
);
|
|
4937
|
+
}
|
|
4938
|
+
function campaignReviewDataHasUnsupportedSignalClaim(data) {
|
|
4939
|
+
const copyText = campaignReviewDataCopyParts(data).join(" ").toLowerCase();
|
|
4940
|
+
const claimsSignal = /\b(hiring|funding|raised|launched|expanding|appointed|announced|recent news|new role|job posting)\b/.test(copyText);
|
|
4941
|
+
return claimsSignal && !campaignReviewDataHasSignalBasis(data);
|
|
4942
|
+
}
|
|
4943
|
+
function campaignReviewDataHasApprovalLock(data) {
|
|
4944
|
+
const metadata = asRecord(data.fit_metadata ?? data.metadata);
|
|
4945
|
+
const approval = String(data.approval_status ?? data.delivery_approval_status ?? metadata.approval_status ?? "").toLowerCase();
|
|
4946
|
+
const exportStatus = String(data.export_status ?? data.exportStatus ?? "").toLowerCase();
|
|
4947
|
+
return data.export_ready === false || data.exportReady === false || data.delivery_approved === false || data.deliveryApproved === false || ["pending", "pending_approval", "blocked", "approval_required", "held"].includes(approval) || ["pending", "blocked", "approval_required", "held"].includes(exportStatus);
|
|
4948
|
+
}
|
|
4949
|
+
function campaignReviewDataHasHoldoutAttribution(data) {
|
|
4950
|
+
const fitMetadata = asRecord(data.fit_metadata ?? data.fitMetadata);
|
|
4951
|
+
const metadata = asRecord(data.metadata);
|
|
4952
|
+
const holdout = asRecord(
|
|
4953
|
+
fitMetadata.learning_holdout ?? fitMetadata.learningHoldout ?? metadata.learning_holdout ?? metadata.learningHoldout ?? data.learning_holdout ?? data.learningHoldout
|
|
4954
|
+
);
|
|
4955
|
+
const experimentKey = stringValue(holdout.experiment_key ?? holdout.experimentKey ?? data.experiment_key ?? data.experimentKey);
|
|
4956
|
+
const cohort = stringValue(holdout.cohort_role ?? holdout.cohortRole ?? data.cohort_role ?? data.learning_cohort ?? data.learningCohort);
|
|
4957
|
+
const brainApplied = holdout.brain_applied ?? holdout.brainApplied ?? data.brain_applied ?? data.signaliz_brain_applied;
|
|
4958
|
+
return Boolean(experimentKey && cohort && brainApplied !== void 0);
|
|
4959
|
+
}
|
|
4960
|
+
function campaignReviewStatusHasFeedbackReadiness(status) {
|
|
4961
|
+
const diagnostics = asRecord(status.diagnostics);
|
|
4962
|
+
const feedbackReadiness = asRecord(diagnostics.feedback_readiness ?? diagnostics.feedbackReadiness);
|
|
4963
|
+
const feedbackSubstrate = asRecord(diagnostics.feedback_substrate ?? diagnostics.feedbackSubstrate);
|
|
4964
|
+
const evidenceCounts = asRecord(diagnostics.evidence_counts ?? diagnostics.evidenceCounts);
|
|
4965
|
+
return feedbackReadiness.ready === true || feedbackReadiness.webhook_configured === true || feedbackSubstrate.stage === "ready" || Number(evidenceCounts.feedback_events ?? 0) > 0;
|
|
4966
|
+
}
|
|
4967
|
+
function campaignReviewMoatState(status, holdoutRows) {
|
|
4968
|
+
const diagnostics = asRecord(status.diagnostics);
|
|
4969
|
+
const evidenceCounts = asRecord(diagnostics.evidence_counts ?? diagnostics.evidenceCounts);
|
|
4970
|
+
const embeddedHoldout = asRecord(diagnostics.embedded_holdout ?? diagnostics.embeddedHoldout);
|
|
4971
|
+
const holdoutLift = asRecord(diagnostics.holdout_lift ?? diagnostics.holdoutLift ?? diagnostics.holdout_measurement ?? diagnostics.holdoutMeasurement);
|
|
4972
|
+
const controlSample = Math.max(
|
|
4973
|
+
Number(evidenceCounts.holdout_control_sample_size ?? 0),
|
|
4974
|
+
Number(evidenceCounts.embedded_holdout_control_sample ?? 0),
|
|
4975
|
+
Number(embeddedHoldout.control_sample_size ?? 0)
|
|
4976
|
+
);
|
|
4977
|
+
const learnedSample = Math.max(
|
|
4978
|
+
Number(evidenceCounts.holdout_learned_sample_size ?? 0),
|
|
4979
|
+
Number(evidenceCounts.embedded_holdout_learned_sample ?? 0),
|
|
4980
|
+
Number(embeddedHoldout.learned_sample_size ?? 0)
|
|
4981
|
+
);
|
|
4982
|
+
const feedbackEvents = Math.max(
|
|
4983
|
+
Number(evidenceCounts.feedback_events ?? 0),
|
|
4984
|
+
Number(evidenceCounts.campaign_build_feedback_events ?? 0),
|
|
4985
|
+
Number(evidenceCounts.delivery_holdout_sent_outcomes ?? 0)
|
|
4986
|
+
);
|
|
4987
|
+
const proved = diagnostics.closed_loop_proof_ready === true || holdoutLift.honest_measurement === true && holdoutLift.positive_lift === true;
|
|
4988
|
+
if (proved) {
|
|
4989
|
+
return {
|
|
4990
|
+
state: "proved",
|
|
4991
|
+
detail: "Real attributed feedback shows positive lift for explicit control and learned cohorts."
|
|
4992
|
+
};
|
|
4993
|
+
}
|
|
4994
|
+
if (controlSample > 0 && learnedSample > 0 && feedbackEvents > 0) {
|
|
4995
|
+
return {
|
|
4996
|
+
state: "moved_needs_lift_volume",
|
|
4997
|
+
detail: `Control and learned cohorts have attributed feedback (${controlSample} control, ${learnedSample} learned, ${feedbackEvents} feedback event(s)); keep collecting lift volume before claiming proof.`
|
|
4998
|
+
};
|
|
4999
|
+
}
|
|
5000
|
+
return {
|
|
5001
|
+
state: "scaffolding_ready",
|
|
5002
|
+
detail: holdoutRows > 0 ? `${holdoutRows} sampled row(s) carry holdout attribution, but real control/learned feedback lift is not proved yet.` : "Holdout and feedback scaffolding may be ready, but no real control/learned feedback lift is proved yet."
|
|
5003
|
+
};
|
|
5004
|
+
}
|
|
4035
5005
|
function createCampaignBuilderReadinessLane(route, plan) {
|
|
4036
5006
|
const builtIn = campaignBuilderBuiltInForRoute(route);
|
|
4037
5007
|
const customRoute = route.provider !== "signaliz" && route.provider !== "csv" && builtIn === void 0;
|
|
@@ -4073,6 +5043,8 @@ function readinessLaneLabel(route, builtIn) {
|
|
|
4073
5043
|
const labels = {
|
|
4074
5044
|
lead_generation: "Signaliz lead generation",
|
|
4075
5045
|
local_leads: "Signaliz local leads",
|
|
5046
|
+
company_discovery: "Signaliz company discovery",
|
|
5047
|
+
people_discovery: "Signaliz people discovery",
|
|
4076
5048
|
email_finding: "Signaliz email finding",
|
|
4077
5049
|
email_verification: "Signaliz email verification",
|
|
4078
5050
|
signals: "Signaliz signals"
|
|
@@ -4157,6 +5129,35 @@ function summarizeCampaignBuilderProofDryRun(dryRunResult) {
|
|
|
4157
5129
|
plannedTargetCount: dryRunResult.plannedTargetCount ?? dryRunResult.planned_target_count ?? null
|
|
4158
5130
|
};
|
|
4159
5131
|
}
|
|
5132
|
+
function summarizeCampaignBuilderProofLearnBack(plan) {
|
|
5133
|
+
if (Object.keys(plan).length === 0) return { ready: false };
|
|
5134
|
+
const memoryPolicy = asRecord(plan.memory_write_policy);
|
|
5135
|
+
const memoryItemsPolicy = asRecord(memoryPolicy.gtm_memory_items);
|
|
5136
|
+
const sequence = Array.isArray(plan.post_build_sequence) ? plan.post_build_sequence.map((step) => {
|
|
5137
|
+
const record = asRecord(step);
|
|
5138
|
+
return compact({
|
|
5139
|
+
step: record.step,
|
|
5140
|
+
tool: stringValue(record.tool),
|
|
5141
|
+
approval_boundary: stringValue(record.approval_boundary),
|
|
5142
|
+
reason: stringValue(record.reason)
|
|
5143
|
+
});
|
|
5144
|
+
}).filter((step) => typeof step.tool === "string") : [];
|
|
5145
|
+
return {
|
|
5146
|
+
ready: sequence.length > 0,
|
|
5147
|
+
source_tool: firstNonEmptyString(plan.source_tool, plan.sourceTool),
|
|
5148
|
+
post_build_sequence: sequence,
|
|
5149
|
+
memory_write_policy: {
|
|
5150
|
+
target_tables: Array.isArray(memoryPolicy.target_tables) ? memoryPolicy.target_tables : [],
|
|
5151
|
+
gtm_memory_items: {
|
|
5152
|
+
shareable: memoryItemsPolicy.shareable === false ? false : memoryItemsPolicy.shareable ?? null,
|
|
5153
|
+
allowed_redaction_states: Array.isArray(memoryItemsPolicy.allowed_redaction_states) ? memoryItemsPolicy.allowed_redaction_states : [],
|
|
5154
|
+
raw_private_fields_withheld: Array.isArray(memoryItemsPolicy.raw_private_fields_withheld) ? memoryItemsPolicy.raw_private_fields_withheld : []
|
|
5155
|
+
}
|
|
5156
|
+
},
|
|
5157
|
+
approval_policy: firstNonEmptyString(plan.approval_policy, plan.approvalPolicy),
|
|
5158
|
+
privacy_policy: firstNonEmptyString(plan.privacy_policy, plan.privacyPolicy)
|
|
5159
|
+
};
|
|
5160
|
+
}
|
|
4160
5161
|
function firstNonEmptyString(...values) {
|
|
4161
5162
|
for (const value of values) {
|
|
4162
5163
|
if (typeof value === "string" && value.trim()) return value;
|
|
@@ -4639,14 +5640,87 @@ var Ops = class {
|
|
|
4639
5640
|
const body = typeof params === "string" ? { prompt: params } : buildOpsCreateBody(params);
|
|
4640
5641
|
return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_create", body)));
|
|
4641
5642
|
}
|
|
5643
|
+
async schedule(params) {
|
|
5644
|
+
const createBody = typeof params === "string" ? { prompt: params, cadence: "daily" } : { ...buildOpsCreateBody(params), cadence: params.cadence ?? "daily" };
|
|
5645
|
+
const { activate: _activate, ...body } = createBody;
|
|
5646
|
+
return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_schedule", body)));
|
|
5647
|
+
}
|
|
5648
|
+
async scheduleAndWait(params) {
|
|
5649
|
+
const options = typeof params === "string" ? { schedule: { prompt: params, cadence: "daily" }, run: {}, wait: {} } : buildOpsScheduleAndWaitOptions(params);
|
|
5650
|
+
const raw = await this.call("ops_schedule_and_wait", buildOpsScheduleAndWaitBody(options));
|
|
5651
|
+
return normalizeOpsScheduleAndWaitCallResult(raw, options.wait, {
|
|
5652
|
+
approvalMessage: "ops.scheduleAndWait requires an approved schedulable Op. Retry with confirmSpend=true after reviewing approval details.",
|
|
5653
|
+
notCreatedMessage: "ops.scheduleAndWait requires ops_schedule_and_wait to create an op_id. Use ops.schedule for approval review flows."
|
|
5654
|
+
});
|
|
5655
|
+
}
|
|
5656
|
+
/** Schedule a recurring Op that delivers through a customer-owned Nango API connection. */
|
|
5657
|
+
async scheduleNangoAction(input) {
|
|
5658
|
+
return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_nango_schedule", buildOpsNangoScheduleBody(input))));
|
|
5659
|
+
}
|
|
5660
|
+
/** Schedule a recurring Nango-backed Op, run the first tick, and return result readback. */
|
|
5661
|
+
async scheduleNangoActionAndWait(input) {
|
|
5662
|
+
const options = buildOpsNangoScheduleAndWaitOptions(input);
|
|
5663
|
+
const raw = await this.call("ops_nango_schedule_and_wait", buildOpsNangoScheduleAndWaitBody(options));
|
|
5664
|
+
return normalizeOpsScheduleAndWaitCallResult(raw, options.wait, {
|
|
5665
|
+
approvalMessage: "ops.scheduleNangoActionAndWait requires an approved Nango-backed Op. Retry with confirmSpend=true after reviewing approval details.",
|
|
5666
|
+
notCreatedMessage: "ops.scheduleNangoActionAndWait requires ops_nango_schedule_and_wait to create an op_id. Use ops.scheduleNangoAction for approval review flows."
|
|
5667
|
+
});
|
|
5668
|
+
}
|
|
4642
5669
|
async execute(params) {
|
|
4643
5670
|
const body = typeof params === "string" ? { prompt: params } : buildOpsExecuteBody(params);
|
|
4644
5671
|
return normalizeOpsExecuteResult(withExecutionRefs(await this.call("ops_execute", body)));
|
|
4645
5672
|
}
|
|
5673
|
+
async executeAndWait(params) {
|
|
5674
|
+
const options = typeof params === "string" ? { execute: { prompt: params, auto_run: true }, wait: {} } : buildOpsExecuteAndWaitOptions(params);
|
|
5675
|
+
const execute = await this.execute(options.execute);
|
|
5676
|
+
if (execute.approval_required || execute.error_code === "APPROVAL_REQUIRED") {
|
|
5677
|
+
throw new SignalizError({
|
|
5678
|
+
code: "APPROVAL_REQUIRED",
|
|
5679
|
+
errorType: "validation",
|
|
5680
|
+
message: "ops.executeAndWait requires an approved executable Op. Retry with confirmSpend=true after reviewing approval details.",
|
|
5681
|
+
details: { execute }
|
|
5682
|
+
});
|
|
5683
|
+
}
|
|
5684
|
+
if (!execute.op_id) {
|
|
5685
|
+
throw new SignalizError({
|
|
5686
|
+
code: "OP_NOT_CREATED",
|
|
5687
|
+
errorType: "validation",
|
|
5688
|
+
message: "ops.executeAndWait requires ops_execute to create an op_id. Use ops.execute for dry runs or approval review flows.",
|
|
5689
|
+
details: { execute }
|
|
5690
|
+
});
|
|
5691
|
+
}
|
|
5692
|
+
const waited = await this.waitForResults({
|
|
5693
|
+
...options.wait,
|
|
5694
|
+
op_id: execute.op_id
|
|
5695
|
+
});
|
|
5696
|
+
const runId = execute.run_id ?? execute.runId ?? waited.status.run_id ?? waited.status.runId ?? null;
|
|
5697
|
+
return {
|
|
5698
|
+
...waited,
|
|
5699
|
+
execute,
|
|
5700
|
+
run_id: runId,
|
|
5701
|
+
runId,
|
|
5702
|
+
execution_refs: mergeExecutionRefsFrom([execute, waited])
|
|
5703
|
+
};
|
|
5704
|
+
}
|
|
4646
5705
|
async run(params) {
|
|
4647
5706
|
const body = typeof params === "string" ? { op_id: params } : buildOpsRunBody(params);
|
|
4648
5707
|
return normalizeOpsRunResult(withExecutionRefs(await this.call("ops_run", body)));
|
|
4649
5708
|
}
|
|
5709
|
+
async runAndWait(params) {
|
|
5710
|
+
const options = typeof params === "string" ? { op_id: params } : buildOpsRunAndWaitOptions(params);
|
|
5711
|
+
if (!options.op_id) throw new Error("ops.runAndWait requires op_id or opId");
|
|
5712
|
+
const run = await this.run({
|
|
5713
|
+
op_id: options.op_id,
|
|
5714
|
+
instruction: options.instruction,
|
|
5715
|
+
force: options.force
|
|
5716
|
+
});
|
|
5717
|
+
const waited = await this.waitForResults(options);
|
|
5718
|
+
return {
|
|
5719
|
+
...waited,
|
|
5720
|
+
run,
|
|
5721
|
+
execution_refs: mergeExecutionRefsFrom([run, waited])
|
|
5722
|
+
};
|
|
5723
|
+
}
|
|
4650
5724
|
async status(params) {
|
|
4651
5725
|
const body = typeof params === "string" ? { op_id: params } : buildOpsStatusBody(params);
|
|
4652
5726
|
return normalizeOpsStatusResult(withExecutionRefs(await this.call("ops_status", body)));
|
|
@@ -4655,21 +5729,188 @@ var Ops = class {
|
|
|
4655
5729
|
const body = typeof params === "string" ? { op_id: params } : buildOpsResultsBody(params);
|
|
4656
5730
|
return normalizeOpsResultsResult(withExecutionRefs(await this.call("ops_results", body)));
|
|
4657
5731
|
}
|
|
4658
|
-
async
|
|
4659
|
-
const
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
return normalizeOpsProofResult(data);
|
|
5732
|
+
async waitForResults(params) {
|
|
5733
|
+
const options = typeof params === "string" ? { op_id: params } : buildOpsWaitForResultsOptions(params);
|
|
5734
|
+
if (!options.op_id) throw new Error("ops.waitForResults requires op_id or opId");
|
|
5735
|
+
const waitResult = await this.call("ops_wait", buildOpsWaitBody(options));
|
|
5736
|
+
return normalizeOpsWaitForResultsResult(waitResult, options);
|
|
4664
5737
|
}
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
5738
|
+
/** Create a short-lived Nango Connect session from the Ops namespace. */
|
|
5739
|
+
async createNangoConnectSession(input) {
|
|
5740
|
+
return this.call("nango_connect_session_create", {
|
|
5741
|
+
provider_id: input.providerId,
|
|
5742
|
+
integration_id: input.integrationId,
|
|
5743
|
+
provider_display_name: input.providerDisplayName,
|
|
5744
|
+
integration_display_name: input.integrationDisplayName,
|
|
5745
|
+
allowed_integrations: input.allowedIntegrations,
|
|
5746
|
+
surface: input.surface,
|
|
5747
|
+
source: input.source,
|
|
5748
|
+
user_email: input.userEmail,
|
|
5749
|
+
user_display_name: input.userDisplayName
|
|
5750
|
+
});
|
|
5751
|
+
}
|
|
5752
|
+
/** Prepare the full Nango provider search, connect, pull/export, Ops, and route flow. */
|
|
5753
|
+
async prepareNangoIntegrationFlow(input = {}) {
|
|
5754
|
+
return this.call("nango_integration_flow_prepare", {
|
|
5755
|
+
query: input.query,
|
|
5756
|
+
search: input.search,
|
|
5757
|
+
provider_id: input.providerId,
|
|
5758
|
+
provider: input.provider,
|
|
5759
|
+
integration_id: input.integrationId,
|
|
5760
|
+
provider_config_key: input.providerConfigKey,
|
|
5761
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
5762
|
+
connection_id: input.connectionId,
|
|
5763
|
+
nango_connection_id: input.nangoConnectionId,
|
|
5764
|
+
intent: input.intent,
|
|
5765
|
+
action_name: input.actionName,
|
|
5766
|
+
tool_name: input.toolName,
|
|
5767
|
+
proxy_path: input.proxyPath,
|
|
5768
|
+
method: input.method,
|
|
5769
|
+
input: input.input,
|
|
5770
|
+
cadence: input.cadence,
|
|
5771
|
+
field_map: input.fieldMap,
|
|
5772
|
+
required_fields: input.requiredFields,
|
|
5773
|
+
confirm_spend: input.confirmSpend,
|
|
5774
|
+
write_confirmed: input.writeConfirmed,
|
|
5775
|
+
layer: input.layer,
|
|
5776
|
+
campaign_id: input.campaignId,
|
|
5777
|
+
limit: input.limit,
|
|
5778
|
+
include_provider_catalog: input.includeProviderCatalog
|
|
5779
|
+
});
|
|
5780
|
+
}
|
|
5781
|
+
/** List Nango-backed action tools for a workspace connection without executing them. */
|
|
5782
|
+
async listNangoTools(options = {}) {
|
|
5783
|
+
return this.call("nango_mcp_tools_list", {
|
|
5784
|
+
workspace_connection_id: options.workspaceConnectionId,
|
|
5785
|
+
connection_id: options.connectionId,
|
|
5786
|
+
provider_config_key: options.providerConfigKey,
|
|
5787
|
+
integration_id: options.integrationId,
|
|
5788
|
+
nango_connection_id: options.nangoConnectionId,
|
|
5789
|
+
format: options.format,
|
|
5790
|
+
include_raw: options.includeRaw
|
|
5791
|
+
});
|
|
5792
|
+
}
|
|
5793
|
+
/** Audit connected Nango rows, action/proxy readiness, and read/write proof gaps. */
|
|
5794
|
+
async proveNangoReadWrite(options = {}) {
|
|
5795
|
+
return this.call("nango_mcp_read_write_audit", {
|
|
5796
|
+
workspace_connection_id: options.workspaceConnectionId,
|
|
5797
|
+
connection_id: options.connectionId,
|
|
5798
|
+
provider_config_key: options.providerConfigKey,
|
|
5799
|
+
integration_id: options.integrationId,
|
|
5800
|
+
nango_connection_id: options.nangoConnectionId,
|
|
5801
|
+
limit: options.limit,
|
|
5802
|
+
include_raw: options.includeRaw,
|
|
5803
|
+
read_proxy_path: options.readProxyPath,
|
|
5804
|
+
write_proxy_path: options.writeProxyPath,
|
|
5805
|
+
method: options.method,
|
|
5806
|
+
execute_read_probe: options.executeReadProbe,
|
|
5807
|
+
execute_write_probe: options.executeWriteProbe,
|
|
5808
|
+
confirm: options.confirm,
|
|
5809
|
+
confirm_write: options.confirmWrite,
|
|
5810
|
+
input: options.input,
|
|
5811
|
+
write_input: options.writeInput
|
|
5812
|
+
});
|
|
5813
|
+
}
|
|
5814
|
+
/** Dry-run or execute a Nango-backed action tool through the approval-aware MCP bridge. */
|
|
5815
|
+
async callNangoTool(input) {
|
|
5816
|
+
return this.call("nango_mcp_tool_call", {
|
|
5817
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
5818
|
+
connection_id: input.connectionId,
|
|
5819
|
+
provider_config_key: input.providerConfigKey,
|
|
5820
|
+
integration_id: input.integrationId,
|
|
5821
|
+
nango_connection_id: input.nangoConnectionId,
|
|
5822
|
+
action_name: input.actionName,
|
|
5823
|
+
tool_name: input.toolName,
|
|
5824
|
+
delivery_mode: input.deliveryMode,
|
|
5825
|
+
proxy_path: input.proxyPath,
|
|
5826
|
+
nango_proxy_path: input.nangoProxyPath,
|
|
5827
|
+
method: input.method,
|
|
5828
|
+
http_method: input.httpMethod,
|
|
5829
|
+
proxy_headers: input.proxyHeaders,
|
|
5830
|
+
input: input.input,
|
|
5831
|
+
async: input.async,
|
|
5832
|
+
max_retries: input.maxRetries,
|
|
5833
|
+
dry_run: input.dryRun,
|
|
5834
|
+
confirm: input.confirm,
|
|
5835
|
+
confirm_write: input.confirmWrite
|
|
5836
|
+
});
|
|
5837
|
+
}
|
|
5838
|
+
/** Execute a Nango action and poll its async result when a status URL/action id is returned. */
|
|
5839
|
+
async callNangoToolAndWait(input) {
|
|
5840
|
+
const result = await this.call("nango_mcp_tool_call_and_wait", {
|
|
5841
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
5842
|
+
connection_id: input.connectionId,
|
|
5843
|
+
provider_config_key: input.providerConfigKey,
|
|
5844
|
+
integration_id: input.integrationId,
|
|
5845
|
+
nango_connection_id: input.nangoConnectionId,
|
|
5846
|
+
action_name: input.actionName,
|
|
5847
|
+
tool_name: input.toolName,
|
|
5848
|
+
delivery_mode: input.deliveryMode,
|
|
5849
|
+
proxy_path: input.proxyPath,
|
|
5850
|
+
nango_proxy_path: input.nangoProxyPath,
|
|
5851
|
+
method: input.method,
|
|
5852
|
+
http_method: input.httpMethod,
|
|
5853
|
+
proxy_headers: input.proxyHeaders,
|
|
5854
|
+
input: input.input,
|
|
5855
|
+
async: input.async ?? true,
|
|
5856
|
+
max_retries: input.maxRetries,
|
|
5857
|
+
dry_run: input.dryRun,
|
|
5858
|
+
confirm: input.confirm,
|
|
5859
|
+
confirm_write: input.confirmWrite,
|
|
5860
|
+
interval_ms: input.intervalMs,
|
|
5861
|
+
max_polls: input.maxPolls,
|
|
5862
|
+
timeout_ms: input.timeoutMs
|
|
5863
|
+
});
|
|
5864
|
+
const packet = asRecord2(result);
|
|
5865
|
+
const actionId = optionalString(packet.actionId) ?? optionalString(packet.action_id);
|
|
5866
|
+
const statusUrl = optionalString(packet.statusUrl) ?? optionalString(packet.status_url);
|
|
5867
|
+
const maxPolls = Number(packet.maxPolls ?? packet.max_polls ?? 0);
|
|
5868
|
+
const intervalMs = Number(packet.intervalMs ?? packet.interval_ms ?? 0);
|
|
5869
|
+
const timeoutMs = Number(packet.timeoutMs ?? packet.timeout_ms ?? 0);
|
|
5870
|
+
const timedOut = Boolean(packet.timedOut ?? packet.timed_out);
|
|
5871
|
+
return {
|
|
5872
|
+
...packet,
|
|
5873
|
+
success: typeof packet.success === "boolean" ? packet.success : void 0,
|
|
5874
|
+
call: packet.call,
|
|
5875
|
+
result: packet.result,
|
|
5876
|
+
status: optionalString(packet.status),
|
|
5877
|
+
action_id: actionId,
|
|
5878
|
+
actionId,
|
|
5879
|
+
status_url: statusUrl,
|
|
5880
|
+
statusUrl,
|
|
5881
|
+
polls: Number(packet.polls ?? 0),
|
|
5882
|
+
max_polls: maxPolls,
|
|
5883
|
+
maxPolls,
|
|
5884
|
+
interval_ms: intervalMs,
|
|
5885
|
+
intervalMs,
|
|
5886
|
+
timeout_ms: timeoutMs,
|
|
5887
|
+
timeoutMs,
|
|
5888
|
+
timed_out: timedOut,
|
|
5889
|
+
timedOut
|
|
5890
|
+
};
|
|
5891
|
+
}
|
|
5892
|
+
/** Poll an async Nango action result by action id or status URL. */
|
|
5893
|
+
async getNangoActionResult(input) {
|
|
5894
|
+
return this.call("nango_mcp_action_result_get", {
|
|
5895
|
+
action_id: input.actionId,
|
|
5896
|
+
status_url: input.statusUrl
|
|
5897
|
+
});
|
|
5898
|
+
}
|
|
5899
|
+
async proof(params = {}) {
|
|
5900
|
+
const data = await this.call("ops_proof", {
|
|
5901
|
+
window_hours: params.windowHours,
|
|
5902
|
+
output_format: "json"
|
|
5903
|
+
});
|
|
5904
|
+
return normalizeOpsProofResult(data);
|
|
5905
|
+
}
|
|
5906
|
+
async debug(params) {
|
|
5907
|
+
const options = typeof params === "string" ? { op_id: params } : buildOpsDebugOptions(params);
|
|
5908
|
+
const diagnosticErrors = [];
|
|
5909
|
+
const status = await this.status(options.op_id);
|
|
5910
|
+
const refs = /* @__PURE__ */ new Map();
|
|
5911
|
+
const addRefs = (items) => {
|
|
5912
|
+
for (const ref of items ?? []) refs.set(`${ref.kind}:${ref.id}`, ref);
|
|
5913
|
+
};
|
|
4673
5914
|
const recordError = (step, err) => {
|
|
4674
5915
|
diagnosticErrors.push({
|
|
4675
5916
|
step,
|
|
@@ -4681,51 +5922,57 @@ var Ops = class {
|
|
|
4681
5922
|
addRefs(collectExecutionReferences(status.latest_run));
|
|
4682
5923
|
}
|
|
4683
5924
|
const runRefs = Array.from(refs.values()).filter((ref) => ref.kind === "trigger_run" || ref.kind === "dataplane_run" || ref.kind === "replay_run");
|
|
4684
|
-
|
|
4685
|
-
for (const ref of runRefs) {
|
|
4686
|
-
try {
|
|
4687
|
-
const result = await this.getTriggerRunStatus(ref.id);
|
|
4688
|
-
const runs = "runs" in result ? result.runs : [result];
|
|
4689
|
-
runStatuses.push(...runs);
|
|
4690
|
-
for (const run of runs) addRefs(run.execution_refs);
|
|
4691
|
-
} catch (err) {
|
|
4692
|
-
recordError(`run-status:${ref.id}`, err);
|
|
4693
|
-
}
|
|
4694
|
-
}
|
|
5925
|
+
let runStatuses = [];
|
|
4695
5926
|
let queue;
|
|
4696
|
-
if (options.include_queue !== false) {
|
|
4697
|
-
try {
|
|
4698
|
-
queue = await this.getQueueStatus({ summary: true });
|
|
4699
|
-
addRefs(queue.execution_refs);
|
|
4700
|
-
} catch (err) {
|
|
4701
|
-
recordError("queue", err);
|
|
4702
|
-
}
|
|
4703
|
-
}
|
|
4704
5927
|
let dashboardRecent;
|
|
4705
|
-
if (options.include_dashboard !== false) {
|
|
4706
|
-
try {
|
|
4707
|
-
dashboardRecent = await this.getDashboard({
|
|
4708
|
-
section: "recent",
|
|
4709
|
-
limit: options.dashboard_limit ?? 10,
|
|
4710
|
-
timeRangeDays: options.time_range_days
|
|
4711
|
-
});
|
|
4712
|
-
} catch (err) {
|
|
4713
|
-
recordError("dashboard:recent", err);
|
|
4714
|
-
}
|
|
4715
|
-
}
|
|
4716
5928
|
let results;
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
5929
|
+
await Promise.all([
|
|
5930
|
+
(async () => {
|
|
5931
|
+
if (runRefs.length === 0) return;
|
|
5932
|
+
try {
|
|
5933
|
+
const result = await this.getTriggerRunStatus({ run_ids: runRefs.map((ref) => ref.id) });
|
|
5934
|
+
const runs = "runs" in result ? result.runs : [result];
|
|
5935
|
+
runStatuses = runs;
|
|
5936
|
+
for (const run of runs) addRefs(run.execution_refs);
|
|
5937
|
+
} catch (err) {
|
|
5938
|
+
recordError(runRefs.length === 1 ? `run-status:${runRefs[0].id}` : "run-status:batch", err);
|
|
5939
|
+
}
|
|
5940
|
+
})(),
|
|
5941
|
+
(async () => {
|
|
5942
|
+
if (options.include_queue === false) return;
|
|
5943
|
+
try {
|
|
5944
|
+
queue = await this.getQueueStatus({ summary: true });
|
|
5945
|
+
addRefs(queue.execution_refs);
|
|
5946
|
+
} catch (err) {
|
|
5947
|
+
recordError("queue", err);
|
|
5948
|
+
}
|
|
5949
|
+
})(),
|
|
5950
|
+
(async () => {
|
|
5951
|
+
if (options.include_dashboard === false) return;
|
|
5952
|
+
try {
|
|
5953
|
+
dashboardRecent = await this.getDashboard({
|
|
5954
|
+
section: "recent",
|
|
5955
|
+
limit: options.dashboard_limit ?? 10,
|
|
5956
|
+
timeRangeDays: options.time_range_days
|
|
5957
|
+
});
|
|
5958
|
+
} catch (err) {
|
|
5959
|
+
recordError("dashboard:recent", err);
|
|
5960
|
+
}
|
|
5961
|
+
})(),
|
|
5962
|
+
(async () => {
|
|
5963
|
+
if (!options.include_results) return;
|
|
5964
|
+
try {
|
|
5965
|
+
results = await this.results({
|
|
5966
|
+
op_id: options.op_id,
|
|
5967
|
+
limit: options.results_limit ?? 25,
|
|
5968
|
+
include_failed_runs: true
|
|
5969
|
+
});
|
|
5970
|
+
addRefs(results.execution_refs);
|
|
5971
|
+
} catch (err) {
|
|
5972
|
+
recordError("results", err);
|
|
5973
|
+
}
|
|
5974
|
+
})()
|
|
5975
|
+
]);
|
|
4729
5976
|
const executionRefs = Array.from(refs.values());
|
|
4730
5977
|
const replayCandidates = executionRefs.filter((ref) => ref.kind === "execution_event");
|
|
4731
5978
|
const nextActions = buildDebugNextActions(status, executionRefs, diagnosticErrors);
|
|
@@ -4927,6 +6174,69 @@ function mergeExecutionRefs(result) {
|
|
|
4927
6174
|
for (const ref of collectExecutionReferences(result)) add(ref);
|
|
4928
6175
|
return Array.from(refs.values());
|
|
4929
6176
|
}
|
|
6177
|
+
function mergeExecutionRefsFrom(results) {
|
|
6178
|
+
const refs = /* @__PURE__ */ new Map();
|
|
6179
|
+
for (const result of results) {
|
|
6180
|
+
if (!result) continue;
|
|
6181
|
+
for (const ref of mergeExecutionRefs(result)) refs.set(`${ref.kind}:${ref.id}`, ref);
|
|
6182
|
+
}
|
|
6183
|
+
return Array.from(refs.values());
|
|
6184
|
+
}
|
|
6185
|
+
function normalizeOpsScheduleAndWaitCallResult(raw, waitOptions, messages) {
|
|
6186
|
+
if (raw.approval_required || raw.approvalRequired || raw.error_code === "APPROVAL_REQUIRED" || raw.errorCode === "APPROVAL_REQUIRED") {
|
|
6187
|
+
throw new SignalizError({
|
|
6188
|
+
code: "APPROVAL_REQUIRED",
|
|
6189
|
+
errorType: "validation",
|
|
6190
|
+
message: messages.approvalMessage,
|
|
6191
|
+
details: { schedule: raw }
|
|
6192
|
+
});
|
|
6193
|
+
}
|
|
6194
|
+
const opId = stringValue2(raw.op_id ?? raw.opId);
|
|
6195
|
+
if (!opId) {
|
|
6196
|
+
throw new SignalizError({
|
|
6197
|
+
code: "OP_NOT_CREATED",
|
|
6198
|
+
errorType: "validation",
|
|
6199
|
+
message: messages.notCreatedMessage,
|
|
6200
|
+
details: { schedule: raw }
|
|
6201
|
+
});
|
|
6202
|
+
}
|
|
6203
|
+
const scheduleRaw = asRecord2(raw.schedule ?? raw.schedule_result ?? raw.scheduleResult);
|
|
6204
|
+
const runRaw = asRecord2(raw.run ?? raw.run_result ?? raw.runResult);
|
|
6205
|
+
const schedule = normalizeOpsCreateResult(withExecutionRefs(
|
|
6206
|
+
Object.keys(scheduleRaw).length > 0 ? scheduleRaw : {
|
|
6207
|
+
...raw,
|
|
6208
|
+
op_id: opId,
|
|
6209
|
+
routine_id: raw.routine_id ?? raw.routineId ?? opId,
|
|
6210
|
+
status: "ready",
|
|
6211
|
+
phase: "scheduled",
|
|
6212
|
+
next_action: raw.next_action ?? raw.nextAction
|
|
6213
|
+
}
|
|
6214
|
+
));
|
|
6215
|
+
const run = normalizeOpsRunResult(withExecutionRefs(
|
|
6216
|
+
Object.keys(runRaw).length > 0 ? runRaw : {
|
|
6217
|
+
success: raw.success !== false,
|
|
6218
|
+
op_id: opId,
|
|
6219
|
+
routine_id: raw.routine_id ?? raw.routineId ?? opId,
|
|
6220
|
+
run_id: raw.run_id ?? raw.runId ?? null,
|
|
6221
|
+
status: "running",
|
|
6222
|
+
phase: "queued",
|
|
6223
|
+
next_action: raw.next_action ?? raw.nextAction,
|
|
6224
|
+
results_count: 0,
|
|
6225
|
+
results_url: raw.results_url ?? raw.resultsUrl,
|
|
6226
|
+
delivery_status: raw.delivery_status ?? raw.deliveryStatus
|
|
6227
|
+
}
|
|
6228
|
+
));
|
|
6229
|
+
const waited = normalizeOpsWaitForResultsResult(raw, { ...waitOptions, op_id: opId });
|
|
6230
|
+
const runId = run.run_id ?? run.runId ?? waited.run_id ?? waited.runId ?? waited.status.run_id ?? waited.status.runId ?? null;
|
|
6231
|
+
return {
|
|
6232
|
+
...waited,
|
|
6233
|
+
schedule,
|
|
6234
|
+
run,
|
|
6235
|
+
run_id: runId,
|
|
6236
|
+
runId,
|
|
6237
|
+
execution_refs: mergeExecutionRefsFrom([schedule, run, waited])
|
|
6238
|
+
};
|
|
6239
|
+
}
|
|
4930
6240
|
function normalizeOpsPrimitiveRetryPolicy(policy = {}) {
|
|
4931
6241
|
return {
|
|
4932
6242
|
...policy,
|
|
@@ -5002,8 +6312,122 @@ function normalizeOpsPrimitive(primitive) {
|
|
|
5002
6312
|
observability: normalizeOpsPrimitiveObservabilityPolicy(primitive.observability)
|
|
5003
6313
|
};
|
|
5004
6314
|
}
|
|
6315
|
+
function normalizeOpsExecutionToolCall(rawCall) {
|
|
6316
|
+
const call = asRecord2(rawCall);
|
|
6317
|
+
return {
|
|
6318
|
+
...call,
|
|
6319
|
+
tool: stringValue2(call.tool),
|
|
6320
|
+
arguments: asRecord2(call.arguments),
|
|
6321
|
+
purpose: stringValue2(call.purpose)
|
|
6322
|
+
};
|
|
6323
|
+
}
|
|
6324
|
+
function normalizeOpsExecutionScheduleContract(rawSchedule) {
|
|
6325
|
+
const schedule = asRecord2(rawSchedule);
|
|
6326
|
+
const wakeOnEvents = Array.isArray(schedule.wake_on_events) ? schedule.wake_on_events.map(String) : Array.isArray(schedule.wakeOnEvents) ? schedule.wakeOnEvents.map(String) : [];
|
|
6327
|
+
return {
|
|
6328
|
+
...schedule,
|
|
6329
|
+
create_tool: stringValue2(schedule.create_tool ?? schedule.createTool),
|
|
6330
|
+
createTool: stringValue2(schedule.createTool ?? schedule.create_tool),
|
|
6331
|
+
activate_tool: stringValue2(schedule.activate_tool ?? schedule.activateTool),
|
|
6332
|
+
activateTool: stringValue2(schedule.activateTool ?? schedule.activate_tool),
|
|
6333
|
+
cadence: stringValue2(schedule.cadence, "manual"),
|
|
6334
|
+
recurrence: stringValue2(schedule.recurrence),
|
|
6335
|
+
wake_on_events: wakeOnEvents,
|
|
6336
|
+
wakeOnEvents
|
|
6337
|
+
};
|
|
6338
|
+
}
|
|
6339
|
+
function normalizeOpsExecutionApprovalContract(rawApproval) {
|
|
6340
|
+
const approval = asRecord2(rawApproval);
|
|
6341
|
+
return {
|
|
6342
|
+
...approval,
|
|
6343
|
+
required: Boolean(approval.required),
|
|
6344
|
+
tool: stringValue2(approval.tool),
|
|
6345
|
+
reason: stringValue2(approval.reason)
|
|
6346
|
+
};
|
|
6347
|
+
}
|
|
6348
|
+
function normalizeOpsExecutionMonitorContract(rawMonitor) {
|
|
6349
|
+
const monitor = asRecord2(rawMonitor);
|
|
6350
|
+
const pollAfterMs = numberValue(monitor.poll_after_ms ?? monitor.pollAfterMs);
|
|
6351
|
+
return {
|
|
6352
|
+
...monitor,
|
|
6353
|
+
status_tool: stringValue2(monitor.status_tool ?? monitor.statusTool),
|
|
6354
|
+
statusTool: stringValue2(monitor.statusTool ?? monitor.status_tool),
|
|
6355
|
+
wait_tool: stringValue2(monitor.wait_tool ?? monitor.waitTool),
|
|
6356
|
+
waitTool: stringValue2(monitor.waitTool ?? monitor.wait_tool),
|
|
6357
|
+
results_tool: stringValue2(monitor.results_tool ?? monitor.resultsTool),
|
|
6358
|
+
resultsTool: stringValue2(monitor.resultsTool ?? monitor.results_tool),
|
|
6359
|
+
poll_after_ms: pollAfterMs,
|
|
6360
|
+
pollAfterMs
|
|
6361
|
+
};
|
|
6362
|
+
}
|
|
6363
|
+
function normalizeOpsExecutionResultContract(rawResult) {
|
|
6364
|
+
const result = asRecord2(rawResult);
|
|
6365
|
+
const shape = Array.isArray(result.shape) ? result.shape.map(String) : [];
|
|
6366
|
+
return {
|
|
6367
|
+
...result,
|
|
6368
|
+
tool: stringValue2(result.tool),
|
|
6369
|
+
wait_tool: stringValue2(result.wait_tool ?? result.waitTool),
|
|
6370
|
+
waitTool: stringValue2(result.waitTool ?? result.wait_tool),
|
|
6371
|
+
shape,
|
|
6372
|
+
empty_result_recovery: stringValue2(result.empty_result_recovery ?? result.emptyResultRecovery),
|
|
6373
|
+
emptyResultRecovery: stringValue2(result.emptyResultRecovery ?? result.empty_result_recovery)
|
|
6374
|
+
};
|
|
6375
|
+
}
|
|
6376
|
+
function normalizeOpsExecutionNangoRouteContract(rawRoute) {
|
|
6377
|
+
if (!rawRoute || typeof rawRoute !== "object" || Array.isArray(rawRoute)) return void 0;
|
|
6378
|
+
const route = asRecord2(rawRoute);
|
|
6379
|
+
const requiredFields = Array.isArray(route.required_fields) ? route.required_fields.map(String) : Array.isArray(route.requiredFields) ? route.requiredFields.map(String) : [];
|
|
6380
|
+
return {
|
|
6381
|
+
...route,
|
|
6382
|
+
enabled: route.enabled !== false,
|
|
6383
|
+
connect_tool: stringValue2(route.connect_tool ?? route.connectTool),
|
|
6384
|
+
connectTool: stringValue2(route.connectTool ?? route.connect_tool),
|
|
6385
|
+
discover_tool: stringValue2(route.discover_tool ?? route.discoverTool),
|
|
6386
|
+
discoverTool: stringValue2(route.discoverTool ?? route.discover_tool),
|
|
6387
|
+
dry_run_tool: stringValue2(route.dry_run_tool ?? route.dryRunTool),
|
|
6388
|
+
dryRunTool: stringValue2(route.dryRunTool ?? route.dry_run_tool),
|
|
6389
|
+
execute_tool: stringValue2(route.execute_tool ?? route.executeTool),
|
|
6390
|
+
executeTool: stringValue2(route.executeTool ?? route.execute_tool),
|
|
6391
|
+
execute_and_wait_tool: stringValue2(route.execute_and_wait_tool ?? route.executeAndWaitTool),
|
|
6392
|
+
executeAndWaitTool: stringValue2(route.executeAndWaitTool ?? route.execute_and_wait_tool),
|
|
6393
|
+
schedule_tool: stringValue2(route.schedule_tool ?? route.scheduleTool),
|
|
6394
|
+
scheduleTool: stringValue2(route.scheduleTool ?? route.schedule_tool),
|
|
6395
|
+
schedule_and_wait_tool: stringValue2(route.schedule_and_wait_tool ?? route.scheduleAndWaitTool),
|
|
6396
|
+
scheduleAndWaitTool: stringValue2(route.scheduleAndWaitTool ?? route.schedule_and_wait_tool),
|
|
6397
|
+
result_tool: stringValue2(route.result_tool ?? route.resultTool),
|
|
6398
|
+
resultTool: stringValue2(route.resultTool ?? route.result_tool),
|
|
6399
|
+
write_gate: stringValue2(route.write_gate ?? route.writeGate),
|
|
6400
|
+
writeGate: stringValue2(route.writeGate ?? route.write_gate),
|
|
6401
|
+
required_fields: requiredFields,
|
|
6402
|
+
requiredFields,
|
|
6403
|
+
schedule_arguments: asRecord2(route.schedule_arguments ?? route.scheduleArguments),
|
|
6404
|
+
scheduleArguments: asRecord2(route.scheduleArguments ?? route.schedule_arguments),
|
|
6405
|
+
schedule_and_wait_arguments: asRecord2(route.schedule_and_wait_arguments ?? route.scheduleAndWaitArguments),
|
|
6406
|
+
scheduleAndWaitArguments: asRecord2(route.scheduleAndWaitArguments ?? route.schedule_and_wait_arguments)
|
|
6407
|
+
};
|
|
6408
|
+
}
|
|
6409
|
+
function normalizeOpsExecutionContract(rawContract) {
|
|
6410
|
+
if (!rawContract || typeof rawContract !== "object" || Array.isArray(rawContract)) return void 0;
|
|
6411
|
+
const contract = asRecord2(rawContract);
|
|
6412
|
+
const nangoRoute = normalizeOpsExecutionNangoRouteContract(contract.nango_route ?? contract.nangoRoute);
|
|
6413
|
+
const sequence = Array.isArray(contract.sequence) ? contract.sequence.map(normalizeOpsExecutionToolCall) : [];
|
|
6414
|
+
return {
|
|
6415
|
+
...contract,
|
|
6416
|
+
mode: stringValue2(contract.mode, "run_once"),
|
|
6417
|
+
run_now: normalizeOpsExecutionToolCall(contract.run_now ?? contract.runNow),
|
|
6418
|
+
runNow: normalizeOpsExecutionToolCall(contract.runNow ?? contract.run_now),
|
|
6419
|
+
schedule: normalizeOpsExecutionScheduleContract(contract.schedule),
|
|
6420
|
+
approval: normalizeOpsExecutionApprovalContract(contract.approval),
|
|
6421
|
+
monitor: normalizeOpsExecutionMonitorContract(contract.monitor),
|
|
6422
|
+
result_contract: normalizeOpsExecutionResultContract(contract.result_contract ?? contract.resultContract),
|
|
6423
|
+
resultContract: normalizeOpsExecutionResultContract(contract.resultContract ?? contract.result_contract),
|
|
6424
|
+
...nangoRoute ? { nango_route: nangoRoute, nangoRoute } : {},
|
|
6425
|
+
sequence
|
|
6426
|
+
};
|
|
6427
|
+
}
|
|
5005
6428
|
function normalizeOpsPlanResult(result) {
|
|
5006
6429
|
const primitiveGraph = result.primitive_graph ?? result.primitiveGraph;
|
|
6430
|
+
const executionContract = normalizeOpsExecutionContract(result.execution_contract ?? result.executionContract);
|
|
5007
6431
|
return {
|
|
5008
6432
|
...result,
|
|
5009
6433
|
plan_id: result.plan_id ?? result.planId,
|
|
@@ -5027,7 +6451,8 @@ function normalizeOpsPlanResult(result) {
|
|
|
5027
6451
|
destination_status: result.destination_status ?? result.destinationStatus,
|
|
5028
6452
|
destinationStatus: result.destinationStatus ?? result.destination_status,
|
|
5029
6453
|
primitive_graph: primitiveGraph?.map(normalizeOpsPrimitive),
|
|
5030
|
-
primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive)
|
|
6454
|
+
primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive),
|
|
6455
|
+
...executionContract ? { execution_contract: executionContract, executionContract } : {}
|
|
5031
6456
|
};
|
|
5032
6457
|
}
|
|
5033
6458
|
function normalizeOpsCreateResult(result) {
|
|
@@ -5049,7 +6474,18 @@ function normalizeOpsCreateResult(result) {
|
|
|
5049
6474
|
deliveryStatus: result.deliveryStatus ?? result.delivery_status,
|
|
5050
6475
|
estimated_credits: result.estimated_credits ?? result.estimatedCredits,
|
|
5051
6476
|
estimatedCredits: result.estimatedCredits ?? result.estimated_credits,
|
|
5052
|
-
|
|
6477
|
+
error_code: result.error_code ?? result.errorCode,
|
|
6478
|
+
errorCode: result.errorCode ?? result.error_code,
|
|
6479
|
+
approval_required: result.approval_required ?? result.approvalRequired,
|
|
6480
|
+
approvalRequired: result.approvalRequired ?? result.approval_required,
|
|
6481
|
+
retry_arguments: result.retry_arguments ?? result.retryArguments,
|
|
6482
|
+
retryArguments: result.retryArguments ?? result.retry_arguments,
|
|
6483
|
+
blockers: result.blockers,
|
|
6484
|
+
plan: result.plan ? normalizeOpsPlanResult(result.plan) : result.plan,
|
|
6485
|
+
next_step: result.next_step ?? result.nextStep,
|
|
6486
|
+
nextStep: result.nextStep ?? result.next_step,
|
|
6487
|
+
next_steps: result.next_steps ?? result.nextSteps,
|
|
6488
|
+
nextSteps: result.nextSteps ?? result.next_steps
|
|
5053
6489
|
};
|
|
5054
6490
|
}
|
|
5055
6491
|
function normalizeOpsExecuteResult(result) {
|
|
@@ -5177,6 +6613,40 @@ function normalizeOpsStatusResult(result) {
|
|
|
5177
6613
|
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
|
|
5178
6614
|
};
|
|
5179
6615
|
}
|
|
6616
|
+
function normalizeOpsResultsSummary(value) {
|
|
6617
|
+
const summary = asRecord2(value);
|
|
6618
|
+
if (Object.keys(summary).length === 0) return void 0;
|
|
6619
|
+
const resultsTotal = summary.results_total ?? summary.resultsTotal;
|
|
6620
|
+
const nextCursor = summary.next_cursor ?? summary.nextCursor ?? null;
|
|
6621
|
+
const resultsUrl = summary.results_url ?? summary.resultsUrl;
|
|
6622
|
+
const nextAction = summary.next_action ?? summary.nextAction;
|
|
6623
|
+
const runId = summary.run_id ?? summary.runId ?? null;
|
|
6624
|
+
const creditsUsed = summary.credits_used ?? summary.creditsUsed;
|
|
6625
|
+
return {
|
|
6626
|
+
...summary,
|
|
6627
|
+
label: optionalString(summary.label),
|
|
6628
|
+
status: optionalString(summary.status),
|
|
6629
|
+
phase: optionalString(summary.phase),
|
|
6630
|
+
results_count: numberValue(summary.results_count ?? summary.resultsCount),
|
|
6631
|
+
resultsCount: numberValue(summary.results_count ?? summary.resultsCount),
|
|
6632
|
+
results_total: resultsTotal === null || resultsTotal === void 0 ? resultsTotal : numberValue(resultsTotal),
|
|
6633
|
+
resultsTotal: resultsTotal === null || resultsTotal === void 0 ? resultsTotal : numberValue(resultsTotal),
|
|
6634
|
+
delivery_status: optionalString(summary.delivery_status ?? summary.deliveryStatus),
|
|
6635
|
+
deliveryStatus: optionalString(summary.delivery_status ?? summary.deliveryStatus),
|
|
6636
|
+
has_more: Boolean(summary.has_more ?? summary.hasMore),
|
|
6637
|
+
hasMore: Boolean(summary.has_more ?? summary.hasMore),
|
|
6638
|
+
next_cursor: nextCursor === null ? null : optionalString(nextCursor),
|
|
6639
|
+
nextCursor: nextCursor === null ? null : optionalString(nextCursor),
|
|
6640
|
+
results_url: optionalString(resultsUrl),
|
|
6641
|
+
resultsUrl: optionalString(resultsUrl),
|
|
6642
|
+
next_action: optionalString(nextAction),
|
|
6643
|
+
nextAction: optionalString(nextAction),
|
|
6644
|
+
run_id: runId === null ? null : optionalString(runId),
|
|
6645
|
+
runId: runId === null ? null : optionalString(runId),
|
|
6646
|
+
credits_used: creditsUsed === void 0 ? void 0 : numberValue(creditsUsed),
|
|
6647
|
+
creditsUsed: creditsUsed === void 0 ? void 0 : numberValue(creditsUsed)
|
|
6648
|
+
};
|
|
6649
|
+
}
|
|
5180
6650
|
function normalizeOpsResultsResult(result) {
|
|
5181
6651
|
const nextCursor = result.next_cursor ?? result.nextCursor ?? null;
|
|
5182
6652
|
const hasMore = result.has_more ?? result.hasMore ?? false;
|
|
@@ -5201,7 +6671,104 @@ function normalizeOpsResultsResult(result) {
|
|
|
5201
6671
|
results_url: result.results_url ?? result.resultsUrl,
|
|
5202
6672
|
resultsUrl: result.resultsUrl ?? result.results_url,
|
|
5203
6673
|
delivery_status: result.delivery_status ?? result.deliveryStatus,
|
|
5204
|
-
deliveryStatus: result.deliveryStatus ?? result.delivery_status
|
|
6674
|
+
deliveryStatus: result.deliveryStatus ?? result.delivery_status,
|
|
6675
|
+
summary: normalizeOpsResultsSummary(result.summary)
|
|
6676
|
+
};
|
|
6677
|
+
}
|
|
6678
|
+
function normalizeOpsWaitForResultsPoll(value, fallbackPoll) {
|
|
6679
|
+
const raw = asRecord2(value);
|
|
6680
|
+
const checkedAt = stringValue2(raw.checked_at ?? raw.checkedAt);
|
|
6681
|
+
const resultsCount = raw.results_count ?? raw.resultsCount;
|
|
6682
|
+
const runId = raw.run_id ?? raw.runId ?? null;
|
|
6683
|
+
const nextAction = raw.next_action ?? raw.nextAction;
|
|
6684
|
+
return {
|
|
6685
|
+
...raw,
|
|
6686
|
+
poll: numberValue(raw.poll) || fallbackPoll,
|
|
6687
|
+
checked_at: checkedAt,
|
|
6688
|
+
checkedAt,
|
|
6689
|
+
status: stringValue2(raw.status, "unknown"),
|
|
6690
|
+
phase: optionalString(raw.phase),
|
|
6691
|
+
results_count: resultsCount === void 0 ? void 0 : numberValue(resultsCount),
|
|
6692
|
+
resultsCount: resultsCount === void 0 ? void 0 : numberValue(resultsCount),
|
|
6693
|
+
run_id: runId === null ? null : optionalString(runId),
|
|
6694
|
+
runId: runId === null ? null : optionalString(runId),
|
|
6695
|
+
next_action: optionalString(nextAction),
|
|
6696
|
+
nextAction: optionalString(nextAction)
|
|
6697
|
+
};
|
|
6698
|
+
}
|
|
6699
|
+
function normalizeOpsWaitForResultsResult(result, options) {
|
|
6700
|
+
const opId = stringValue2(result.op_id ?? result.opId ?? options.op_id);
|
|
6701
|
+
const routineId = stringValue2(result.routine_id ?? result.routineId ?? opId);
|
|
6702
|
+
const runId = result.run_id ?? result.runId ?? null;
|
|
6703
|
+
const timedOut = Boolean(result.timed_out ?? result.timedOut);
|
|
6704
|
+
const statusRaw = asRecord2(result.status_result ?? result.statusResult);
|
|
6705
|
+
const resultsRaw = asRecord2(result.results_result ?? result.resultsResult);
|
|
6706
|
+
const historySource = Array.isArray(result.poll_history) ? result.poll_history : Array.isArray(result.history) ? result.history : [];
|
|
6707
|
+
const history = historySource.map((item, index) => normalizeOpsWaitForResultsPoll(item, index + 1));
|
|
6708
|
+
const status = normalizeOpsStatusResult(withExecutionRefs({
|
|
6709
|
+
success: result.success !== false,
|
|
6710
|
+
op_id: opId,
|
|
6711
|
+
routine_id: routineId,
|
|
6712
|
+
run_id: runId,
|
|
6713
|
+
status: stringValue2(result.status, "unknown"),
|
|
6714
|
+
phase: stringValue2(result.phase, "unknown"),
|
|
6715
|
+
next_action: stringValue2(result.next_action ?? result.nextAction),
|
|
6716
|
+
results_count: numberValue(result.results_count ?? result.resultsCount),
|
|
6717
|
+
results_url: optionalString(result.results_url ?? result.resultsUrl),
|
|
6718
|
+
delivery_status: optionalString(result.delivery_status ?? result.deliveryStatus),
|
|
6719
|
+
...statusRaw
|
|
6720
|
+
}));
|
|
6721
|
+
const includeResults = options.include_results !== false && options.includeResults !== false;
|
|
6722
|
+
const hasResultsPacket = Object.keys(resultsRaw).length > 0 || Array.isArray(result.results);
|
|
6723
|
+
const results = includeResults && hasResultsPacket ? normalizeOpsResultsResult(withExecutionRefs({
|
|
6724
|
+
success: result.success !== false,
|
|
6725
|
+
op_id: opId,
|
|
6726
|
+
routine_id: routineId,
|
|
6727
|
+
run_id: runId,
|
|
6728
|
+
status: stringValue2(result.status, status.status),
|
|
6729
|
+
phase: stringValue2(result.phase, status.phase),
|
|
6730
|
+
results_count: numberValue(result.results_count ?? result.resultsCount),
|
|
6731
|
+
results_total: result.results_total ?? result.resultsTotal ?? null,
|
|
6732
|
+
results: Array.isArray(result.results) ? result.results : [],
|
|
6733
|
+
next_cursor: result.next_cursor ?? result.nextCursor ?? null,
|
|
6734
|
+
has_more: Boolean(result.has_more ?? result.hasMore),
|
|
6735
|
+
next_action: stringValue2(result.next_action ?? result.nextAction),
|
|
6736
|
+
results_url: optionalString(result.results_url ?? result.resultsUrl),
|
|
6737
|
+
delivery_status: optionalString(result.delivery_status ?? result.deliveryStatus),
|
|
6738
|
+
...resultsRaw
|
|
6739
|
+
})) : void 0;
|
|
6740
|
+
const polls = numberValue(result.polls) || history.length;
|
|
6741
|
+
const maxPolls = result.max_polls ?? result.maxPolls;
|
|
6742
|
+
const intervalMs = result.interval_ms ?? result.intervalMs;
|
|
6743
|
+
const timeoutMs = result.timeout_ms ?? result.timeoutMs;
|
|
6744
|
+
const stopReason = result.stop_reason ?? result.stopReason;
|
|
6745
|
+
const nextAction = result.next_action ?? result.nextAction ?? results?.next_action ?? status.next_action;
|
|
6746
|
+
return {
|
|
6747
|
+
...result,
|
|
6748
|
+
success: result.success !== false && !timedOut,
|
|
6749
|
+
op_id: opId,
|
|
6750
|
+
opId,
|
|
6751
|
+
routine_id: routineId,
|
|
6752
|
+
routineId,
|
|
6753
|
+
run_id: runId === null ? null : optionalString(runId),
|
|
6754
|
+
runId: runId === null ? null : optionalString(runId),
|
|
6755
|
+
status,
|
|
6756
|
+
results,
|
|
6757
|
+
timed_out: timedOut,
|
|
6758
|
+
timedOut,
|
|
6759
|
+
polls,
|
|
6760
|
+
max_polls: maxPolls === void 0 ? void 0 : numberValue(maxPolls),
|
|
6761
|
+
maxPolls: maxPolls === void 0 ? void 0 : numberValue(maxPolls),
|
|
6762
|
+
interval_ms: intervalMs === void 0 ? void 0 : numberValue(intervalMs),
|
|
6763
|
+
intervalMs: intervalMs === void 0 ? void 0 : numberValue(intervalMs),
|
|
6764
|
+
timeout_ms: timeoutMs === void 0 ? void 0 : numberValue(timeoutMs),
|
|
6765
|
+
timeoutMs: timeoutMs === void 0 ? void 0 : numberValue(timeoutMs),
|
|
6766
|
+
stop_reason: optionalString(stopReason),
|
|
6767
|
+
stopReason: optionalString(stopReason),
|
|
6768
|
+
history,
|
|
6769
|
+
next_action: optionalString(nextAction),
|
|
6770
|
+
nextAction: optionalString(nextAction),
|
|
6771
|
+
execution_refs: mergeExecutionRefsFrom([result, status, results, { history }])
|
|
5205
6772
|
};
|
|
5206
6773
|
}
|
|
5207
6774
|
function normalizeOpsProofResult(data) {
|
|
@@ -5281,11 +6848,107 @@ function normalizeOpsProofResult(data) {
|
|
|
5281
6848
|
raw: data
|
|
5282
6849
|
};
|
|
5283
6850
|
}
|
|
6851
|
+
function normalizeOpsAutopilotSchedulePacket(rawPacket) {
|
|
6852
|
+
const packet = asRecord2(rawPacket);
|
|
6853
|
+
return {
|
|
6854
|
+
...packet,
|
|
6855
|
+
cadence: stringValue2(packet.cadence, "manual"),
|
|
6856
|
+
recurrence: stringValue2(packet.recurrence),
|
|
6857
|
+
activate_with: stringValue2(packet.activate_with ?? packet.activateWith),
|
|
6858
|
+
activateWith: stringValue2(packet.activate_with ?? packet.activateWith),
|
|
6859
|
+
run_now_with: stringValue2(packet.run_now_with ?? packet.runNowWith),
|
|
6860
|
+
runNowWith: stringValue2(packet.run_now_with ?? packet.runNowWith),
|
|
6861
|
+
monitor_with: stringValue2(packet.monitor_with ?? packet.monitorWith),
|
|
6862
|
+
monitorWith: stringValue2(packet.monitor_with ?? packet.monitorWith),
|
|
6863
|
+
retrieve_with: stringValue2(packet.retrieve_with ?? packet.retrieveWith),
|
|
6864
|
+
retrieveWith: stringValue2(packet.retrieve_with ?? packet.retrieveWith)
|
|
6865
|
+
};
|
|
6866
|
+
}
|
|
6867
|
+
function normalizeOpsAutopilotNangoRoutePacket(rawPacket) {
|
|
6868
|
+
if (!rawPacket || typeof rawPacket !== "object" || Array.isArray(rawPacket)) return void 0;
|
|
6869
|
+
const packet = asRecord2(rawPacket);
|
|
6870
|
+
const requiredFields = Array.isArray(packet.required_fields) ? packet.required_fields.map(String) : Array.isArray(packet.requiredFields) ? packet.requiredFields.map(String) : [];
|
|
6871
|
+
return {
|
|
6872
|
+
...packet,
|
|
6873
|
+
enabled: packet.enabled !== false,
|
|
6874
|
+
route_label: stringValue2(packet.route_label ?? packet.routeLabel),
|
|
6875
|
+
routeLabel: stringValue2(packet.route_label ?? packet.routeLabel),
|
|
6876
|
+
connect_tool: stringValue2(packet.connect_tool ?? packet.connectTool),
|
|
6877
|
+
connectTool: stringValue2(packet.connect_tool ?? packet.connectTool),
|
|
6878
|
+
discover_tool: stringValue2(packet.discover_tool ?? packet.discoverTool),
|
|
6879
|
+
discoverTool: stringValue2(packet.discover_tool ?? packet.discoverTool),
|
|
6880
|
+
dry_run_tool: stringValue2(packet.dry_run_tool ?? packet.dryRunTool),
|
|
6881
|
+
dryRunTool: stringValue2(packet.dry_run_tool ?? packet.dryRunTool),
|
|
6882
|
+
execute_tool: stringValue2(packet.execute_tool ?? packet.executeTool),
|
|
6883
|
+
executeTool: stringValue2(packet.execute_tool ?? packet.executeTool),
|
|
6884
|
+
execute_and_wait_tool: stringValue2(packet.execute_and_wait_tool ?? packet.executeAndWaitTool),
|
|
6885
|
+
executeAndWaitTool: stringValue2(packet.execute_and_wait_tool ?? packet.executeAndWaitTool),
|
|
6886
|
+
schedule_tool: stringValue2(packet.schedule_tool ?? packet.scheduleTool),
|
|
6887
|
+
scheduleTool: stringValue2(packet.schedule_tool ?? packet.scheduleTool),
|
|
6888
|
+
schedule_and_wait_tool: stringValue2(packet.schedule_and_wait_tool ?? packet.scheduleAndWaitTool),
|
|
6889
|
+
scheduleAndWaitTool: stringValue2(packet.schedule_and_wait_tool ?? packet.scheduleAndWaitTool),
|
|
6890
|
+
result_tool: stringValue2(packet.result_tool ?? packet.resultTool),
|
|
6891
|
+
resultTool: stringValue2(packet.result_tool ?? packet.resultTool),
|
|
6892
|
+
write_gate: stringValue2(packet.write_gate ?? packet.writeGate),
|
|
6893
|
+
writeGate: stringValue2(packet.write_gate ?? packet.writeGate),
|
|
6894
|
+
required_fields: requiredFields,
|
|
6895
|
+
requiredFields,
|
|
6896
|
+
placeholders: asRecord2(packet.placeholders),
|
|
6897
|
+
dry_run_arguments: asRecord2(packet.dry_run_arguments ?? packet.dryRunArguments),
|
|
6898
|
+
dryRunArguments: asRecord2(packet.dry_run_arguments ?? packet.dryRunArguments),
|
|
6899
|
+
execute_arguments: asRecord2(packet.execute_arguments ?? packet.executeArguments),
|
|
6900
|
+
executeArguments: asRecord2(packet.execute_arguments ?? packet.executeArguments),
|
|
6901
|
+
execute_and_wait_arguments: asRecord2(packet.execute_and_wait_arguments ?? packet.executeAndWaitArguments),
|
|
6902
|
+
executeAndWaitArguments: asRecord2(packet.execute_and_wait_arguments ?? packet.executeAndWaitArguments),
|
|
6903
|
+
schedule_arguments: asRecord2(packet.schedule_arguments ?? packet.scheduleArguments),
|
|
6904
|
+
scheduleArguments: asRecord2(packet.schedule_arguments ?? packet.scheduleArguments),
|
|
6905
|
+
schedule_and_wait_arguments: asRecord2(packet.schedule_and_wait_arguments ?? packet.scheduleAndWaitArguments),
|
|
6906
|
+
scheduleAndWaitArguments: asRecord2(packet.schedule_and_wait_arguments ?? packet.scheduleAndWaitArguments),
|
|
6907
|
+
result_arguments: asRecord2(packet.result_arguments ?? packet.resultArguments),
|
|
6908
|
+
resultArguments: asRecord2(packet.result_arguments ?? packet.resultArguments)
|
|
6909
|
+
};
|
|
6910
|
+
}
|
|
6911
|
+
function normalizeOpsAutopilotResultPacket(rawPacket) {
|
|
6912
|
+
const packet = asRecord2(rawPacket);
|
|
6913
|
+
const resultShape = Array.isArray(packet.result_shape) ? packet.result_shape.map(String) : Array.isArray(packet.resultShape) ? packet.resultShape.map(String) : [];
|
|
6914
|
+
const deliveryReceipts = Array.isArray(packet.delivery_receipts) ? packet.delivery_receipts.map(String) : Array.isArray(packet.deliveryReceipts) ? packet.deliveryReceipts.map(String) : [];
|
|
6915
|
+
return {
|
|
6916
|
+
...packet,
|
|
6917
|
+
retrieve_tool: stringValue2(packet.retrieve_tool ?? packet.retrieveTool),
|
|
6918
|
+
retrieveTool: stringValue2(packet.retrieve_tool ?? packet.retrieveTool),
|
|
6919
|
+
result_shape: resultShape,
|
|
6920
|
+
resultShape,
|
|
6921
|
+
delivery_receipts: deliveryReceipts,
|
|
6922
|
+
deliveryReceipts,
|
|
6923
|
+
empty_result_recovery: stringValue2(packet.empty_result_recovery ?? packet.emptyResultRecovery),
|
|
6924
|
+
emptyResultRecovery: stringValue2(packet.empty_result_recovery ?? packet.emptyResultRecovery)
|
|
6925
|
+
};
|
|
6926
|
+
}
|
|
6927
|
+
function normalizeOpsAutopilotOperatingPacket(rawPacket) {
|
|
6928
|
+
if (!rawPacket || typeof rawPacket !== "object" || Array.isArray(rawPacket)) return void 0;
|
|
6929
|
+
const packet = asRecord2(rawPacket);
|
|
6930
|
+
const nangoRoute = normalizeOpsAutopilotNangoRoutePacket(packet.nango_route ?? packet.nangoRoute);
|
|
6931
|
+
const approvalBoundaries = Array.isArray(packet.approval_boundaries) ? packet.approval_boundaries.map(String) : Array.isArray(packet.approvalBoundaries) ? packet.approvalBoundaries.map(String) : [];
|
|
6932
|
+
return {
|
|
6933
|
+
...packet,
|
|
6934
|
+
north_star: stringValue2(packet.north_star ?? packet.northStar),
|
|
6935
|
+
northStar: stringValue2(packet.north_star ?? packet.northStar),
|
|
6936
|
+
schedule: normalizeOpsAutopilotSchedulePacket(packet.schedule),
|
|
6937
|
+
...nangoRoute ? { nango_route: nangoRoute, nangoRoute } : {},
|
|
6938
|
+
result_contract: normalizeOpsAutopilotResultPacket(packet.result_contract ?? packet.resultContract),
|
|
6939
|
+
resultContract: normalizeOpsAutopilotResultPacket(packet.result_contract ?? packet.resultContract),
|
|
6940
|
+
approval_boundaries: approvalBoundaries,
|
|
6941
|
+
approvalBoundaries,
|
|
6942
|
+
saved_command_hint: stringValue2(packet.saved_command_hint ?? packet.savedCommandHint),
|
|
6943
|
+
savedCommandHint: stringValue2(packet.saved_command_hint ?? packet.savedCommandHint)
|
|
6944
|
+
};
|
|
6945
|
+
}
|
|
5284
6946
|
function normalizeOpsAutopilotMotion(rawMotion) {
|
|
5285
6947
|
const motion = asRecord2(rawMotion);
|
|
5286
6948
|
const targetCount = numberValue(motion.target_count ?? motion.targetCount);
|
|
5287
6949
|
const estimatedCredits = numberValue(motion.estimated_credits ?? motion.estimatedCredits);
|
|
5288
6950
|
const mcpSequence = Array.isArray(motion.mcp_sequence) ? motion.mcp_sequence : Array.isArray(motion.mcpSequence) ? motion.mcpSequence : [];
|
|
6951
|
+
const operatingPacket = normalizeOpsAutopilotOperatingPacket(motion.operating_packet ?? motion.operatingPacket);
|
|
5289
6952
|
return {
|
|
5290
6953
|
...motion,
|
|
5291
6954
|
id: stringValue2(motion.id),
|
|
@@ -5308,12 +6971,16 @@ function normalizeOpsAutopilotMotion(rawMotion) {
|
|
|
5308
6971
|
cli_command: optionalString(motion.cli_command ?? motion.cliCommand),
|
|
5309
6972
|
cliCommand: optionalString(motion.cli_command ?? motion.cliCommand),
|
|
5310
6973
|
mcp_sequence: mcpSequence,
|
|
5311
|
-
mcpSequence
|
|
6974
|
+
mcpSequence,
|
|
6975
|
+
...operatingPacket ? { operating_packet: operatingPacket, operatingPacket } : {}
|
|
5312
6976
|
};
|
|
5313
6977
|
}
|
|
5314
6978
|
function normalizeOpsAutopilotResult(result) {
|
|
5315
6979
|
const primary = normalizeOpsAutopilotMotion(result.primary_motion ?? result.primaryMotion);
|
|
5316
6980
|
const motions = Array.isArray(result.motions) ? result.motions.map(normalizeOpsAutopilotMotion) : [];
|
|
6981
|
+
const operatingPacket = normalizeOpsAutopilotOperatingPacket(
|
|
6982
|
+
result.operating_packet ?? result.operatingPacket ?? primary.operating_packet ?? primary.operatingPacket
|
|
6983
|
+
);
|
|
5317
6984
|
const queryErrors = Array.isArray(result.query_errors) ? result.query_errors.map(String) : Array.isArray(result.queryErrors) ? result.queryErrors.map(String) : [];
|
|
5318
6985
|
return {
|
|
5319
6986
|
...result,
|
|
@@ -5329,6 +6996,7 @@ function normalizeOpsAutopilotResult(result) {
|
|
|
5329
6996
|
scaleRule: optionalString(result.scale_rule ?? result.scaleRule),
|
|
5330
6997
|
agent_handoff: optionalString(result.agent_handoff ?? result.agentHandoff),
|
|
5331
6998
|
agentHandoff: optionalString(result.agent_handoff ?? result.agentHandoff),
|
|
6999
|
+
...operatingPacket ? { operating_packet: operatingPacket, operatingPacket } : {},
|
|
5332
7000
|
proof_state: optionalString(result.proof_state ?? result.proofState),
|
|
5333
7001
|
proofState: optionalString(result.proof_state ?? result.proofState),
|
|
5334
7002
|
proof_summary: result.proof_summary ?? result.proofSummary,
|
|
@@ -5593,11 +7261,125 @@ function normalizeOpsRoutineTickItemsResult(result) {
|
|
|
5593
7261
|
hasMore
|
|
5594
7262
|
};
|
|
5595
7263
|
}
|
|
7264
|
+
function buildOpsNangoScheduleBody(input) {
|
|
7265
|
+
const {
|
|
7266
|
+
workspaceConnectionId,
|
|
7267
|
+
workspace_connection_id,
|
|
7268
|
+
connectionId,
|
|
7269
|
+
connection_id,
|
|
7270
|
+
providerConfigKey,
|
|
7271
|
+
provider_config_key,
|
|
7272
|
+
integrationId,
|
|
7273
|
+
integration_id,
|
|
7274
|
+
nangoConnectionId,
|
|
7275
|
+
nango_connection_id,
|
|
7276
|
+
actionName,
|
|
7277
|
+
action_name,
|
|
7278
|
+
toolName,
|
|
7279
|
+
tool_name,
|
|
7280
|
+
proxyPath,
|
|
7281
|
+
proxy_path,
|
|
7282
|
+
nangoProxyPath,
|
|
7283
|
+
nango_proxy_path,
|
|
7284
|
+
method,
|
|
7285
|
+
httpMethod,
|
|
7286
|
+
http_method,
|
|
7287
|
+
input: nangoInput,
|
|
7288
|
+
arguments: nangoArguments,
|
|
7289
|
+
fieldMap,
|
|
7290
|
+
field_map,
|
|
7291
|
+
requiredFields,
|
|
7292
|
+
required_fields,
|
|
7293
|
+
writeConfirmed,
|
|
7294
|
+
write_confirmed,
|
|
7295
|
+
agentWriteConfirmed,
|
|
7296
|
+
agent_write_confirmed,
|
|
7297
|
+
config,
|
|
7298
|
+
destinations: _destinations,
|
|
7299
|
+
...schedule
|
|
7300
|
+
} = input;
|
|
7301
|
+
return {
|
|
7302
|
+
...buildOpsCreateBody({
|
|
7303
|
+
...schedule,
|
|
7304
|
+
cadence: schedule.cadence ?? "daily"
|
|
7305
|
+
}),
|
|
7306
|
+
workspace_connection_id: workspace_connection_id ?? workspaceConnectionId,
|
|
7307
|
+
connection_id: connection_id ?? connectionId,
|
|
7308
|
+
provider_config_key: provider_config_key ?? providerConfigKey,
|
|
7309
|
+
integration_id: integration_id ?? integrationId,
|
|
7310
|
+
nango_connection_id: nango_connection_id ?? nangoConnectionId,
|
|
7311
|
+
action_name: action_name ?? actionName,
|
|
7312
|
+
tool_name: tool_name ?? toolName,
|
|
7313
|
+
proxy_path: proxy_path ?? proxyPath ?? nango_proxy_path ?? nangoProxyPath,
|
|
7314
|
+
nango_proxy_path: nango_proxy_path ?? nangoProxyPath,
|
|
7315
|
+
method: method ?? http_method ?? httpMethod,
|
|
7316
|
+
input: nangoInput ?? nangoArguments,
|
|
7317
|
+
field_map: field_map ?? fieldMap,
|
|
7318
|
+
required_fields: required_fields ?? requiredFields,
|
|
7319
|
+
write_confirmed: write_confirmed ?? writeConfirmed,
|
|
7320
|
+
agent_write_confirmed: agent_write_confirmed ?? agentWriteConfirmed,
|
|
7321
|
+
config
|
|
7322
|
+
};
|
|
7323
|
+
}
|
|
7324
|
+
function buildOpsNangoScheduleAndWaitOptions(params) {
|
|
7325
|
+
const {
|
|
7326
|
+
force,
|
|
7327
|
+
instruction,
|
|
7328
|
+
nextCursor,
|
|
7329
|
+
includeFailedRuns,
|
|
7330
|
+
intervalMs,
|
|
7331
|
+
maxPolls,
|
|
7332
|
+
timeoutMs,
|
|
7333
|
+
includeResults,
|
|
7334
|
+
cursor,
|
|
7335
|
+
state,
|
|
7336
|
+
limit,
|
|
7337
|
+
include_failed_runs,
|
|
7338
|
+
interval_ms,
|
|
7339
|
+
max_polls,
|
|
7340
|
+
timeout_ms,
|
|
7341
|
+
include_results,
|
|
7342
|
+
...schedule
|
|
7343
|
+
} = params;
|
|
7344
|
+
return {
|
|
7345
|
+
schedule: {
|
|
7346
|
+
...schedule,
|
|
7347
|
+
cadence: schedule.cadence ?? "daily"
|
|
7348
|
+
},
|
|
7349
|
+
run: {
|
|
7350
|
+
force,
|
|
7351
|
+
instruction
|
|
7352
|
+
},
|
|
7353
|
+
wait: {
|
|
7354
|
+
cursor: cursor ?? nextCursor,
|
|
7355
|
+
state,
|
|
7356
|
+
limit,
|
|
7357
|
+
include_failed_runs: include_failed_runs ?? includeFailedRuns,
|
|
7358
|
+
interval_ms: interval_ms ?? intervalMs,
|
|
7359
|
+
max_polls: max_polls ?? maxPolls,
|
|
7360
|
+
timeout_ms: timeout_ms ?? timeoutMs,
|
|
7361
|
+
include_results: include_results ?? includeResults
|
|
7362
|
+
}
|
|
7363
|
+
};
|
|
7364
|
+
}
|
|
7365
|
+
function buildOpsNangoScheduleAndWaitBody(options) {
|
|
7366
|
+
const waitBody = buildOpsWaitBody(options.wait);
|
|
7367
|
+
const { op_id: _opId, ...waitWithoutOp } = waitBody;
|
|
7368
|
+
return {
|
|
7369
|
+
...buildOpsNangoScheduleBody(options.schedule),
|
|
7370
|
+
...waitWithoutOp,
|
|
7371
|
+
instruction: options.run.instruction,
|
|
7372
|
+
force: options.run.force
|
|
7373
|
+
};
|
|
7374
|
+
}
|
|
5596
7375
|
function buildOpsPlanBody(params) {
|
|
5597
|
-
const { targetCount, companyDomains, customAiPrompt, signalPrompt, outputPrompt, ...rest } = params;
|
|
7376
|
+
const { targetCount, wakeOnEvents, companyDomains, customAiPrompt, signalPrompt, outputPrompt, ...rest } = params;
|
|
7377
|
+
const destinations = Array.isArray(rest.destinations) ? rest.destinations.map(normalizeOpsDestinationRequest) : rest.destinations;
|
|
5598
7378
|
return {
|
|
5599
7379
|
...rest,
|
|
7380
|
+
destinations,
|
|
5600
7381
|
target_count: rest.target_count ?? targetCount,
|
|
7382
|
+
wake_on_events: rest.wake_on_events ?? wakeOnEvents,
|
|
5601
7383
|
company_domains: rest.company_domains ?? companyDomains,
|
|
5602
7384
|
custom_ai_prompt: rest.custom_ai_prompt ?? customAiPrompt,
|
|
5603
7385
|
signal_prompt: rest.signal_prompt ?? signalPrompt,
|
|
@@ -5620,6 +7402,95 @@ function buildOpsExecuteBody(params) {
|
|
|
5620
7402
|
output_format: rest.output_format ?? outputFormat
|
|
5621
7403
|
};
|
|
5622
7404
|
}
|
|
7405
|
+
function buildOpsExecuteAndWaitOptions(params) {
|
|
7406
|
+
const {
|
|
7407
|
+
nextCursor,
|
|
7408
|
+
includeFailedRuns,
|
|
7409
|
+
intervalMs,
|
|
7410
|
+
maxPolls,
|
|
7411
|
+
timeoutMs,
|
|
7412
|
+
includeResults,
|
|
7413
|
+
cursor,
|
|
7414
|
+
state,
|
|
7415
|
+
limit,
|
|
7416
|
+
include_failed_runs,
|
|
7417
|
+
interval_ms,
|
|
7418
|
+
max_polls,
|
|
7419
|
+
timeout_ms,
|
|
7420
|
+
include_results,
|
|
7421
|
+
...execute
|
|
7422
|
+
} = params;
|
|
7423
|
+
return {
|
|
7424
|
+
execute: {
|
|
7425
|
+
...execute,
|
|
7426
|
+
auto_run: execute.auto_run ?? execute.autoRun ?? true
|
|
7427
|
+
},
|
|
7428
|
+
wait: {
|
|
7429
|
+
cursor: cursor ?? nextCursor,
|
|
7430
|
+
state,
|
|
7431
|
+
limit,
|
|
7432
|
+
include_failed_runs: include_failed_runs ?? includeFailedRuns,
|
|
7433
|
+
interval_ms: interval_ms ?? intervalMs,
|
|
7434
|
+
max_polls: max_polls ?? maxPolls,
|
|
7435
|
+
timeout_ms: timeout_ms ?? timeoutMs,
|
|
7436
|
+
include_results: include_results ?? includeResults
|
|
7437
|
+
}
|
|
7438
|
+
};
|
|
7439
|
+
}
|
|
7440
|
+
function buildOpsScheduleAndWaitOptions(params) {
|
|
7441
|
+
const {
|
|
7442
|
+
force,
|
|
7443
|
+
instruction,
|
|
7444
|
+
nextCursor,
|
|
7445
|
+
includeFailedRuns,
|
|
7446
|
+
intervalMs,
|
|
7447
|
+
maxPolls,
|
|
7448
|
+
timeoutMs,
|
|
7449
|
+
includeResults,
|
|
7450
|
+
cursor,
|
|
7451
|
+
state,
|
|
7452
|
+
limit,
|
|
7453
|
+
include_failed_runs,
|
|
7454
|
+
interval_ms,
|
|
7455
|
+
max_polls,
|
|
7456
|
+
timeout_ms,
|
|
7457
|
+
include_results,
|
|
7458
|
+
...schedule
|
|
7459
|
+
} = params;
|
|
7460
|
+
return {
|
|
7461
|
+
schedule: {
|
|
7462
|
+
...schedule,
|
|
7463
|
+
cadence: schedule.cadence ?? "daily"
|
|
7464
|
+
},
|
|
7465
|
+
run: {
|
|
7466
|
+
force,
|
|
7467
|
+
instruction
|
|
7468
|
+
},
|
|
7469
|
+
wait: {
|
|
7470
|
+
cursor: cursor ?? nextCursor,
|
|
7471
|
+
state,
|
|
7472
|
+
limit,
|
|
7473
|
+
include_failed_runs: include_failed_runs ?? includeFailedRuns,
|
|
7474
|
+
interval_ms: interval_ms ?? intervalMs,
|
|
7475
|
+
max_polls: max_polls ?? maxPolls,
|
|
7476
|
+
timeout_ms: timeout_ms ?? timeoutMs,
|
|
7477
|
+
include_results: include_results ?? includeResults
|
|
7478
|
+
}
|
|
7479
|
+
};
|
|
7480
|
+
}
|
|
7481
|
+
function buildOpsScheduleAndWaitBody(options) {
|
|
7482
|
+
const waitBody = buildOpsWaitBody(options.wait);
|
|
7483
|
+
const { op_id: _opId, ...waitWithoutOp } = waitBody;
|
|
7484
|
+
return {
|
|
7485
|
+
...buildOpsCreateBody({
|
|
7486
|
+
...options.schedule,
|
|
7487
|
+
cadence: options.schedule.cadence ?? "daily"
|
|
7488
|
+
}),
|
|
7489
|
+
...waitWithoutOp,
|
|
7490
|
+
instruction: options.run.instruction,
|
|
7491
|
+
force: options.run.force
|
|
7492
|
+
};
|
|
7493
|
+
}
|
|
5623
7494
|
function buildOpsRunBody(params) {
|
|
5624
7495
|
const { opId, ...rest } = params;
|
|
5625
7496
|
return {
|
|
@@ -5627,6 +7498,28 @@ function buildOpsRunBody(params) {
|
|
|
5627
7498
|
op_id: rest.op_id ?? opId
|
|
5628
7499
|
};
|
|
5629
7500
|
}
|
|
7501
|
+
function buildOpsRunAndWaitOptions(params) {
|
|
7502
|
+
const {
|
|
7503
|
+
opId,
|
|
7504
|
+
nextCursor,
|
|
7505
|
+
includeFailedRuns,
|
|
7506
|
+
intervalMs,
|
|
7507
|
+
maxPolls,
|
|
7508
|
+
timeoutMs,
|
|
7509
|
+
includeResults,
|
|
7510
|
+
...rest
|
|
7511
|
+
} = params;
|
|
7512
|
+
return {
|
|
7513
|
+
...rest,
|
|
7514
|
+
op_id: rest.op_id ?? opId,
|
|
7515
|
+
cursor: rest.cursor ?? nextCursor,
|
|
7516
|
+
include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
|
|
7517
|
+
interval_ms: rest.interval_ms ?? intervalMs,
|
|
7518
|
+
max_polls: rest.max_polls ?? maxPolls,
|
|
7519
|
+
timeout_ms: rest.timeout_ms ?? timeoutMs,
|
|
7520
|
+
include_results: rest.include_results ?? includeResults
|
|
7521
|
+
};
|
|
7522
|
+
}
|
|
5630
7523
|
function buildOpsStatusBody(params) {
|
|
5631
7524
|
const { opId, ...rest } = params;
|
|
5632
7525
|
return {
|
|
@@ -5643,6 +7536,50 @@ function buildOpsResultsBody(params) {
|
|
|
5643
7536
|
include_failed_runs: rest.include_failed_runs ?? includeFailedRuns
|
|
5644
7537
|
};
|
|
5645
7538
|
}
|
|
7539
|
+
function buildOpsWaitForResultsOptions(params) {
|
|
7540
|
+
const {
|
|
7541
|
+
opId,
|
|
7542
|
+
nextCursor,
|
|
7543
|
+
includeFailedRuns,
|
|
7544
|
+
intervalMs,
|
|
7545
|
+
maxPolls,
|
|
7546
|
+
timeoutMs,
|
|
7547
|
+
includeResults,
|
|
7548
|
+
...rest
|
|
7549
|
+
} = params;
|
|
7550
|
+
return {
|
|
7551
|
+
...rest,
|
|
7552
|
+
op_id: rest.op_id ?? opId,
|
|
7553
|
+
cursor: rest.cursor ?? nextCursor,
|
|
7554
|
+
include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
|
|
7555
|
+
interval_ms: rest.interval_ms ?? intervalMs,
|
|
7556
|
+
max_polls: rest.max_polls ?? maxPolls,
|
|
7557
|
+
timeout_ms: rest.timeout_ms ?? timeoutMs,
|
|
7558
|
+
include_results: rest.include_results ?? includeResults
|
|
7559
|
+
};
|
|
7560
|
+
}
|
|
7561
|
+
function buildOpsWaitBody(params) {
|
|
7562
|
+
const {
|
|
7563
|
+
opId,
|
|
7564
|
+
nextCursor,
|
|
7565
|
+
includeFailedRuns,
|
|
7566
|
+
intervalMs,
|
|
7567
|
+
maxPolls,
|
|
7568
|
+
timeoutMs,
|
|
7569
|
+
includeResults,
|
|
7570
|
+
...rest
|
|
7571
|
+
} = params;
|
|
7572
|
+
return {
|
|
7573
|
+
...rest,
|
|
7574
|
+
op_id: rest.op_id ?? opId,
|
|
7575
|
+
cursor: rest.cursor ?? nextCursor,
|
|
7576
|
+
include_failed_runs: rest.include_failed_runs ?? includeFailedRuns,
|
|
7577
|
+
interval_ms: rest.interval_ms ?? intervalMs,
|
|
7578
|
+
max_polls: rest.max_polls ?? maxPolls,
|
|
7579
|
+
timeout_ms: rest.timeout_ms ?? timeoutMs,
|
|
7580
|
+
include_results: rest.include_results ?? includeResults
|
|
7581
|
+
};
|
|
7582
|
+
}
|
|
5646
7583
|
function buildOpsDebugOptions(params) {
|
|
5647
7584
|
const {
|
|
5648
7585
|
opId,
|
|
@@ -5720,6 +7657,8 @@ function normalizeOpsSinkRequest(sink) {
|
|
|
5720
7657
|
nangoAction,
|
|
5721
7658
|
proxyPath,
|
|
5722
7659
|
nangoProxyPath,
|
|
7660
|
+
method,
|
|
7661
|
+
httpMethod,
|
|
5723
7662
|
fieldMap,
|
|
5724
7663
|
requiredFields,
|
|
5725
7664
|
writeConfirmed,
|
|
@@ -5738,6 +7677,7 @@ function normalizeOpsSinkRequest(sink) {
|
|
|
5738
7677
|
const nango_action = rest.nango_action ?? nangoAction;
|
|
5739
7678
|
const proxy_path = rest.proxy_path ?? proxyPath;
|
|
5740
7679
|
const nango_proxy_path = rest.nango_proxy_path ?? nangoProxyPath;
|
|
7680
|
+
const http_method = rest.http_method ?? httpMethod;
|
|
5741
7681
|
const field_map = rest.field_map ?? fieldMap;
|
|
5742
7682
|
const required_fields = rest.required_fields ?? requiredFields;
|
|
5743
7683
|
const write_confirmed = rest.write_confirmed ?? writeConfirmed;
|
|
@@ -5752,6 +7692,9 @@ function normalizeOpsSinkRequest(sink) {
|
|
|
5752
7692
|
if (nango_action !== void 0 && normalizedConfig.nango_action === void 0) normalizedConfig.nango_action = nango_action;
|
|
5753
7693
|
if (proxy_path !== void 0 && normalizedConfig.proxy_path === void 0) normalizedConfig.proxy_path = proxy_path;
|
|
5754
7694
|
if (nango_proxy_path !== void 0 && normalizedConfig.nango_proxy_path === void 0) normalizedConfig.nango_proxy_path = nango_proxy_path;
|
|
7695
|
+
if (method !== void 0 && normalizedConfig.method === void 0) normalizedConfig.method = method;
|
|
7696
|
+
if (http_method !== void 0 && normalizedConfig.http_method === void 0) normalizedConfig.http_method = http_method;
|
|
7697
|
+
if (normalizedConfig.method === void 0 && http_method !== void 0) normalizedConfig.method = http_method;
|
|
5755
7698
|
if (field_map !== void 0 && normalizedConfig.field_map === void 0) normalizedConfig.field_map = field_map;
|
|
5756
7699
|
if (required_fields !== void 0 && normalizedConfig.required_fields === void 0) normalizedConfig.required_fields = required_fields;
|
|
5757
7700
|
if (write_confirmed !== void 0 && normalizedConfig.write_confirmed === void 0) normalizedConfig.write_confirmed = write_confirmed;
|
|
@@ -5771,6 +7714,8 @@ function normalizeOpsSinkRequest(sink) {
|
|
|
5771
7714
|
nango_action,
|
|
5772
7715
|
proxy_path,
|
|
5773
7716
|
nango_proxy_path,
|
|
7717
|
+
method,
|
|
7718
|
+
http_method,
|
|
5774
7719
|
field_map,
|
|
5775
7720
|
required_fields,
|
|
5776
7721
|
write_confirmed,
|
|
@@ -5778,6 +7723,10 @@ function normalizeOpsSinkRequest(sink) {
|
|
|
5778
7723
|
config: normalizedConfig
|
|
5779
7724
|
};
|
|
5780
7725
|
}
|
|
7726
|
+
function normalizeOpsDestinationRequest(destination) {
|
|
7727
|
+
if (!destination || typeof destination !== "object" || Array.isArray(destination)) return destination;
|
|
7728
|
+
return normalizeOpsSinkRequest(destination);
|
|
7729
|
+
}
|
|
5781
7730
|
function normalizeOpsSinkConfigRequest(config) {
|
|
5782
7731
|
const out = { ...config ?? {} };
|
|
5783
7732
|
if (out.connection_id === void 0 && out.connectionId !== void 0) out.connection_id = out.connectionId;
|
|
@@ -5791,6 +7740,8 @@ function normalizeOpsSinkConfigRequest(config) {
|
|
|
5791
7740
|
if (out.nango_action === void 0 && out.nangoAction !== void 0) out.nango_action = out.nangoAction;
|
|
5792
7741
|
if (out.proxy_path === void 0 && out.proxyPath !== void 0) out.proxy_path = out.proxyPath;
|
|
5793
7742
|
if (out.nango_proxy_path === void 0 && out.nangoProxyPath !== void 0) out.nango_proxy_path = out.nangoProxyPath;
|
|
7743
|
+
if (out.http_method === void 0 && out.httpMethod !== void 0) out.http_method = out.httpMethod;
|
|
7744
|
+
if (out.method === void 0 && out.http_method !== void 0) out.method = out.http_method;
|
|
5794
7745
|
if (out.field_map === void 0 && out.fieldMap !== void 0) out.field_map = out.fieldMap;
|
|
5795
7746
|
if (out.required_fields === void 0 && out.requiredFields !== void 0) out.required_fields = out.requiredFields;
|
|
5796
7747
|
if (out.write_confirmed === void 0 && out.writeConfirmed !== void 0) out.write_confirmed = out.writeConfirmed;
|
|
@@ -5864,7 +7815,6 @@ function toSnakeConfig(params) {
|
|
|
5864
7815
|
return {
|
|
5865
7816
|
system_prompt: params.systemPrompt || params.system_prompt || "You are a senior business research analyst. Use multi-model evidence carefully and return concise structured enrichment.",
|
|
5866
7817
|
user_template: params.userTemplate || params.user_template || params.prompt,
|
|
5867
|
-
model: params.model,
|
|
5868
7818
|
temperature: params.temperature,
|
|
5869
7819
|
max_concurrency: params.maxConcurrency || params.max_concurrency,
|
|
5870
7820
|
max_tokens: params.maxTokens || params.max_tokens,
|
|
@@ -5888,13 +7838,10 @@ var Ai = class {
|
|
|
5888
7838
|
/**
|
|
5889
7839
|
* Run Custom AI Enrichment - Multi Model.
|
|
5890
7840
|
*
|
|
5891
|
-
* Uses
|
|
5892
|
-
*
|
|
7841
|
+
* Uses the hosted default model with bounded synthesis, then returns the
|
|
7842
|
+
* requested structured output fields.
|
|
5893
7843
|
*/
|
|
5894
7844
|
async multiModel(params) {
|
|
5895
|
-
if (!params.model) {
|
|
5896
|
-
throw new Error('model is required. Use an OpenRouter id such as "anthropic/claude-sonnet-4" or "google/gemini-2.5-flash".');
|
|
5897
|
-
}
|
|
5898
7845
|
if (!params.prompt && !params.userTemplate && !params.user_template) {
|
|
5899
7846
|
throw new Error("prompt or userTemplate is required.");
|
|
5900
7847
|
}
|
|
@@ -6111,6 +8058,10 @@ var GtmKernel = class {
|
|
|
6111
8058
|
days: options.days,
|
|
6112
8059
|
network_days: options.networkDays,
|
|
6113
8060
|
min_sample_size: options.minSampleSize,
|
|
8061
|
+
holdout_min_sample_size: options.holdoutMinSampleSize,
|
|
8062
|
+
predictive_min_labeled_outcomes: options.predictiveMinLabeledOutcomes,
|
|
8063
|
+
predictive_min_positive_outcomes: options.predictiveMinPositiveOutcomes,
|
|
8064
|
+
predictive_min_memory_sample_size: options.predictiveMinMemorySampleSize,
|
|
6114
8065
|
min_workspace_count: options.minWorkspaceCount,
|
|
6115
8066
|
min_privacy_k: options.minPrivacyK,
|
|
6116
8067
|
include_memory: options.includeMemory,
|
|
@@ -6177,9 +8128,11 @@ var GtmKernel = class {
|
|
|
6177
8128
|
write_routine_outcomes: input.writeRoutineOutcomes
|
|
6178
8129
|
});
|
|
6179
8130
|
}
|
|
6180
|
-
/** Start a background Instantly webhook-events pull and route results into the GTM feedback loop. */
|
|
8131
|
+
/** Start a background Instantly webhook-events or email-history pull and route results into the GTM feedback loop. */
|
|
6181
8132
|
async pullInstantlyFeedback(input) {
|
|
6182
8133
|
return this.callMcp("gtm_instantly_feedback_pull", {
|
|
8134
|
+
source: input.source,
|
|
8135
|
+
instantly_profile: input.instantlyProfile,
|
|
6183
8136
|
campaign_id: input.campaignId,
|
|
6184
8137
|
campaign_build_id: input.campaignBuildId,
|
|
6185
8138
|
provider_link_id: input.providerLinkId,
|
|
@@ -6191,6 +8144,9 @@ var GtmKernel = class {
|
|
|
6191
8144
|
to: input.to,
|
|
6192
8145
|
limit: input.limit,
|
|
6193
8146
|
max_pages: input.maxPages,
|
|
8147
|
+
email_type: input.emailType,
|
|
8148
|
+
mode: input.mode,
|
|
8149
|
+
sort_order: input.sortOrder,
|
|
6194
8150
|
create_memory: input.createMemory,
|
|
6195
8151
|
write_routine_outcomes: input.writeRoutineOutcomes,
|
|
6196
8152
|
dry_run: input.dryRun,
|
|
@@ -6261,6 +8217,16 @@ var GtmKernel = class {
|
|
|
6261
8217
|
min_privacy_k: input.minPrivacyK
|
|
6262
8218
|
});
|
|
6263
8219
|
}
|
|
8220
|
+
/** Queue a dry-run-first bridge from imported historical feedback to attribution-only Campaign Build surrogates. */
|
|
8221
|
+
async runHistoricalCampaignBuildBridge(input = {}) {
|
|
8222
|
+
return this.callMcp("gtm_historical_campaign_build_bridge_run", {
|
|
8223
|
+
dry_run: input.dryRun,
|
|
8224
|
+
write_approved: input.writeApproved,
|
|
8225
|
+
max_events: input.maxEvents,
|
|
8226
|
+
max_campaigns: input.maxCampaigns,
|
|
8227
|
+
min_feedback_events: input.minFeedbackEvents
|
|
8228
|
+
});
|
|
8229
|
+
}
|
|
6264
8230
|
/** Prepare a provider-agnostic feedback webhook URL for Smartlead, HeyReach, Airbyte, or custom sender events. */
|
|
6265
8231
|
async prepareFeedbackWebhook(input) {
|
|
6266
8232
|
return this.callMcp("gtm_feedback_webhook_prepare", {
|
|
@@ -6320,6 +8286,7 @@ var GtmKernel = class {
|
|
|
6320
8286
|
days: input.days,
|
|
6321
8287
|
network_days: input.networkDays,
|
|
6322
8288
|
min_sample_size: input.minSampleSize,
|
|
8289
|
+
holdout_min_sample_size: input.holdoutMinSampleSize,
|
|
6323
8290
|
min_workspace_count: input.minWorkspaceCount,
|
|
6324
8291
|
min_privacy_k: input.minPrivacyK,
|
|
6325
8292
|
include_memory: input.includeMemory,
|
|
@@ -6340,6 +8307,7 @@ var GtmKernel = class {
|
|
|
6340
8307
|
days: input.days,
|
|
6341
8308
|
network_days: input.networkDays,
|
|
6342
8309
|
min_sample_size: input.minSampleSize,
|
|
8310
|
+
holdout_min_sample_size: input.holdoutMinSampleSize,
|
|
6343
8311
|
min_workspace_count: input.minWorkspaceCount,
|
|
6344
8312
|
min_privacy_k: input.minPrivacyK,
|
|
6345
8313
|
include_memory: input.includeMemory,
|
|
@@ -6464,6 +8432,29 @@ var GtmKernel = class {
|
|
|
6464
8432
|
include_details: options.includeDetails
|
|
6465
8433
|
});
|
|
6466
8434
|
}
|
|
8435
|
+
/** Search the Agency Autopilot safe-action catalog for agency-style lead lists, Clay tables, and GTM motions. */
|
|
8436
|
+
async agencyAutopilotCapabilityCatalog(options = {}) {
|
|
8437
|
+
return this.callMcp("gtm_agency_autopilot_capability_catalog", {
|
|
8438
|
+
query: options.query,
|
|
8439
|
+
family: options.family,
|
|
8440
|
+
phase: options.phase,
|
|
8441
|
+
account_label: options.accountLabel,
|
|
8442
|
+
workspace_label: options.workspaceLabel,
|
|
8443
|
+
target_count: options.targetCount,
|
|
8444
|
+
limit: options.limit,
|
|
8445
|
+
include_agent_prompts: options.includeAgentPrompts
|
|
8446
|
+
});
|
|
8447
|
+
}
|
|
8448
|
+
/** Search agency operating playbooks Agency Autopilot can use for lead lists, Clay tables, GTM motions, and proof gates. */
|
|
8449
|
+
async agencyAutopilotPlaybookCatalog(options = {}) {
|
|
8450
|
+
return this.callMcp("gtm_agency_autopilot_playbook_catalog", {
|
|
8451
|
+
query: options.query,
|
|
8452
|
+
playbook_slug: options.playbookSlug,
|
|
8453
|
+
outcome_type: options.outcomeType,
|
|
8454
|
+
limit: options.limit,
|
|
8455
|
+
include_required_fields: options.includeRequiredFields
|
|
8456
|
+
});
|
|
8457
|
+
}
|
|
6467
8458
|
/** Build the read-only Memory, Brain, risk, and provider-route runbook needed before planning a campaign. */
|
|
6468
8459
|
async campaignStartContext(input = {}) {
|
|
6469
8460
|
return this.callMcp("gtm_campaign_start_context", {
|
|
@@ -6822,6 +8813,35 @@ var GtmKernel = class {
|
|
|
6822
8813
|
user_display_name: input.userDisplayName
|
|
6823
8814
|
});
|
|
6824
8815
|
}
|
|
8816
|
+
/** Prepare the full Nango provider search, connect, pull/export, Ops, and campaign-route flow. */
|
|
8817
|
+
async prepareNangoIntegrationFlow(input = {}) {
|
|
8818
|
+
return this.callMcp("nango_integration_flow_prepare", {
|
|
8819
|
+
query: input.query,
|
|
8820
|
+
search: input.search,
|
|
8821
|
+
provider_id: input.providerId,
|
|
8822
|
+
provider: input.provider,
|
|
8823
|
+
integration_id: input.integrationId,
|
|
8824
|
+
provider_config_key: input.providerConfigKey,
|
|
8825
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
8826
|
+
connection_id: input.connectionId,
|
|
8827
|
+
nango_connection_id: input.nangoConnectionId,
|
|
8828
|
+
intent: input.intent,
|
|
8829
|
+
action_name: input.actionName,
|
|
8830
|
+
tool_name: input.toolName,
|
|
8831
|
+
proxy_path: input.proxyPath,
|
|
8832
|
+
method: input.method,
|
|
8833
|
+
input: input.input,
|
|
8834
|
+
cadence: input.cadence,
|
|
8835
|
+
field_map: input.fieldMap,
|
|
8836
|
+
required_fields: input.requiredFields,
|
|
8837
|
+
confirm_spend: input.confirmSpend,
|
|
8838
|
+
write_confirmed: input.writeConfirmed,
|
|
8839
|
+
layer: input.layer,
|
|
8840
|
+
campaign_id: input.campaignId,
|
|
8841
|
+
limit: input.limit,
|
|
8842
|
+
include_provider_catalog: input.includeProviderCatalog
|
|
8843
|
+
});
|
|
8844
|
+
}
|
|
6825
8845
|
/** List Nango-backed action tools for a workspace connection without executing them. */
|
|
6826
8846
|
async listNangoTools(options = {}) {
|
|
6827
8847
|
return this.callMcp("nango_mcp_tools_list", {
|
|
@@ -6844,6 +8864,12 @@ var GtmKernel = class {
|
|
|
6844
8864
|
nango_connection_id: input.nangoConnectionId,
|
|
6845
8865
|
action_name: input.actionName,
|
|
6846
8866
|
tool_name: input.toolName,
|
|
8867
|
+
delivery_mode: input.deliveryMode,
|
|
8868
|
+
proxy_path: input.proxyPath,
|
|
8869
|
+
nango_proxy_path: input.nangoProxyPath,
|
|
8870
|
+
method: input.method,
|
|
8871
|
+
http_method: input.httpMethod,
|
|
8872
|
+
proxy_headers: input.proxyHeaders,
|
|
6847
8873
|
input: input.input,
|
|
6848
8874
|
async: input.async,
|
|
6849
8875
|
max_retries: input.maxRetries,
|
|
@@ -6993,6 +9019,7 @@ function compact2(value) {
|
|
|
6993
9019
|
}
|
|
6994
9020
|
|
|
6995
9021
|
// src/index.ts
|
|
9022
|
+
var MCP_TOOL_CACHE_TTL_MS = 3e4;
|
|
6996
9023
|
function inferMcpToolCategory(toolName) {
|
|
6997
9024
|
if (typeof toolName !== "string" || !toolName) return void 0;
|
|
6998
9025
|
if (toolName.startsWith("ops_") || toolName === "get_ops_readiness" || toolName === "get_gtm_ops_readiness" || toolName.startsWith("gtm_") || [
|
|
@@ -7124,6 +9151,21 @@ var Signaliz = class {
|
|
|
7124
9151
|
}
|
|
7125
9152
|
/** List all available MCP tools */
|
|
7126
9153
|
async listTools() {
|
|
9154
|
+
const now = Date.now();
|
|
9155
|
+
if (this.toolListCache && this.toolListCache.expiresAt > now) {
|
|
9156
|
+
return this.toolListCache.promise;
|
|
9157
|
+
}
|
|
9158
|
+
const promise = this.fetchTools().catch((error) => {
|
|
9159
|
+
if (this.toolListCache?.promise === promise) this.toolListCache = void 0;
|
|
9160
|
+
throw error;
|
|
9161
|
+
});
|
|
9162
|
+
this.toolListCache = {
|
|
9163
|
+
expiresAt: now + MCP_TOOL_CACHE_TTL_MS,
|
|
9164
|
+
promise
|
|
9165
|
+
};
|
|
9166
|
+
return promise;
|
|
9167
|
+
}
|
|
9168
|
+
async fetchTools() {
|
|
7127
9169
|
try {
|
|
7128
9170
|
const manifest = await this.client.mcp("tools/call", {
|
|
7129
9171
|
name: "get_tool_manifest",
|