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