@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/README.md +15 -33
- package/dist/{chunk-KTWDTUCI.mjs → chunk-KA66GBVZ.mjs} +87 -224
- package/dist/index.d.mts +34 -4
- package/dist/index.d.ts +34 -4
- package/dist/index.js +87 -224
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +87 -224
- package/dist/mcp-config.mjs +1 -1
- package/package.json +1 -1
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
|
-
/**
|
|
172
|
+
/** @deprecated Company Signals is always synchronous; this option is ignored. */
|
|
149
173
|
waitForResult?: boolean;
|
|
150
|
-
/** Maximum
|
|
174
|
+
/** Maximum server-side synchronous execution window. */
|
|
151
175
|
maxWaitMs?: number;
|
|
152
|
-
/**
|
|
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
|
-
|
|
489
|
+
const data = await this.client.post("api/v1/company-signals", request);
|
|
489
490
|
if (isCoreProductDryRun(data)) return normalizeCoreProductDryRunResult(data);
|
|
490
|
-
|
|
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
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
-
|
|
534
|
+
const data = await this.client.post("api/v1/signal-to-copy", request);
|
|
604
535
|
if (isCoreProductDryRun(data)) return normalizeCoreProductDryRunResult(data);
|
|
605
|
-
|
|
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
|
|
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
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
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
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
);
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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,
|
|
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 } :
|
|
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
|
-
|
|
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 ??
|
|
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
|
|
1343
|
-
|
|
1344
|
-
}
|
|
1345
|
-
|
|
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);
|