@signaliz/sdk 1.0.23 → 1.0.24

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
@@ -34,12 +34,24 @@ const signals = await signaliz.enrichCompanySignals({
34
34
  researchPrompt: 'expansion priorities',
35
35
  });
36
36
 
37
+ // Persist a no-wait run ID and resume it later without duplicate spend.
38
+ const queuedSignals = await signaliz.enrichCompanySignals({
39
+ companyDomain: 'example.com',
40
+ waitForResult: false,
41
+ });
42
+ const resumedSignals = await signaliz.enrichCompanySignals({
43
+ signalRunId: queuedSignals.signalRunId,
44
+ });
45
+
37
46
  const copy = await signaliz.signalToCopy({
38
47
  companyDomain: 'example.com',
39
48
  personName: 'Jane Doe',
40
49
  title: 'VP Sales',
41
50
  campaignOffer: 'pipeline intelligence',
42
51
  researchPrompt: 'expansion priorities',
52
+ // Cache-first and shallow by default; opt into either behavior explicitly.
53
+ skipCache: false,
54
+ enableDeepSearch: false,
43
55
  });
44
56
  ```
45
57
 
@@ -56,11 +68,16 @@ const copyBatch = await signaliz.createSignalCopyBatch(copyRequests, { concurren
56
68
 
57
69
  Each batch accepts up to 5,000 items. Company Signal Enrichment transparently
58
70
  resumes long-running research through the same `/company-signals` endpoint;
59
- callers never need an internal Trigger.dev status URL.
71
+ callers never need an internal Trigger.dev status URL. The SDK follows the
72
+ server's adaptive polling hints by default and still honors `pollIntervalMs`
73
+ when a caller explicitly overrides the cadence.
60
74
 
61
75
  Company Signal Enrichment defaults `online` and `enableDeepSearch` to `true`
62
76
  unless the caller explicitly disables them. Signal to Copy AI returns three
63
77
  complete, evidence-backed email variations when supported signals are available.
78
+ Signal to Copy is cache-first and defaults `enableDeepSearch` to `false` so it
79
+ normally finishes within an agent turn; set `skipCache` or `enableDeepSearch`
80
+ only when fresh or deeper research is required.
64
81
  Unclassified evidence is returned by signal enrichment but is not used to
65
82
  generate outreach copy.
66
83
 
@@ -402,6 +402,7 @@ var Signaliz = class {
402
402
  async enrichCompanySignals(params) {
403
403
  const online = params.online ?? true;
404
404
  const request = compact({
405
+ signal_run_id: params.signalRunId,
405
406
  company_domain: params.companyDomain,
406
407
  company_name: params.companyName,
407
408
  research_prompt: params.researchPrompt,
@@ -413,15 +414,17 @@ var Signaliz = class {
413
414
  enable_outreach_intelligence: params.enableOutreachIntelligence,
414
415
  enable_predictive_intelligence: params.enablePredictiveIntelligence,
415
416
  skip_cache: params.skipCache,
416
- wait_for_result: params.waitForResult !== false,
417
+ // REST always returns a resumable run instead of holding the connection;
418
+ // waitForResult controls this SDK's polling loop below.
419
+ wait_for_result: false,
417
420
  max_wait_ms: params.maxWaitMs
418
421
  });
419
422
  let data = await this.client.post("api/v1/company-signals", request);
420
423
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
421
424
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
422
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
423
425
  const startedAt = Date.now();
424
426
  while (Date.now() - startedAt < maxWaitMs) {
427
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
425
428
  const status = await this.client.post("api/v1/company-signals", {
426
429
  ...request,
427
430
  signal_run_id: data.run_id
@@ -437,7 +440,7 @@ var Signaliz = class {
437
440
  data = status.output ?? status.result ?? status.data ?? status;
438
441
  break;
439
442
  }
440
- await sleep2(pollIntervalMs);
443
+ data = status;
441
444
  }
442
445
  if (isPendingSignalResponse(data)) {
443
446
  throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
@@ -445,6 +448,8 @@ var Signaliz = class {
445
448
  }
446
449
  return {
447
450
  success: data.success ?? true,
451
+ status: data.status,
452
+ signalRunId: data.signal_run_id ?? data.run_id,
448
453
  company: {
449
454
  name: data.company?.name ?? params.companyName ?? null,
450
455
  domain: data.company?.domain ?? params.companyDomain ?? null
@@ -476,15 +481,16 @@ var Signaliz = class {
476
481
  title: params.title,
477
482
  campaign_offer: params.campaignOffer,
478
483
  research_prompt: params.researchPrompt,
479
- signal_run_id: params.signalRunId
484
+ signal_run_id: params.signalRunId,
485
+ skip_cache: params.skipCache,
486
+ enable_deep_search: params.enableDeepSearch
480
487
  });
481
488
  let data = await this.client.post("api/v1/signal-to-copy", request);
482
489
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
483
490
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
484
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
485
491
  const startedAt = Date.now();
486
492
  while (Date.now() - startedAt < maxWaitMs) {
487
- await sleep2(pollIntervalMs);
493
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
488
494
  data = await this.client.post("api/v1/signal-to-copy", {
489
495
  ...request,
490
496
  signal_run_id: data.run_id
@@ -544,6 +550,19 @@ function isCompletedSignalRun(data) {
544
550
  function isFailedSignalRun(data) {
545
551
  return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out"].includes(String(data.status || "").toLowerCase());
546
552
  }
553
+ function signalPollDelayMs(data, override) {
554
+ if (override !== void 0) return Math.max(250, override);
555
+ const retryAfterMs = Number(data.retry_after_ms);
556
+ const nextPollSeconds = Number(data.next_poll_after_seconds);
557
+ const hinted = Number.isFinite(retryAfterMs) && retryAfterMs > 0 ? retryAfterMs : Number.isFinite(nextPollSeconds) && nextPollSeconds > 0 ? nextPollSeconds * 1e3 : 2e3;
558
+ return Math.min(6e4, Math.max(250, hinted));
559
+ }
560
+ async function waitForNextSignalPoll(data, override, startedAt, maxWaitMs) {
561
+ const remainingMs = maxWaitMs - (Date.now() - startedAt);
562
+ if (remainingMs <= 0) return false;
563
+ await sleep2(Math.min(signalPollDelayMs(data, override), remainingMs));
564
+ return Date.now() - startedAt < maxWaitMs;
565
+ }
547
566
  function sleep2(ms) {
548
567
  return new Promise((resolve) => setTimeout(resolve, ms));
549
568
  }
package/dist/index.d.mts CHANGED
@@ -65,6 +65,8 @@ interface VerifyEmailResult {
65
65
  raw: Record<string, unknown>;
66
66
  }
67
67
  interface CompanySignalEnrichmentParams {
68
+ /** Resume an existing enrichment without creating another provider run. */
69
+ signalRunId?: string;
68
70
  companyDomain?: string;
69
71
  companyName?: string;
70
72
  researchPrompt?: string;
@@ -95,6 +97,8 @@ interface CompanySignal {
95
97
  }
96
98
  interface CompanySignalEnrichmentResult {
97
99
  success: boolean;
100
+ status?: string;
101
+ signalRunId?: string;
98
102
  company: {
99
103
  name: string | null;
100
104
  domain: string | null;
@@ -113,6 +117,10 @@ interface SignalToCopyParams {
113
117
  campaignOffer: string;
114
118
  researchPrompt?: string;
115
119
  signalRunId?: string;
120
+ /** Bypass cached company signals and start fresh research. */
121
+ skipCache?: boolean;
122
+ /** Opt into slower deep research. Defaults to false. */
123
+ enableDeepSearch?: boolean;
116
124
  waitForResult?: boolean;
117
125
  maxWaitMs?: number;
118
126
  pollIntervalMs?: number;
package/dist/index.d.ts CHANGED
@@ -65,6 +65,8 @@ interface VerifyEmailResult {
65
65
  raw: Record<string, unknown>;
66
66
  }
67
67
  interface CompanySignalEnrichmentParams {
68
+ /** Resume an existing enrichment without creating another provider run. */
69
+ signalRunId?: string;
68
70
  companyDomain?: string;
69
71
  companyName?: string;
70
72
  researchPrompt?: string;
@@ -95,6 +97,8 @@ interface CompanySignal {
95
97
  }
96
98
  interface CompanySignalEnrichmentResult {
97
99
  success: boolean;
100
+ status?: string;
101
+ signalRunId?: string;
98
102
  company: {
99
103
  name: string | null;
100
104
  domain: string | null;
@@ -113,6 +117,10 @@ interface SignalToCopyParams {
113
117
  campaignOffer: string;
114
118
  researchPrompt?: string;
115
119
  signalRunId?: string;
120
+ /** Bypass cached company signals and start fresh research. */
121
+ skipCache?: boolean;
122
+ /** Opt into slower deep research. Defaults to false. */
123
+ enableDeepSearch?: boolean;
116
124
  waitForResult?: boolean;
117
125
  maxWaitMs?: number;
118
126
  pollIntervalMs?: number;
package/dist/index.js CHANGED
@@ -429,6 +429,7 @@ var Signaliz = class {
429
429
  async enrichCompanySignals(params) {
430
430
  const online = params.online ?? true;
431
431
  const request = compact({
432
+ signal_run_id: params.signalRunId,
432
433
  company_domain: params.companyDomain,
433
434
  company_name: params.companyName,
434
435
  research_prompt: params.researchPrompt,
@@ -440,15 +441,17 @@ var Signaliz = class {
440
441
  enable_outreach_intelligence: params.enableOutreachIntelligence,
441
442
  enable_predictive_intelligence: params.enablePredictiveIntelligence,
442
443
  skip_cache: params.skipCache,
443
- wait_for_result: params.waitForResult !== false,
444
+ // REST always returns a resumable run instead of holding the connection;
445
+ // waitForResult controls this SDK's polling loop below.
446
+ wait_for_result: false,
444
447
  max_wait_ms: params.maxWaitMs
445
448
  });
446
449
  let data = await this.client.post("api/v1/company-signals", request);
447
450
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
448
451
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
449
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
450
452
  const startedAt = Date.now();
451
453
  while (Date.now() - startedAt < maxWaitMs) {
454
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
452
455
  const status = await this.client.post("api/v1/company-signals", {
453
456
  ...request,
454
457
  signal_run_id: data.run_id
@@ -464,7 +467,7 @@ var Signaliz = class {
464
467
  data = status.output ?? status.result ?? status.data ?? status;
465
468
  break;
466
469
  }
467
- await sleep2(pollIntervalMs);
470
+ data = status;
468
471
  }
469
472
  if (isPendingSignalResponse(data)) {
470
473
  throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
@@ -472,6 +475,8 @@ var Signaliz = class {
472
475
  }
473
476
  return {
474
477
  success: data.success ?? true,
478
+ status: data.status,
479
+ signalRunId: data.signal_run_id ?? data.run_id,
475
480
  company: {
476
481
  name: data.company?.name ?? params.companyName ?? null,
477
482
  domain: data.company?.domain ?? params.companyDomain ?? null
@@ -503,15 +508,16 @@ var Signaliz = class {
503
508
  title: params.title,
504
509
  campaign_offer: params.campaignOffer,
505
510
  research_prompt: params.researchPrompt,
506
- signal_run_id: params.signalRunId
511
+ signal_run_id: params.signalRunId,
512
+ skip_cache: params.skipCache,
513
+ enable_deep_search: params.enableDeepSearch
507
514
  });
508
515
  let data = await this.client.post("api/v1/signal-to-copy", request);
509
516
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
510
517
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
511
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
512
518
  const startedAt = Date.now();
513
519
  while (Date.now() - startedAt < maxWaitMs) {
514
- await sleep2(pollIntervalMs);
520
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
515
521
  data = await this.client.post("api/v1/signal-to-copy", {
516
522
  ...request,
517
523
  signal_run_id: data.run_id
@@ -571,6 +577,19 @@ function isCompletedSignalRun(data) {
571
577
  function isFailedSignalRun(data) {
572
578
  return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out"].includes(String(data.status || "").toLowerCase());
573
579
  }
580
+ function signalPollDelayMs(data, override) {
581
+ if (override !== void 0) return Math.max(250, override);
582
+ const retryAfterMs = Number(data.retry_after_ms);
583
+ const nextPollSeconds = Number(data.next_poll_after_seconds);
584
+ const hinted = Number.isFinite(retryAfterMs) && retryAfterMs > 0 ? retryAfterMs : Number.isFinite(nextPollSeconds) && nextPollSeconds > 0 ? nextPollSeconds * 1e3 : 2e3;
585
+ return Math.min(6e4, Math.max(250, hinted));
586
+ }
587
+ async function waitForNextSignalPoll(data, override, startedAt, maxWaitMs) {
588
+ const remainingMs = maxWaitMs - (Date.now() - startedAt);
589
+ if (remainingMs <= 0) return false;
590
+ await sleep2(Math.min(signalPollDelayMs(data, override), remainingMs));
591
+ return Date.now() - startedAt < maxWaitMs;
592
+ }
574
593
  function sleep2(ms) {
575
594
  return new Promise((resolve) => setTimeout(resolve, ms));
576
595
  }
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-EQ3WI2UU.mjs";
4
+ } from "./chunk-GWTSOG6D.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError
@@ -433,6 +433,7 @@ var Signaliz = class {
433
433
  async enrichCompanySignals(params) {
434
434
  const online = params.online ?? true;
435
435
  const request = compact({
436
+ signal_run_id: params.signalRunId,
436
437
  company_domain: params.companyDomain,
437
438
  company_name: params.companyName,
438
439
  research_prompt: params.researchPrompt,
@@ -444,15 +445,17 @@ var Signaliz = class {
444
445
  enable_outreach_intelligence: params.enableOutreachIntelligence,
445
446
  enable_predictive_intelligence: params.enablePredictiveIntelligence,
446
447
  skip_cache: params.skipCache,
447
- wait_for_result: params.waitForResult !== false,
448
+ // REST always returns a resumable run instead of holding the connection;
449
+ // waitForResult controls this SDK's polling loop below.
450
+ wait_for_result: false,
448
451
  max_wait_ms: params.maxWaitMs
449
452
  });
450
453
  let data = await this.client.post("api/v1/company-signals", request);
451
454
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
452
455
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
453
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
454
456
  const startedAt = Date.now();
455
457
  while (Date.now() - startedAt < maxWaitMs) {
458
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
456
459
  const status = await this.client.post("api/v1/company-signals", {
457
460
  ...request,
458
461
  signal_run_id: data.run_id
@@ -468,7 +471,7 @@ var Signaliz = class {
468
471
  data = status.output ?? status.result ?? status.data ?? status;
469
472
  break;
470
473
  }
471
- await sleep2(pollIntervalMs);
474
+ data = status;
472
475
  }
473
476
  if (isPendingSignalResponse(data)) {
474
477
  throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
@@ -476,6 +479,8 @@ var Signaliz = class {
476
479
  }
477
480
  return {
478
481
  success: data.success ?? true,
482
+ status: data.status,
483
+ signalRunId: data.signal_run_id ?? data.run_id,
479
484
  company: {
480
485
  name: data.company?.name ?? params.companyName ?? null,
481
486
  domain: data.company?.domain ?? params.companyDomain ?? null
@@ -507,15 +512,16 @@ var Signaliz = class {
507
512
  title: params.title,
508
513
  campaign_offer: params.campaignOffer,
509
514
  research_prompt: params.researchPrompt,
510
- signal_run_id: params.signalRunId
515
+ signal_run_id: params.signalRunId,
516
+ skip_cache: params.skipCache,
517
+ enable_deep_search: params.enableDeepSearch
511
518
  });
512
519
  let data = await this.client.post("api/v1/signal-to-copy", request);
513
520
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
514
521
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
515
- const pollIntervalMs = Math.max(250, params.pollIntervalMs ?? 2e3);
516
522
  const startedAt = Date.now();
517
523
  while (Date.now() - startedAt < maxWaitMs) {
518
- await sleep2(pollIntervalMs);
524
+ if (!await waitForNextSignalPoll(data, params.pollIntervalMs, startedAt, maxWaitMs)) break;
519
525
  data = await this.client.post("api/v1/signal-to-copy", {
520
526
  ...request,
521
527
  signal_run_id: data.run_id
@@ -575,6 +581,19 @@ function isCompletedSignalRun(data) {
575
581
  function isFailedSignalRun(data) {
576
582
  return ["failed", "error", "cancelled", "canceled", "crashed", "timed_out"].includes(String(data.status || "").toLowerCase());
577
583
  }
584
+ function signalPollDelayMs(data, override) {
585
+ if (override !== void 0) return Math.max(250, override);
586
+ const retryAfterMs = Number(data.retry_after_ms);
587
+ const nextPollSeconds = Number(data.next_poll_after_seconds);
588
+ const hinted = Number.isFinite(retryAfterMs) && retryAfterMs > 0 ? retryAfterMs : Number.isFinite(nextPollSeconds) && nextPollSeconds > 0 ? nextPollSeconds * 1e3 : 2e3;
589
+ return Math.min(6e4, Math.max(250, hinted));
590
+ }
591
+ async function waitForNextSignalPoll(data, override, startedAt, maxWaitMs) {
592
+ const remainingMs = maxWaitMs - (Date.now() - startedAt);
593
+ if (remainingMs <= 0) return false;
594
+ await sleep2(Math.min(signalPollDelayMs(data, override), remainingMs));
595
+ return Date.now() - startedAt < maxWaitMs;
596
+ }
578
597
  function sleep2(ms) {
579
598
  return new Promise((resolve) => setTimeout(resolve, ms));
580
599
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Signaliz
4
- } from "./chunk-EQ3WI2UU.mjs";
4
+ } from "./chunk-GWTSOG6D.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.23",
3
+ "version": "1.0.24",
4
4
  "description": "Signaliz SDK for Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",