@signaliz/sdk 1.0.1

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.js ADDED
@@ -0,0 +1,570 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Signaliz: () => Signaliz,
24
+ SignalizError: () => SignalizError
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/errors.ts
29
+ var SignalizError = class extends Error {
30
+ constructor(data) {
31
+ super(data.message);
32
+ this.name = "SignalizError";
33
+ this.code = data.code;
34
+ this.errorType = data.errorType;
35
+ this.retryAfter = data.retryAfter;
36
+ this.details = data.details;
37
+ }
38
+ get isRetryable() {
39
+ return this.errorType === "rate_limited" || this.errorType === "timeout" || this.errorType === "provider_error";
40
+ }
41
+ };
42
+ function parseError(status, body) {
43
+ if (body?.error && typeof body.error === "object") {
44
+ return new SignalizError({
45
+ code: body.error.code || `HTTP_${status}`,
46
+ message: body.error.message || `Request failed with status ${status}`,
47
+ errorType: mapErrorType(body.error.code, status),
48
+ retryAfter: body.error.retry_after,
49
+ details: body.error.details
50
+ });
51
+ }
52
+ return new SignalizError({
53
+ code: `HTTP_${status}`,
54
+ message: body?.message || body?.error || `Request failed with status ${status}`,
55
+ errorType: mapErrorType(void 0, status)
56
+ });
57
+ }
58
+ function mapErrorType(code, status) {
59
+ if (code === "RATE_LIMITED" || status === 429) return "rate_limited";
60
+ if (code === "VALIDATION_ERROR" || status === 400) return "validation";
61
+ if (code === "NOT_FOUND" || status === 404) return "not_found";
62
+ if (code === "AUTH_EXPIRED" || status === 401) return "auth_expired";
63
+ if (code === "INSUFFICIENT_CREDITS" || status === 402) return "insufficient_credits";
64
+ if (code === "TIMEOUT" || status === 504) return "timeout";
65
+ if (status >= 500) return "provider_error";
66
+ return "unknown";
67
+ }
68
+
69
+ // src/client.ts
70
+ var DEFAULT_BASE_URL = "https://api.signaliz.com/functions/v1";
71
+ var DEFAULT_TIMEOUT = 12e4;
72
+ var DEFAULT_MAX_RETRIES = 3;
73
+ var HttpClient = class {
74
+ constructor(config) {
75
+ this.baseUrl = config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL;
76
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
77
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
78
+ this.apiKey = config.apiKey;
79
+ this.clientId = config.clientId;
80
+ this.clientSecret = config.clientSecret;
81
+ if (!this.apiKey && !(this.clientId && this.clientSecret)) {
82
+ throw new Error("Signaliz: provide either apiKey or clientId + clientSecret");
83
+ }
84
+ }
85
+ async request(functionName, body, method = "POST") {
86
+ let lastError;
87
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
88
+ try {
89
+ const token = await this.getToken();
90
+ const url = `${this.baseUrl}/${functionName}`;
91
+ const controller = new AbortController();
92
+ const timer = setTimeout(() => controller.abort(), this.timeout);
93
+ const init = {
94
+ method,
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ Authorization: `Bearer ${token}`
98
+ },
99
+ signal: controller.signal
100
+ };
101
+ if (method === "POST") {
102
+ init.body = JSON.stringify(body);
103
+ }
104
+ const res = await fetch(url, init);
105
+ clearTimeout(timer);
106
+ if (!res.ok) {
107
+ const errBody = await res.json().catch(() => ({}));
108
+ const err = parseError(res.status, errBody);
109
+ if (err.isRetryable && attempt < this.maxRetries) {
110
+ const wait = err.retryAfter ? err.retryAfter * 1e3 : Math.min(1e3 * Math.pow(2, attempt), 1e4);
111
+ await sleep(wait);
112
+ lastError = err;
113
+ continue;
114
+ }
115
+ throw err;
116
+ }
117
+ return await res.json();
118
+ } catch (e) {
119
+ if (e instanceof SignalizError) throw e;
120
+ if (e.name === "AbortError") {
121
+ const timeout = new SignalizError({
122
+ code: "TIMEOUT",
123
+ message: `Request timed out after ${this.timeout}ms`,
124
+ errorType: "timeout"
125
+ });
126
+ if (attempt < this.maxRetries) {
127
+ lastError = timeout;
128
+ await sleep(1e3 * Math.pow(2, attempt));
129
+ continue;
130
+ }
131
+ throw timeout;
132
+ }
133
+ lastError = e;
134
+ if (attempt < this.maxRetries) {
135
+ await sleep(1e3 * Math.pow(2, attempt));
136
+ continue;
137
+ }
138
+ }
139
+ }
140
+ throw lastError || new Error("Request failed after retries");
141
+ }
142
+ /** Convenience wrapper for POST-based edge function calls */
143
+ async post(functionName, body) {
144
+ return this.request(functionName, body, "POST");
145
+ }
146
+ /** JSON-RPC call to the MCP server */
147
+ async mcp(method, params = {}) {
148
+ const token = await this.getToken();
149
+ const url = `${this.baseUrl}/signaliz-mcp`;
150
+ const res = await fetch(url, {
151
+ method: "POST",
152
+ headers: {
153
+ "Content-Type": "application/json",
154
+ Authorization: `Bearer ${token}`
155
+ },
156
+ body: JSON.stringify({
157
+ jsonrpc: "2.0",
158
+ id: Date.now(),
159
+ method,
160
+ params
161
+ })
162
+ });
163
+ const data = await res.json();
164
+ if (data.error) {
165
+ throw new SignalizError({
166
+ code: data.error.code?.toString() || "MCP_ERROR",
167
+ message: data.error.message || "MCP request failed",
168
+ errorType: "unknown"
169
+ });
170
+ }
171
+ if (data.result?.content?.[0]?.text) {
172
+ try {
173
+ return JSON.parse(data.result.content[0].text);
174
+ } catch {
175
+ return data.result.content[0].text;
176
+ }
177
+ }
178
+ if (data.result?.structuredContent) {
179
+ return data.result.structuredContent;
180
+ }
181
+ return data.result;
182
+ }
183
+ async getToken() {
184
+ if (this.apiKey) return this.apiKey;
185
+ if (this.accessToken) return this.accessToken;
186
+ const res = await fetch("https://api.signaliz.com/token", {
187
+ method: "POST",
188
+ headers: { "Content-Type": "application/json" },
189
+ body: JSON.stringify({
190
+ grant_type: "client_credentials",
191
+ client_id: this.clientId,
192
+ client_secret: this.clientSecret
193
+ })
194
+ });
195
+ if (!res.ok) {
196
+ throw new SignalizError({
197
+ code: "AUTH_FAILED",
198
+ message: "Failed to obtain access token",
199
+ errorType: "auth_expired"
200
+ });
201
+ }
202
+ const data = await res.json();
203
+ this.accessToken = data.access_token;
204
+ return this.accessToken;
205
+ }
206
+ };
207
+ function sleep(ms) {
208
+ return new Promise((r) => setTimeout(r, ms));
209
+ }
210
+
211
+ // src/resources/emails.ts
212
+ var Emails = class {
213
+ constructor(client) {
214
+ this.client = client;
215
+ }
216
+ /** Find and verify an email address for a person at a company */
217
+ async find(params) {
218
+ const body = {
219
+ company_domain: params.companyDomain
220
+ };
221
+ if (params.fullName) body.full_name = params.fullName;
222
+ if (params.firstName) body.first_name = params.firstName;
223
+ if (params.lastName) body.last_name = params.lastName;
224
+ if (params.linkedinUrl) body.linkedin_url = params.linkedinUrl;
225
+ if (params.companyName) body.company_name = params.companyName;
226
+ const data = await this.client.mcp("tools/call", {
227
+ name: "find_emails_with_verification",
228
+ arguments: body
229
+ });
230
+ return {
231
+ email: data.email,
232
+ firstName: data.first_name,
233
+ lastName: data.last_name,
234
+ confidence: data.confidence ?? data.confidence_score ?? 0,
235
+ verificationStatus: data.verification_status ?? "unknown",
236
+ providerUsed: data.provider_used ?? data.source ?? "unknown"
237
+ };
238
+ }
239
+ /** Verify a single email address */
240
+ async verify(email) {
241
+ const data = await this.client.mcp("tools/call", {
242
+ name: "verify_email",
243
+ arguments: { email }
244
+ });
245
+ return {
246
+ email: data.email ?? email,
247
+ isValid: data.is_valid ?? false,
248
+ isDeliverable: data.is_deliverable ?? false,
249
+ isCatchAll: data.is_catch_all ?? false,
250
+ provider: data.provider,
251
+ confidenceScore: data.confidence_score ?? 0,
252
+ verificationSource: data.verification_source
253
+ };
254
+ }
255
+ };
256
+
257
+ // src/resources/signals.ts
258
+ var Signals = class {
259
+ constructor(client) {
260
+ this.client = client;
261
+ }
262
+ /** Enrich a company with actionable signals (V1) */
263
+ async enrich(params) {
264
+ const args = {
265
+ company_name: params.companyName
266
+ };
267
+ if (params.domain) args.domain = params.domain;
268
+ if (params.researchPrompt) args.research_prompt = params.researchPrompt;
269
+ if (params.signalTypes) args.signal_types = params.signalTypes;
270
+ const data = await this.client.mcp("tools/call", {
271
+ name: "enrich_company_signals",
272
+ arguments: args
273
+ });
274
+ return {
275
+ companyName: data.company_name ?? params.companyName,
276
+ signals: (data.signals ?? []).map((s) => ({
277
+ title: s.title,
278
+ signalType: s.signal_type,
279
+ confidenceScore: s.confidence_score ?? 0,
280
+ detectedAt: s.detected_at ?? "",
281
+ url: s.url,
282
+ content: s.content ?? ""
283
+ })),
284
+ totalSignals: data.total_signals ?? data.signals?.length ?? 0,
285
+ fromCache: data.from_cache ?? false
286
+ };
287
+ }
288
+ /** Enrich a company with actionable signals (V2 — clean response + online mode) */
289
+ async enrichV2(params) {
290
+ const args = {};
291
+ if (params.companyName) args.company_name = params.companyName;
292
+ if (params.domain) args.domain = params.domain;
293
+ if (params.companyDomain) args.company_domain = params.companyDomain;
294
+ if (params.researchPrompt) args.research_prompt = params.researchPrompt;
295
+ if (params.signalTypes) args.signal_types = params.signalTypes;
296
+ if (params.online !== void 0) args.online = params.online;
297
+ if (params.targetSignalCount) args.target_signal_count = params.targetSignalCount;
298
+ if (params.lookbackDays) args.lookback_days = params.lookbackDays;
299
+ if (params.model) args.model = params.model;
300
+ if (params.enableDeepSearch) args.enable_deep_search = params.enableDeepSearch;
301
+ if (params.enableOutreachIntelligence) args.enable_outreach_intelligence = params.enableOutreachIntelligence;
302
+ if (params.enablePredictiveIntelligence) args.enable_predictive_intelligence = params.enablePredictiveIntelligence;
303
+ if (params.icpId) args.icp_id = params.icpId;
304
+ if (params.cacheTtlHours !== void 0) args.cache_ttl_hours = params.cacheTtlHours;
305
+ if (params.skipCache) args.skip_cache = params.skipCache;
306
+ const data = await this.client.post("company-signal-enrichment-v2", args);
307
+ return {
308
+ success: data.success ?? false,
309
+ company: {
310
+ name: data.company?.name ?? null,
311
+ domain: data.company?.domain ?? null
312
+ },
313
+ signals: (data.signals ?? []).map((s) => ({
314
+ id: s.id,
315
+ title: s.title,
316
+ type: s.type,
317
+ content: s.content ?? "",
318
+ date: s.date ?? null,
319
+ sourceUrl: s.source_url ?? null,
320
+ sourceType: s.source_type ?? "unknown",
321
+ confidence: s.confidence ?? null
322
+ })),
323
+ signalCount: data.signal_count ?? 0,
324
+ intelligence: data.intelligence ? {
325
+ executiveSummary: data.intelligence.executive_summary ?? null,
326
+ keyThemes: data.intelligence.key_themes ?? [],
327
+ relevanceScore: data.intelligence.relevance_score ?? null,
328
+ outreach: data.intelligence.outreach ? {
329
+ urgencyScore: data.intelligence.outreach.urgency_score ?? null,
330
+ bestTiming: data.intelligence.outreach.best_timing ?? null,
331
+ primaryAngle: data.intelligence.outreach.primary_angle ?? null,
332
+ ctas: data.intelligence.outreach.ctas ? {
333
+ soft: data.intelligence.outreach.ctas.soft,
334
+ direct: data.intelligence.outreach.ctas.direct,
335
+ valueFirst: data.intelligence.outreach.ctas.value_first
336
+ } : null,
337
+ conversationStarters: data.intelligence.outreach.conversation_starters ?? []
338
+ } : null,
339
+ predictions: (data.intelligence.predictions ?? []).map((p) => ({
340
+ prediction: p.prediction,
341
+ confidence: p.confidence,
342
+ targetPersona: p.target_persona ?? null,
343
+ recommendedAction: p.recommended_action ?? null
344
+ }))
345
+ } : null,
346
+ credits: {
347
+ charged: data.credits?.charged ?? 0,
348
+ billingType: data.credits?.billing_type ?? "unknown",
349
+ breakdown: {
350
+ signalCredits: data.credits?.breakdown?.signal_credits ?? 0,
351
+ modelCostUsd: data.credits?.breakdown?.model_cost_usd ?? 0,
352
+ modelCredits: data.credits?.breakdown?.model_credits ?? 0,
353
+ explanation: data.credits?.breakdown?.explanation ?? ""
354
+ }
355
+ },
356
+ metadata: {
357
+ version: data.metadata?.version ?? "",
358
+ model: data.metadata?.model ?? "",
359
+ online: data.metadata?.online ?? false,
360
+ processingTimeMs: data.metadata?.processing_time_ms ?? 0
361
+ }
362
+ };
363
+ }
364
+ };
365
+
366
+ // src/resources/systems.ts
367
+ var Systems = class {
368
+ constructor(client) {
369
+ this.client = client;
370
+ }
371
+ /** Create a new pipeline/system */
372
+ async create(params) {
373
+ const data = await this.client.mcp("tools/call", {
374
+ name: "create_system",
375
+ arguments: {
376
+ name: params.name,
377
+ description: params.description,
378
+ capabilities: params.capabilities,
379
+ field_mappings: params.fieldMappings
380
+ }
381
+ });
382
+ return {
383
+ id: data.system_id ?? data.id,
384
+ name: data.name ?? params.name,
385
+ status: data.status ?? "created",
386
+ nodeCount: data.node_count ?? params.capabilities.length,
387
+ createdAt: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
388
+ };
389
+ }
390
+ /** Run a system with input data */
391
+ async run(systemId, params) {
392
+ const data = await this.client.mcp("tools/call", {
393
+ name: "run_system",
394
+ arguments: {
395
+ system_id: systemId,
396
+ input_data: params.data,
397
+ async: params.async ?? false
398
+ }
399
+ });
400
+ return {
401
+ runId: data.run_id ?? data.id,
402
+ status: data.status ?? "running",
403
+ totalRows: data.total_rows,
404
+ completedRows: data.completed_rows ?? 0,
405
+ creditsUsed: data.credits_used ?? 0
406
+ };
407
+ }
408
+ /** Get a system by ID */
409
+ async get(systemId) {
410
+ const data = await this.client.mcp("tools/call", {
411
+ name: "get_system",
412
+ arguments: { system_id: systemId }
413
+ });
414
+ return {
415
+ id: data.id ?? systemId,
416
+ name: data.name,
417
+ status: data.status,
418
+ nodeCount: data.node_count ?? 0,
419
+ createdAt: data.created_at
420
+ };
421
+ }
422
+ /** List all systems */
423
+ async list() {
424
+ const data = await this.client.mcp("tools/call", {
425
+ name: "list_systems",
426
+ arguments: {}
427
+ });
428
+ return (data.systems ?? data ?? []).map((s) => ({
429
+ id: s.id,
430
+ name: s.name,
431
+ status: s.status,
432
+ nodeCount: s.node_count ?? 0,
433
+ createdAt: s.created_at
434
+ }));
435
+ }
436
+ };
437
+
438
+ // src/resources/runs.ts
439
+ var Runs = class {
440
+ constructor(client) {
441
+ this.client = client;
442
+ }
443
+ /** Get run status */
444
+ async get(runId) {
445
+ const data = await this.client.mcp("tools/call", {
446
+ name: "get_run_results",
447
+ arguments: { run_id: runId }
448
+ });
449
+ return {
450
+ runId: data.run_id ?? runId,
451
+ status: data.status,
452
+ totalRows: data.total_rows,
453
+ completedRows: data.completed_rows ?? 0,
454
+ creditsUsed: data.credits_used ?? 0
455
+ };
456
+ }
457
+ /** Poll until a run completes. Returns final result. */
458
+ async waitForCompletion(runId, pollIntervalMs = 2e3) {
459
+ while (true) {
460
+ const run = await this.get(runId);
461
+ if (["completed", "failed", "cancelled", "crashed", "timed_out", "interrupted", "system_failure"].includes(run.status)) {
462
+ return run;
463
+ }
464
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
465
+ }
466
+ }
467
+ /**
468
+ * Stream run progress as an async iterator.
469
+ * Usage: for await (const event of signaliz.runs.stream(runId)) { ... }
470
+ */
471
+ async *stream(runId, pollIntervalMs = 1500) {
472
+ let lastCompleted = -1;
473
+ while (true) {
474
+ const run = await this.get(runId);
475
+ const event = {
476
+ runId,
477
+ status: run.status,
478
+ completedRows: run.completedRows ?? 0,
479
+ totalRows: run.totalRows ?? 0,
480
+ creditsUsed: run.creditsUsed ?? 0
481
+ };
482
+ if (event.completedRows !== lastCompleted) {
483
+ lastCompleted = event.completedRows;
484
+ yield event;
485
+ }
486
+ if (["completed", "failed", "cancelled"].includes(run.status)) {
487
+ return;
488
+ }
489
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
490
+ }
491
+ }
492
+ };
493
+
494
+ // src/resources/http.ts
495
+ var Http = class {
496
+ constructor(client) {
497
+ this.client = client;
498
+ }
499
+ /** Proxy an HTTP request through Signaliz */
500
+ async request(params) {
501
+ const data = await this.client.mcp("tools/call", {
502
+ name: "http_request",
503
+ arguments: {
504
+ url: params.url,
505
+ method: params.method,
506
+ headers: params.headers,
507
+ body: params.body ? JSON.stringify(params.body) : void 0
508
+ }
509
+ });
510
+ return {
511
+ statusCode: data.status_code ?? data.statusCode ?? 200,
512
+ headers: data.headers ?? {},
513
+ body: data.body ?? data.response ?? data
514
+ };
515
+ }
516
+ };
517
+
518
+ // src/index.ts
519
+ var Signaliz = class {
520
+ constructor(config) {
521
+ this.client = new HttpClient(config);
522
+ this.emails = new Emails(this.client);
523
+ this.signals = new Signals(this.client);
524
+ this.systems = new Systems(this.client);
525
+ this.runs = new Runs(this.client);
526
+ this.http = new Http(this.client);
527
+ }
528
+ /** Get current workspace info including credits */
529
+ async getWorkspace() {
530
+ const data = await this.client.mcp("tools/call", {
531
+ name: "get_workspace",
532
+ arguments: {}
533
+ });
534
+ return {
535
+ id: data.workspace_id ?? data.id,
536
+ name: data.workspace_name ?? data.name ?? "Unknown",
537
+ creditsRemaining: data.credits_remaining ?? data.credits ?? 0,
538
+ plan: data.plan ?? "unknown"
539
+ };
540
+ }
541
+ /** List all available MCP tools */
542
+ async listTools() {
543
+ const data = await this.client.mcp("tools/list", {});
544
+ const tools = data?.tools ?? data ?? [];
545
+ return tools.map((t) => ({
546
+ name: t.name,
547
+ description: (t.description ?? "").slice(0, 120),
548
+ category: t.annotations?.category,
549
+ costCredits: t.annotations?.cost_credits
550
+ }));
551
+ }
552
+ /** Discover tools by natural language query */
553
+ async discover(query, category) {
554
+ const data = await this.client.mcp("tools/call", {
555
+ name: "discover_capabilities",
556
+ arguments: { query, category }
557
+ });
558
+ return (data.matches ?? []).map((m) => ({
559
+ name: m.tool,
560
+ description: m.description,
561
+ category: m.category,
562
+ costCredits: m.cost_credits
563
+ }));
564
+ }
565
+ };
566
+ // Annotate the CommonJS export names for ESM import in node:
567
+ 0 && (module.exports = {
568
+ Signaliz,
569
+ SignalizError
570
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,8 @@
1
+ import {
2
+ Signaliz,
3
+ SignalizError
4
+ } from "./chunk-R657OZE7.mjs";
5
+ export {
6
+ Signaliz,
7
+ SignalizError
8
+ };
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node