@signaliz/sdk 1.0.29 → 1.0.31
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 +4 -2
- package/dist/{chunk-R4DIAP7P.mjs → chunk-P3ICLKAE.mjs} +345 -133
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +345 -133
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +345 -133
- package/dist/mcp-config.mjs +1 -1
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -77,8 +77,10 @@ resumes long-running research through the same `/company-signals` endpoint;
|
|
|
77
77
|
callers never need an internal Trigger.dev status URL. The SDK follows the
|
|
78
78
|
server's adaptive polling hints by default and still honors `pollIntervalMs`
|
|
79
79
|
when a caller explicitly overrides the cadence.
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
All four products are transported in 25-row REST chunks. Exact duplicate tasks
|
|
81
|
+
are single-flighted across the full batch before chunking, without changing
|
|
82
|
+
input order or result cardinality. Signal to Copy also shares company research
|
|
83
|
+
across copy recipients.
|
|
82
84
|
|
|
83
85
|
Company Signal Enrichment defaults `online` and `enableDeepSearch` to `true`
|
|
84
86
|
unless the caller explicitly disables them. Signal to Copy AI returns three
|
|
@@ -353,89 +353,51 @@ var Signaliz = class {
|
|
|
353
353
|
this.client = new HttpClient(config);
|
|
354
354
|
}
|
|
355
355
|
async findEmail(params) {
|
|
356
|
-
const data = await this.client.post("api/v1/find-email",
|
|
357
|
-
|
|
358
|
-
full_name: params.fullName,
|
|
359
|
-
first_name: params.firstName,
|
|
360
|
-
last_name: params.lastName,
|
|
361
|
-
linkedin_url: params.linkedinUrl,
|
|
362
|
-
company_name: params.companyName,
|
|
363
|
-
skip_cache: params.skipCache
|
|
364
|
-
}));
|
|
365
|
-
const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
366
|
-
const found = Boolean(email) && data.found !== false;
|
|
367
|
-
const verificationStatus = data.verification_status ?? data.status ?? "unknown";
|
|
368
|
-
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
369
|
-
const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
|
|
370
|
-
const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
|
|
371
|
-
const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
|
|
372
|
-
const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
373
|
-
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
374
|
-
return {
|
|
375
|
-
success: data.success !== false && found,
|
|
376
|
-
found,
|
|
377
|
-
email,
|
|
378
|
-
firstName: data.first_name,
|
|
379
|
-
lastName: data.last_name,
|
|
380
|
-
confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
|
|
381
|
-
verificationStatus,
|
|
382
|
-
isVerified: verified,
|
|
383
|
-
isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
|
|
384
|
-
isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
|
|
385
|
-
verificationFreshness,
|
|
386
|
-
verificationAgeDays,
|
|
387
|
-
verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
|
|
388
|
-
needsReverification,
|
|
389
|
-
providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
|
|
390
|
-
error: found ? void 0 : data.error ?? "No verified email found",
|
|
391
|
-
errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
|
|
392
|
-
raw: data
|
|
393
|
-
};
|
|
356
|
+
const data = await this.client.post("api/v1/find-email", findEmailRequestBody(params));
|
|
357
|
+
return normalizeFindEmailResult(data);
|
|
394
358
|
}
|
|
395
359
|
async findEmails(params, options) {
|
|
396
|
-
|
|
360
|
+
validateBatchSize(params);
|
|
361
|
+
const startedAt = Date.now();
|
|
362
|
+
const round = await this.runCoreBatchRound(
|
|
363
|
+
"api/v1/find-email",
|
|
364
|
+
params.map((item, index) => ({ index, request: findEmailRequestBody(item) })),
|
|
365
|
+
options
|
|
366
|
+
);
|
|
367
|
+
return finalizeCoreBatch(
|
|
368
|
+
params.length,
|
|
369
|
+
startedAt,
|
|
370
|
+
round,
|
|
371
|
+
(item) => normalizeFindEmailResult(item.raw)
|
|
372
|
+
);
|
|
397
373
|
}
|
|
398
374
|
async verifyEmail(email, options) {
|
|
399
375
|
const data = await this.client.post("api/v1/verify-email", {
|
|
400
376
|
email,
|
|
401
377
|
skip_cache: options?.skipCache
|
|
402
378
|
});
|
|
403
|
-
|
|
404
|
-
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
405
|
-
return {
|
|
406
|
-
email: data.email ?? email,
|
|
407
|
-
isValid: data.is_valid ?? data.valid ?? verified,
|
|
408
|
-
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
409
|
-
isCatchAll: data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
410
|
-
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
411
|
-
provider: data.provider,
|
|
412
|
-
verificationSource: data.verification_source,
|
|
413
|
-
raw: data
|
|
414
|
-
};
|
|
379
|
+
return normalizeVerifyEmailResult(email, data);
|
|
415
380
|
}
|
|
416
381
|
async verifyEmails(emails, options) {
|
|
417
|
-
|
|
382
|
+
validateBatchSize(emails);
|
|
383
|
+
const startedAt = Date.now();
|
|
384
|
+
const round = await this.runCoreBatchRound(
|
|
385
|
+
"api/v1/verify-email",
|
|
386
|
+
emails.map((email, index) => ({
|
|
387
|
+
index,
|
|
388
|
+
request: { email, skip_cache: options?.skipCache }
|
|
389
|
+
})),
|
|
390
|
+
options
|
|
391
|
+
);
|
|
392
|
+
return finalizeCoreBatch(
|
|
393
|
+
emails.length,
|
|
394
|
+
startedAt,
|
|
395
|
+
round,
|
|
396
|
+
(item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
|
|
397
|
+
);
|
|
418
398
|
}
|
|
419
399
|
async enrichCompanySignals(params) {
|
|
420
|
-
const
|
|
421
|
-
const request = compact({
|
|
422
|
-
signal_run_id: params.signalRunId,
|
|
423
|
-
company_domain: params.companyDomain,
|
|
424
|
-
company_name: params.companyName,
|
|
425
|
-
research_prompt: params.researchPrompt,
|
|
426
|
-
signal_types: params.signalTypes,
|
|
427
|
-
target_signal_count: params.targetSignalCount,
|
|
428
|
-
lookback_days: params.lookbackDays,
|
|
429
|
-
online,
|
|
430
|
-
enable_deep_search: params.enableDeepSearch ?? online,
|
|
431
|
-
enable_outreach_intelligence: params.enableOutreachIntelligence,
|
|
432
|
-
enable_predictive_intelligence: params.enablePredictiveIntelligence,
|
|
433
|
-
skip_cache: params.skipCache,
|
|
434
|
-
// REST always returns a resumable run instead of holding the connection;
|
|
435
|
-
// waitForResult controls this SDK's polling loop below.
|
|
436
|
-
wait_for_result: false,
|
|
437
|
-
max_wait_ms: params.maxWaitMs
|
|
438
|
-
});
|
|
400
|
+
const request = companySignalRequestBody(params);
|
|
439
401
|
let data = await this.client.post("api/v1/company-signals", request);
|
|
440
402
|
if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
|
|
441
403
|
const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
|
|
@@ -463,47 +425,68 @@ var Signaliz = class {
|
|
|
463
425
|
throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
|
|
464
426
|
}
|
|
465
427
|
}
|
|
466
|
-
return
|
|
467
|
-
success: data.success ?? true,
|
|
468
|
-
status: data.status,
|
|
469
|
-
signalRunId: data.signal_run_id ?? data.run_id,
|
|
470
|
-
company: {
|
|
471
|
-
name: data.company?.name ?? params.companyName ?? null,
|
|
472
|
-
domain: data.company?.domain ?? params.companyDomain ?? null
|
|
473
|
-
},
|
|
474
|
-
signals: (data.signals ?? []).map((signal) => {
|
|
475
|
-
const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
|
|
476
|
-
return {
|
|
477
|
-
id: signal.id,
|
|
478
|
-
title: signal.title ?? "",
|
|
479
|
-
type: signal.type ?? signal.signal_type ?? "unknown",
|
|
480
|
-
content: signal.content ?? signal.description ?? "",
|
|
481
|
-
date: signal.date ?? signal.detected_at ?? null,
|
|
482
|
-
datePrecision: signal.date_precision,
|
|
483
|
-
sourceUrl: signal.source_url ?? signal.url ?? null,
|
|
484
|
-
sourceType: signal.source_type,
|
|
485
|
-
sourceProvenance: signal.source_provenance,
|
|
486
|
-
confidence: signal.confidence ?? signal.confidence_score ?? null,
|
|
487
|
-
entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
|
|
488
|
-
signalFamily: signal.signal_family,
|
|
489
|
-
eventType: signal.signal_event_type,
|
|
490
|
-
eventLabel: signal.signal_event_label,
|
|
491
|
-
classification: signal.signal_classification ?? null,
|
|
492
|
-
derived: signal.derived === true,
|
|
493
|
-
evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
|
|
494
|
-
signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
|
|
495
|
-
metadata
|
|
496
|
-
};
|
|
497
|
-
}),
|
|
498
|
-
signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
|
|
499
|
-
intelligence: data.intelligence ?? null,
|
|
500
|
-
credits: data.credits,
|
|
501
|
-
metadata: data.metadata,
|
|
502
|
-
raw: data
|
|
503
|
-
};
|
|
428
|
+
return normalizeCompanySignalResult(params, data);
|
|
504
429
|
}
|
|
505
430
|
async enrichCompanies(companies, options) {
|
|
506
|
-
|
|
431
|
+
validateBatchSize(companies);
|
|
432
|
+
const startedAt = Date.now();
|
|
433
|
+
const results = new Array(companies.length);
|
|
434
|
+
let pending = companies.map((params, index) => ({
|
|
435
|
+
index,
|
|
436
|
+
request: companySignalRequestBody(params)
|
|
437
|
+
}));
|
|
438
|
+
while (pending.length > 0) {
|
|
439
|
+
const round = await this.runCoreBatchRound("api/v1/company-signals", pending, options);
|
|
440
|
+
const taskByIndex = new Map(pending.map((task) => [task.index, task]));
|
|
441
|
+
const nextPending = [];
|
|
442
|
+
let nextDelayMs = 6e4;
|
|
443
|
+
for (const item of round) {
|
|
444
|
+
const params = companies[item.index];
|
|
445
|
+
const task = taskByIndex.get(item.index);
|
|
446
|
+
if (!item.success || !item.raw) {
|
|
447
|
+
results[item.index] = { index: item.index, success: false, error: item.error || "Company Signal batch request failed" };
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
|
|
451
|
+
results[item.index] = { index: item.index, success: true, data: normalizeCompanySignalResult(params, item.raw) };
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
|
|
455
|
+
if (Date.now() - startedAt >= maxWaitMs) {
|
|
456
|
+
results[item.index] = {
|
|
457
|
+
index: item.index,
|
|
458
|
+
success: false,
|
|
459
|
+
error: `Company signal enrichment ${item.raw.signal_run_id || item.raw.run_id || ""} did not complete within ${maxWaitMs}ms`
|
|
460
|
+
};
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
const signalRunId = item.raw.signal_run_id || item.raw.run_id;
|
|
464
|
+
if (!signalRunId) {
|
|
465
|
+
results[item.index] = { index: item.index, success: false, error: "Company signal enrichment is processing without a signal_run_id" };
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
nextDelayMs = Math.min(
|
|
469
|
+
nextDelayMs,
|
|
470
|
+
signalPollDelayMs(item.raw, params.pollIntervalMs),
|
|
471
|
+
maxWaitMs - (Date.now() - startedAt)
|
|
472
|
+
);
|
|
473
|
+
nextPending.push({
|
|
474
|
+
...task,
|
|
475
|
+
request: { ...task.request, signal_run_id: signalRunId }
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (nextPending.length === 0) break;
|
|
479
|
+
await sleep2(Math.max(1, nextDelayMs));
|
|
480
|
+
pending = nextPending;
|
|
481
|
+
}
|
|
482
|
+
const succeeded = results.filter((item) => item.success).length;
|
|
483
|
+
return {
|
|
484
|
+
total: companies.length,
|
|
485
|
+
succeeded,
|
|
486
|
+
failed: companies.length - succeeded,
|
|
487
|
+
durationMs: Date.now() - startedAt,
|
|
488
|
+
results
|
|
489
|
+
};
|
|
507
490
|
}
|
|
508
491
|
async signalToCopy(params) {
|
|
509
492
|
const request = signalToCopyRequestBody(params);
|
|
@@ -526,29 +509,31 @@ var Signaliz = class {
|
|
|
526
509
|
return normalizeSignalToCopyResult(data);
|
|
527
510
|
}
|
|
528
511
|
async createSignalCopyBatch(requests, options) {
|
|
529
|
-
|
|
530
|
-
throw new Error("Signaliz batch requests require at least one item");
|
|
531
|
-
}
|
|
532
|
-
if (requests.length > 5e3) {
|
|
533
|
-
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${requests.length}`);
|
|
534
|
-
}
|
|
512
|
+
validateBatchSize(requests);
|
|
535
513
|
const startedAt = Date.now();
|
|
514
|
+
const deduplicated = dedupeExactBatchItems(requests, (params) => JSON.stringify({
|
|
515
|
+
request: signalToCopyRequestBody(params),
|
|
516
|
+
wait_for_result: params.waitForResult,
|
|
517
|
+
max_wait_ms: params.maxWaitMs,
|
|
518
|
+
poll_interval_ms: params.pollIntervalMs
|
|
519
|
+
}));
|
|
520
|
+
const uniqueRequests = deduplicated.uniqueItems;
|
|
536
521
|
const chunks = [];
|
|
537
|
-
for (let offset = 0; offset <
|
|
538
|
-
chunks.push({ offset, requests:
|
|
522
|
+
for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
|
|
523
|
+
chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
|
|
539
524
|
}
|
|
540
|
-
const serverConcurrency =
|
|
525
|
+
const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
|
|
541
526
|
const chunkBatch = await runBatch(
|
|
542
527
|
chunks,
|
|
543
528
|
(chunk) => this.runSignalCopyBatchChunk(chunk.requests, serverConcurrency),
|
|
544
|
-
|
|
529
|
+
{ concurrency: chunkConcurrency }
|
|
545
530
|
);
|
|
546
|
-
const
|
|
531
|
+
const uniqueResults = new Array(uniqueRequests.length);
|
|
547
532
|
for (const chunkResult of chunkBatch.results) {
|
|
548
533
|
const chunk = chunks[chunkResult.index];
|
|
549
534
|
if (!chunkResult.success || !chunkResult.data) {
|
|
550
535
|
for (let index = 0; index < chunk.requests.length; index += 1) {
|
|
551
|
-
|
|
536
|
+
uniqueResults[chunk.offset + index] = {
|
|
552
537
|
index: chunk.offset + index,
|
|
553
538
|
success: false,
|
|
554
539
|
error: chunkResult.error || "Signal to Copy batch request failed"
|
|
@@ -557,9 +542,13 @@ var Signaliz = class {
|
|
|
557
542
|
continue;
|
|
558
543
|
}
|
|
559
544
|
for (const item of chunkResult.data) {
|
|
560
|
-
|
|
545
|
+
uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
|
|
561
546
|
}
|
|
562
547
|
}
|
|
548
|
+
const results = requests.map((_, index) => ({
|
|
549
|
+
...uniqueResults[deduplicated.sourceIndexByInput[index]],
|
|
550
|
+
index
|
|
551
|
+
}));
|
|
563
552
|
const succeeded = results.filter((item) => item.success).length;
|
|
564
553
|
return {
|
|
565
554
|
total: requests.length,
|
|
@@ -631,6 +620,55 @@ var Signaliz = class {
|
|
|
631
620
|
}
|
|
632
621
|
return results;
|
|
633
622
|
}
|
|
623
|
+
async runCoreBatchRound(path, tasks, options) {
|
|
624
|
+
const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
|
|
625
|
+
const deduplicated = dedupeExactBatchItems(tasks, (task) => JSON.stringify(task.request));
|
|
626
|
+
const uniqueTasks = deduplicated.uniqueItems;
|
|
627
|
+
const chunks = [];
|
|
628
|
+
for (let offset = 0; offset < uniqueTasks.length; offset += 25) {
|
|
629
|
+
chunks.push({ offset, tasks: uniqueTasks.slice(offset, offset + 25) });
|
|
630
|
+
}
|
|
631
|
+
const chunkBatch = await runBatch(chunks, async (chunk) => {
|
|
632
|
+
const data = await this.client.post(path, {
|
|
633
|
+
requests: chunk.tasks.map((task) => task.request),
|
|
634
|
+
concurrency: serverConcurrency
|
|
635
|
+
});
|
|
636
|
+
if (!Array.isArray(data.results) || data.results.length !== chunk.tasks.length) {
|
|
637
|
+
throw new Error(`${path} batch returned an invalid result count`);
|
|
638
|
+
}
|
|
639
|
+
if (data.results.some((row, index) => row.index !== index)) {
|
|
640
|
+
throw new Error(`${path} batch returned results out of order`);
|
|
641
|
+
}
|
|
642
|
+
return data.results;
|
|
643
|
+
}, { concurrency: chunkConcurrency });
|
|
644
|
+
const uniqueResults = new Array(uniqueTasks.length);
|
|
645
|
+
for (const chunkResult of chunkBatch.results) {
|
|
646
|
+
const chunk = chunks[chunkResult.index];
|
|
647
|
+
if (!chunkResult.success || !chunkResult.data) {
|
|
648
|
+
for (let index = 0; index < chunk.tasks.length; index += 1) {
|
|
649
|
+
uniqueResults[chunk.offset + index] = {
|
|
650
|
+
index: chunk.tasks[index].index,
|
|
651
|
+
success: false,
|
|
652
|
+
error: chunkResult.error || `${path} batch request failed`
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
for (let index = 0; index < chunkResult.data.length; index += 1) {
|
|
658
|
+
const raw = chunkResult.data[index];
|
|
659
|
+
uniqueResults[chunk.offset + index] = {
|
|
660
|
+
index: chunk.tasks[index].index,
|
|
661
|
+
success: raw.success !== false,
|
|
662
|
+
raw,
|
|
663
|
+
error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return tasks.map((task, index) => ({
|
|
668
|
+
...uniqueResults[deduplicated.sourceIndexByInput[index]],
|
|
669
|
+
index: task.index
|
|
670
|
+
}));
|
|
671
|
+
}
|
|
634
672
|
async listTools() {
|
|
635
673
|
const result = await this.client.mcp("tools/list");
|
|
636
674
|
return result.tools ?? [];
|
|
@@ -646,6 +684,188 @@ var Signaliz = class {
|
|
|
646
684
|
function compact(input) {
|
|
647
685
|
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
|
|
648
686
|
}
|
|
687
|
+
function findEmailRequestBody(params) {
|
|
688
|
+
return compact({
|
|
689
|
+
company_domain: params.companyDomain,
|
|
690
|
+
full_name: params.fullName,
|
|
691
|
+
first_name: params.firstName,
|
|
692
|
+
last_name: params.lastName,
|
|
693
|
+
linkedin_url: params.linkedinUrl,
|
|
694
|
+
company_name: params.companyName,
|
|
695
|
+
skip_cache: params.skipCache
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
function normalizeFindEmailResult(data) {
|
|
699
|
+
const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
700
|
+
const found = Boolean(email) && data.found !== false;
|
|
701
|
+
const verificationStatus = data.verification_status ?? data.status ?? "unknown";
|
|
702
|
+
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
703
|
+
const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
|
|
704
|
+
const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
|
|
705
|
+
const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
|
|
706
|
+
const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
707
|
+
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
708
|
+
return {
|
|
709
|
+
success: data.success !== false && found,
|
|
710
|
+
found,
|
|
711
|
+
email,
|
|
712
|
+
firstName: data.first_name,
|
|
713
|
+
lastName: data.last_name,
|
|
714
|
+
confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
|
|
715
|
+
verificationStatus,
|
|
716
|
+
isVerified: verified,
|
|
717
|
+
isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
|
|
718
|
+
isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
|
|
719
|
+
verificationFreshness,
|
|
720
|
+
verificationAgeDays,
|
|
721
|
+
verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
|
|
722
|
+
needsReverification,
|
|
723
|
+
providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
|
|
724
|
+
error: found ? void 0 : data.error ?? "No verified email found",
|
|
725
|
+
errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
|
|
726
|
+
raw: data
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
function normalizeVerifyEmailResult(email, data) {
|
|
730
|
+
const verificationStatus = String(data.verification_status ?? "").toLowerCase();
|
|
731
|
+
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
732
|
+
return {
|
|
733
|
+
email: data.email ?? email,
|
|
734
|
+
isValid: data.is_valid ?? data.valid ?? verified,
|
|
735
|
+
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
736
|
+
isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
737
|
+
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
738
|
+
provider: data.provider,
|
|
739
|
+
verificationSource: data.verification_source,
|
|
740
|
+
raw: data
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
function companySignalRequestBody(params) {
|
|
744
|
+
const online = params.online ?? true;
|
|
745
|
+
return compact({
|
|
746
|
+
signal_run_id: params.signalRunId,
|
|
747
|
+
company_domain: params.companyDomain,
|
|
748
|
+
company_name: params.companyName,
|
|
749
|
+
research_prompt: params.researchPrompt,
|
|
750
|
+
signal_types: params.signalTypes,
|
|
751
|
+
target_signal_count: params.targetSignalCount,
|
|
752
|
+
lookback_days: params.lookbackDays,
|
|
753
|
+
online,
|
|
754
|
+
enable_deep_search: params.enableDeepSearch ?? online,
|
|
755
|
+
enable_outreach_intelligence: params.enableOutreachIntelligence,
|
|
756
|
+
enable_predictive_intelligence: params.enablePredictiveIntelligence,
|
|
757
|
+
skip_cache: params.skipCache,
|
|
758
|
+
// REST always returns a resumable run instead of holding the connection;
|
|
759
|
+
// waitForResult controls the SDK polling loop.
|
|
760
|
+
wait_for_result: false,
|
|
761
|
+
max_wait_ms: params.maxWaitMs
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
function normalizeCompanySignalResult(params, data) {
|
|
765
|
+
return {
|
|
766
|
+
success: data.success ?? true,
|
|
767
|
+
status: data.status,
|
|
768
|
+
signalRunId: data.signal_run_id ?? data.run_id,
|
|
769
|
+
company: {
|
|
770
|
+
name: data.company?.name ?? params.companyName ?? null,
|
|
771
|
+
domain: data.company?.domain ?? params.companyDomain ?? null
|
|
772
|
+
},
|
|
773
|
+
signals: (data.signals ?? []).map((signal) => {
|
|
774
|
+
const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
|
|
775
|
+
return {
|
|
776
|
+
id: signal.id,
|
|
777
|
+
title: signal.title ?? "",
|
|
778
|
+
type: signal.type ?? signal.signal_type ?? "unknown",
|
|
779
|
+
content: signal.content ?? signal.description ?? "",
|
|
780
|
+
date: signal.date ?? signal.detected_at ?? null,
|
|
781
|
+
datePrecision: signal.date_precision,
|
|
782
|
+
sourceUrl: signal.source_url ?? signal.url ?? null,
|
|
783
|
+
sourceType: signal.source_type,
|
|
784
|
+
sourceProvenance: signal.source_provenance,
|
|
785
|
+
confidence: signal.confidence ?? signal.confidence_score ?? null,
|
|
786
|
+
entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
|
|
787
|
+
signalFamily: signal.signal_family,
|
|
788
|
+
eventType: signal.signal_event_type,
|
|
789
|
+
eventLabel: signal.signal_event_label,
|
|
790
|
+
classification: signal.signal_classification ?? null,
|
|
791
|
+
derived: signal.derived === true,
|
|
792
|
+
evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
|
|
793
|
+
signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
|
|
794
|
+
metadata
|
|
795
|
+
};
|
|
796
|
+
}),
|
|
797
|
+
signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
|
|
798
|
+
intelligence: data.intelligence ?? null,
|
|
799
|
+
credits: data.credits,
|
|
800
|
+
metadata: data.metadata,
|
|
801
|
+
raw: data
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
function validateBatchSize(items) {
|
|
805
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
806
|
+
throw new Error("Signaliz batch requests require at least one item");
|
|
807
|
+
}
|
|
808
|
+
if (items.length > 5e3) {
|
|
809
|
+
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
function validatedBatchConcurrency(options) {
|
|
813
|
+
const concurrency = options?.concurrency ?? 10;
|
|
814
|
+
if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
|
|
815
|
+
throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
|
|
816
|
+
}
|
|
817
|
+
return concurrency;
|
|
818
|
+
}
|
|
819
|
+
function batchConcurrencyPlan(options) {
|
|
820
|
+
const concurrency = validatedBatchConcurrency(options);
|
|
821
|
+
const serverConcurrency = Math.min(10, concurrency);
|
|
822
|
+
return {
|
|
823
|
+
serverConcurrency,
|
|
824
|
+
chunkConcurrency: Math.max(1, Math.floor(concurrency / serverConcurrency))
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
function dedupeExactBatchItems(items, keyForItem) {
|
|
828
|
+
const uniqueItems = [];
|
|
829
|
+
const sourceIndexByInput = [];
|
|
830
|
+
const uniqueIndexByKey = /* @__PURE__ */ new Map();
|
|
831
|
+
for (const item of items) {
|
|
832
|
+
const key = keyForItem(item);
|
|
833
|
+
let uniqueIndex = uniqueIndexByKey.get(key);
|
|
834
|
+
if (uniqueIndex === void 0) {
|
|
835
|
+
uniqueIndex = uniqueItems.length;
|
|
836
|
+
uniqueIndexByKey.set(key, uniqueIndex);
|
|
837
|
+
uniqueItems.push(item);
|
|
838
|
+
}
|
|
839
|
+
sourceIndexByInput.push(uniqueIndex);
|
|
840
|
+
}
|
|
841
|
+
return { uniqueItems, sourceIndexByInput };
|
|
842
|
+
}
|
|
843
|
+
function finalizeCoreBatch(total, startedAt, round, normalize) {
|
|
844
|
+
const results = new Array(total);
|
|
845
|
+
for (const item of round) {
|
|
846
|
+
if (!item.success || !item.raw) {
|
|
847
|
+
results[item.index] = { index: item.index, success: false, error: item.error || "Signaliz batch item failed" };
|
|
848
|
+
continue;
|
|
849
|
+
}
|
|
850
|
+
try {
|
|
851
|
+
results[item.index] = { index: item.index, success: true, data: normalize(item) };
|
|
852
|
+
} catch (error) {
|
|
853
|
+
results[item.index] = {
|
|
854
|
+
index: item.index,
|
|
855
|
+
success: false,
|
|
856
|
+
error: error instanceof Error ? error.message : String(error)
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
const succeeded = results.filter((item) => item.success).length;
|
|
861
|
+
return {
|
|
862
|
+
total,
|
|
863
|
+
succeeded,
|
|
864
|
+
failed: total - succeeded,
|
|
865
|
+
durationMs: Date.now() - startedAt,
|
|
866
|
+
results
|
|
867
|
+
};
|
|
868
|
+
}
|
|
649
869
|
function signalToCopyRequestBody(params) {
|
|
650
870
|
return compact({
|
|
651
871
|
company_domain: params.companyDomain,
|
|
@@ -707,16 +927,8 @@ function sleep2(ms) {
|
|
|
707
927
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
708
928
|
}
|
|
709
929
|
async function runBatch(items, execute, options) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
if (items.length > 5e3) {
|
|
714
|
-
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
|
|
715
|
-
}
|
|
716
|
-
const concurrency = options?.concurrency ?? 10;
|
|
717
|
-
if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
|
|
718
|
-
throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
|
|
719
|
-
}
|
|
930
|
+
validateBatchSize(items);
|
|
931
|
+
const concurrency = validatedBatchConcurrency(options);
|
|
720
932
|
const startedAt = Date.now();
|
|
721
933
|
const results = new Array(items.length);
|
|
722
934
|
let nextIndex = 0;
|
package/dist/index.d.mts
CHANGED
|
@@ -204,6 +204,7 @@ declare class Signaliz {
|
|
|
204
204
|
signalToCopy(params: SignalToCopyParams): Promise<SignalToCopyResult>;
|
|
205
205
|
createSignalCopyBatch(requests: SignalToCopyParams[], options?: BatchOptions): Promise<BatchResult<SignalToCopyResult>>;
|
|
206
206
|
private runSignalCopyBatchChunk;
|
|
207
|
+
private runCoreBatchRound;
|
|
207
208
|
listTools(): Promise<MCPToolInfo[]>;
|
|
208
209
|
health(): Promise<PlatformHealth>;
|
|
209
210
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -204,6 +204,7 @@ declare class Signaliz {
|
|
|
204
204
|
signalToCopy(params: SignalToCopyParams): Promise<SignalToCopyResult>;
|
|
205
205
|
createSignalCopyBatch(requests: SignalToCopyParams[], options?: BatchOptions): Promise<BatchResult<SignalToCopyResult>>;
|
|
206
206
|
private runSignalCopyBatchChunk;
|
|
207
|
+
private runCoreBatchRound;
|
|
207
208
|
listTools(): Promise<MCPToolInfo[]>;
|
|
208
209
|
health(): Promise<PlatformHealth>;
|
|
209
210
|
}
|