@signaliz/sdk 1.0.57 → 1.0.59

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 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 or throw a terminal error in this same call.
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,16 @@ 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. This includes
118
+ `ok: false`, non-empty error fields or error arrays, and terminal provider
119
+ statuses such as `timed_out` or `crashed`; an informational `message` alone is
120
+ not an error. Find Email withholds the email and every send-safe indicator,
121
+ Verify Email withholds deliverability and confidence, and Company Signals and
122
+ Signal to Copy withhold contradictory signals, narratives, and copy. Normalized
123
+ `error` and `errorCode` fields explain the failure while the original response
124
+ remains available in `raw` for audit.
125
+
115
126
  For an ambiguous single request or batch submission failure, retry with the
116
127
  same `idempotencyKey` to recover the original request, durable job, or provider
117
128
  run without duplicate work or spend. The key is portable across REST API, MCP,
@@ -692,7 +692,7 @@ var Signaliz = class {
692
692
  }
693
693
  for (let index = 0; index < requests.length; index += 1) {
694
694
  const item = data.results[index];
695
- if (item.success === false) {
695
+ if (coreProductResponseFailed(item)) {
696
696
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
697
697
  index,
698
698
  success: false,
@@ -701,7 +701,11 @@ var Signaliz = class {
701
701
  rateLimited.push({ index, params: requests[index], raw: item });
702
702
  continue;
703
703
  }
704
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
704
+ results[index] = batchItemFailure(
705
+ index,
706
+ coreProductErrorMessage(item) || "Signal to Copy failed",
707
+ item
708
+ );
705
709
  continue;
706
710
  }
707
711
  try {
@@ -802,9 +806,9 @@ var Signaliz = class {
802
806
  const raw = chunkResult.data[index];
803
807
  uniqueResults[chunk.offset + index] = {
804
808
  index: chunk.tasks[index].index,
805
- success: raw.success !== false,
809
+ success: !coreProductResponseFailed(raw),
806
810
  raw,
807
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
811
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
808
812
  };
809
813
  }
810
814
  }
@@ -874,7 +878,7 @@ function batchItemFailure(index, error, raw) {
874
878
  };
875
879
  }
876
880
  function recoverableJobRowFailed(row) {
877
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
881
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
878
882
  }
879
883
  function newBatchIdempotencyKey(label) {
880
884
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -924,7 +928,9 @@ function normalizeCoreProductDryRunResult(data) {
924
928
  };
925
929
  }
926
930
  function normalizeFindEmailResult(data) {
927
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
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;
928
934
  const found = Boolean(email) && data.found !== false;
929
935
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
930
936
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -934,20 +940,20 @@ function normalizeFindEmailResult(data) {
934
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()));
935
941
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
936
942
  return {
937
- success: data.success !== false && found,
943
+ success: !failed && found,
938
944
  found,
939
945
  email,
940
946
  firstName: data.first_name,
941
947
  lastName: data.last_name,
942
- confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
943
- verificationStatus,
944
- isVerified: verified,
945
- isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
948
+ confidence: failed ? 0 : data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
949
+ verificationStatus: failed ? "error" : verificationStatus,
950
+ isVerified: !failed && verified,
951
+ isVerifiedForSending: !failed && !needsReverification && data.verified_for_sending === true,
946
952
  isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
947
953
  verificationFreshness,
948
954
  verificationAgeDays,
949
955
  verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
950
- needsReverification,
956
+ needsReverification: failed || needsReverification,
951
957
  providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
952
958
  creditsUsed: data.credits_used,
953
959
  estimatedExternalCostUsd: data.estimated_external_cost_usd,
@@ -961,28 +967,32 @@ function normalizeFindEmailResult(data) {
961
967
  liveProviderCalled: data.live_provider_called,
962
968
  openrouterCalled: data.openrouter_called,
963
969
  byoOpenrouterUsed: data.byo_openrouter_used,
964
- error: found ? void 0 : data.error ?? "No verified email found",
965
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
970
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
971
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
966
972
  raw: data
967
973
  };
968
974
  }
969
975
  function normalizeVerifyEmailResult(email, data) {
976
+ const failed = coreProductResponseFailed(data);
970
977
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
971
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
978
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
979
+ const malformed = data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed";
972
980
  return {
973
- success: data.success !== false,
981
+ success: !failed,
982
+ error: failed ? coreProductErrorMessage(data) : void 0,
983
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
974
984
  email: data.email ?? email,
975
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
985
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
976
986
  verificationRunId: data.verification_run_id ?? data.run_id,
977
987
  retryAfterMs: data.retry_after_ms,
978
988
  nextPollAfterSeconds: data.next_poll_after_seconds,
979
- isValid: data.is_valid ?? data.valid ?? verified,
980
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
981
- isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
989
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
990
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
991
+ isMalformed: malformed,
982
992
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
983
- verifiedForSending: data.verified_for_sending === true,
984
- verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
985
- confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
993
+ verifiedForSending: !failed && data.verified_for_sending === true,
994
+ verificationVerdict: failed ? malformed ? "malformed" : "error" : data.verification_verdict ?? data.verification_status ?? "unknown",
995
+ confidenceScore: failed ? 0 : data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
986
996
  provider: data.provider,
987
997
  verificationSource: data.verification_source,
988
998
  billingReplayed: data.billing_replayed,
@@ -1025,9 +1035,12 @@ function companySignalRequestBody(params) {
1025
1035
  });
1026
1036
  }
1027
1037
  function normalizeCompanySignalResult(params, data) {
1028
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1038
+ const failed = coreProductResponseFailed(data);
1039
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1029
1040
  return {
1030
- success: data.success ?? true,
1041
+ success: !failed,
1042
+ error: failed ? coreProductErrorMessage(data) : void 0,
1043
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1031
1044
  status: data.status,
1032
1045
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1033
1046
  company: {
@@ -1052,16 +1065,16 @@ function normalizeCompanySignalResult(params, data) {
1052
1065
  classification: signal.signal_classification ?? null
1053
1066
  };
1054
1067
  }),
1055
- signalCount: data.signal_count ?? data.total_signals ?? rawSignals.length,
1056
- signalSummary: data.signal_summary ?? null,
1057
- intelligence: data.intelligence ?? null,
1058
- copyFuel: data.copy_fuel ?? null,
1059
- evidenceValidation: data.evidence_validation,
1060
- evidenceSources: data.metadata?.evidence_sources ?? data.evidence_sources,
1061
- evidenceCount: data.evidence_count,
1062
- evidenceCountTotal: data.evidence_count_total,
1063
- evidenceSourcesOmitted: data.evidence_sources_omitted,
1064
- evidenceScope: data.evidence_scope,
1068
+ signalCount: failed ? 0 : data.signal_count ?? data.total_signals ?? rawSignals.length,
1069
+ signalSummary: failed ? null : data.signal_summary ?? null,
1070
+ intelligence: failed ? null : data.intelligence ?? null,
1071
+ copyFuel: failed ? null : data.copy_fuel ?? null,
1072
+ evidenceValidation: failed ? void 0 : data.evidence_validation,
1073
+ evidenceSources: failed ? [] : data.metadata?.evidence_sources ?? data.evidence_sources,
1074
+ evidenceCount: failed ? 0 : data.evidence_count,
1075
+ evidenceCountTotal: failed ? 0 : data.evidence_count_total,
1076
+ evidenceSourcesOmitted: failed ? 0 : data.evidence_sources_omitted,
1077
+ evidenceScope: failed ? void 0 : data.evidence_scope,
1065
1078
  billingMetadata: data.billing_metadata,
1066
1079
  resultReturnedFrom: data.result_returned_from,
1067
1080
  cacheHit: data.cache_hit,
@@ -1324,11 +1337,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1324
1337
  const results = new Array(total);
1325
1338
  for (const item of round) {
1326
1339
  if (!item.success || !item.raw) {
1327
- results[item.index] = batchItemFailure(
1340
+ const failure = batchItemFailure(
1328
1341
  item.index,
1329
1342
  item.error || "Signaliz batch item failed",
1330
1343
  item.raw ?? item
1331
1344
  );
1345
+ if (item.raw?.is_malformed === true) {
1346
+ failure.data = normalize(item);
1347
+ }
1348
+ results[item.index] = failure;
1332
1349
  continue;
1333
1350
  }
1334
1351
  try {
@@ -1401,21 +1418,25 @@ function validateCoreProductMaxWaitMs(value) {
1401
1418
  }
1402
1419
  }
1403
1420
  function normalizeSignalToCopyResult(data) {
1421
+ const failed = coreProductResponseFailed(data);
1404
1422
  return {
1405
- success: data.success ?? true,
1423
+ success: !failed,
1424
+ error: failed ? coreProductErrorMessage(data) : void 0,
1425
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1406
1426
  status: data.status,
1407
- runId: data.signal_run_id ?? data.run_id,
1427
+ runId: data.run_id ?? data.signal_run_id,
1428
+ companySignalRunId: data.company_signal_run_id,
1408
1429
  resumeContextPersisted: data.resume_context_persisted,
1409
- strongestSignal: data.strongest_signal ?? "",
1410
- whyNow: data.why_now ?? "",
1411
- subjectLine: data.subject_line ?? "",
1412
- openingLine: data.opening_line ?? "",
1413
- confidence: data.confidence ?? 0,
1414
- evidenceUrl: data.evidence_url ?? "",
1430
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1431
+ whyNow: failed ? "" : data.why_now ?? "",
1432
+ subjectLine: failed ? "" : data.subject_line ?? "",
1433
+ openingLine: failed ? "" : data.opening_line ?? "",
1434
+ confidence: failed ? 0 : data.confidence ?? 0,
1435
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1415
1436
  researchPrompt: data.research_prompt,
1416
1437
  empty: data.empty,
1417
1438
  emptyReason: data.empty_reason,
1418
- researchMetadata: data.research_metadata,
1439
+ researchMetadata: failed ? void 0 : data.research_metadata,
1419
1440
  billingMetadata: data.billing_metadata,
1420
1441
  resultReturnedFrom: data.result_returned_from,
1421
1442
  cacheHit: data.cache_hit,
@@ -1424,7 +1445,7 @@ function normalizeSignalToCopyResult(data) {
1424
1445
  liveProviderCalled: data.live_provider_called,
1425
1446
  aiProviderCalled: data.ai_provider_called,
1426
1447
  byoAiUsed: data.byo_ai_used,
1427
- variations: (data.variations ?? []).map((variation) => ({
1448
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1428
1449
  style: variation.style,
1429
1450
  subjectLine: variation.subject_line ?? "",
1430
1451
  openingLine: variation.opening_line ?? "",
@@ -1436,8 +1457,56 @@ function normalizeSignalToCopyResult(data) {
1436
1457
  };
1437
1458
  }
1438
1459
  function isPendingSignalResponse(data) {
1460
+ if (coreProductResponseFailed(data)) return false;
1439
1461
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1440
1462
  }
1463
+ function coreProductResponseFailed(data) {
1464
+ if (data.success === false || data.ok === false) return true;
1465
+ if (hasCoreProductFailureValue(data.error_code) || hasCoreProductFailureValue(data.errorCode)) return true;
1466
+ if (hasCoreProductFailureValue(data.error) || hasCoreProductFailureValue(data.error_message) || hasCoreProductFailureValue(data.errorMessage)) return true;
1467
+ if (Array.isArray(data.errors) && data.errors.length > 0) return true;
1468
+ return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out", "system_failure"].includes(String(data.status || "").toLowerCase());
1469
+ }
1470
+ function hasCoreProductFailureValue(value) {
1471
+ if (typeof value === "string") return value.trim().length > 0;
1472
+ if (Array.isArray(value)) return value.length > 0;
1473
+ if (value && typeof value === "object") return Object.keys(value).length > 0;
1474
+ return value === true || typeof value === "number" && value !== 0;
1475
+ }
1476
+ function coreProductErrorMessage(data) {
1477
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1478
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1479
+ const candidates = [
1480
+ nested?.message,
1481
+ firstError?.message,
1482
+ data.error_message,
1483
+ data.errorMessage,
1484
+ data.message,
1485
+ typeof data.error === "string" ? data.error : void 0
1486
+ ];
1487
+ for (const candidate of candidates) {
1488
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1489
+ }
1490
+ return void 0;
1491
+ }
1492
+ function coreProductErrorCode(data) {
1493
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1494
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1495
+ const details = firstError?.details && typeof firstError.details === "object" ? firstError.details : void 0;
1496
+ const candidates = [
1497
+ data.error_code,
1498
+ data.errorCode,
1499
+ nested?.code,
1500
+ details?.error_code,
1501
+ details?.legacy_error_code,
1502
+ firstError?.code,
1503
+ data.code
1504
+ ];
1505
+ for (const candidate of candidates) {
1506
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1507
+ }
1508
+ return void 0;
1509
+ }
1441
1510
  function assertTerminalSignalResponse(data, capability) {
1442
1511
  if (isPendingSignalResponse(data) || data.job_id) {
1443
1512
  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?: string;
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?: string;
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
@@ -719,7 +719,7 @@ var Signaliz = class {
719
719
  }
720
720
  for (let index = 0; index < requests.length; index += 1) {
721
721
  const item = data.results[index];
722
- if (item.success === false) {
722
+ if (coreProductResponseFailed(item)) {
723
723
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
724
724
  index,
725
725
  success: false,
@@ -728,7 +728,11 @@ var Signaliz = class {
728
728
  rateLimited.push({ index, params: requests[index], raw: item });
729
729
  continue;
730
730
  }
731
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
731
+ results[index] = batchItemFailure(
732
+ index,
733
+ coreProductErrorMessage(item) || "Signal to Copy failed",
734
+ item
735
+ );
732
736
  continue;
733
737
  }
734
738
  try {
@@ -829,9 +833,9 @@ var Signaliz = class {
829
833
  const raw = chunkResult.data[index];
830
834
  uniqueResults[chunk.offset + index] = {
831
835
  index: chunk.tasks[index].index,
832
- success: raw.success !== false,
836
+ success: !coreProductResponseFailed(raw),
833
837
  raw,
834
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
838
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path} item failed` : void 0
835
839
  };
836
840
  }
837
841
  }
@@ -901,7 +905,7 @@ function batchItemFailure(index, error, raw) {
901
905
  };
902
906
  }
903
907
  function recoverableJobRowFailed(row) {
904
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
908
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
905
909
  }
906
910
  function newBatchIdempotencyKey(label) {
907
911
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -951,7 +955,9 @@ function normalizeCoreProductDryRunResult(data) {
951
955
  };
952
956
  }
953
957
  function normalizeFindEmailResult(data) {
954
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
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;
955
961
  const found = Boolean(email) && data.found !== false;
956
962
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
957
963
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -961,20 +967,20 @@ function normalizeFindEmailResult(data) {
961
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()));
962
968
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
963
969
  return {
964
- success: data.success !== false && found,
970
+ success: !failed && found,
965
971
  found,
966
972
  email,
967
973
  firstName: data.first_name,
968
974
  lastName: data.last_name,
969
- confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
970
- verificationStatus,
971
- isVerified: verified,
972
- isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
975
+ confidence: failed ? 0 : data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
976
+ verificationStatus: failed ? "error" : verificationStatus,
977
+ isVerified: !failed && verified,
978
+ isVerifiedForSending: !failed && !needsReverification && data.verified_for_sending === true,
973
979
  isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
974
980
  verificationFreshness,
975
981
  verificationAgeDays,
976
982
  verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
977
- needsReverification,
983
+ needsReverification: failed || needsReverification,
978
984
  providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
979
985
  creditsUsed: data.credits_used,
980
986
  estimatedExternalCostUsd: data.estimated_external_cost_usd,
@@ -988,28 +994,32 @@ function normalizeFindEmailResult(data) {
988
994
  liveProviderCalled: data.live_provider_called,
989
995
  openrouterCalled: data.openrouter_called,
990
996
  byoOpenrouterUsed: data.byo_openrouter_used,
991
- error: found ? void 0 : data.error ?? "No verified email found",
992
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
997
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
998
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
993
999
  raw: data
994
1000
  };
995
1001
  }
996
1002
  function normalizeVerifyEmailResult(email, data) {
1003
+ const failed = coreProductResponseFailed(data);
997
1004
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
998
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
1005
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
1006
+ const malformed = data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed";
999
1007
  return {
1000
- success: data.success !== false,
1008
+ success: !failed,
1009
+ error: failed ? coreProductErrorMessage(data) : void 0,
1010
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1001
1011
  email: data.email ?? email,
1002
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1012
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1003
1013
  verificationRunId: data.verification_run_id ?? data.run_id,
1004
1014
  retryAfterMs: data.retry_after_ms,
1005
1015
  nextPollAfterSeconds: data.next_poll_after_seconds,
1006
- isValid: data.is_valid ?? data.valid ?? verified,
1007
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
1008
- isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
1016
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
1017
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
1018
+ isMalformed: malformed,
1009
1019
  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,
1011
- verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
1012
- confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1020
+ verifiedForSending: !failed && data.verified_for_sending === true,
1021
+ verificationVerdict: failed ? malformed ? "malformed" : "error" : data.verification_verdict ?? data.verification_status ?? "unknown",
1022
+ confidenceScore: failed ? 0 : data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1013
1023
  provider: data.provider,
1014
1024
  verificationSource: data.verification_source,
1015
1025
  billingReplayed: data.billing_replayed,
@@ -1052,9 +1062,12 @@ function companySignalRequestBody(params) {
1052
1062
  });
1053
1063
  }
1054
1064
  function normalizeCompanySignalResult(params, data) {
1055
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1065
+ const failed = coreProductResponseFailed(data);
1066
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1056
1067
  return {
1057
- success: data.success ?? true,
1068
+ success: !failed,
1069
+ error: failed ? coreProductErrorMessage(data) : void 0,
1070
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1058
1071
  status: data.status,
1059
1072
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1060
1073
  company: {
@@ -1079,16 +1092,16 @@ function normalizeCompanySignalResult(params, data) {
1079
1092
  classification: signal.signal_classification ?? null
1080
1093
  };
1081
1094
  }),
1082
- signalCount: data.signal_count ?? data.total_signals ?? rawSignals.length,
1083
- signalSummary: data.signal_summary ?? null,
1084
- intelligence: data.intelligence ?? null,
1085
- copyFuel: data.copy_fuel ?? null,
1086
- evidenceValidation: data.evidence_validation,
1087
- evidenceSources: data.metadata?.evidence_sources ?? data.evidence_sources,
1088
- evidenceCount: data.evidence_count,
1089
- evidenceCountTotal: data.evidence_count_total,
1090
- evidenceSourcesOmitted: data.evidence_sources_omitted,
1091
- evidenceScope: data.evidence_scope,
1095
+ signalCount: failed ? 0 : data.signal_count ?? data.total_signals ?? rawSignals.length,
1096
+ signalSummary: failed ? null : data.signal_summary ?? null,
1097
+ intelligence: failed ? null : data.intelligence ?? null,
1098
+ copyFuel: failed ? null : data.copy_fuel ?? null,
1099
+ evidenceValidation: failed ? void 0 : data.evidence_validation,
1100
+ evidenceSources: failed ? [] : data.metadata?.evidence_sources ?? data.evidence_sources,
1101
+ evidenceCount: failed ? 0 : data.evidence_count,
1102
+ evidenceCountTotal: failed ? 0 : data.evidence_count_total,
1103
+ evidenceSourcesOmitted: failed ? 0 : data.evidence_sources_omitted,
1104
+ evidenceScope: failed ? void 0 : data.evidence_scope,
1092
1105
  billingMetadata: data.billing_metadata,
1093
1106
  resultReturnedFrom: data.result_returned_from,
1094
1107
  cacheHit: data.cache_hit,
@@ -1351,11 +1364,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1351
1364
  const results = new Array(total);
1352
1365
  for (const item of round) {
1353
1366
  if (!item.success || !item.raw) {
1354
- results[item.index] = batchItemFailure(
1367
+ const failure = batchItemFailure(
1355
1368
  item.index,
1356
1369
  item.error || "Signaliz batch item failed",
1357
1370
  item.raw ?? item
1358
1371
  );
1372
+ if (item.raw?.is_malformed === true) {
1373
+ failure.data = normalize(item);
1374
+ }
1375
+ results[item.index] = failure;
1359
1376
  continue;
1360
1377
  }
1361
1378
  try {
@@ -1428,21 +1445,25 @@ function validateCoreProductMaxWaitMs(value) {
1428
1445
  }
1429
1446
  }
1430
1447
  function normalizeSignalToCopyResult(data) {
1448
+ const failed = coreProductResponseFailed(data);
1431
1449
  return {
1432
- success: data.success ?? true,
1450
+ success: !failed,
1451
+ error: failed ? coreProductErrorMessage(data) : void 0,
1452
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1433
1453
  status: data.status,
1434
- runId: data.signal_run_id ?? data.run_id,
1454
+ runId: data.run_id ?? data.signal_run_id,
1455
+ companySignalRunId: data.company_signal_run_id,
1435
1456
  resumeContextPersisted: data.resume_context_persisted,
1436
- strongestSignal: data.strongest_signal ?? "",
1437
- whyNow: data.why_now ?? "",
1438
- subjectLine: data.subject_line ?? "",
1439
- openingLine: data.opening_line ?? "",
1440
- confidence: data.confidence ?? 0,
1441
- evidenceUrl: data.evidence_url ?? "",
1457
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1458
+ whyNow: failed ? "" : data.why_now ?? "",
1459
+ subjectLine: failed ? "" : data.subject_line ?? "",
1460
+ openingLine: failed ? "" : data.opening_line ?? "",
1461
+ confidence: failed ? 0 : data.confidence ?? 0,
1462
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1442
1463
  researchPrompt: data.research_prompt,
1443
1464
  empty: data.empty,
1444
1465
  emptyReason: data.empty_reason,
1445
- researchMetadata: data.research_metadata,
1466
+ researchMetadata: failed ? void 0 : data.research_metadata,
1446
1467
  billingMetadata: data.billing_metadata,
1447
1468
  resultReturnedFrom: data.result_returned_from,
1448
1469
  cacheHit: data.cache_hit,
@@ -1451,7 +1472,7 @@ function normalizeSignalToCopyResult(data) {
1451
1472
  liveProviderCalled: data.live_provider_called,
1452
1473
  aiProviderCalled: data.ai_provider_called,
1453
1474
  byoAiUsed: data.byo_ai_used,
1454
- variations: (data.variations ?? []).map((variation) => ({
1475
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1455
1476
  style: variation.style,
1456
1477
  subjectLine: variation.subject_line ?? "",
1457
1478
  openingLine: variation.opening_line ?? "",
@@ -1463,8 +1484,56 @@ function normalizeSignalToCopyResult(data) {
1463
1484
  };
1464
1485
  }
1465
1486
  function isPendingSignalResponse(data) {
1487
+ if (coreProductResponseFailed(data)) return false;
1466
1488
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1467
1489
  }
1490
+ function coreProductResponseFailed(data) {
1491
+ if (data.success === false || data.ok === false) return true;
1492
+ if (hasCoreProductFailureValue(data.error_code) || hasCoreProductFailureValue(data.errorCode)) return true;
1493
+ if (hasCoreProductFailureValue(data.error) || hasCoreProductFailureValue(data.error_message) || hasCoreProductFailureValue(data.errorMessage)) return true;
1494
+ if (Array.isArray(data.errors) && data.errors.length > 0) return true;
1495
+ return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out", "system_failure"].includes(String(data.status || "").toLowerCase());
1496
+ }
1497
+ function hasCoreProductFailureValue(value) {
1498
+ if (typeof value === "string") return value.trim().length > 0;
1499
+ if (Array.isArray(value)) return value.length > 0;
1500
+ if (value && typeof value === "object") return Object.keys(value).length > 0;
1501
+ return value === true || typeof value === "number" && value !== 0;
1502
+ }
1503
+ function coreProductErrorMessage(data) {
1504
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1505
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1506
+ const candidates = [
1507
+ nested?.message,
1508
+ firstError?.message,
1509
+ data.error_message,
1510
+ data.errorMessage,
1511
+ data.message,
1512
+ typeof data.error === "string" ? data.error : void 0
1513
+ ];
1514
+ for (const candidate of candidates) {
1515
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1516
+ }
1517
+ return void 0;
1518
+ }
1519
+ function coreProductErrorCode(data) {
1520
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1521
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1522
+ const details = firstError?.details && typeof firstError.details === "object" ? firstError.details : void 0;
1523
+ const candidates = [
1524
+ data.error_code,
1525
+ data.errorCode,
1526
+ nested?.code,
1527
+ details?.error_code,
1528
+ details?.legacy_error_code,
1529
+ firstError?.code,
1530
+ data.code
1531
+ ];
1532
+ for (const candidate of candidates) {
1533
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1534
+ }
1535
+ return void 0;
1536
+ }
1468
1537
  function assertTerminalSignalResponse(data, capability) {
1469
1538
  if (isPendingSignalResponse(data) || data.job_id) {
1470
1539
  throw new Error(`${capability} violated the synchronous response contract.`);
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-SZ3H5W5L.mjs";
4
+ } from "./chunk-VKBUQTDS.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError
@@ -723,7 +723,7 @@ var Signaliz = class {
723
723
  }
724
724
  for (let index = 0; index < requests.length; index += 1) {
725
725
  const item = data.results[index];
726
- if (item.success === false) {
726
+ if (coreProductResponseFailed(item)) {
727
727
  if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
728
728
  index,
729
729
  success: false,
@@ -732,7 +732,11 @@ var Signaliz = class {
732
732
  rateLimited.push({ index, params: requests[index], raw: item });
733
733
  continue;
734
734
  }
735
- results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
735
+ results[index] = batchItemFailure(
736
+ index,
737
+ coreProductErrorMessage(item) || "Signal to Copy failed",
738
+ item
739
+ );
736
740
  continue;
737
741
  }
738
742
  try {
@@ -833,9 +837,9 @@ var Signaliz = class {
833
837
  const raw = chunkResult.data[index];
834
838
  uniqueResults[chunk.offset + index] = {
835
839
  index: chunk.tasks[index].index,
836
- success: raw.success !== false,
840
+ success: !coreProductResponseFailed(raw),
837
841
  raw,
838
- error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path2} item failed` : void 0
842
+ error: coreProductResponseFailed(raw) ? coreProductErrorMessage(raw) || coreProductErrorCode(raw) || `${path2} item failed` : void 0
839
843
  };
840
844
  }
841
845
  }
@@ -905,7 +909,7 @@ function batchItemFailure(index, error, raw) {
905
909
  };
906
910
  }
907
911
  function recoverableJobRowFailed(row) {
908
- return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
912
+ return coreProductResponseFailed(row) || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
909
913
  }
910
914
  function newBatchIdempotencyKey(label) {
911
915
  const nonce = globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`;
@@ -955,7 +959,9 @@ function normalizeCoreProductDryRunResult(data) {
955
959
  };
956
960
  }
957
961
  function normalizeFindEmailResult(data) {
958
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
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;
959
965
  const found = Boolean(email) && data.found !== false;
960
966
  const verificationStatus = data.verification_status ?? (data.is_valid === true ? "valid" : data.status ?? "unknown");
961
967
  const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
@@ -965,20 +971,20 @@ function normalizeFindEmailResult(data) {
965
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()));
966
972
  const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
967
973
  return {
968
- success: data.success !== false && found,
974
+ success: !failed && found,
969
975
  found,
970
976
  email,
971
977
  firstName: data.first_name,
972
978
  lastName: data.last_name,
973
- confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
974
- verificationStatus,
975
- isVerified: verified,
976
- isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
979
+ confidence: failed ? 0 : data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
980
+ verificationStatus: failed ? "error" : verificationStatus,
981
+ isVerified: !failed && verified,
982
+ isVerifiedForSending: !failed && !needsReverification && data.verified_for_sending === true,
977
983
  isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
978
984
  verificationFreshness,
979
985
  verificationAgeDays,
980
986
  verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
981
- needsReverification,
987
+ needsReverification: failed || needsReverification,
982
988
  providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
983
989
  creditsUsed: data.credits_used,
984
990
  estimatedExternalCostUsd: data.estimated_external_cost_usd,
@@ -992,28 +998,32 @@ function normalizeFindEmailResult(data) {
992
998
  liveProviderCalled: data.live_provider_called,
993
999
  openrouterCalled: data.openrouter_called,
994
1000
  byoOpenrouterUsed: data.byo_openrouter_used,
995
- error: found ? void 0 : data.error ?? "No verified email found",
996
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
1001
+ error: found ? void 0 : coreProductErrorMessage(data) ?? "No verified email found",
1002
+ errorCode: found ? void 0 : coreProductErrorCode(data) ?? "EMAIL_NOT_FOUND",
997
1003
  raw: data
998
1004
  };
999
1005
  }
1000
1006
  function normalizeVerifyEmailResult(email, data) {
1007
+ const failed = coreProductResponseFailed(data);
1001
1008
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
1002
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
1009
+ const verified = !failed && (data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus));
1010
+ const malformed = data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed";
1003
1011
  return {
1004
- success: data.success !== false,
1012
+ success: !failed,
1013
+ error: failed ? coreProductErrorMessage(data) : void 0,
1014
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1005
1015
  email: data.email ?? email,
1006
- status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1016
+ status: !failed && String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1007
1017
  verificationRunId: data.verification_run_id ?? data.run_id,
1008
1018
  retryAfterMs: data.retry_after_ms,
1009
1019
  nextPollAfterSeconds: data.next_poll_after_seconds,
1010
- isValid: data.is_valid ?? data.valid ?? verified,
1011
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
1012
- isMalformed: data.is_malformed === true || data.verification_verdict === "malformed" || data.verification_status === "malformed" || data.deliverability_status === "malformed",
1020
+ isValid: failed ? false : data.is_valid ?? data.valid ?? verified,
1021
+ isDeliverable: failed ? false : data.is_deliverable ?? data.deliverable ?? verified,
1022
+ isMalformed: malformed,
1013
1023
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
1014
- verifiedForSending: data.verified_for_sending === true,
1015
- verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
1016
- confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1024
+ verifiedForSending: !failed && data.verified_for_sending === true,
1025
+ verificationVerdict: failed ? malformed ? "malformed" : "error" : data.verification_verdict ?? data.verification_status ?? "unknown",
1026
+ confidenceScore: failed ? 0 : data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1017
1027
  provider: data.provider,
1018
1028
  verificationSource: data.verification_source,
1019
1029
  billingReplayed: data.billing_replayed,
@@ -1056,9 +1066,12 @@ function companySignalRequestBody(params) {
1056
1066
  });
1057
1067
  }
1058
1068
  function normalizeCompanySignalResult(params, data) {
1059
- const rawSignals = data.signals ?? data.signal_feed ?? [];
1069
+ const failed = coreProductResponseFailed(data);
1070
+ const rawSignals = failed ? [] : data.signals ?? data.signal_feed ?? [];
1060
1071
  return {
1061
- success: data.success ?? true,
1072
+ success: !failed,
1073
+ error: failed ? coreProductErrorMessage(data) : void 0,
1074
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1062
1075
  status: data.status,
1063
1076
  signalRunId: data.signal_run_id ?? data.run_id ?? params.signalRunId,
1064
1077
  company: {
@@ -1083,16 +1096,16 @@ function normalizeCompanySignalResult(params, data) {
1083
1096
  classification: signal.signal_classification ?? null
1084
1097
  };
1085
1098
  }),
1086
- signalCount: data.signal_count ?? data.total_signals ?? rawSignals.length,
1087
- signalSummary: data.signal_summary ?? null,
1088
- intelligence: data.intelligence ?? null,
1089
- copyFuel: data.copy_fuel ?? null,
1090
- evidenceValidation: data.evidence_validation,
1091
- evidenceSources: data.metadata?.evidence_sources ?? data.evidence_sources,
1092
- evidenceCount: data.evidence_count,
1093
- evidenceCountTotal: data.evidence_count_total,
1094
- evidenceSourcesOmitted: data.evidence_sources_omitted,
1095
- evidenceScope: data.evidence_scope,
1099
+ signalCount: failed ? 0 : data.signal_count ?? data.total_signals ?? rawSignals.length,
1100
+ signalSummary: failed ? null : data.signal_summary ?? null,
1101
+ intelligence: failed ? null : data.intelligence ?? null,
1102
+ copyFuel: failed ? null : data.copy_fuel ?? null,
1103
+ evidenceValidation: failed ? void 0 : data.evidence_validation,
1104
+ evidenceSources: failed ? [] : data.metadata?.evidence_sources ?? data.evidence_sources,
1105
+ evidenceCount: failed ? 0 : data.evidence_count,
1106
+ evidenceCountTotal: failed ? 0 : data.evidence_count_total,
1107
+ evidenceSourcesOmitted: failed ? 0 : data.evidence_sources_omitted,
1108
+ evidenceScope: failed ? void 0 : data.evidence_scope,
1096
1109
  billingMetadata: data.billing_metadata,
1097
1110
  resultReturnedFrom: data.result_returned_from,
1098
1111
  cacheHit: data.cache_hit,
@@ -1355,11 +1368,15 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1355
1368
  const results = new Array(total);
1356
1369
  for (const item of round) {
1357
1370
  if (!item.success || !item.raw) {
1358
- results[item.index] = batchItemFailure(
1371
+ const failure = batchItemFailure(
1359
1372
  item.index,
1360
1373
  item.error || "Signaliz batch item failed",
1361
1374
  item.raw ?? item
1362
1375
  );
1376
+ if (item.raw?.is_malformed === true) {
1377
+ failure.data = normalize(item);
1378
+ }
1379
+ results[item.index] = failure;
1363
1380
  continue;
1364
1381
  }
1365
1382
  try {
@@ -1432,21 +1449,25 @@ function validateCoreProductMaxWaitMs(value) {
1432
1449
  }
1433
1450
  }
1434
1451
  function normalizeSignalToCopyResult(data) {
1452
+ const failed = coreProductResponseFailed(data);
1435
1453
  return {
1436
- success: data.success ?? true,
1454
+ success: !failed,
1455
+ error: failed ? coreProductErrorMessage(data) : void 0,
1456
+ errorCode: failed ? coreProductErrorCode(data) : void 0,
1437
1457
  status: data.status,
1438
- runId: data.signal_run_id ?? data.run_id,
1458
+ runId: data.run_id ?? data.signal_run_id,
1459
+ companySignalRunId: data.company_signal_run_id,
1439
1460
  resumeContextPersisted: data.resume_context_persisted,
1440
- strongestSignal: data.strongest_signal ?? "",
1441
- whyNow: data.why_now ?? "",
1442
- subjectLine: data.subject_line ?? "",
1443
- openingLine: data.opening_line ?? "",
1444
- confidence: data.confidence ?? 0,
1445
- evidenceUrl: data.evidence_url ?? "",
1461
+ strongestSignal: failed ? "" : data.strongest_signal ?? "",
1462
+ whyNow: failed ? "" : data.why_now ?? "",
1463
+ subjectLine: failed ? "" : data.subject_line ?? "",
1464
+ openingLine: failed ? "" : data.opening_line ?? "",
1465
+ confidence: failed ? 0 : data.confidence ?? 0,
1466
+ evidenceUrl: failed ? "" : data.evidence_url ?? "",
1446
1467
  researchPrompt: data.research_prompt,
1447
1468
  empty: data.empty,
1448
1469
  emptyReason: data.empty_reason,
1449
- researchMetadata: data.research_metadata,
1470
+ researchMetadata: failed ? void 0 : data.research_metadata,
1450
1471
  billingMetadata: data.billing_metadata,
1451
1472
  resultReturnedFrom: data.result_returned_from,
1452
1473
  cacheHit: data.cache_hit,
@@ -1455,7 +1476,7 @@ function normalizeSignalToCopyResult(data) {
1455
1476
  liveProviderCalled: data.live_provider_called,
1456
1477
  aiProviderCalled: data.ai_provider_called,
1457
1478
  byoAiUsed: data.byo_ai_used,
1458
- variations: (data.variations ?? []).map((variation) => ({
1479
+ variations: (failed ? [] : data.variations ?? []).map((variation) => ({
1459
1480
  style: variation.style,
1460
1481
  subjectLine: variation.subject_line ?? "",
1461
1482
  openingLine: variation.opening_line ?? "",
@@ -1467,8 +1488,56 @@ function normalizeSignalToCopyResult(data) {
1467
1488
  };
1468
1489
  }
1469
1490
  function isPendingSignalResponse(data) {
1491
+ if (coreProductResponseFailed(data)) return false;
1470
1492
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1471
1493
  }
1494
+ function coreProductResponseFailed(data) {
1495
+ if (data.success === false || data.ok === false) return true;
1496
+ if (hasCoreProductFailureValue(data.error_code) || hasCoreProductFailureValue(data.errorCode)) return true;
1497
+ if (hasCoreProductFailureValue(data.error) || hasCoreProductFailureValue(data.error_message) || hasCoreProductFailureValue(data.errorMessage)) return true;
1498
+ if (Array.isArray(data.errors) && data.errors.length > 0) return true;
1499
+ return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out", "system_failure"].includes(String(data.status || "").toLowerCase());
1500
+ }
1501
+ function hasCoreProductFailureValue(value) {
1502
+ if (typeof value === "string") return value.trim().length > 0;
1503
+ if (Array.isArray(value)) return value.length > 0;
1504
+ if (value && typeof value === "object") return Object.keys(value).length > 0;
1505
+ return value === true || typeof value === "number" && value !== 0;
1506
+ }
1507
+ function coreProductErrorMessage(data) {
1508
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1509
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1510
+ const candidates = [
1511
+ nested?.message,
1512
+ firstError?.message,
1513
+ data.error_message,
1514
+ data.errorMessage,
1515
+ data.message,
1516
+ typeof data.error === "string" ? data.error : void 0
1517
+ ];
1518
+ for (const candidate of candidates) {
1519
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1520
+ }
1521
+ return void 0;
1522
+ }
1523
+ function coreProductErrorCode(data) {
1524
+ const nested = data.error && typeof data.error === "object" ? data.error : void 0;
1525
+ const firstError = Array.isArray(data.errors) ? data.errors[0] : void 0;
1526
+ const details = firstError?.details && typeof firstError.details === "object" ? firstError.details : void 0;
1527
+ const candidates = [
1528
+ data.error_code,
1529
+ data.errorCode,
1530
+ nested?.code,
1531
+ details?.error_code,
1532
+ details?.legacy_error_code,
1533
+ firstError?.code,
1534
+ data.code
1535
+ ];
1536
+ for (const candidate of candidates) {
1537
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
1538
+ }
1539
+ return void 0;
1540
+ }
1472
1541
  function assertTerminalSignalResponse(data, capability) {
1473
1542
  if (isPendingSignalResponse(data) || data.job_id) {
1474
1543
  throw new Error(`${capability} violated the synchronous response contract.`);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Signaliz
4
- } from "./chunk-SZ3H5W5L.mjs";
4
+ } from "./chunk-VKBUQTDS.mjs";
5
5
 
6
6
  // src/mcp-config.ts
7
7
  import * as fs from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaliz/sdk",
3
- "version": "1.0.57",
3
+ "version": "1.0.59",
4
4
  "description": "Signaliz SDK for Signals Everything, Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",