@signaliz/sdk 1.0.56 → 1.0.58
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 +8 -1
- package/dist/{chunk-K7RDDRMJ.mjs → chunk-EAKP4DSS.mjs} +148 -31
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +148 -31
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +148 -31
- package/dist/mcp-config.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,7 +87,8 @@ const copy = await signaliz.signalToCopy({
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
// Company Signals and Signal to Copy are hard synchronous contracts: these
|
|
90
|
-
// methods return complete data
|
|
90
|
+
// methods return complete data, an explicit success:false result, or throw a
|
|
91
|
+
// non-2xx terminal error in this same call.
|
|
91
92
|
```
|
|
92
93
|
|
|
93
94
|
The four row-oriented products support bounded batch execution over the same REST endpoints.
|
|
@@ -112,6 +113,12 @@ Failed rows preserve `errorCode`, `retryEligible`, and `retryAfterSeconds`
|
|
|
112
113
|
when the REST API supplies them, including after automatic row retries are
|
|
113
114
|
exhausted.
|
|
114
115
|
|
|
116
|
+
Every single-result method treats an error payload as `success: false`, even if
|
|
117
|
+
an upstream HTTP 200 omits or contradicts the success flag. Find Email also
|
|
118
|
+
withholds any email from a contradictory error response. Verify Email, Company
|
|
119
|
+
Signals, and Signal to Copy expose normalized `error` and `errorCode` fields;
|
|
120
|
+
the original response remains available in `raw`.
|
|
121
|
+
|
|
115
122
|
For an ambiguous single request or batch submission failure, retry with the
|
|
116
123
|
same `idempotencyKey` to recover the original request, durable job, or provider
|
|
117
124
|
run without duplicate work or spend. The key is portable across REST API, MCP,
|
|
@@ -532,9 +532,10 @@ var Signaliz = class {
|
|
|
532
532
|
);
|
|
533
533
|
}
|
|
534
534
|
const startedAt = Date.now();
|
|
535
|
-
const deduplicated = dedupeExactBatchItems(
|
|
536
|
-
|
|
537
|
-
|
|
535
|
+
const deduplicated = dedupeExactBatchItems(
|
|
536
|
+
requests,
|
|
537
|
+
(params) => coreProductBatchRequestKey("api/v1/signal-to-copy", signalToCopyRequestBody(params))
|
|
538
|
+
);
|
|
538
539
|
const uniqueRequests = deduplicated.uniqueItems;
|
|
539
540
|
const uniqueInputIndices = new Array(uniqueRequests.length);
|
|
540
541
|
deduplicated.sourceIndexByInput.forEach((uniqueIndex, inputIndex) => {
|
|
@@ -691,7 +692,7 @@ var Signaliz = class {
|
|
|
691
692
|
}
|
|
692
693
|
for (let index = 0; index < requests.length; index += 1) {
|
|
693
694
|
const item = data.results[index];
|
|
694
|
-
if (item
|
|
695
|
+
if (coreProductResponseFailed(item)) {
|
|
695
696
|
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
696
697
|
index,
|
|
697
698
|
success: false,
|
|
@@ -700,7 +701,11 @@ var Signaliz = class {
|
|
|
700
701
|
rateLimited.push({ index, params: requests[index], raw: item });
|
|
701
702
|
continue;
|
|
702
703
|
}
|
|
703
|
-
results[index] = batchItemFailure(
|
|
704
|
+
results[index] = batchItemFailure(
|
|
705
|
+
index,
|
|
706
|
+
coreProductErrorMessage(item) || "Signal to Copy failed",
|
|
707
|
+
item
|
|
708
|
+
);
|
|
704
709
|
continue;
|
|
705
710
|
}
|
|
706
711
|
try {
|
|
@@ -731,7 +736,10 @@ var Signaliz = class {
|
|
|
731
736
|
}
|
|
732
737
|
async runCoreBatchRound(path, tasks, options, rowRateLimitAttempt = 0) {
|
|
733
738
|
const { serverConcurrency, chunkConcurrency } = path === "api/v1/company-signals" ? batchConcurrencyPlan(options, 25, 25) : batchConcurrencyPlan(options);
|
|
734
|
-
const deduplicated = dedupeExactBatchItems(
|
|
739
|
+
const deduplicated = dedupeExactBatchItems(
|
|
740
|
+
tasks,
|
|
741
|
+
(task) => coreProductBatchRequestKey(path, task.request)
|
|
742
|
+
);
|
|
735
743
|
const uniqueTasks = deduplicated.uniqueItems;
|
|
736
744
|
const recoverableBatch = path === "api/v1/find-email" ? { label: "Find Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path === "api/v1/verify-email" ? { label: "Verify Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : void 0;
|
|
737
745
|
if (path !== "api/v1/company-signals" && recoverableBatch && uniqueTasks.length > 25) {
|
|
@@ -798,9 +806,9 @@ var Signaliz = class {
|
|
|
798
806
|
const raw = chunkResult.data[index];
|
|
799
807
|
uniqueResults[chunk.offset + index] = {
|
|
800
808
|
index: chunk.tasks[index].index,
|
|
801
|
-
success: raw
|
|
809
|
+
success: !coreProductResponseFailed(raw),
|
|
802
810
|
raw,
|
|
803
|
-
error: raw
|
|
811
|
+
error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
|
|
804
812
|
};
|
|
805
813
|
}
|
|
806
814
|
}
|
|
@@ -870,7 +878,7 @@ function batchItemFailure(index, error, raw) {
|
|
|
870
878
|
};
|
|
871
879
|
}
|
|
872
880
|
function recoverableJobRowFailed(row) {
|
|
873
|
-
return row
|
|
881
|
+
return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
874
882
|
}
|
|
875
883
|
function newBatchIdempotencyKey(label) {
|
|
876
884
|
const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
@@ -920,7 +928,9 @@ function normalizeCoreProductDryRunResult(data) {
|
|
|
920
928
|
};
|
|
921
929
|
}
|
|
922
930
|
function normalizeFindEmailResult(data) {
|
|
923
|
-
const
|
|
931
|
+
const failed = coreProductResponseFailed(data);
|
|
932
|
+
const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
933
|
+
const email = failed ? null : rawEmail;
|
|
924
934
|
const found = Boolean(email) && data.found !== false;
|
|
925
935
|
const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
|
|
926
936
|
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
@@ -930,7 +940,7 @@ function normalizeFindEmailResult(data) {
|
|
|
930
940
|
const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
931
941
|
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
932
942
|
return {
|
|
933
|
-
success:
|
|
943
|
+
success: !failed && found,
|
|
934
944
|
found,
|
|
935
945
|
email,
|
|
936
946
|
firstName: data.first_name,
|
|
@@ -957,26 +967,29 @@ function normalizeFindEmailResult(data) {
|
|
|
957
967
|
liveProviderCalled: data.live_provider_called,
|
|
958
968
|
openrouterCalled: data.openrouter_called,
|
|
959
969
|
byoOpenrouterUsed: data.byo_openrouter_used,
|
|
960
|
-
error: found ? void 0 : data
|
|
961
|
-
errorCode: found ? void 0 : data
|
|
970
|
+
error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
|
|
971
|
+
errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
|
|
962
972
|
raw: data
|
|
963
973
|
};
|
|
964
974
|
}
|
|
965
975
|
function normalizeVerifyEmailResult(email, data) {
|
|
976
|
+
const failed = coreProductResponseFailed(data);
|
|
966
977
|
const verificationStatus = String(data.verification_status ?? "").toLowerCase();
|
|
967
|
-
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
978
|
+
const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
|
|
968
979
|
return {
|
|
969
|
-
success:
|
|
980
|
+
success: !failed,
|
|
981
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
982
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
970
983
|
email: data.email ?? email,
|
|
971
|
-
status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
984
|
+
status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
972
985
|
verificationRunId: data.verification_run_id ?? data.run_id,
|
|
973
986
|
retryAfterMs: data.retry_after_ms,
|
|
974
987
|
nextPollAfterSeconds: data.next_poll_after_seconds,
|
|
975
|
-
isValid: data.is_valid ?? data.valid ?? verified,
|
|
976
|
-
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
988
|
+
isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
|
|
989
|
+
isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
|
|
977
990
|
isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
|
|
978
991
|
isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
979
|
-
verifiedForSending: data.verified_for_sending === true,
|
|
992
|
+
verifiedForSending: !failed && data.verified_for_sending === true,
|
|
980
993
|
verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
|
|
981
994
|
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
982
995
|
provider: data.provider,
|
|
@@ -1021,9 +1034,12 @@ function companySignalRequestBody(params) {
|
|
|
1021
1034
|
});
|
|
1022
1035
|
}
|
|
1023
1036
|
function normalizeCompanySignalResult(params, data) {
|
|
1024
|
-
const
|
|
1037
|
+
const failed = coreProductResponseFailed(data);
|
|
1038
|
+
const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
|
|
1025
1039
|
return {
|
|
1026
|
-
success:
|
|
1040
|
+
success: !failed,
|
|
1041
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1042
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1027
1043
|
status: data.status,
|
|
1028
1044
|
signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
|
|
1029
1045
|
company: {
|
|
@@ -1247,15 +1263,88 @@ function dedupeExactBatchItems(items, keyForItem) {
|
|
|
1247
1263
|
}
|
|
1248
1264
|
return { uniqueItems, sourceIndexByInput };
|
|
1249
1265
|
}
|
|
1266
|
+
function normalizedBatchText(value) {
|
|
1267
|
+
return typeof value === "string" ? value.trim().toLowerCase().replace(/\s+/g, " ") : "";
|
|
1268
|
+
}
|
|
1269
|
+
function normalizedBatchDomain(value) {
|
|
1270
|
+
return normalizedBatchText(value).replace(/^https?:\/\//, "").replace(/^www\./, "").split(/[/?#]/, 1)[0].replace(/\.+$/, "");
|
|
1271
|
+
}
|
|
1272
|
+
function normalizedBatchLinkedIn(value) {
|
|
1273
|
+
return normalizedBatchText(value).replace(/\/+$/, "");
|
|
1274
|
+
}
|
|
1275
|
+
function normalizedBatchList(value) {
|
|
1276
|
+
return Array.isArray(value) ? value.map(normalizedBatchText).filter(Boolean).sort() : [];
|
|
1277
|
+
}
|
|
1278
|
+
function normalizedFindEmailBatchName(request) {
|
|
1279
|
+
const fullName = normalizedBatchText(request.full_name);
|
|
1280
|
+
const componentName = [normalizedBatchText(request.first_name), normalizedBatchText(request.last_name)].filter(Boolean).join(" ");
|
|
1281
|
+
if (!fullName || !componentName || fullName === componentName) return fullName || componentName;
|
|
1282
|
+
return JSON.stringify([fullName, componentName]);
|
|
1283
|
+
}
|
|
1284
|
+
function coreProductBatchRequestKey(path, request) {
|
|
1285
|
+
if (path === "api/v1/find-email") {
|
|
1286
|
+
return JSON.stringify([
|
|
1287
|
+
normalizedFindEmailBatchName(request),
|
|
1288
|
+
normalizedBatchDomain(request.company_domain),
|
|
1289
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1290
|
+
normalizedBatchText(request.company_name),
|
|
1291
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1292
|
+
]);
|
|
1293
|
+
}
|
|
1294
|
+
if (path === "api/v1/verify-email") {
|
|
1295
|
+
return JSON.stringify([
|
|
1296
|
+
normalizedBatchText(request.email),
|
|
1297
|
+
request.skip_cache === true || request.bypass_cache === true,
|
|
1298
|
+
request.skip_catch_all_verification === true,
|
|
1299
|
+
request.skip_esp_check === true
|
|
1300
|
+
]);
|
|
1301
|
+
}
|
|
1302
|
+
if (path === "api/v1/company-signals") {
|
|
1303
|
+
const online = request.online !== false;
|
|
1304
|
+
const deepSearch = request.enable_deep_search === void 0 ? online : request.enable_deep_search !== false;
|
|
1305
|
+
return JSON.stringify([
|
|
1306
|
+
normalizedBatchText(request.signal_run_id),
|
|
1307
|
+
normalizedBatchDomain(request.company_domain || request.domain),
|
|
1308
|
+
normalizedBatchText(request.company_name),
|
|
1309
|
+
normalizedBatchText(request.company_id),
|
|
1310
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1311
|
+
normalizedBatchText(request.industry),
|
|
1312
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1313
|
+
normalizedBatchList(request.signal_types),
|
|
1314
|
+
Number(request.target_signal_count) || null,
|
|
1315
|
+
Number(request.lookback_days) || null,
|
|
1316
|
+
online,
|
|
1317
|
+
deepSearch,
|
|
1318
|
+
normalizedBatchText(request.search_mode || "balanced"),
|
|
1319
|
+
request.enable_outreach_intelligence === true,
|
|
1320
|
+
request.enable_predictive_intelligence === true,
|
|
1321
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1322
|
+
]);
|
|
1323
|
+
}
|
|
1324
|
+
return JSON.stringify([
|
|
1325
|
+
normalizedBatchDomain(request.company_domain),
|
|
1326
|
+
typeof request.person_name === "string" ? request.person_name.trim() : "",
|
|
1327
|
+
typeof request.title === "string" ? request.title.trim() : "",
|
|
1328
|
+
typeof request.campaign_offer === "string" ? request.campaign_offer.trim() : "",
|
|
1329
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1330
|
+
typeof request.signal_run_id === "string" ? request.signal_run_id.trim() : "",
|
|
1331
|
+
request.skip_cache === true,
|
|
1332
|
+
request.enable_deep_search === true
|
|
1333
|
+
]);
|
|
1334
|
+
}
|
|
1250
1335
|
function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
1251
1336
|
const results = new Array(total);
|
|
1252
1337
|
for (const item of round) {
|
|
1253
1338
|
if (!item.success || !item.raw) {
|
|
1254
|
-
|
|
1339
|
+
const failure = batchItemFailure(
|
|
1255
1340
|
item.index,
|
|
1256
1341
|
item.error || "Signaliz batch item failed",
|
|
1257
1342
|
item.raw ?? item
|
|
1258
1343
|
);
|
|
1344
|
+
if (item.raw?.is_malformed === true) {
|
|
1345
|
+
failure.data = normalize(item);
|
|
1346
|
+
}
|
|
1347
|
+
results[item.index] = failure;
|
|
1259
1348
|
continue;
|
|
1260
1349
|
}
|
|
1261
1350
|
try {
|
|
@@ -1328,17 +1417,21 @@ function validateCoreProductMaxWaitMs(value) {
|
|
|
1328
1417
|
}
|
|
1329
1418
|
}
|
|
1330
1419
|
function normalizeSignalToCopyResult(data) {
|
|
1420
|
+
const failed = coreProductResponseFailed(data);
|
|
1331
1421
|
return {
|
|
1332
|
-
success:
|
|
1422
|
+
success: !failed,
|
|
1423
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1424
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1333
1425
|
status: data.status,
|
|
1334
|
-
runId: data.
|
|
1426
|
+
runId: data.run_id ?? data.signal_run_id,
|
|
1427
|
+
companySignalRunId: data.company_signal_run_id,
|
|
1335
1428
|
resumeContextPersisted: data.resume_context_persisted,
|
|
1336
|
-
strongestSignal: data.strongest_signal ?? "",
|
|
1337
|
-
whyNow: data.why_now ?? "",
|
|
1338
|
-
subjectLine: data.subject_line ?? "",
|
|
1339
|
-
openingLine: data.opening_line ?? "",
|
|
1340
|
-
confidence: data.confidence ?? 0,
|
|
1341
|
-
evidenceUrl: data.evidence_url ?? "",
|
|
1429
|
+
strongestSignal: failed ? "" : data.strongest_signal ?? "",
|
|
1430
|
+
whyNow: failed ? "" : data.why_now ?? "",
|
|
1431
|
+
subjectLine: failed ? "" : data.subject_line ?? "",
|
|
1432
|
+
openingLine: failed ? "" : data.opening_line ?? "",
|
|
1433
|
+
confidence: failed ? 0 : data.confidence ?? 0,
|
|
1434
|
+
evidenceUrl: failed ? "" : data.evidence_url ?? "",
|
|
1342
1435
|
researchPrompt: data.research_prompt,
|
|
1343
1436
|
empty: data.empty,
|
|
1344
1437
|
emptyReason: data.empty_reason,
|
|
@@ -1351,7 +1444,7 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1351
1444
|
liveProviderCalled: data.live_provider_called,
|
|
1352
1445
|
aiProviderCalled: data.ai_provider_called,
|
|
1353
1446
|
byoAiUsed: data.byo_ai_used,
|
|
1354
|
-
variations: (data.variations ?? []).map((variation) => ({
|
|
1447
|
+
variations: (failed ? [] : data.variations ?? []).map((variation) => ({
|
|
1355
1448
|
style: variation.style,
|
|
1356
1449
|
subjectLine: variation.subject_line ?? "",
|
|
1357
1450
|
openingLine: variation.opening_line ?? "",
|
|
@@ -1363,8 +1456,32 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1363
1456
|
};
|
|
1364
1457
|
}
|
|
1365
1458
|
function isPendingSignalResponse(data) {
|
|
1459
|
+
if (coreProductResponseFailed(data)) return false;
|
|
1366
1460
|
return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
|
|
1367
1461
|
}
|
|
1462
|
+
function coreProductResponseFailed(data) {
|
|
1463
|
+
if (data.success === false) return true;
|
|
1464
|
+
if (typeof data.error_code === "string" && data.error_code.trim()) return true;
|
|
1465
|
+
if (typeof data.error === "string" && data.error.trim()) return true;
|
|
1466
|
+
if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
|
|
1467
|
+
return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
|
|
1468
|
+
}
|
|
1469
|
+
function coreProductErrorMessage(data) {
|
|
1470
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1471
|
+
const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
|
|
1472
|
+
for (const candidate of candidates) {
|
|
1473
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1474
|
+
}
|
|
1475
|
+
return void 0;
|
|
1476
|
+
}
|
|
1477
|
+
function coreProductErrorCode(data) {
|
|
1478
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1479
|
+
const candidates = [data.error_code, nested?.code, data.code];
|
|
1480
|
+
for (const candidate of candidates) {
|
|
1481
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1482
|
+
}
|
|
1483
|
+
return void 0;
|
|
1484
|
+
}
|
|
1368
1485
|
function assertTerminalSignalResponse(data, capability) {
|
|
1369
1486
|
if (isPendingSignalResponse(data) || data.job_id) {
|
|
1370
1487
|
throw new Error(`${capability} violated the synchronous response contract.`);
|
package/dist/index.d.mts
CHANGED
|
@@ -116,6 +116,8 @@ interface FindEmailResult {
|
|
|
116
116
|
}
|
|
117
117
|
interface VerifyEmailResult {
|
|
118
118
|
success: boolean;
|
|
119
|
+
error?: string;
|
|
120
|
+
errorCode?: string;
|
|
119
121
|
email: string;
|
|
120
122
|
/** Execution state. Processing results are never send-safe. */
|
|
121
123
|
status: 'processing' | 'completed';
|
|
@@ -216,6 +218,8 @@ interface CompanySignal {
|
|
|
216
218
|
}
|
|
217
219
|
interface CompanySignalEnrichmentResult {
|
|
218
220
|
success: boolean;
|
|
221
|
+
error?: string;
|
|
222
|
+
errorCode?: string;
|
|
219
223
|
status?: string;
|
|
220
224
|
signalRunId?: string;
|
|
221
225
|
company: {
|
|
@@ -353,12 +357,15 @@ interface SignalToCopyVariation {
|
|
|
353
357
|
openingLine: string;
|
|
354
358
|
cta: string;
|
|
355
359
|
prediction?: string;
|
|
356
|
-
email
|
|
360
|
+
email: string;
|
|
357
361
|
}
|
|
358
362
|
interface SignalToCopyResult {
|
|
359
363
|
success: boolean;
|
|
364
|
+
error?: string;
|
|
365
|
+
errorCode?: string;
|
|
360
366
|
status?: string;
|
|
361
367
|
runId?: string;
|
|
368
|
+
companySignalRunId?: string;
|
|
362
369
|
resumeContextPersisted?: boolean;
|
|
363
370
|
strongestSignal: string;
|
|
364
371
|
whyNow: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -116,6 +116,8 @@ interface FindEmailResult {
|
|
|
116
116
|
}
|
|
117
117
|
interface VerifyEmailResult {
|
|
118
118
|
success: boolean;
|
|
119
|
+
error?: string;
|
|
120
|
+
errorCode?: string;
|
|
119
121
|
email: string;
|
|
120
122
|
/** Execution state. Processing results are never send-safe. */
|
|
121
123
|
status: 'processing' | 'completed';
|
|
@@ -216,6 +218,8 @@ interface CompanySignal {
|
|
|
216
218
|
}
|
|
217
219
|
interface CompanySignalEnrichmentResult {
|
|
218
220
|
success: boolean;
|
|
221
|
+
error?: string;
|
|
222
|
+
errorCode?: string;
|
|
219
223
|
status?: string;
|
|
220
224
|
signalRunId?: string;
|
|
221
225
|
company: {
|
|
@@ -353,12 +357,15 @@ interface SignalToCopyVariation {
|
|
|
353
357
|
openingLine: string;
|
|
354
358
|
cta: string;
|
|
355
359
|
prediction?: string;
|
|
356
|
-
email
|
|
360
|
+
email: string;
|
|
357
361
|
}
|
|
358
362
|
interface SignalToCopyResult {
|
|
359
363
|
success: boolean;
|
|
364
|
+
error?: string;
|
|
365
|
+
errorCode?: string;
|
|
360
366
|
status?: string;
|
|
361
367
|
runId?: string;
|
|
368
|
+
companySignalRunId?: string;
|
|
362
369
|
resumeContextPersisted?: boolean;
|
|
363
370
|
strongestSignal: string;
|
|
364
371
|
whyNow: string;
|
package/dist/index.js
CHANGED
|
@@ -559,9 +559,10 @@ var Signaliz = class {
|
|
|
559
559
|
);
|
|
560
560
|
}
|
|
561
561
|
const startedAt = Date.now();
|
|
562
|
-
const deduplicated = dedupeExactBatchItems(
|
|
563
|
-
|
|
564
|
-
|
|
562
|
+
const deduplicated = dedupeExactBatchItems(
|
|
563
|
+
requests,
|
|
564
|
+
(params) => coreProductBatchRequestKey("api/v1/signal-to-copy", signalToCopyRequestBody(params))
|
|
565
|
+
);
|
|
565
566
|
const uniqueRequests = deduplicated.uniqueItems;
|
|
566
567
|
const uniqueInputIndices = new Array(uniqueRequests.length);
|
|
567
568
|
deduplicated.sourceIndexByInput.forEach((uniqueIndex, inputIndex) => {
|
|
@@ -718,7 +719,7 @@ var Signaliz = class {
|
|
|
718
719
|
}
|
|
719
720
|
for (let index = 0; index < requests.length; index += 1) {
|
|
720
721
|
const item = data.results[index];
|
|
721
|
-
if (item
|
|
722
|
+
if (coreProductResponseFailed(item)) {
|
|
722
723
|
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
723
724
|
index,
|
|
724
725
|
success: false,
|
|
@@ -727,7 +728,11 @@ var Signaliz = class {
|
|
|
727
728
|
rateLimited.push({ index, params: requests[index], raw: item });
|
|
728
729
|
continue;
|
|
729
730
|
}
|
|
730
|
-
results[index] = batchItemFailure(
|
|
731
|
+
results[index] = batchItemFailure(
|
|
732
|
+
index,
|
|
733
|
+
coreProductErrorMessage(item) || "Signal to Copy failed",
|
|
734
|
+
item
|
|
735
|
+
);
|
|
731
736
|
continue;
|
|
732
737
|
}
|
|
733
738
|
try {
|
|
@@ -758,7 +763,10 @@ var Signaliz = class {
|
|
|
758
763
|
}
|
|
759
764
|
async runCoreBatchRound(path, tasks, options, rowRateLimitAttempt = 0) {
|
|
760
765
|
const { serverConcurrency, chunkConcurrency } = path === "api/v1/company-signals" ? batchConcurrencyPlan(options, 25, 25) : batchConcurrencyPlan(options);
|
|
761
|
-
const deduplicated = dedupeExactBatchItems(
|
|
766
|
+
const deduplicated = dedupeExactBatchItems(
|
|
767
|
+
tasks,
|
|
768
|
+
(task) => coreProductBatchRequestKey(path, task.request)
|
|
769
|
+
);
|
|
762
770
|
const uniqueTasks = deduplicated.uniqueItems;
|
|
763
771
|
const recoverableBatch = path === "api/v1/find-email" ? { label: "Find Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path === "api/v1/verify-email" ? { label: "Verify Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : void 0;
|
|
764
772
|
if (path !== "api/v1/company-signals" && recoverableBatch && uniqueTasks.length > 25) {
|
|
@@ -825,9 +833,9 @@ var Signaliz = class {
|
|
|
825
833
|
const raw = chunkResult.data[index];
|
|
826
834
|
uniqueResults[chunk.offset + index] = {
|
|
827
835
|
index: chunk.tasks[index].index,
|
|
828
|
-
success: raw
|
|
836
|
+
success: !coreProductResponseFailed(raw),
|
|
829
837
|
raw,
|
|
830
|
-
error: raw
|
|
838
|
+
error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
|
|
831
839
|
};
|
|
832
840
|
}
|
|
833
841
|
}
|
|
@@ -897,7 +905,7 @@ function batchItemFailure(index, error, raw) {
|
|
|
897
905
|
};
|
|
898
906
|
}
|
|
899
907
|
function recoverableJobRowFailed(row) {
|
|
900
|
-
return row
|
|
908
|
+
return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
901
909
|
}
|
|
902
910
|
function newBatchIdempotencyKey(label) {
|
|
903
911
|
const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
@@ -947,7 +955,9 @@ function normalizeCoreProductDryRunResult(data) {
|
|
|
947
955
|
};
|
|
948
956
|
}
|
|
949
957
|
function normalizeFindEmailResult(data) {
|
|
950
|
-
const
|
|
958
|
+
const failed = coreProductResponseFailed(data);
|
|
959
|
+
const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
960
|
+
const email = failed ? null : rawEmail;
|
|
951
961
|
const found = Boolean(email) && data.found !== false;
|
|
952
962
|
const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
|
|
953
963
|
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
@@ -957,7 +967,7 @@ function normalizeFindEmailResult(data) {
|
|
|
957
967
|
const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
958
968
|
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
959
969
|
return {
|
|
960
|
-
success:
|
|
970
|
+
success: !failed && found,
|
|
961
971
|
found,
|
|
962
972
|
email,
|
|
963
973
|
firstName: data.first_name,
|
|
@@ -984,26 +994,29 @@ function normalizeFindEmailResult(data) {
|
|
|
984
994
|
liveProviderCalled: data.live_provider_called,
|
|
985
995
|
openrouterCalled: data.openrouter_called,
|
|
986
996
|
byoOpenrouterUsed: data.byo_openrouter_used,
|
|
987
|
-
error: found ? void 0 : data
|
|
988
|
-
errorCode: found ? void 0 : data
|
|
997
|
+
error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
|
|
998
|
+
errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
|
|
989
999
|
raw: data
|
|
990
1000
|
};
|
|
991
1001
|
}
|
|
992
1002
|
function normalizeVerifyEmailResult(email, data) {
|
|
1003
|
+
const failed = coreProductResponseFailed(data);
|
|
993
1004
|
const verificationStatus = String(data.verification_status ?? "").toLowerCase();
|
|
994
|
-
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
1005
|
+
const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
|
|
995
1006
|
return {
|
|
996
|
-
success:
|
|
1007
|
+
success: !failed,
|
|
1008
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1009
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
997
1010
|
email: data.email ?? email,
|
|
998
|
-
status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
1011
|
+
status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
999
1012
|
verificationRunId: data.verification_run_id ?? data.run_id,
|
|
1000
1013
|
retryAfterMs: data.retry_after_ms,
|
|
1001
1014
|
nextPollAfterSeconds: data.next_poll_after_seconds,
|
|
1002
|
-
isValid: data.is_valid ?? data.valid ?? verified,
|
|
1003
|
-
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
1015
|
+
isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
|
|
1016
|
+
isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
|
|
1004
1017
|
isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
|
|
1005
1018
|
isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
1006
|
-
verifiedForSending: data.verified_for_sending === true,
|
|
1019
|
+
verifiedForSending: !failed && data.verified_for_sending === true,
|
|
1007
1020
|
verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
|
|
1008
1021
|
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
1009
1022
|
provider: data.provider,
|
|
@@ -1048,9 +1061,12 @@ function companySignalRequestBody(params) {
|
|
|
1048
1061
|
});
|
|
1049
1062
|
}
|
|
1050
1063
|
function normalizeCompanySignalResult(params, data) {
|
|
1051
|
-
const
|
|
1064
|
+
const failed = coreProductResponseFailed(data);
|
|
1065
|
+
const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
|
|
1052
1066
|
return {
|
|
1053
|
-
success:
|
|
1067
|
+
success: !failed,
|
|
1068
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1069
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1054
1070
|
status: data.status,
|
|
1055
1071
|
signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
|
|
1056
1072
|
company: {
|
|
@@ -1274,15 +1290,88 @@ function dedupeExactBatchItems(items, keyForItem) {
|
|
|
1274
1290
|
}
|
|
1275
1291
|
return { uniqueItems, sourceIndexByInput };
|
|
1276
1292
|
}
|
|
1293
|
+
function normalizedBatchText(value) {
|
|
1294
|
+
return typeof value === "string" ? value.trim().toLowerCase().replace(/\s+/g, " ") : "";
|
|
1295
|
+
}
|
|
1296
|
+
function normalizedBatchDomain(value) {
|
|
1297
|
+
return normalizedBatchText(value).replace(/^https?:\/\//, "").replace(/^www\./, "").split(/[/?#]/, 1)[0].replace(/\.+$/, "");
|
|
1298
|
+
}
|
|
1299
|
+
function normalizedBatchLinkedIn(value) {
|
|
1300
|
+
return normalizedBatchText(value).replace(/\/+$/, "");
|
|
1301
|
+
}
|
|
1302
|
+
function normalizedBatchList(value) {
|
|
1303
|
+
return Array.isArray(value) ? value.map(normalizedBatchText).filter(Boolean).sort() : [];
|
|
1304
|
+
}
|
|
1305
|
+
function normalizedFindEmailBatchName(request) {
|
|
1306
|
+
const fullName = normalizedBatchText(request.full_name);
|
|
1307
|
+
const componentName = [normalizedBatchText(request.first_name), normalizedBatchText(request.last_name)].filter(Boolean).join(" ");
|
|
1308
|
+
if (!fullName || !componentName || fullName === componentName) return fullName || componentName;
|
|
1309
|
+
return JSON.stringify([fullName, componentName]);
|
|
1310
|
+
}
|
|
1311
|
+
function coreProductBatchRequestKey(path, request) {
|
|
1312
|
+
if (path === "api/v1/find-email") {
|
|
1313
|
+
return JSON.stringify([
|
|
1314
|
+
normalizedFindEmailBatchName(request),
|
|
1315
|
+
normalizedBatchDomain(request.company_domain),
|
|
1316
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1317
|
+
normalizedBatchText(request.company_name),
|
|
1318
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1319
|
+
]);
|
|
1320
|
+
}
|
|
1321
|
+
if (path === "api/v1/verify-email") {
|
|
1322
|
+
return JSON.stringify([
|
|
1323
|
+
normalizedBatchText(request.email),
|
|
1324
|
+
request.skip_cache === true || request.bypass_cache === true,
|
|
1325
|
+
request.skip_catch_all_verification === true,
|
|
1326
|
+
request.skip_esp_check === true
|
|
1327
|
+
]);
|
|
1328
|
+
}
|
|
1329
|
+
if (path === "api/v1/company-signals") {
|
|
1330
|
+
const online = request.online !== false;
|
|
1331
|
+
const deepSearch = request.enable_deep_search === void 0 ? online : request.enable_deep_search !== false;
|
|
1332
|
+
return JSON.stringify([
|
|
1333
|
+
normalizedBatchText(request.signal_run_id),
|
|
1334
|
+
normalizedBatchDomain(request.company_domain || request.domain),
|
|
1335
|
+
normalizedBatchText(request.company_name),
|
|
1336
|
+
normalizedBatchText(request.company_id),
|
|
1337
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1338
|
+
normalizedBatchText(request.industry),
|
|
1339
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1340
|
+
normalizedBatchList(request.signal_types),
|
|
1341
|
+
Number(request.target_signal_count) || null,
|
|
1342
|
+
Number(request.lookback_days) || null,
|
|
1343
|
+
online,
|
|
1344
|
+
deepSearch,
|
|
1345
|
+
normalizedBatchText(request.search_mode || "balanced"),
|
|
1346
|
+
request.enable_outreach_intelligence === true,
|
|
1347
|
+
request.enable_predictive_intelligence === true,
|
|
1348
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1349
|
+
]);
|
|
1350
|
+
}
|
|
1351
|
+
return JSON.stringify([
|
|
1352
|
+
normalizedBatchDomain(request.company_domain),
|
|
1353
|
+
typeof request.person_name === "string" ? request.person_name.trim() : "",
|
|
1354
|
+
typeof request.title === "string" ? request.title.trim() : "",
|
|
1355
|
+
typeof request.campaign_offer === "string" ? request.campaign_offer.trim() : "",
|
|
1356
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1357
|
+
typeof request.signal_run_id === "string" ? request.signal_run_id.trim() : "",
|
|
1358
|
+
request.skip_cache === true,
|
|
1359
|
+
request.enable_deep_search === true
|
|
1360
|
+
]);
|
|
1361
|
+
}
|
|
1277
1362
|
function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
1278
1363
|
const results = new Array(total);
|
|
1279
1364
|
for (const item of round) {
|
|
1280
1365
|
if (!item.success || !item.raw) {
|
|
1281
|
-
|
|
1366
|
+
const failure = batchItemFailure(
|
|
1282
1367
|
item.index,
|
|
1283
1368
|
item.error || "Signaliz batch item failed",
|
|
1284
1369
|
item.raw ?? item
|
|
1285
1370
|
);
|
|
1371
|
+
if (item.raw?.is_malformed === true) {
|
|
1372
|
+
failure.data = normalize(item);
|
|
1373
|
+
}
|
|
1374
|
+
results[item.index] = failure;
|
|
1286
1375
|
continue;
|
|
1287
1376
|
}
|
|
1288
1377
|
try {
|
|
@@ -1355,17 +1444,21 @@ function validateCoreProductMaxWaitMs(value) {
|
|
|
1355
1444
|
}
|
|
1356
1445
|
}
|
|
1357
1446
|
function normalizeSignalToCopyResult(data) {
|
|
1447
|
+
const failed = coreProductResponseFailed(data);
|
|
1358
1448
|
return {
|
|
1359
|
-
success:
|
|
1449
|
+
success: !failed,
|
|
1450
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1451
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1360
1452
|
status: data.status,
|
|
1361
|
-
runId: data.
|
|
1453
|
+
runId: data.run_id ?? data.signal_run_id,
|
|
1454
|
+
companySignalRunId: data.company_signal_run_id,
|
|
1362
1455
|
resumeContextPersisted: data.resume_context_persisted,
|
|
1363
|
-
strongestSignal: data.strongest_signal ?? "",
|
|
1364
|
-
whyNow: data.why_now ?? "",
|
|
1365
|
-
subjectLine: data.subject_line ?? "",
|
|
1366
|
-
openingLine: data.opening_line ?? "",
|
|
1367
|
-
confidence: data.confidence ?? 0,
|
|
1368
|
-
evidenceUrl: data.evidence_url ?? "",
|
|
1456
|
+
strongestSignal: failed ? "" : data.strongest_signal ?? "",
|
|
1457
|
+
whyNow: failed ? "" : data.why_now ?? "",
|
|
1458
|
+
subjectLine: failed ? "" : data.subject_line ?? "",
|
|
1459
|
+
openingLine: failed ? "" : data.opening_line ?? "",
|
|
1460
|
+
confidence: failed ? 0 : data.confidence ?? 0,
|
|
1461
|
+
evidenceUrl: failed ? "" : data.evidence_url ?? "",
|
|
1369
1462
|
researchPrompt: data.research_prompt,
|
|
1370
1463
|
empty: data.empty,
|
|
1371
1464
|
emptyReason: data.empty_reason,
|
|
@@ -1378,7 +1471,7 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1378
1471
|
liveProviderCalled: data.live_provider_called,
|
|
1379
1472
|
aiProviderCalled: data.ai_provider_called,
|
|
1380
1473
|
byoAiUsed: data.byo_ai_used,
|
|
1381
|
-
variations: (data.variations ?? []).map((variation) => ({
|
|
1474
|
+
variations: (failed ? [] : data.variations ?? []).map((variation) => ({
|
|
1382
1475
|
style: variation.style,
|
|
1383
1476
|
subjectLine: variation.subject_line ?? "",
|
|
1384
1477
|
openingLine: variation.opening_line ?? "",
|
|
@@ -1390,8 +1483,32 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1390
1483
|
};
|
|
1391
1484
|
}
|
|
1392
1485
|
function isPendingSignalResponse(data) {
|
|
1486
|
+
if (coreProductResponseFailed(data)) return false;
|
|
1393
1487
|
return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
|
|
1394
1488
|
}
|
|
1489
|
+
function coreProductResponseFailed(data) {
|
|
1490
|
+
if (data.success === false) return true;
|
|
1491
|
+
if (typeof data.error_code === "string" && data.error_code.trim()) return true;
|
|
1492
|
+
if (typeof data.error === "string" && data.error.trim()) return true;
|
|
1493
|
+
if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
|
|
1494
|
+
return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
|
|
1495
|
+
}
|
|
1496
|
+
function coreProductErrorMessage(data) {
|
|
1497
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1498
|
+
const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
|
|
1499
|
+
for (const candidate of candidates) {
|
|
1500
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1501
|
+
}
|
|
1502
|
+
return void 0;
|
|
1503
|
+
}
|
|
1504
|
+
function coreProductErrorCode(data) {
|
|
1505
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1506
|
+
const candidates = [data.error_code, nested?.code, data.code];
|
|
1507
|
+
for (const candidate of candidates) {
|
|
1508
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1509
|
+
}
|
|
1510
|
+
return void 0;
|
|
1511
|
+
}
|
|
1395
1512
|
function assertTerminalSignalResponse(data, capability) {
|
|
1396
1513
|
if (isPendingSignalResponse(data) || data.job_id) {
|
|
1397
1514
|
throw new Error(`${capability} violated the synchronous response contract.`);
|
package/dist/index.mjs
CHANGED
package/dist/mcp-config.js
CHANGED
|
@@ -563,9 +563,10 @@ var Signaliz = class {
|
|
|
563
563
|
);
|
|
564
564
|
}
|
|
565
565
|
const startedAt = Date.now();
|
|
566
|
-
const deduplicated = dedupeExactBatchItems(
|
|
567
|
-
|
|
568
|
-
|
|
566
|
+
const deduplicated = dedupeExactBatchItems(
|
|
567
|
+
requests,
|
|
568
|
+
(params) => coreProductBatchRequestKey("api/v1/signal-to-copy", signalToCopyRequestBody(params))
|
|
569
|
+
);
|
|
569
570
|
const uniqueRequests = deduplicated.uniqueItems;
|
|
570
571
|
const uniqueInputIndices = new Array(uniqueRequests.length);
|
|
571
572
|
deduplicated.sourceIndexByInput.forEach((uniqueIndex, inputIndex) => {
|
|
@@ -722,7 +723,7 @@ var Signaliz = class {
|
|
|
722
723
|
}
|
|
723
724
|
for (let index = 0; index < requests.length; index += 1) {
|
|
724
725
|
const item = data.results[index];
|
|
725
|
-
if (item
|
|
726
|
+
if (coreProductResponseFailed(item)) {
|
|
726
727
|
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
727
728
|
index,
|
|
728
729
|
success: false,
|
|
@@ -731,7 +732,11 @@ var Signaliz = class {
|
|
|
731
732
|
rateLimited.push({ index, params: requests[index], raw: item });
|
|
732
733
|
continue;
|
|
733
734
|
}
|
|
734
|
-
results[index] = batchItemFailure(
|
|
735
|
+
results[index] = batchItemFailure(
|
|
736
|
+
index,
|
|
737
|
+
coreProductErrorMessage(item) || "Signal to Copy failed",
|
|
738
|
+
item
|
|
739
|
+
);
|
|
735
740
|
continue;
|
|
736
741
|
}
|
|
737
742
|
try {
|
|
@@ -762,7 +767,10 @@ var Signaliz = class {
|
|
|
762
767
|
}
|
|
763
768
|
async runCoreBatchRound(path2, tasks, options, rowRateLimitAttempt = 0) {
|
|
764
769
|
const { serverConcurrency, chunkConcurrency } = path2 === "api/v1/company-signals" ? batchConcurrencyPlan(options, 25, 25) : batchConcurrencyPlan(options);
|
|
765
|
-
const deduplicated = dedupeExactBatchItems(
|
|
770
|
+
const deduplicated = dedupeExactBatchItems(
|
|
771
|
+
tasks,
|
|
772
|
+
(task) => coreProductBatchRequestKey(path2, task.request)
|
|
773
|
+
);
|
|
766
774
|
const uniqueTasks = deduplicated.uniqueItems;
|
|
767
775
|
const recoverableBatch = path2 === "api/v1/find-email" ? { label: "Find Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : path2 === "api/v1/verify-email" ? { label: "Verify Email", pageSize: 500, maxWaitMs: 20 * 6e4 } : void 0;
|
|
768
776
|
if (path2 !== "api/v1/company-signals" && recoverableBatch && uniqueTasks.length > 25) {
|
|
@@ -829,9 +837,9 @@ var Signaliz = class {
|
|
|
829
837
|
const raw = chunkResult.data[index];
|
|
830
838
|
uniqueResults[chunk.offset + index] = {
|
|
831
839
|
index: chunk.tasks[index].index,
|
|
832
|
-
success: raw
|
|
840
|
+
success: !coreProductResponseFailed(raw),
|
|
833
841
|
raw,
|
|
834
|
-
error: raw
|
|
842
|
+
error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path2} item failed` : void 0
|
|
835
843
|
};
|
|
836
844
|
}
|
|
837
845
|
}
|
|
@@ -901,7 +909,7 @@ function batchItemFailure(index, error, raw) {
|
|
|
901
909
|
};
|
|
902
910
|
}
|
|
903
911
|
function recoverableJobRowFailed(row) {
|
|
904
|
-
return row
|
|
912
|
+
return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
905
913
|
}
|
|
906
914
|
function newBatchIdempotencyKey(label) {
|
|
907
915
|
const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
@@ -951,7 +959,9 @@ function normalizeCoreProductDryRunResult(data) {
|
|
|
951
959
|
};
|
|
952
960
|
}
|
|
953
961
|
function normalizeFindEmailResult(data) {
|
|
954
|
-
const
|
|
962
|
+
const failed = coreProductResponseFailed(data);
|
|
963
|
+
const rawEmail = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
964
|
+
const email = failed ? null : rawEmail;
|
|
955
965
|
const found = Boolean(email) && data.found !== false;
|
|
956
966
|
const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
|
|
957
967
|
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
@@ -961,7 +971,7 @@ function normalizeFindEmailResult(data) {
|
|
|
961
971
|
const verified = !explicitlyNotSendSafe && (data.is_valid === true || data.isValid === true || data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
962
972
|
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
963
973
|
return {
|
|
964
|
-
success:
|
|
974
|
+
success: !failed && found,
|
|
965
975
|
found,
|
|
966
976
|
email,
|
|
967
977
|
firstName: data.first_name,
|
|
@@ -988,26 +998,29 @@ function normalizeFindEmailResult(data) {
|
|
|
988
998
|
liveProviderCalled: data.live_provider_called,
|
|
989
999
|
openrouterCalled: data.openrouter_called,
|
|
990
1000
|
byoOpenrouterUsed: data.byo_openrouter_used,
|
|
991
|
-
error: found ? void 0 : data
|
|
992
|
-
errorCode: found ? void 0 : data
|
|
1001
|
+
error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
|
|
1002
|
+
errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
|
|
993
1003
|
raw: data
|
|
994
1004
|
};
|
|
995
1005
|
}
|
|
996
1006
|
function normalizeVerifyEmailResult(email, data) {
|
|
1007
|
+
const failed = coreProductResponseFailed(data);
|
|
997
1008
|
const verificationStatus = String(data.verification_status ?? "").toLowerCase();
|
|
998
|
-
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
1009
|
+
const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
|
|
999
1010
|
return {
|
|
1000
|
-
success:
|
|
1011
|
+
success: !failed,
|
|
1012
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1013
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1001
1014
|
email: data.email ?? email,
|
|
1002
|
-
status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
1015
|
+
status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
|
|
1003
1016
|
verificationRunId: data.verification_run_id ?? data.run_id,
|
|
1004
1017
|
retryAfterMs: data.retry_after_ms,
|
|
1005
1018
|
nextPollAfterSeconds: data.next_poll_after_seconds,
|
|
1006
|
-
isValid: data.is_valid ?? data.valid ?? verified,
|
|
1007
|
-
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
1019
|
+
isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
|
|
1020
|
+
isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
|
|
1008
1021
|
isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
|
|
1009
1022
|
isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
1010
|
-
verifiedForSending: data.verified_for_sending === true,
|
|
1023
|
+
verifiedForSending: !failed && data.verified_for_sending === true,
|
|
1011
1024
|
verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
|
|
1012
1025
|
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
1013
1026
|
provider: data.provider,
|
|
@@ -1052,9 +1065,12 @@ function companySignalRequestBody(params) {
|
|
|
1052
1065
|
});
|
|
1053
1066
|
}
|
|
1054
1067
|
function normalizeCompanySignalResult(params, data) {
|
|
1055
|
-
const
|
|
1068
|
+
const failed = coreProductResponseFailed(data);
|
|
1069
|
+
const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
|
|
1056
1070
|
return {
|
|
1057
|
-
success:
|
|
1071
|
+
success: !failed,
|
|
1072
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1073
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1058
1074
|
status: data.status,
|
|
1059
1075
|
signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
|
|
1060
1076
|
company: {
|
|
@@ -1278,15 +1294,88 @@ function dedupeExactBatchItems(items, keyForItem) {
|
|
|
1278
1294
|
}
|
|
1279
1295
|
return { uniqueItems, sourceIndexByInput };
|
|
1280
1296
|
}
|
|
1297
|
+
function normalizedBatchText(value) {
|
|
1298
|
+
return typeof value === "string" ? value.trim().toLowerCase().replace(/\s+/g, " ") : "";
|
|
1299
|
+
}
|
|
1300
|
+
function normalizedBatchDomain(value) {
|
|
1301
|
+
return normalizedBatchText(value).replace(/^https?:\/\//, "").replace(/^www\./, "").split(/[/?#]/, 1)[0].replace(/\.+$/, "");
|
|
1302
|
+
}
|
|
1303
|
+
function normalizedBatchLinkedIn(value) {
|
|
1304
|
+
return normalizedBatchText(value).replace(/\/+$/, "");
|
|
1305
|
+
}
|
|
1306
|
+
function normalizedBatchList(value) {
|
|
1307
|
+
return Array.isArray(value) ? value.map(normalizedBatchText).filter(Boolean).sort() : [];
|
|
1308
|
+
}
|
|
1309
|
+
function normalizedFindEmailBatchName(request) {
|
|
1310
|
+
const fullName = normalizedBatchText(request.full_name);
|
|
1311
|
+
const componentName = [normalizedBatchText(request.first_name), normalizedBatchText(request.last_name)].filter(Boolean).join(" ");
|
|
1312
|
+
if (!fullName || !componentName || fullName === componentName) return fullName || componentName;
|
|
1313
|
+
return JSON.stringify([fullName, componentName]);
|
|
1314
|
+
}
|
|
1315
|
+
function coreProductBatchRequestKey(path2, request) {
|
|
1316
|
+
if (path2 === "api/v1/find-email") {
|
|
1317
|
+
return JSON.stringify([
|
|
1318
|
+
normalizedFindEmailBatchName(request),
|
|
1319
|
+
normalizedBatchDomain(request.company_domain),
|
|
1320
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1321
|
+
normalizedBatchText(request.company_name),
|
|
1322
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1323
|
+
]);
|
|
1324
|
+
}
|
|
1325
|
+
if (path2 === "api/v1/verify-email") {
|
|
1326
|
+
return JSON.stringify([
|
|
1327
|
+
normalizedBatchText(request.email),
|
|
1328
|
+
request.skip_cache === true || request.bypass_cache === true,
|
|
1329
|
+
request.skip_catch_all_verification === true,
|
|
1330
|
+
request.skip_esp_check === true
|
|
1331
|
+
]);
|
|
1332
|
+
}
|
|
1333
|
+
if (path2 === "api/v1/company-signals") {
|
|
1334
|
+
const online = request.online !== false;
|
|
1335
|
+
const deepSearch = request.enable_deep_search === void 0 ? online : request.enable_deep_search !== false;
|
|
1336
|
+
return JSON.stringify([
|
|
1337
|
+
normalizedBatchText(request.signal_run_id),
|
|
1338
|
+
normalizedBatchDomain(request.company_domain || request.domain),
|
|
1339
|
+
normalizedBatchText(request.company_name),
|
|
1340
|
+
normalizedBatchText(request.company_id),
|
|
1341
|
+
normalizedBatchLinkedIn(request.linkedin_url),
|
|
1342
|
+
normalizedBatchText(request.industry),
|
|
1343
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1344
|
+
normalizedBatchList(request.signal_types),
|
|
1345
|
+
Number(request.target_signal_count) || null,
|
|
1346
|
+
Number(request.lookback_days) || null,
|
|
1347
|
+
online,
|
|
1348
|
+
deepSearch,
|
|
1349
|
+
normalizedBatchText(request.search_mode || "balanced"),
|
|
1350
|
+
request.enable_outreach_intelligence === true,
|
|
1351
|
+
request.enable_predictive_intelligence === true,
|
|
1352
|
+
request.skip_cache === true || request.bypass_cache === true
|
|
1353
|
+
]);
|
|
1354
|
+
}
|
|
1355
|
+
return JSON.stringify([
|
|
1356
|
+
normalizedBatchDomain(request.company_domain),
|
|
1357
|
+
typeof request.person_name === "string" ? request.person_name.trim() : "",
|
|
1358
|
+
typeof request.title === "string" ? request.title.trim() : "",
|
|
1359
|
+
typeof request.campaign_offer === "string" ? request.campaign_offer.trim() : "",
|
|
1360
|
+
typeof request.research_prompt === "string" ? request.research_prompt.trim() : "",
|
|
1361
|
+
typeof request.signal_run_id === "string" ? request.signal_run_id.trim() : "",
|
|
1362
|
+
request.skip_cache === true,
|
|
1363
|
+
request.enable_deep_search === true
|
|
1364
|
+
]);
|
|
1365
|
+
}
|
|
1281
1366
|
function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
1282
1367
|
const results = new Array(total);
|
|
1283
1368
|
for (const item of round) {
|
|
1284
1369
|
if (!item.success || !item.raw) {
|
|
1285
|
-
|
|
1370
|
+
const failure = batchItemFailure(
|
|
1286
1371
|
item.index,
|
|
1287
1372
|
item.error || "Signaliz batch item failed",
|
|
1288
1373
|
item.raw ?? item
|
|
1289
1374
|
);
|
|
1375
|
+
if (item.raw?.is_malformed === true) {
|
|
1376
|
+
failure.data = normalize(item);
|
|
1377
|
+
}
|
|
1378
|
+
results[item.index] = failure;
|
|
1290
1379
|
continue;
|
|
1291
1380
|
}
|
|
1292
1381
|
try {
|
|
@@ -1359,17 +1448,21 @@ function validateCoreProductMaxWaitMs(value) {
|
|
|
1359
1448
|
}
|
|
1360
1449
|
}
|
|
1361
1450
|
function normalizeSignalToCopyResult(data) {
|
|
1451
|
+
const failed = coreProductResponseFailed(data);
|
|
1362
1452
|
return {
|
|
1363
|
-
success:
|
|
1453
|
+
success: !failed,
|
|
1454
|
+
error: failed ? coreProductErrorMessage(data) : void 0,
|
|
1455
|
+
errorCode: failed ? coreProductErrorCode(data) : void 0,
|
|
1364
1456
|
status: data.status,
|
|
1365
|
-
runId: data.
|
|
1457
|
+
runId: data.run_id ?? data.signal_run_id,
|
|
1458
|
+
companySignalRunId: data.company_signal_run_id,
|
|
1366
1459
|
resumeContextPersisted: data.resume_context_persisted,
|
|
1367
|
-
strongestSignal: data.strongest_signal ?? "",
|
|
1368
|
-
whyNow: data.why_now ?? "",
|
|
1369
|
-
subjectLine: data.subject_line ?? "",
|
|
1370
|
-
openingLine: data.opening_line ?? "",
|
|
1371
|
-
confidence: data.confidence ?? 0,
|
|
1372
|
-
evidenceUrl: data.evidence_url ?? "",
|
|
1460
|
+
strongestSignal: failed ? "" : data.strongest_signal ?? "",
|
|
1461
|
+
whyNow: failed ? "" : data.why_now ?? "",
|
|
1462
|
+
subjectLine: failed ? "" : data.subject_line ?? "",
|
|
1463
|
+
openingLine: failed ? "" : data.opening_line ?? "",
|
|
1464
|
+
confidence: failed ? 0 : data.confidence ?? 0,
|
|
1465
|
+
evidenceUrl: failed ? "" : data.evidence_url ?? "",
|
|
1373
1466
|
researchPrompt: data.research_prompt,
|
|
1374
1467
|
empty: data.empty,
|
|
1375
1468
|
emptyReason: data.empty_reason,
|
|
@@ -1382,7 +1475,7 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1382
1475
|
liveProviderCalled: data.live_provider_called,
|
|
1383
1476
|
aiProviderCalled: data.ai_provider_called,
|
|
1384
1477
|
byoAiUsed: data.byo_ai_used,
|
|
1385
|
-
variations: (data.variations ?? []).map((variation) => ({
|
|
1478
|
+
variations: (failed ? [] : data.variations ?? []).map((variation) => ({
|
|
1386
1479
|
style: variation.style,
|
|
1387
1480
|
subjectLine: variation.subject_line ?? "",
|
|
1388
1481
|
openingLine: variation.opening_line ?? "",
|
|
@@ -1394,8 +1487,32 @@ function normalizeSignalToCopyResult(data) {
|
|
|
1394
1487
|
};
|
|
1395
1488
|
}
|
|
1396
1489
|
function isPendingSignalResponse(data) {
|
|
1490
|
+
if (coreProductResponseFailed(data)) return false;
|
|
1397
1491
|
return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
|
|
1398
1492
|
}
|
|
1493
|
+
function coreProductResponseFailed(data) {
|
|
1494
|
+
if (data.success === false) return true;
|
|
1495
|
+
if (typeof data.error_code === "string" && data.error_code.trim()) return true;
|
|
1496
|
+
if (typeof data.error === "string" && data.error.trim()) return true;
|
|
1497
|
+
if (data.error && typeof data.error === "object" && Object.keys(data.error).length > 0) return true;
|
|
1498
|
+
return ["failed", "error", "cancelled", "canceled"].includes(String(data.status || "").toLowerCase());
|
|
1499
|
+
}
|
|
1500
|
+
function coreProductErrorMessage(data) {
|
|
1501
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1502
|
+
const candidates = [nested?.message, data.message, typeof data.error === "string" ? data.error : void 0];
|
|
1503
|
+
for (const candidate of candidates) {
|
|
1504
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1505
|
+
}
|
|
1506
|
+
return void 0;
|
|
1507
|
+
}
|
|
1508
|
+
function coreProductErrorCode(data) {
|
|
1509
|
+
const nested = data.error && typeof data.error === "object" ? data.error : void 0;
|
|
1510
|
+
const candidates = [data.error_code, nested?.code, data.code];
|
|
1511
|
+
for (const candidate of candidates) {
|
|
1512
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
1513
|
+
}
|
|
1514
|
+
return void 0;
|
|
1515
|
+
}
|
|
1399
1516
|
function assertTerminalSignalResponse(data, capability) {
|
|
1400
1517
|
if (isPendingSignalResponse(data) || data.job_id) {
|
|
1401
1518
|
throw new Error(`${capability} violated the synchronous response contract.`);
|
package/dist/mcp-config.mjs
CHANGED
package/package.json
CHANGED