@signaliz/sdk 1.0.47 → 1.0.49

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/dist/index.d.ts CHANGED
@@ -92,11 +92,21 @@ interface FindEmailResult {
92
92
  verifiedAt: string | null;
93
93
  needsReverification: boolean;
94
94
  providerUsed: string;
95
+ creditsUsed?: number;
96
+ estimatedExternalCostUsd?: number;
97
+ billingMetadata?: Record<string, unknown>;
98
+ resultReturnedFrom?: string;
99
+ cacheHit?: boolean;
100
+ freshEnrichmentUsed?: boolean;
101
+ liveProviderCalled?: boolean;
102
+ openrouterCalled?: boolean;
103
+ byoOpenrouterUsed?: boolean;
95
104
  error?: string;
96
105
  errorCode?: string;
97
106
  raw: Record<string, unknown>;
98
107
  }
99
108
  interface VerifyEmailResult {
109
+ success: boolean;
100
110
  email: string;
101
111
  /** Execution state. Processing results are never send-safe. */
102
112
  status: 'processing' | 'completed';
@@ -107,9 +117,21 @@ interface VerifyEmailResult {
107
117
  isValid: boolean;
108
118
  isDeliverable: boolean;
109
119
  isCatchAll: boolean;
120
+ /** Explicit send-safety verdict. Missing or false never becomes true by inference. */
121
+ verifiedForSending: boolean;
122
+ verificationVerdict: string;
110
123
  confidenceScore: number;
111
124
  provider?: string;
112
125
  verificationSource?: string;
126
+ billingReplayed?: boolean;
127
+ creditsUsed?: number;
128
+ billingMetadata?: Record<string, unknown>;
129
+ resultReturnedFrom?: string;
130
+ cacheHit?: boolean;
131
+ freshEnrichmentUsed?: boolean;
132
+ liveProviderCalled?: boolean;
133
+ openrouterCalled?: boolean;
134
+ byoOpenrouterUsed?: boolean;
113
135
  raw: Record<string, unknown>;
114
136
  }
115
137
  interface VerifyEmailOptions {
@@ -141,15 +163,17 @@ interface CompanySignalEnrichmentParams {
141
163
  lookbackDays?: number;
142
164
  online?: boolean;
143
165
  enableDeepSearch?: boolean;
166
+ /** Web coverage policy. Balanced targets an average all-in search budget below one cent. */
167
+ searchMode?: 'fast' | 'balanced' | 'coverage';
144
168
  includeSummary?: boolean;
145
169
  enableOutreachIntelligence?: boolean;
146
170
  enablePredictiveIntelligence?: boolean;
147
171
  skipCache?: boolean;
148
- /** Wait for a queued Trigger.dev enrichment to finish. Defaults to true. */
172
+ /** @deprecated Company Signals is always synchronous; this option is ignored. */
149
173
  waitForResult?: boolean;
150
- /** Maximum time to wait for a queued enrichment. Defaults to 20 minutes. */
174
+ /** Maximum server-side synchronous execution window. */
151
175
  maxWaitMs?: number;
152
- /** Delay between queued-enrichment status checks. Defaults to 2 seconds. */
176
+ /** @deprecated Company Signals never returns a polling contract. */
153
177
  pollIntervalMs?: number;
154
178
  /** Return a no-spend plan without provider calls or jobs. */
155
179
  dryRun?: boolean;
@@ -162,7 +186,9 @@ interface CompanySignal {
162
186
  type: string;
163
187
  content: string;
164
188
  date?: string | null;
189
+ detectedAt?: string | null;
165
190
  datePrecision?: string;
191
+ hasSpecificDate?: boolean;
166
192
  sourceUrl?: string | null;
167
193
  sourceType?: string;
168
194
  sourceProvenance?: string;
@@ -199,7 +225,10 @@ interface CompanySignalEnrichmentResult {
199
225
  billingMetadata?: Record<string, unknown>;
200
226
  resultReturnedFrom?: string;
201
227
  cacheHit?: boolean;
228
+ freshEnrichmentUsed?: boolean;
202
229
  liveProviderCalled?: boolean;
230
+ aiProviderCalled?: boolean;
231
+ byoAiUsed?: boolean;
203
232
  metadata?: Record<string, unknown>;
204
233
  raw: Record<string, unknown>;
205
234
  }
@@ -214,8 +243,10 @@ interface SignalToCopyParams {
214
243
  skipCache?: boolean;
215
244
  /** Opt into slower deep research. Defaults to false. */
216
245
  enableDeepSearch?: boolean;
246
+ /** @deprecated Signal to Copy is always synchronous; this option is ignored. */
217
247
  waitForResult?: boolean;
218
248
  maxWaitMs?: number;
249
+ /** @deprecated Signal to Copy never returns a polling contract. */
219
250
  pollIntervalMs?: number;
220
251
  /** Return a no-spend plan without provider calls or jobs. */
221
252
  dryRun?: boolean;
@@ -306,7 +337,6 @@ declare class Signaliz {
306
337
  createSignalCopyBatch(requests: SignalToCopyParams[], options?: BatchOptions): Promise<BatchResult<SignalToCopyResult>>;
307
338
  private runCoreProductDryRun;
308
339
  private runSignalCopyBatchChunks;
309
- private runAvailableSignalCopyBatchJob;
310
340
  private runRecoverableCoreBatchJob;
311
341
  private runSignalCopyBatchChunk;
312
342
  private runCoreBatchRound;
package/dist/index.js CHANGED
@@ -484,39 +484,16 @@ var Signaliz = class {
484
484
  );
485
485
  }
486
486
  async enrichCompanySignals(params) {
487
+ validateCoreProductMaxWaitMs(params.maxWaitMs);
487
488
  const request = companySignalRequestBody(params);
488
- let data = await this.client.post("api/v1/company-signals", request);
489
+ const data = await this.client.post("api/v1/company-signals", request);
489
490
  if (isCoreProductDryRun(data)) return normalizeCoreProductDryRunResult(data);
490
- if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
491
- const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
492
- const startedAt = Date.now();
493
- while (Date.now() - startedAt < maxWaitMs) {
494
- if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
495
- const status = await this.client.post("api/v1/company-signals", {
496
- ...request,
497
- signal_run_id: data.run_id
498
- });
499
- if (isCompletedSignalRun(status)) {
500
- data = status.output ?? status.result ?? status.data ?? status;
501
- break;
502
- }
503
- if (isFailedSignalRun(status)) {
504
- throw new Error(`Company signal enrichment ${data.run_id} failed with status ${status.status || "unknown"}`);
505
- }
506
- if (!isPendingSignalResponse(status)) {
507
- data = status.output ?? status.result ?? status.data ?? status;
508
- break;
509
- }
510
- data = status;
511
- }
512
- if (isPendingSignalResponse(data)) {
513
- throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
514
- }
515
- }
491
+ assertTerminalSignalResponse(data, "Company Signals");
516
492
  return normalizeCompanySignalResult(params, data);
517
493
  }
518
494
  async enrichCompanies(companies, options) {
519
495
  validateBatchSize(companies);
496
+ companies.forEach((params) => validateCoreProductMaxWaitMs(params.maxWaitMs));
520
497
  if (options?.dryRun === true) {
521
498
  return this.runCoreProductDryRun(
522
499
  "api/v1/company-signals",
@@ -525,68 +502,22 @@ var Signaliz = class {
525
502
  );
526
503
  }
527
504
  const startedAt = Date.now();
528
- const results = new Array(companies.length);
529
505
  const initialTasks = companies.map((params, index) => ({
530
506
  index,
531
507
  request: companySignalRequestBody(params)
532
508
  }));
533
- const recoverableBatch = companySignalRecoverableBatchOptions(companies, initialTasks);
534
- let pending = initialTasks;
535
- let firstRound = true;
536
- while (pending.length > 0) {
537
- const round = await this.runCoreBatchRound(
538
- "api/v1/company-signals",
539
- pending,
540
- options,
541
- firstRound ? recoverableBatch : void 0
542
- );
543
- firstRound = false;
544
- const taskByIndex = new Map(pending.map((task) => [task.index, task]));
545
- const nextPending = [];
546
- let nextDelayMs = 6e4;
547
- for (const item of round) {
548
- const params = companies[item.index];
549
- const task = taskByIndex.get(item.index);
550
- if (!item.success || !item.raw) {
551
- results[item.index] = batchItemFailure(
552
- item.index,
553
- item.error || "Company Signal batch request failed",
554
- item.raw ?? item
555
- );
556
- continue;
557
- }
558
- if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
559
- results[item.index] = { index: item.index, success: true, data: normalizeCompanySignalResult(params, item.raw) };
560
- continue;
561
- }
562
- const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
563
- if (Date.now() - startedAt >= maxWaitMs) {
564
- results[item.index] = {
565
- index: item.index,
566
- success: false,
567
- error: `Company signal enrichment ${item.raw.signal_run_id || item.raw.run_id || ""} did not complete within ${maxWaitMs}ms`
568
- };
569
- continue;
570
- }
571
- const signalRunId = item.raw.signal_run_id || item.raw.run_id;
572
- if (!signalRunId) {
573
- results[item.index] = { index: item.index, success: false, error: "Company signal enrichment is processing without a signal_run_id" };
574
- continue;
575
- }
576
- nextDelayMs = Math.min(
577
- nextDelayMs,
578
- signalPollDelayMs(item.raw, params.pollIntervalMs),
579
- maxWaitMs - (Date.now() - startedAt)
580
- );
581
- nextPending.push({
582
- ...task,
583
- request: { ...task.request, signal_run_id: signalRunId }
584
- });
509
+ const round = await this.runCoreBatchRound("api/v1/company-signals", initialTasks, options);
510
+ const results = round.map((item) => {
511
+ if (!item.success || !item.raw) {
512
+ return batchItemFailure(item.index, item.error || "Company Signal batch request failed", item.raw ?? item);
585
513
  }
586
- if (nextPending.length === 0) break;
587
- await sleep2(Math.max(1, nextDelayMs));
588
- pending = nextPending;
589
- }
514
+ try {
515
+ assertTerminalSignalResponse(item.raw, "Company Signals");
516
+ return { index: item.index, success: true, data: normalizeCompanySignalResult(companies[item.index], item.raw) };
517
+ } catch (error) {
518
+ return batchItemFailure(item.index, error instanceof Error ? error.message : String(error), item.raw);
519
+ }
520
+ });
590
521
  const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
591
522
  const succeeded = compactedResults.filter((item) => item.success).length;
592
523
  return {
@@ -600,21 +531,9 @@ var Signaliz = class {
600
531
  async signalToCopy(params) {
601
532
  validateSignalToCopyParams(params);
602
533
  const request = signalToCopyRequestBody(params);
603
- let data = await this.client.post("api/v1/signal-to-copy", request);
534
+ const data = await this.client.post("api/v1/signal-to-copy", request);
604
535
  if (isCoreProductDryRun(data)) return normalizeCoreProductDryRunResult(data);
605
- if (params.waitForResult !== false && (data.signal_run_id || data.run_id) && isPendingSignalResponse(data)) {
606
- const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
607
- const startedAt = Date.now();
608
- while (Date.now() - startedAt < maxWaitMs) {
609
- if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
610
- const signalRunId = data.signal_run_id || data.run_id;
611
- data = await this.client.post("api/v1/signal-to-copy", data.resume_context_persisted === true ? { signal_run_id: signalRunId } : { ...request, signal_run_id: signalRunId });
612
- if (!isPendingSignalResponse(data)) break;
613
- }
614
- if (isPendingSignalResponse(data)) {
615
- throw new Error(`Signal Copy ${data.run_id} did not complete within ${maxWaitMs}ms`);
616
- }
617
- }
536
+ assertTerminalSignalResponse(data, "Signal to Copy");
618
537
  return normalizeSignalToCopyResult(data);
619
538
  }
620
539
  async createSignalCopyBatch(requests, options) {
@@ -629,16 +548,10 @@ var Signaliz = class {
629
548
  }
630
549
  const startedAt = Date.now();
631
550
  const deduplicated = dedupeExactBatchItems(requests, (params) => JSON.stringify({
632
- request: signalToCopyRequestBody(params),
633
- wait_for_result: params.waitForResult,
634
- max_wait_ms: params.maxWaitMs,
635
- poll_interval_ms: params.pollIntervalMs
551
+ request: signalToCopyRequestBody(params)
636
552
  }));
637
553
  const uniqueRequests = deduplicated.uniqueItems;
638
- const canUseRecoverableAvailableDataJob = uniqueRequests.length > 25 && uniqueRequests.every(
639
- (params) => (!params.signalRunId || !params.signalRunId.startsWith("copy_") && [params.companyDomain, params.personName, params.title, params.campaignOffer].every((value) => typeof value === "string" && Boolean(value.trim()))) && params.waitForResult !== false && params.skipCache !== true && params.enableDeepSearch !== true && params.maxWaitMs === void 0 && params.pollIntervalMs === void 0
640
- );
641
- const uniqueResults = canUseRecoverableAvailableDataJob ? await this.runAvailableSignalCopyBatchJob(uniqueRequests, options) : await this.runSignalCopyBatchChunks(uniqueRequests, options);
554
+ const uniqueResults = await this.runSignalCopyBatchChunks(uniqueRequests, options);
642
555
  const results = requests.map((_, index) => ({
643
556
  ...uniqueResults[deduplicated.sourceIndexByInput[index]],
644
557
  index
@@ -694,22 +607,6 @@ var Signaliz = class {
694
607
  }
695
608
  return uniqueResults;
696
609
  }
697
- async runAvailableSignalCopyBatchJob(requests, options) {
698
- const rows = await this.runRecoverableCoreBatchJob(
699
- "api/v1/signal-to-copy",
700
- requests.map(signalToCopyRequestBody),
701
- "Signal to Copy",
702
- 500,
703
- 20 * 6e4,
704
- options?.idempotencyKey
705
- );
706
- const results = new Array(requests.length);
707
- for (const row of rows) {
708
- const index = Number(row.index);
709
- results[index] = recoverableJobRowFailed(row) ? batchItemFailure(index, row.error || row.message || "Signal to Copy failed", row) : { index, success: true, data: normalizeSignalToCopyResult(row) };
710
- }
711
- return results;
712
- }
713
610
  async runRecoverableCoreBatchJob(path, requests, label, pageSize = 500, maxWaitMs = 20 * 6e4, idempotencyKey) {
714
611
  const startedAt = Date.now();
715
612
  const submissionIdempotencyKey = idempotencyKey?.trim() || newBatchIdempotencyKey(label);
@@ -781,77 +678,35 @@ var Signaliz = class {
781
678
  return rows;
782
679
  }
783
680
  async runSignalCopyBatchChunk(requests, concurrency, rowRateLimitAttempt = 0) {
784
- const startedAt = Date.now();
785
681
  const results = new Array(requests.length);
786
682
  const rateLimited = [];
787
- let pending = requests.map((params, index) => ({
788
- index,
789
- params,
790
- request: signalToCopyRequestBody(params)
791
- }));
792
- while (pending.length > 0) {
793
- const data = await this.client.post("api/v1/signal-to-copy", {
794
- requests: pending.map((item) => item.request),
795
- concurrency
796
- });
797
- if (!Array.isArray(data.results) || data.results.length !== pending.length) {
798
- throw new Error("Signal to Copy batch returned an invalid result count");
799
- }
800
- const nextPending = [];
801
- let nextDelayMs = 6e4;
802
- for (let index = 0; index < pending.length; index += 1) {
803
- const task = pending[index];
804
- const item = data.results[index];
805
- if (item.success === false) {
806
- if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
807
- index: task.index,
808
- success: false,
809
- raw: item
810
- })) {
811
- rateLimited.push({ index: task.index, params: task.params, raw: item });
812
- continue;
813
- }
814
- results[task.index] = batchItemFailure(
815
- task.index,
816
- item.error || item.message || "Signal to Copy failed",
817
- item
818
- );
819
- continue;
820
- }
821
- if (!isPendingSignalResponse(item)) {
822
- results[task.index] = { index: task.index, success: true, data: normalizeSignalToCopyResult(item) };
823
- continue;
824
- }
825
- if (task.params.waitForResult === false) {
826
- results[task.index] = { index: task.index, success: true, data: normalizeSignalToCopyResult(item) };
827
- continue;
828
- }
829
- const maxWaitMs = Math.max(1e3, task.params.maxWaitMs ?? 20 * 6e4);
830
- if (Date.now() - startedAt >= maxWaitMs) {
831
- results[task.index] = {
832
- index: task.index,
833
- success: false,
834
- error: `Signal Copy ${item.signal_run_id || item.run_id || ""} did not complete within ${maxWaitMs}ms`
835
- };
836
- continue;
837
- }
838
- const signalRunId = item.signal_run_id || item.run_id;
839
- if (!signalRunId) {
840
- results[task.index] = { index: task.index, success: false, error: "Signal Copy is processing without a signal_run_id" };
683
+ const data = await this.client.post("api/v1/signal-to-copy", {
684
+ requests: requests.map(signalToCopyRequestBody),
685
+ concurrency
686
+ });
687
+ if (!Array.isArray(data.results) || data.results.length !== requests.length) {
688
+ throw new Error("Signal to Copy batch returned an invalid result count");
689
+ }
690
+ for (let index = 0; index < requests.length; index += 1) {
691
+ const item = data.results[index];
692
+ if (item.success === false) {
693
+ if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
694
+ index,
695
+ success: false,
696
+ raw: item
697
+ })) {
698
+ rateLimited.push({ index, params: requests[index], raw: item });
841
699
  continue;
842
700
  }
843
- nextDelayMs = Math.min(
844
- nextDelayMs,
845
- signalPollDelayMs(item, task.params.pollIntervalMs),
846
- maxWaitMs - (Date.now() - startedAt)
847
- );
848
- nextPending.push({
849
- ...task,
850
- request: item.resume_context_persisted === true ? { signal_run_id: signalRunId } : { ...task.request, signal_run_id: signalRunId }
851
- });
701
+ results[index] = batchItemFailure(index, item.error || item.message || "Signal to Copy failed", item);
702
+ continue;
703
+ }
704
+ try {
705
+ assertTerminalSignalResponse(item, "Signal to Copy");
706
+ results[index] = { index, success: true, data: normalizeSignalToCopyResult(item) };
707
+ } catch (error) {
708
+ results[index] = batchItemFailure(index, error instanceof Error ? error.message : String(error), item);
852
709
  }
853
- pending = nextPending;
854
- if (pending.length > 0) await sleep2(nextDelayMs);
855
710
  }
856
711
  if (rateLimited.length > 0) {
857
712
  await sleep2(rowRateLimitDelayMs(rateLimited.map((item) => ({
@@ -870,12 +725,12 @@ var Signaliz = class {
870
725
  }
871
726
  return results;
872
727
  }
873
- async runCoreBatchRound(path, tasks, options, companyRecoverableBatch, rowRateLimitAttempt = 0) {
728
+ async runCoreBatchRound(path, tasks, options, rowRateLimitAttempt = 0) {
874
729
  const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
875
730
  const deduplicated = dedupeExactBatchItems(tasks, (task) => JSON.stringify(task.request));
876
731
  const uniqueTasks = deduplicated.uniqueItems;
877
- 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 } : companyRecoverableBatch;
878
- if (recoverableBatch && uniqueTasks.length > 25) {
732
+ 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;
733
+ if (path !== "api/v1/company-signals" && recoverableBatch && uniqueTasks.length > 25) {
879
734
  const rows = await this.runRecoverableCoreBatchJob(
880
735
  path,
881
736
  uniqueTasks.map((task) => task.request),
@@ -947,7 +802,6 @@ var Signaliz = class {
947
802
  path,
948
803
  retryTasks,
949
804
  options,
950
- void 0,
951
805
  rowRateLimitAttempt + 1
952
806
  );
953
807
  const retriedByIndex = new Map(retried.map((item) => [item.index, item]));
@@ -1076,6 +930,15 @@ function normalizeFindEmailResult(data) {
1076
930
  verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
1077
931
  needsReverification,
1078
932
  providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
933
+ creditsUsed: data.credits_used,
934
+ estimatedExternalCostUsd: data.estimated_external_cost_usd,
935
+ billingMetadata: data.billing_metadata,
936
+ resultReturnedFrom: data.result_returned_from,
937
+ cacheHit: data.cache_hit,
938
+ freshEnrichmentUsed: data.fresh_enrichment_used,
939
+ liveProviderCalled: data.live_provider_called,
940
+ openrouterCalled: data.openrouter_called,
941
+ byoOpenrouterUsed: data.byo_openrouter_used,
1079
942
  error: found ? void 0 : data.error ?? "No verified email found",
1080
943
  errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
1081
944
  raw: data
@@ -1085,6 +948,7 @@ function normalizeVerifyEmailResult(email, data) {
1085
948
  const verificationStatus = String(data.verification_status ?? "").toLowerCase();
1086
949
  const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
1087
950
  return {
951
+ success: data.success !== false,
1088
952
  email: data.email ?? email,
1089
953
  status: String(data.status || "").toLowerCase() === "processing" ? "processing" : "completed",
1090
954
  verificationRunId: data.verification_run_id ?? data.run_id,
@@ -1093,9 +957,20 @@ function normalizeVerifyEmailResult(email, data) {
1093
957
  isValid: data.is_valid ?? data.valid ?? verified,
1094
958
  isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
1095
959
  isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
960
+ verifiedForSending: data.verified_for_sending === true,
961
+ verificationVerdict: data.verification_verdict ?? data.verification_status ?? "unknown",
1096
962
  confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
1097
963
  provider: data.provider,
1098
964
  verificationSource: data.verification_source,
965
+ billingReplayed: data.billing_replayed,
966
+ creditsUsed: data.credits_used,
967
+ billingMetadata: data.billing_metadata,
968
+ resultReturnedFrom: data.result_returned_from,
969
+ cacheHit: data.cache_hit,
970
+ freshEnrichmentUsed: data.fresh_enrichment_used,
971
+ liveProviderCalled: data.live_provider_called,
972
+ openrouterCalled: data.openrouter_called,
973
+ byoOpenrouterUsed: data.byo_openrouter_used,
1099
974
  raw: data
1100
975
  };
1101
976
  }
@@ -1111,41 +986,17 @@ function companySignalRequestBody(params) {
1111
986
  lookback_days: params.lookbackDays,
1112
987
  online,
1113
988
  enable_deep_search: params.enableDeepSearch ?? online,
989
+ search_mode: params.searchMode ?? "balanced",
1114
990
  include_summary: params.includeSummary,
1115
991
  enable_outreach_intelligence: params.enableOutreachIntelligence,
1116
992
  enable_predictive_intelligence: params.enablePredictiveIntelligence,
1117
993
  skip_cache: params.skipCache,
1118
- // REST always returns a resumable run instead of holding the connection;
1119
- // waitForResult controls the SDK polling loop.
1120
- wait_for_result: false,
994
+ wait_for_result: true,
1121
995
  max_wait_ms: params.maxWaitMs,
1122
996
  dry_run: params.dryRun,
1123
997
  idempotency_key: params.idempotencyKey
1124
998
  });
1125
999
  }
1126
- function companySignalRecoverableBatchOptions(companies, tasks) {
1127
- if (companies.length <= 25 || companies.some((params) => params.waitForResult === false || Boolean(params.signalRunId))) {
1128
- return void 0;
1129
- }
1130
- const maxWaitMs = Math.max(1e3, companies[0].maxWaitMs ?? 20 * 6e4);
1131
- if (companies.some((params) => Math.max(1e3, params.maxWaitMs ?? 20 * 6e4) !== maxWaitMs)) {
1132
- return void 0;
1133
- }
1134
- const configKey = (request) => {
1135
- const {
1136
- company_domain: _companyDomain,
1137
- company_name: _companyName,
1138
- signal_run_id: _signalRunId,
1139
- wait_for_result: _waitForResult,
1140
- max_wait_ms: _maxWaitMs,
1141
- ...config
1142
- } = request;
1143
- return JSON.stringify(config);
1144
- };
1145
- const sharedConfig = configKey(tasks[0].request);
1146
- if (tasks.some((task) => configKey(task.request) !== sharedConfig)) return void 0;
1147
- return { label: "Company Signals", pageSize: 25, maxWaitMs };
1148
- }
1149
1000
  function normalizeCompanySignalResult(params, data) {
1150
1001
  const rawSignals = data.signals ?? data.signal_feed ?? [];
1151
1002
  return {
@@ -1163,8 +1014,10 @@ function normalizeCompanySignalResult(params, data) {
1163
1014
  title: signal.title ?? "",
1164
1015
  type: signal.type ?? signal.signal_type ?? "unknown",
1165
1016
  content: signal.content ?? signal.description ?? "",
1166
- date: signal.date ?? signal.detected_at ?? null,
1017
+ date: signal.date ?? null,
1018
+ detectedAt: signal.detected_at ?? null,
1167
1019
  datePrecision: signal.date_precision,
1020
+ hasSpecificDate: signal.has_specific_date ?? metadata?.has_specific_date,
1168
1021
  sourceUrl: signal.source_url ?? signal.url ?? null,
1169
1022
  sourceType: signal.source_type,
1170
1023
  sourceProvenance: signal.source_provenance,
@@ -1193,7 +1046,10 @@ function normalizeCompanySignalResult(params, data) {
1193
1046
  billingMetadata: data.billing_metadata,
1194
1047
  resultReturnedFrom: data.result_returned_from,
1195
1048
  cacheHit: data.cache_hit,
1049
+ freshEnrichmentUsed: data.fresh_enrichment_used,
1196
1050
  liveProviderCalled: data.live_provider_called,
1051
+ aiProviderCalled: data.ai_provider_called,
1052
+ byoAiUsed: data.byo_ai_used,
1197
1053
  metadata: data.metadata,
1198
1054
  raw: data
1199
1055
  };
@@ -1293,11 +1149,13 @@ function signalToCopyRequestBody(params) {
1293
1149
  signal_run_id: params.signalRunId,
1294
1150
  skip_cache: params.skipCache,
1295
1151
  enable_deep_search: params.enableDeepSearch,
1152
+ max_wait_ms: params.maxWaitMs,
1296
1153
  dry_run: params.dryRun,
1297
1154
  idempotency_key: params.idempotencyKey
1298
1155
  });
1299
1156
  }
1300
1157
  function validateSignalToCopyParams(params) {
1158
+ validateCoreProductMaxWaitMs(params.maxWaitMs);
1301
1159
  if (typeof params.signalRunId === "string" && params.signalRunId.trim()) return;
1302
1160
  const missing = [
1303
1161
  ["companyDomain", params.companyDomain],
@@ -1309,6 +1167,12 @@ function validateSignalToCopyParams(params) {
1309
1167
  throw new TypeError(`Signal to Copy requires signalRunId or: ${missing.join(", ")}`);
1310
1168
  }
1311
1169
  }
1170
+ function validateCoreProductMaxWaitMs(value) {
1171
+ if (value === void 0) return;
1172
+ if (!Number.isInteger(value) || value < 1e4 || value > 12e4) {
1173
+ throw new RangeError("maxWaitMs must be an integer between 10000 and 120000");
1174
+ }
1175
+ }
1312
1176
  function normalizeSignalToCopyResult(data) {
1313
1177
  return {
1314
1178
  success: data.success ?? true,
@@ -1339,11 +1203,10 @@ function normalizeSignalToCopyResult(data) {
1339
1203
  function isPendingSignalResponse(data) {
1340
1204
  return ["triggered", "queued", "processing", "pending", "pending_version", "waiting_for_deploy"].includes(String(data.status || "").toLowerCase());
1341
1205
  }
1342
- function isCompletedSignalRun(data) {
1343
- return ["completed", "success", "succeeded"].includes(String(data.status || "").toLowerCase());
1344
- }
1345
- function isFailedSignalRun(data) {
1346
- return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out"].includes(String(data.status || "").toLowerCase());
1206
+ function assertTerminalSignalResponse(data, capability) {
1207
+ if (isPendingSignalResponse(data) || data.job_id) {
1208
+ throw new Error(`${capability} violated the synchronous response contract.`);
1209
+ }
1347
1210
  }
1348
1211
  function signalPollDelayMs(data, override) {
1349
1212
  if (override !== void 0) return Math.max(250, override);
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-KTWDTUCI.mjs";
4
+ } from "./chunk-KA66GBVZ.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError