@signaliz/sdk 1.0.1 → 1.0.4
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 +379 -21
- package/dist/chunk-EVZZQTWE.mjs +4714 -0
- package/dist/cli.js +4220 -68
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +2810 -5
- package/dist/index.d.ts +2810 -5
- package/dist/index.js +4253 -70
- package/dist/index.mjs +27 -3
- package/dist/mcp-config.js +4266 -111
- package/dist/mcp-config.mjs +7 -4
- package/package.json +7 -6
- package/dist/chunk-R657OZE7.mjs +0 -543
package/dist/mcp-config.js
CHANGED
|
@@ -89,11 +89,18 @@ var HttpClient = class {
|
|
|
89
89
|
async request(functionName, body, method = "POST") {
|
|
90
90
|
let lastError;
|
|
91
91
|
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
92
|
+
let timer;
|
|
92
93
|
try {
|
|
93
94
|
const token = await this.getToken();
|
|
94
|
-
const url = `${this.baseUrl}/${functionName}
|
|
95
|
+
const url = new URL(`${this.baseUrl}/${functionName}`);
|
|
96
|
+
if (method === "GET") {
|
|
97
|
+
for (const [key, value] of Object.entries(body)) {
|
|
98
|
+
if (value === void 0 || value === null) continue;
|
|
99
|
+
url.searchParams.set(key, String(value));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
95
102
|
const controller = new AbortController();
|
|
96
|
-
|
|
103
|
+
timer = setTimeout(() => controller.abort(), this.timeout);
|
|
97
104
|
const init = {
|
|
98
105
|
method,
|
|
99
106
|
headers: {
|
|
@@ -106,7 +113,6 @@ var HttpClient = class {
|
|
|
106
113
|
init.body = JSON.stringify(body);
|
|
107
114
|
}
|
|
108
115
|
const res = await fetch(url, init);
|
|
109
|
-
clearTimeout(timer);
|
|
110
116
|
if (!res.ok) {
|
|
111
117
|
const errBody = await res.json().catch(() => ({}));
|
|
112
118
|
const err = parseError(res.status, errBody);
|
|
@@ -139,6 +145,8 @@ var HttpClient = class {
|
|
|
139
145
|
await sleep(1e3 * Math.pow(2, attempt));
|
|
140
146
|
continue;
|
|
141
147
|
}
|
|
148
|
+
} finally {
|
|
149
|
+
if (timer) clearTimeout(timer);
|
|
142
150
|
}
|
|
143
151
|
}
|
|
144
152
|
throw lastError || new Error("Request failed after retries");
|
|
@@ -147,42 +155,90 @@ var HttpClient = class {
|
|
|
147
155
|
async post(functionName, body) {
|
|
148
156
|
return this.request(functionName, body, "POST");
|
|
149
157
|
}
|
|
158
|
+
/** Convenience wrapper for GET-based edge function calls with query params */
|
|
159
|
+
async get(functionName, query = {}) {
|
|
160
|
+
return this.request(functionName, query, "GET");
|
|
161
|
+
}
|
|
150
162
|
/** JSON-RPC call to the MCP server */
|
|
151
163
|
async mcp(method, params = {}) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
method: "POST",
|
|
156
|
-
headers: {
|
|
157
|
-
"Content-Type": "application/json",
|
|
158
|
-
Authorization: `Bearer ${token}`
|
|
159
|
-
},
|
|
160
|
-
body: JSON.stringify({
|
|
161
|
-
jsonrpc: "2.0",
|
|
162
|
-
id: Date.now(),
|
|
163
|
-
method,
|
|
164
|
-
params
|
|
165
|
-
})
|
|
166
|
-
});
|
|
167
|
-
const data = await res.json();
|
|
168
|
-
if (data.error) {
|
|
169
|
-
throw new SignalizError({
|
|
170
|
-
code: data.error.code?.toString() || "MCP_ERROR",
|
|
171
|
-
message: data.error.message || "MCP request failed",
|
|
172
|
-
errorType: "unknown"
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
if (data.result?.content?.[0]?.text) {
|
|
164
|
+
let lastError;
|
|
165
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
166
|
+
let timer;
|
|
176
167
|
try {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
168
|
+
const token = await this.getToken();
|
|
169
|
+
const url = `${this.baseUrl}/signaliz-mcp`;
|
|
170
|
+
const controller = new AbortController();
|
|
171
|
+
timer = setTimeout(() => controller.abort(), this.timeout);
|
|
172
|
+
const res = await fetch(url, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
"Content-Type": "application/json",
|
|
176
|
+
Authorization: `Bearer ${token}`
|
|
177
|
+
},
|
|
178
|
+
body: JSON.stringify({
|
|
179
|
+
jsonrpc: "2.0",
|
|
180
|
+
id: Date.now(),
|
|
181
|
+
method,
|
|
182
|
+
params: normalizeMcpParams(method, params)
|
|
183
|
+
}),
|
|
184
|
+
signal: controller.signal
|
|
185
|
+
});
|
|
186
|
+
const text = await res.text();
|
|
187
|
+
const data = safeJson(text);
|
|
188
|
+
if (!res.ok) {
|
|
189
|
+
const err = parseError(res.status, data ?? { message: text });
|
|
190
|
+
if (err.isRetryable && attempt < this.maxRetries) {
|
|
191
|
+
lastError = err;
|
|
192
|
+
await sleep(err.retryAfter ? err.retryAfter * 1e3 : Math.min(1e3 * Math.pow(2, attempt), 1e4));
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
throw err;
|
|
196
|
+
}
|
|
197
|
+
if (!data) {
|
|
198
|
+
throw new SignalizError({
|
|
199
|
+
code: "INVALID_JSON",
|
|
200
|
+
message: "MCP response was not valid JSON",
|
|
201
|
+
errorType: "provider_error",
|
|
202
|
+
details: { responseText: text.slice(0, 500) }
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
const responseError = isRecord(data) && isRecord(data.error) ? data.error : null;
|
|
206
|
+
if (responseError) {
|
|
207
|
+
const err = new SignalizError({
|
|
208
|
+
code: firstString(responseError.code, isRecord(responseError.data) ? responseError.data.error_code : void 0) || "MCP_ERROR",
|
|
209
|
+
message: firstString(responseError.message) || "MCP request failed",
|
|
210
|
+
errorType: mapMcpErrorType(responseError),
|
|
211
|
+
retryAfter: isRecord(responseError.data) && typeof responseError.data.retry_after === "number" ? responseError.data.retry_after : void 0,
|
|
212
|
+
details: isRecord(responseError.data) ? responseError.data : void 0
|
|
213
|
+
});
|
|
214
|
+
if (err.isRetryable && attempt < this.maxRetries) {
|
|
215
|
+
lastError = err;
|
|
216
|
+
await sleep(err.retryAfter ? err.retryAfter * 1e3 : Math.min(1e3 * Math.pow(2, attempt), 1e4));
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
return unwrapMcpResponse(data);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
if (e instanceof SignalizError && !e.isRetryable) throw e;
|
|
224
|
+
if (e.name === "AbortError") {
|
|
225
|
+
lastError = new SignalizError({
|
|
226
|
+
code: "TIMEOUT",
|
|
227
|
+
message: `MCP request timed out after ${this.timeout}ms`,
|
|
228
|
+
errorType: "timeout"
|
|
229
|
+
});
|
|
230
|
+
} else {
|
|
231
|
+
lastError = e;
|
|
232
|
+
}
|
|
233
|
+
if (attempt < this.maxRetries) {
|
|
234
|
+
await sleep(Math.min(1e3 * Math.pow(2, attempt), 1e4));
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
} finally {
|
|
238
|
+
if (timer) clearTimeout(timer);
|
|
180
239
|
}
|
|
181
240
|
}
|
|
182
|
-
|
|
183
|
-
return data.result.structuredContent;
|
|
184
|
-
}
|
|
185
|
-
return data.result;
|
|
241
|
+
throw lastError || new Error("MCP request failed after retries");
|
|
186
242
|
}
|
|
187
243
|
async getToken() {
|
|
188
244
|
if (this.apiKey) return this.apiKey;
|
|
@@ -211,6 +267,110 @@ var HttpClient = class {
|
|
|
211
267
|
function sleep(ms) {
|
|
212
268
|
return new Promise((r) => setTimeout(r, ms));
|
|
213
269
|
}
|
|
270
|
+
function safeJson(text) {
|
|
271
|
+
try {
|
|
272
|
+
return JSON.parse(text);
|
|
273
|
+
} catch {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function normalizeMcpParams(method, params) {
|
|
278
|
+
if (method !== "tools/call") return params;
|
|
279
|
+
const args = params.arguments;
|
|
280
|
+
if (!args || typeof args !== "object" || Array.isArray(args)) return params;
|
|
281
|
+
return {
|
|
282
|
+
...params,
|
|
283
|
+
arguments: {
|
|
284
|
+
output_format: "json",
|
|
285
|
+
...args
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function isRecord(value) {
|
|
290
|
+
return typeof value === "object" && value !== null;
|
|
291
|
+
}
|
|
292
|
+
function firstString(...values) {
|
|
293
|
+
const value = values.find((item) => typeof item === "string" && item.length > 0);
|
|
294
|
+
return typeof value === "string" ? value : void 0;
|
|
295
|
+
}
|
|
296
|
+
function firstPayloadError(payload) {
|
|
297
|
+
const errors = payload.errors;
|
|
298
|
+
const first = Array.isArray(errors) ? errors[0] : void 0;
|
|
299
|
+
return isRecord(first) ? first : {};
|
|
300
|
+
}
|
|
301
|
+
function unwrapMcpResponse(data) {
|
|
302
|
+
const result = isRecord(data) ? data.result : void 0;
|
|
303
|
+
if (isRecord(result) && result.structuredContent !== void 0) {
|
|
304
|
+
return unwrapMcpPayload(result.structuredContent);
|
|
305
|
+
}
|
|
306
|
+
const content = isRecord(result) ? result.content : void 0;
|
|
307
|
+
const firstContent = Array.isArray(content) ? content[0] : void 0;
|
|
308
|
+
const text = isRecord(firstContent) ? firstContent.text : void 0;
|
|
309
|
+
if (typeof text === "string") {
|
|
310
|
+
const parsed = safeJson(text);
|
|
311
|
+
return unwrapMcpPayload(parsed ?? text);
|
|
312
|
+
}
|
|
313
|
+
return unwrapMcpPayload(result);
|
|
314
|
+
}
|
|
315
|
+
function unwrapMcpPayload(payload) {
|
|
316
|
+
if (isRecord(payload)) {
|
|
317
|
+
if (payload.ok === true && Object.prototype.hasOwnProperty.call(payload, "result")) {
|
|
318
|
+
return payload.result;
|
|
319
|
+
}
|
|
320
|
+
if (payload.ok === false) {
|
|
321
|
+
const first = firstPayloadError(payload);
|
|
322
|
+
const code = firstString(first.code, payload.error_code, payload.code) || (payload.approval_required ? "APPROVAL_REQUIRED" : "MCP_ERROR");
|
|
323
|
+
throw new SignalizError({
|
|
324
|
+
code,
|
|
325
|
+
message: firstString(first.message, payload.message, payload.summary, payload.error) || "MCP request failed",
|
|
326
|
+
errorType: mapErrorTypeFromCode(code),
|
|
327
|
+
details: {
|
|
328
|
+
...payload,
|
|
329
|
+
...isRecord(first.details) ? first.details : {}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (payload.success === true && Object.prototype.hasOwnProperty.call(payload, "data")) {
|
|
334
|
+
return payload.data;
|
|
335
|
+
}
|
|
336
|
+
if (payload.success === false) {
|
|
337
|
+
const first = firstPayloadError(payload);
|
|
338
|
+
const code = firstString(first.code, payload.error_code) || (payload.approval_required ? "APPROVAL_REQUIRED" : "MCP_ERROR");
|
|
339
|
+
throw new SignalizError({
|
|
340
|
+
code,
|
|
341
|
+
message: firstString(first.message, payload.message, payload.summary) || "MCP request failed",
|
|
342
|
+
errorType: mapErrorTypeFromCode(code),
|
|
343
|
+
details: {
|
|
344
|
+
...payload,
|
|
345
|
+
...isRecord(first.details) ? first.details : {}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return payload;
|
|
351
|
+
}
|
|
352
|
+
function mapMcpErrorType(error) {
|
|
353
|
+
const errorRecord = isRecord(error) ? error : {};
|
|
354
|
+
const data = isRecord(errorRecord.data) ? errorRecord.data : {};
|
|
355
|
+
const code = String(data.error_code || errorRecord.code || "");
|
|
356
|
+
const message = String(errorRecord.message || "").toLowerCase();
|
|
357
|
+
if (code === "429" || message.includes("rate limit")) return "rate_limited";
|
|
358
|
+
if (code === "401" || code === "AUTH_001" || message.includes("auth")) return "auth_expired";
|
|
359
|
+
if (code === "400" || code === "-32602" || message.includes("invalid")) return "validation";
|
|
360
|
+
if (code === "404" || message.includes("not found")) return "not_found";
|
|
361
|
+
if (message.includes("timeout") || message.includes("timed out")) return "timeout";
|
|
362
|
+
return "unknown";
|
|
363
|
+
}
|
|
364
|
+
function mapErrorTypeFromCode(code) {
|
|
365
|
+
if (!code) return "unknown";
|
|
366
|
+
if (code === "RATE_LIMITED") return "rate_limited";
|
|
367
|
+
if (code === "INVALID_ARGUMENT" || code === "VALIDATION_ERROR" || code === "VALIDATION_001" || code === "APPROVAL_REQUIRED" || code === "WEBHOOK_APPROVAL_REQUIRED" || code === "TARGET_LIMIT_EXCEEDED") return "validation";
|
|
368
|
+
if (code === "AUTH_REQUIRED" || code === "AUTH_001") return "auth_expired";
|
|
369
|
+
if (code === "QUOTA_EXCEEDED") return "insufficient_credits";
|
|
370
|
+
if (code === "BUILD_NOT_READY" || code === "ARTIFACT_NOT_READY") return "not_found";
|
|
371
|
+
if (code === "BUILD_FAILED" || code === "INTERNAL_ERROR") return "provider_error";
|
|
372
|
+
return "unknown";
|
|
373
|
+
}
|
|
214
374
|
|
|
215
375
|
// src/resources/emails.ts
|
|
216
376
|
var Emails = class {
|
|
@@ -256,7 +416,57 @@ var Emails = class {
|
|
|
256
416
|
verificationSource: data.verification_source
|
|
257
417
|
};
|
|
258
418
|
}
|
|
419
|
+
/** Submit up to 5,000 contacts for async find + verify processing. */
|
|
420
|
+
async findBatch(contacts) {
|
|
421
|
+
const data = await this.client.mcp("tools/call", {
|
|
422
|
+
name: "find_and_verify_emails",
|
|
423
|
+
arguments: {
|
|
424
|
+
contacts: contacts.map((contact) => ({
|
|
425
|
+
full_name: contact.fullName,
|
|
426
|
+
first_name: contact.firstName,
|
|
427
|
+
last_name: contact.lastName,
|
|
428
|
+
company_domain: contact.companyDomain,
|
|
429
|
+
linkedin_url: contact.linkedinUrl,
|
|
430
|
+
company_name: contact.companyName
|
|
431
|
+
}))
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
return mapBatchJob(data, "find_and_verify_emails");
|
|
435
|
+
}
|
|
436
|
+
/** Submit up to 5,000 email addresses for async verification. */
|
|
437
|
+
async verifyBatch(emails) {
|
|
438
|
+
const data = await this.client.mcp("tools/call", {
|
|
439
|
+
name: "verify_emails",
|
|
440
|
+
arguments: { emails }
|
|
441
|
+
});
|
|
442
|
+
return mapBatchJob(data, "verify_emails");
|
|
443
|
+
}
|
|
444
|
+
/** Poll a batch email job returned by findBatch or verifyBatch. */
|
|
445
|
+
async checkStatus(jobId, opts) {
|
|
446
|
+
return this.client.mcp("tools/call", {
|
|
447
|
+
name: "check_job_status",
|
|
448
|
+
arguments: {
|
|
449
|
+
job_id: jobId,
|
|
450
|
+
page: opts?.page,
|
|
451
|
+
page_size: opts?.pageSize,
|
|
452
|
+
include_partial_results: opts?.includePartialResults
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
259
456
|
};
|
|
457
|
+
function mapBatchJob(data, fallbackCapability) {
|
|
458
|
+
return {
|
|
459
|
+
jobId: data.job_id,
|
|
460
|
+
status: data.status,
|
|
461
|
+
capability: data.capability ?? fallbackCapability,
|
|
462
|
+
itemsTotal: data.items_total ?? data.total ?? 0,
|
|
463
|
+
message: data.message ?? "",
|
|
464
|
+
estimatedTimeSeconds: data.estimated_time_seconds,
|
|
465
|
+
skippedCount: data.skipped_count,
|
|
466
|
+
queuePosition: data.queue_position,
|
|
467
|
+
estimatedStartTime: data.estimated_start_time
|
|
468
|
+
};
|
|
469
|
+
}
|
|
260
470
|
|
|
261
471
|
// src/resources/signals.ts
|
|
262
472
|
var Signals = class {
|
|
@@ -444,25 +654,19 @@ var Runs = class {
|
|
|
444
654
|
constructor(client) {
|
|
445
655
|
this.client = client;
|
|
446
656
|
}
|
|
447
|
-
/** Get run status */
|
|
657
|
+
/** Get run status across Trigger, batch, and dataplane runs. */
|
|
448
658
|
async get(runId) {
|
|
449
659
|
const data = await this.client.mcp("tools/call", {
|
|
450
|
-
name: "
|
|
660
|
+
name: "get_run",
|
|
451
661
|
arguments: { run_id: runId }
|
|
452
662
|
});
|
|
453
|
-
return
|
|
454
|
-
runId: data.run_id ?? runId,
|
|
455
|
-
status: data.status,
|
|
456
|
-
totalRows: data.total_rows,
|
|
457
|
-
completedRows: data.completed_rows ?? 0,
|
|
458
|
-
creditsUsed: data.credits_used ?? 0
|
|
459
|
-
};
|
|
663
|
+
return normalizeRunResult(data, runId);
|
|
460
664
|
}
|
|
461
665
|
/** Poll until a run completes. Returns final result. */
|
|
462
666
|
async waitForCompletion(runId, pollIntervalMs = 2e3) {
|
|
463
667
|
while (true) {
|
|
464
668
|
const run = await this.get(runId);
|
|
465
|
-
if (
|
|
669
|
+
if (isTerminalRunStatus(run.status)) {
|
|
466
670
|
return run;
|
|
467
671
|
}
|
|
468
672
|
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
@@ -487,13 +691,54 @@ var Runs = class {
|
|
|
487
691
|
lastCompleted = event.completedRows;
|
|
488
692
|
yield event;
|
|
489
693
|
}
|
|
490
|
-
if (
|
|
694
|
+
if (isTerminalRunStatus(run.status)) {
|
|
491
695
|
return;
|
|
492
696
|
}
|
|
493
697
|
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
494
698
|
}
|
|
495
699
|
}
|
|
496
700
|
};
|
|
701
|
+
function normalizeRunResult(data, fallbackRunId) {
|
|
702
|
+
const progress = data?.progress && typeof data.progress === "object" ? data.progress : {};
|
|
703
|
+
const status = String(data?.status ?? data?.trigger_status ?? "unknown").toLowerCase();
|
|
704
|
+
const totalRows = numberOrUndefined(
|
|
705
|
+
data?.total_rows ?? data?.totalRows ?? data?.items_total ?? progress.items_total ?? progress.total ?? data?.results_count
|
|
706
|
+
);
|
|
707
|
+
const completedRows = numberOrUndefined(
|
|
708
|
+
data?.completed_rows ?? data?.completedRows ?? progress.items_completed ?? progress.items_succeeded ?? progress.completed ?? data?.results_count
|
|
709
|
+
);
|
|
710
|
+
return {
|
|
711
|
+
runId: data?.run_id ?? data?.job_id ?? fallbackRunId,
|
|
712
|
+
status,
|
|
713
|
+
totalRows,
|
|
714
|
+
completedRows: completedRows ?? 0,
|
|
715
|
+
creditsUsed: numberOrUndefined(data?.credits_used ?? data?.creditsUsed ?? data?.credits_consumed) ?? 0,
|
|
716
|
+
completed: data?.completed ?? isTerminalRunStatus(status),
|
|
717
|
+
retryEligible: data?.retry_eligible,
|
|
718
|
+
triggerStatus: data?.trigger_status,
|
|
719
|
+
output: data?.output ?? data?.results ?? data?.results_preview,
|
|
720
|
+
error: data?.error ?? data?.error_message,
|
|
721
|
+
message: data?.message,
|
|
722
|
+
recoveryGuidance: data?.recovery_guidance,
|
|
723
|
+
raw: data
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
function numberOrUndefined(value) {
|
|
727
|
+
const number = Number(value);
|
|
728
|
+
return Number.isFinite(number) ? number : void 0;
|
|
729
|
+
}
|
|
730
|
+
function isTerminalRunStatus(status) {
|
|
731
|
+
return [
|
|
732
|
+
"completed",
|
|
733
|
+
"failed",
|
|
734
|
+
"cancelled",
|
|
735
|
+
"canceled",
|
|
736
|
+
"crashed",
|
|
737
|
+
"timed_out",
|
|
738
|
+
"interrupted",
|
|
739
|
+
"system_failure"
|
|
740
|
+
].includes(String(status || "").toLowerCase());
|
|
741
|
+
}
|
|
497
742
|
|
|
498
743
|
// src/resources/http.ts
|
|
499
744
|
var Http = class {
|
|
@@ -519,87 +764,3997 @@ var Http = class {
|
|
|
519
764
|
}
|
|
520
765
|
};
|
|
521
766
|
|
|
522
|
-
// src/
|
|
523
|
-
var
|
|
524
|
-
constructor(
|
|
525
|
-
this.client =
|
|
526
|
-
this.emails = new Emails(this.client);
|
|
527
|
-
this.signals = new Signals(this.client);
|
|
528
|
-
this.systems = new Systems(this.client);
|
|
529
|
-
this.runs = new Runs(this.client);
|
|
530
|
-
this.http = new Http(this.client);
|
|
767
|
+
// src/resources/campaigns.ts
|
|
768
|
+
var Campaigns = class {
|
|
769
|
+
constructor(client) {
|
|
770
|
+
this.client = client;
|
|
531
771
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
772
|
+
// ── First-class shorthand API ──────────────────────────────────────────────
|
|
773
|
+
/**
|
|
774
|
+
* Start an async Campaign Build.
|
|
775
|
+
* Returns immediately with a pollable campaign_build_id.
|
|
776
|
+
*
|
|
777
|
+
* ```ts
|
|
778
|
+
* const result = await signaliz.campaigns.build({ name: 'Q3 SaaS', prompt: '...' });
|
|
779
|
+
* console.log(result.campaignBuildId);
|
|
780
|
+
* ```
|
|
781
|
+
*/
|
|
782
|
+
async build(request, options) {
|
|
783
|
+
return this.buildCampaign(request, options);
|
|
784
|
+
}
|
|
785
|
+
/** Scope an agency/client campaign into a markdown brief plus build_campaign dry-run args. */
|
|
786
|
+
async scope(request) {
|
|
787
|
+
return this.scopeCampaign(request);
|
|
788
|
+
}
|
|
789
|
+
/** Get a concise status snapshot — ideal for polling loops. */
|
|
790
|
+
async status(campaignBuildId) {
|
|
791
|
+
return this.getCampaignBuildStatus(campaignBuildId);
|
|
792
|
+
}
|
|
793
|
+
/** Get the full campaign build record including delivery details. */
|
|
794
|
+
async get(campaignBuildId) {
|
|
795
|
+
const data = await this.callMcp("get_campaign_build", {
|
|
796
|
+
campaign_build_id: campaignBuildId
|
|
797
|
+
});
|
|
798
|
+
return mapStatus(data);
|
|
799
|
+
}
|
|
800
|
+
/** Retrieve paginated rows from a completed build. */
|
|
801
|
+
async rows(campaignBuildId, options) {
|
|
802
|
+
return this.getCampaignBuildRows(campaignBuildId, options);
|
|
803
|
+
}
|
|
804
|
+
/** List all artifacts (CSV exports, etc.) for a build. */
|
|
805
|
+
async artifacts(campaignBuildId) {
|
|
806
|
+
return this.listCampaignBuildArtifacts(campaignBuildId);
|
|
807
|
+
}
|
|
808
|
+
/** Cancel a queued or running build. */
|
|
809
|
+
async cancel(campaignBuildId, reason) {
|
|
810
|
+
return this.cancelCampaignBuild(campaignBuildId, reason);
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Poll until a campaign build reaches a terminal status.
|
|
814
|
+
*
|
|
815
|
+
* ```ts
|
|
816
|
+
* const final = await signaliz.campaigns.wait(buildId, {
|
|
817
|
+
* onProgress: (s) => console.log(`${s.recordsProcessed}/${s.recordsTotal}`),
|
|
818
|
+
* });
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
async wait(campaignBuildId, options) {
|
|
822
|
+
return this.waitForCompletion(campaignBuildId, {
|
|
823
|
+
intervalMs: options?.intervalMs,
|
|
824
|
+
timeoutMs: options?.timeoutMs,
|
|
825
|
+
onStatus: options?.onProgress
|
|
537
826
|
});
|
|
827
|
+
}
|
|
828
|
+
// ── Full method names (kept for backward-compat) ───────────────────────────
|
|
829
|
+
async scopeCampaign(request) {
|
|
830
|
+
const data = await this.callMcp("scope_campaign", scopeArgs(request));
|
|
831
|
+
return mapScope(data);
|
|
832
|
+
}
|
|
833
|
+
async buildCampaign(request, options) {
|
|
834
|
+
const args = buildArgs(request);
|
|
835
|
+
if (options?.idempotencyKey) {
|
|
836
|
+
args.idempotency_key = options.idempotencyKey;
|
|
837
|
+
}
|
|
838
|
+
const data = await this.callMcp("build_campaign", args);
|
|
538
839
|
return {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
840
|
+
campaignBuildId: data.campaign_build_id ?? null,
|
|
841
|
+
campaignId: data.campaign_id ?? null,
|
|
842
|
+
campaignObject: data.campaign_object ?? null,
|
|
843
|
+
status: data.dry_run ? "dry_run" : data.status ?? "queued",
|
|
844
|
+
currentPhase: data.dry_run ? "plan" : data.current_phase ?? "acquisition",
|
|
845
|
+
nextPollAfterSeconds: data.next_poll_after_seconds ?? 10,
|
|
846
|
+
message: data.message ?? data.summary ?? "",
|
|
847
|
+
dryRun: data.dry_run === true,
|
|
848
|
+
requestedTargetCount: data.requested_target_count,
|
|
849
|
+
plannedTargetCount: data.planned_target_count,
|
|
850
|
+
estimatedCredits: data.estimated_credits,
|
|
851
|
+
estimatedDurationSeconds: data.estimated_duration_seconds,
|
|
852
|
+
targetLimitApplied: data.target_limit_applied,
|
|
853
|
+
targetLimitReason: data.target_limit_reason,
|
|
854
|
+
maxSupportedTargetCount: data.max_supported_target_count,
|
|
855
|
+
brainContext: data.brain_context ?? {},
|
|
856
|
+
providerRoute: mapProviderRoute(data)
|
|
543
857
|
};
|
|
544
858
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
return
|
|
550
|
-
name: t.name,
|
|
551
|
-
description: (t.description ?? "").slice(0, 120),
|
|
552
|
-
category: t.annotations?.category,
|
|
553
|
-
costCredits: t.annotations?.cost_credits
|
|
554
|
-
}));
|
|
859
|
+
async getCampaignBuildStatus(campaignBuildId) {
|
|
860
|
+
const data = await this.callMcp("get_campaign_build_status", {
|
|
861
|
+
campaign_build_id: campaignBuildId
|
|
862
|
+
});
|
|
863
|
+
return mapStatus(data);
|
|
555
864
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
name: "discover_capabilities",
|
|
560
|
-
arguments: { query, category }
|
|
865
|
+
async listCampaignBuildArtifacts(campaignBuildId) {
|
|
866
|
+
const data = await this.callMcp("list_campaign_build_artifacts", {
|
|
867
|
+
campaign_build_id: campaignBuildId
|
|
561
868
|
});
|
|
562
|
-
return (data.
|
|
563
|
-
name: m.tool,
|
|
564
|
-
description: m.description,
|
|
565
|
-
category: m.category,
|
|
566
|
-
costCredits: m.cost_credits
|
|
567
|
-
}));
|
|
869
|
+
return (data.artifacts ?? []).map(mapArtifact);
|
|
568
870
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
871
|
+
async getCampaignBuildRows(campaignBuildId, options) {
|
|
872
|
+
const args = { campaign_build_id: campaignBuildId };
|
|
873
|
+
if (options?.limit) args.page_size = options.limit;
|
|
874
|
+
if (options?.cursor) args.cursor = options.cursor;
|
|
875
|
+
const filters = {};
|
|
876
|
+
if (options?.segment) filters.segment = options.segment;
|
|
877
|
+
if (options?.rowStatus) filters.row_status = options.rowStatus;
|
|
878
|
+
if (options?.qualified !== void 0) filters.qualified = options.qualified;
|
|
879
|
+
if (Object.keys(filters).length > 0) args.filters = filters;
|
|
880
|
+
const data = await this.callMcp("get_campaign_build_rows", args);
|
|
881
|
+
return {
|
|
882
|
+
campaignBuildId: data.campaign_build_id,
|
|
883
|
+
rows: (data.rows ?? []).map((r, i) => ({
|
|
884
|
+
index: r.index ?? i,
|
|
885
|
+
status: r.status ?? r.row_status ?? "unknown",
|
|
886
|
+
qualified: r.qualified ?? true,
|
|
887
|
+
segment: r.segment ?? null,
|
|
888
|
+
data: r.data ?? r
|
|
889
|
+
})),
|
|
890
|
+
count: data.count ?? 0,
|
|
891
|
+
pageSize: data.page_size ?? 50,
|
|
892
|
+
nextCursor: data.next_cursor ?? null,
|
|
893
|
+
hasMore: data.has_more ?? false
|
|
894
|
+
};
|
|
578
895
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
896
|
+
async approveCampaignDelivery(campaignBuildId, destinationType, options) {
|
|
897
|
+
const args = {
|
|
898
|
+
campaign_build_id: campaignBuildId,
|
|
899
|
+
destination_type: destinationType
|
|
900
|
+
};
|
|
901
|
+
if (options?.destinationId) args.destination_id = options.destinationId;
|
|
902
|
+
if (options?.destinationConfig) args.destination_config = options.destinationConfig;
|
|
903
|
+
const data = await this.callMcp("approve_campaign_delivery", args);
|
|
904
|
+
return {
|
|
905
|
+
campaignBuildId: data.campaign_build_id,
|
|
906
|
+
destinationType: data.destination_type ?? destinationType,
|
|
907
|
+
status: data.status ?? "approved",
|
|
908
|
+
message: data.message ?? "",
|
|
909
|
+
deliveryId: data.delivery_id,
|
|
910
|
+
deliveryIds: data.delivery_ids,
|
|
911
|
+
approvedCount: data.approved_count
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
async cancelCampaignBuild(campaignBuildId, reason) {
|
|
915
|
+
const data = await this.callMcp("cancel_campaign_build", {
|
|
916
|
+
campaign_build_id: campaignBuildId,
|
|
917
|
+
reason: reason ?? "Canceled by user"
|
|
918
|
+
});
|
|
919
|
+
return {
|
|
920
|
+
campaignBuildId: data.campaign_build_id,
|
|
921
|
+
status: data.status ?? "canceled",
|
|
922
|
+
reason: data.reason ?? reason ?? "",
|
|
923
|
+
message: data.message ?? ""
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
async waitForCompletion(campaignBuildId, options) {
|
|
927
|
+
const interval = options?.intervalMs ?? 5e3;
|
|
928
|
+
const timeout = options?.timeoutMs ?? 6e5;
|
|
929
|
+
const start = Date.now();
|
|
930
|
+
while (true) {
|
|
931
|
+
const s = await this.getCampaignBuildStatus(campaignBuildId);
|
|
932
|
+
options?.onStatus?.(s);
|
|
933
|
+
if (["completed", "failed", "canceled"].includes(s.status)) {
|
|
934
|
+
return s;
|
|
935
|
+
}
|
|
936
|
+
if (Date.now() - start > timeout) {
|
|
937
|
+
throw new Error(`Campaign build ${campaignBuildId} timed out after ${timeout}ms (status: ${s.status})`);
|
|
938
|
+
}
|
|
939
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
940
|
+
}
|
|
582
941
|
}
|
|
942
|
+
// ── Internal helpers ─────────────────────────────────────────────────────────
|
|
943
|
+
async callMcp(tool, args) {
|
|
944
|
+
return this.client.mcp("tools/call", { name: tool, arguments: args });
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
function mapStatus(data) {
|
|
583
948
|
return {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
949
|
+
campaignBuildId: data.campaign_build_id,
|
|
950
|
+
campaignId: data.campaign_id ?? null,
|
|
951
|
+
campaignObject: data.campaign_object ?? null,
|
|
952
|
+
name: data.name,
|
|
953
|
+
status: data.status,
|
|
954
|
+
currentPhase: data.current_phase,
|
|
955
|
+
currentPhaseStatus: data.current_phase_status,
|
|
956
|
+
phases: data.phases ?? [],
|
|
957
|
+
recordsTotal: data.records_total ?? 0,
|
|
958
|
+
recordsProcessed: data.records_processed ?? 0,
|
|
959
|
+
recordsSucceeded: data.records_succeeded ?? 0,
|
|
960
|
+
recordsFailed: data.records_failed ?? 0,
|
|
961
|
+
warnings: data.warnings ?? [],
|
|
962
|
+
errors: data.errors ?? [],
|
|
963
|
+
artifactCount: data.artifact_count ?? 0,
|
|
964
|
+
providerRoute: mapProviderRoute(data),
|
|
965
|
+
nextAction: data.next_action ?? "",
|
|
966
|
+
createdAt: data.created_at,
|
|
967
|
+
updatedAt: data.updated_at,
|
|
968
|
+
completedAt: data.completed_at
|
|
587
969
|
};
|
|
588
970
|
}
|
|
589
|
-
function
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
971
|
+
function mapProviderRoute(data) {
|
|
972
|
+
const brainContext = recordOrNull(data?.brain_context);
|
|
973
|
+
const plan = recordOrNull(data?.provider_route_plan) ?? recordOrNull(brainContext?.provider_route_plan);
|
|
974
|
+
const summary = recordOrNull(data?.provider_route_summary) ?? recordOrNull(brainContext?.provider_route_summary) ?? recordOrNull(plan?.summary);
|
|
975
|
+
const blockers = stringArray(data?.provider_route_blockers ?? brainContext?.provider_route_blockers ?? plan?.blockers);
|
|
976
|
+
const warnings = stringArray(data?.provider_route_warnings ?? brainContext?.provider_route_warnings ?? plan?.warnings);
|
|
977
|
+
const ready = booleanOrNull(data?.provider_route_ready ?? brainContext?.provider_route_ready ?? plan?.ready);
|
|
978
|
+
const label = typeof data?.provider_route_label === "string" ? data.provider_route_label : typeof brainContext?.provider_route_label === "string" ? brainContext.provider_route_label : providerRouteLabel(summary, ready);
|
|
979
|
+
if (!plan && !summary && ready === null && blockers.length === 0 && warnings.length === 0 && !label) {
|
|
980
|
+
return null;
|
|
981
|
+
}
|
|
982
|
+
return {
|
|
983
|
+
plan,
|
|
984
|
+
summary,
|
|
985
|
+
ready,
|
|
986
|
+
label: label || "attached",
|
|
987
|
+
blockers,
|
|
988
|
+
warnings
|
|
989
|
+
};
|
|
597
990
|
}
|
|
598
|
-
function
|
|
991
|
+
function recordOrNull(value) {
|
|
992
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
993
|
+
}
|
|
994
|
+
function stringArray(value) {
|
|
995
|
+
return Array.isArray(value) ? value.map((item) => String(item || "").trim()).filter(Boolean) : [];
|
|
996
|
+
}
|
|
997
|
+
function booleanOrNull(value) {
|
|
998
|
+
return typeof value === "boolean" ? value : null;
|
|
999
|
+
}
|
|
1000
|
+
function numberOrNull(value) {
|
|
1001
|
+
const parsed = Number(value);
|
|
1002
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1003
|
+
}
|
|
1004
|
+
function providerRouteLabel(summary, ready) {
|
|
1005
|
+
if (!summary) return ready === true ? "ready" : ready === false ? "blocked" : "";
|
|
1006
|
+
const totalLayers = numberOrNull(summary.total_layers);
|
|
1007
|
+
const readyLayers = numberOrNull(summary.ready_layers);
|
|
1008
|
+
const customProviderLayers = numberOrNull(summary.custom_provider_layers);
|
|
1009
|
+
const signalizDefaultLayers = numberOrNull(summary.signaliz_default_layers);
|
|
1010
|
+
const fallbackLayers = numberOrNull(summary.fallback_layers);
|
|
1011
|
+
const blockedLayers = numberOrNull(summary.blocked_layers);
|
|
1012
|
+
return [
|
|
1013
|
+
totalLayers === null || readyLayers === null ? ready === true ? "ready" : ready === false ? "blocked" : null : `${readyLayers}/${totalLayers} layers ready`,
|
|
1014
|
+
customProviderLayers !== null ? `${customProviderLayers} custom` : null,
|
|
1015
|
+
signalizDefaultLayers !== null ? `${signalizDefaultLayers} Signaliz default` : null,
|
|
1016
|
+
fallbackLayers !== null ? `${fallbackLayers} fallback` : null,
|
|
1017
|
+
blockedLayers !== null ? `${blockedLayers} blocked` : null
|
|
1018
|
+
].filter(Boolean).join(", ");
|
|
1019
|
+
}
|
|
1020
|
+
function mapArtifact(a) {
|
|
599
1021
|
return {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
1022
|
+
id: a.id,
|
|
1023
|
+
campaignBuildId: a.campaign_build_id,
|
|
1024
|
+
artifactType: a.artifact_type,
|
|
1025
|
+
destination: a.destination,
|
|
1026
|
+
storagePath: a.storage_path,
|
|
1027
|
+
signedUrl: a.signed_url,
|
|
1028
|
+
rowCount: a.row_count ?? 0,
|
|
1029
|
+
checksum: a.checksum,
|
|
1030
|
+
metadata: a.metadata ?? {},
|
|
1031
|
+
createdAt: a.created_at
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
function mapScope(data) {
|
|
1035
|
+
return {
|
|
1036
|
+
campaignScopeId: data.campaign_scope_id,
|
|
1037
|
+
clientName: data.client_name,
|
|
1038
|
+
campaignName: data.campaign_name,
|
|
1039
|
+
approach: data.approach,
|
|
1040
|
+
approachLabel: data.approach_label,
|
|
1041
|
+
goal: data.goal,
|
|
1042
|
+
targetCount: data.target_count,
|
|
1043
|
+
icp: data.icp ?? {},
|
|
1044
|
+
personas: data.personas ?? [],
|
|
1045
|
+
sourceStrategy: data.source_strategy ?? [],
|
|
1046
|
+
qualificationPlan: data.qualification_plan ?? [],
|
|
1047
|
+
signalPlan: data.signal_plan ?? [],
|
|
1048
|
+
copyPlan: data.copy_plan ?? {},
|
|
1049
|
+
deliveryPlan: data.delivery_plan ?? {},
|
|
1050
|
+
brainPreflight: data.brain_preflight ?? {},
|
|
1051
|
+
recommendedSignalizTools: data.recommended_signaliz_tools ?? [],
|
|
1052
|
+
buildCampaignArgs: data.build_campaign_args ?? {},
|
|
1053
|
+
mcpFlow: data.mcp_flow ?? [],
|
|
1054
|
+
missingInputs: data.missing_inputs ?? [],
|
|
1055
|
+
estimatedCredits: data.estimated_credits ?? 0,
|
|
1056
|
+
campaignMarkdown: data.campaign_markdown ?? ""
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function scopeArgs(request) {
|
|
1060
|
+
const args = {
|
|
1061
|
+
prompt: request.prompt
|
|
1062
|
+
};
|
|
1063
|
+
if (request.clientName) args.client_name = request.clientName;
|
|
1064
|
+
if (request.clientContext) args.client_context = request.clientContext;
|
|
1065
|
+
if (request.campaignGoal) args.campaign_goal = request.campaignGoal;
|
|
1066
|
+
if (request.targetCount) args.target_count = request.targetCount;
|
|
1067
|
+
if (request.destinations) args.destinations = request.destinations;
|
|
1068
|
+
if (request.knownAccounts) args.known_accounts = request.knownAccounts;
|
|
1069
|
+
if (request.offers) args.offers = request.offers;
|
|
1070
|
+
if (request.proofPoints) args.proof_points = request.proofPoints;
|
|
1071
|
+
if (request.sourceDocs) args.source_docs = request.sourceDocs;
|
|
1072
|
+
if (request.approvalPolicy) args.approval_policy = request.approvalPolicy;
|
|
1073
|
+
return args;
|
|
1074
|
+
}
|
|
1075
|
+
function buildArgs(request) {
|
|
1076
|
+
const args = {
|
|
1077
|
+
name: request.name,
|
|
1078
|
+
prompt: request.prompt
|
|
1079
|
+
};
|
|
1080
|
+
if (request.gtmCampaignId) args.gtm_campaign_id = request.gtmCampaignId;
|
|
1081
|
+
if (request.description) args.description = request.description;
|
|
1082
|
+
if (request.targetCount) args.target_count = request.targetCount;
|
|
1083
|
+
if (request.dryRun !== void 0) args.dry_run = request.dryRun;
|
|
1084
|
+
if (request.allowDownscale !== void 0) args.allow_downscale = request.allowDownscale;
|
|
1085
|
+
if (request.confirmSpend !== void 0) args.confirm_spend = request.confirmSpend;
|
|
1086
|
+
if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
|
|
1087
|
+
if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
|
|
1088
|
+
if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
|
|
1089
|
+
if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
|
|
1090
|
+
if (request.icp) {
|
|
1091
|
+
args.icp = {
|
|
1092
|
+
personas: request.icp.personas,
|
|
1093
|
+
industries: request.icp.industries,
|
|
1094
|
+
company_sizes: request.icp.companySizes,
|
|
1095
|
+
geographies: request.icp.geographies,
|
|
1096
|
+
keywords: request.icp.keywords,
|
|
1097
|
+
exclusions: request.icp.exclusions,
|
|
1098
|
+
require_verified_email: request.icp.requireVerifiedEmail
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
if (request.policy) {
|
|
1102
|
+
args.policy = {
|
|
1103
|
+
max_credits: request.policy.maxCredits,
|
|
1104
|
+
verify_emails: request.policy.verifyEmails,
|
|
1105
|
+
model: request.policy.model
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
if (request.signals) {
|
|
1109
|
+
args.signals = {
|
|
1110
|
+
enabled: request.signals.enabled,
|
|
1111
|
+
types: request.signals.types,
|
|
1112
|
+
custom_prompt: request.signals.customPrompt,
|
|
1113
|
+
confidence_threshold: request.signals.confidenceThreshold,
|
|
1114
|
+
lookback_days: request.signals.lookbackDays
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
if (request.qualification) {
|
|
1118
|
+
args.qualification = {
|
|
1119
|
+
enabled: request.qualification.enabled,
|
|
1120
|
+
model: request.qualification.model
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
if (request.copy) {
|
|
1124
|
+
args.copy = {
|
|
1125
|
+
enabled: request.copy.enabled,
|
|
1126
|
+
tone: request.copy.tone,
|
|
1127
|
+
max_body_words: request.copy.maxBodyWords,
|
|
1128
|
+
sender_context: request.copy.senderContext,
|
|
1129
|
+
offer_context: request.copy.offerContext,
|
|
1130
|
+
model: request.copy.model
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
if (request.delivery) {
|
|
1134
|
+
args.delivery = {
|
|
1135
|
+
enabled: request.delivery.enabled,
|
|
1136
|
+
destination_type: request.delivery.destinationType,
|
|
1137
|
+
approval_required: request.delivery.approvalRequired,
|
|
1138
|
+
include_disqualified: request.delivery.includeDisqualified,
|
|
1139
|
+
destination_config: request.delivery.destinationConfig
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
if (request.enhancers) {
|
|
1143
|
+
const e = {};
|
|
1144
|
+
if (request.enhancers.clay) {
|
|
1145
|
+
e.clay = {
|
|
1146
|
+
enabled: request.enhancers.clay.enabled,
|
|
1147
|
+
mode: request.enhancers.clay.mode,
|
|
1148
|
+
table_id: request.enhancers.clay.tableId,
|
|
1149
|
+
enrichment_fields: request.enhancers.clay.enrichmentFields,
|
|
1150
|
+
api_key_env: request.enhancers.clay.apiKeyEnv
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
if (request.enhancers.octave) {
|
|
1154
|
+
e.octave = {
|
|
1155
|
+
enabled: request.enhancers.octave.enabled,
|
|
1156
|
+
mode: request.enhancers.octave.mode,
|
|
1157
|
+
copy_agent_id: request.enhancers.octave.copyAgentId,
|
|
1158
|
+
qualification_agent_id: request.enhancers.octave.qualificationAgentId,
|
|
1159
|
+
api_key_env: request.enhancers.octave.apiKeyEnv
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
args.enhancers = e;
|
|
1163
|
+
}
|
|
1164
|
+
return args;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// src/resources/campaign-builder-agent.ts
|
|
1168
|
+
var DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS = {
|
|
1169
|
+
requireVerifiedEmail: true,
|
|
1170
|
+
dedupKeys: ["email", "linkedin_url", "company_domain"],
|
|
1171
|
+
allowDownscale: true,
|
|
1172
|
+
signals: {
|
|
1173
|
+
enabled: true,
|
|
1174
|
+
types: ["funding", "hiring", "technology", "news"],
|
|
1175
|
+
confidenceThreshold: 0.7,
|
|
1176
|
+
lookbackDays: 90
|
|
1177
|
+
},
|
|
1178
|
+
qualification: {
|
|
1179
|
+
enabled: true
|
|
1180
|
+
},
|
|
1181
|
+
copy: {
|
|
1182
|
+
enabled: true,
|
|
1183
|
+
tone: "direct",
|
|
1184
|
+
maxBodyWords: 125
|
|
1185
|
+
},
|
|
1186
|
+
delivery: {
|
|
1187
|
+
enabled: true,
|
|
1188
|
+
destinationType: "json",
|
|
1189
|
+
approvalRequired: true
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
var CampaignBuilderAgent = class {
|
|
1193
|
+
constructor(client) {
|
|
1194
|
+
this.client = client;
|
|
1195
|
+
}
|
|
1196
|
+
async createPlan(request, options = {}) {
|
|
1197
|
+
const warnings = [];
|
|
1198
|
+
const workspaceContext = request.workspaceContext ?? await this.getWorkspaceContext(warnings);
|
|
1199
|
+
const scopeResult = options.scopeCampaign === false ? void 0 : await this.scopeCampaign(request, warnings);
|
|
1200
|
+
if (options.discoverCapabilities !== false) {
|
|
1201
|
+
await this.discoverPlannedRoutes(request, warnings);
|
|
1202
|
+
}
|
|
1203
|
+
return createCampaignBuilderAgentPlan(request, {
|
|
1204
|
+
workspaceContext,
|
|
1205
|
+
scopeBuildArgs: asRecord(scopeResult?.build_campaign_args ?? scopeResult?.buildCampaignArgs),
|
|
1206
|
+
warnings
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
async dryRunPlan(plan, options) {
|
|
1210
|
+
let args = buildCampaignArgs({
|
|
1211
|
+
...plan.buildRequest,
|
|
1212
|
+
dryRun: true,
|
|
1213
|
+
confirmSpend: false
|
|
1214
|
+
});
|
|
1215
|
+
if (plan.buildRequest.gtmCampaignId) {
|
|
1216
|
+
const prepare = await this.callMcp(
|
|
1217
|
+
"gtm_campaign_build_execution_prepare",
|
|
1218
|
+
buildExecutionPrepareArgs(plan.buildRequest, true, false)
|
|
1219
|
+
);
|
|
1220
|
+
const blockers = arrayOfStrings(prepare?.blockers) ?? [];
|
|
1221
|
+
if (prepare?.ready_to_launch === false || blockers.length > 0) {
|
|
1222
|
+
throw new Error(`Campaign builder dry-run prepare is blocked: ${blockers.join(", ") || "not ready to dry run"}`);
|
|
1223
|
+
}
|
|
1224
|
+
const preparedArgs = asRecord(prepare?.build_campaign_arguments ?? prepare?.buildCampaignArguments);
|
|
1225
|
+
if (Object.keys(preparedArgs).length > 0) {
|
|
1226
|
+
args = {
|
|
1227
|
+
...preparedArgs,
|
|
1228
|
+
dry_run: true,
|
|
1229
|
+
confirm_spend: false
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
if (options?.idempotencyKey) args.idempotency_key = options.idempotencyKey;
|
|
1234
|
+
const data = await this.callMcp("build_campaign", args);
|
|
1235
|
+
return mapBuildResult(data, true);
|
|
1236
|
+
}
|
|
1237
|
+
async buildApprovedPlan(plan, approval, options) {
|
|
1238
|
+
const missing = getMissingCampaignBuilderApprovals(plan, approval);
|
|
1239
|
+
if (missing.length > 0) {
|
|
1240
|
+
throw new Error(`Campaign builder approval is incomplete: ${missing.map((a) => a.label).join(", ")}`);
|
|
1241
|
+
}
|
|
1242
|
+
let args = buildCampaignArgs({
|
|
1243
|
+
...plan.buildRequest,
|
|
1244
|
+
dryRun: false,
|
|
1245
|
+
confirmSpend: true
|
|
1246
|
+
});
|
|
1247
|
+
if (plan.buildRequest.gtmCampaignId) {
|
|
1248
|
+
const prepare = await this.callMcp(
|
|
1249
|
+
"gtm_campaign_build_execution_prepare",
|
|
1250
|
+
buildExecutionPrepareArgs(plan.buildRequest, false, true)
|
|
1251
|
+
);
|
|
1252
|
+
const blockers = arrayOfStrings(prepare?.blockers) ?? [];
|
|
1253
|
+
if (prepare?.ready_to_launch === false || blockers.length > 0) {
|
|
1254
|
+
throw new Error(`Campaign builder execution prepare is blocked: ${blockers.join(", ") || "not ready to launch"}`);
|
|
1255
|
+
}
|
|
1256
|
+
const preparedArgs = asRecord(prepare?.build_campaign_arguments ?? prepare?.buildCampaignArguments);
|
|
1257
|
+
if (Object.keys(preparedArgs).length > 0) {
|
|
1258
|
+
args = {
|
|
1259
|
+
...preparedArgs,
|
|
1260
|
+
dry_run: false,
|
|
1261
|
+
confirm_spend: true
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
args.required_approvals = plan.approvals.map((item) => item.id);
|
|
1266
|
+
if (options?.idempotencyKey) args.idempotency_key = options.idempotencyKey;
|
|
1267
|
+
const data = await this.callMcp("build_campaign", args);
|
|
1268
|
+
return mapBuildResult(data, false);
|
|
1269
|
+
}
|
|
1270
|
+
async getWorkspaceContext(warnings) {
|
|
1271
|
+
try {
|
|
1272
|
+
const workspace = await this.callMcp("get_workspace", {});
|
|
1273
|
+
return {
|
|
1274
|
+
workspaceId: stringValue(workspace.workspace_id ?? workspace.id),
|
|
1275
|
+
workspaceName: stringValue(workspace.workspace_name ?? workspace.name),
|
|
1276
|
+
plan: stringValue(workspace.plan ?? workspace.plan_name),
|
|
1277
|
+
creditsRemaining: numberOrUndefined2(workspace.credits_remaining ?? workspace.credit_balance ?? workspace.credits)
|
|
1278
|
+
};
|
|
1279
|
+
} catch (error) {
|
|
1280
|
+
warnings.push(`Workspace context lookup failed: ${errorMessage(error)}`);
|
|
1281
|
+
return {};
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
async scopeCampaign(request, warnings) {
|
|
1285
|
+
try {
|
|
1286
|
+
return await this.callMcp("scope_campaign", {
|
|
1287
|
+
prompt: request.goal,
|
|
1288
|
+
client_name: request.clientName,
|
|
1289
|
+
client_context: request.clientContext,
|
|
1290
|
+
campaign_goal: request.goal,
|
|
1291
|
+
target_count: request.targetCount,
|
|
1292
|
+
approval_policy: request.approvalPolicy?.requireHumanApproval ? "human_required" : "standard"
|
|
1293
|
+
});
|
|
1294
|
+
} catch (error) {
|
|
1295
|
+
warnings.push(`Campaign scope lookup failed: ${errorMessage(error)}`);
|
|
1296
|
+
return void 0;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
async discoverPlannedRoutes(request, warnings) {
|
|
1300
|
+
const providers = new Set(
|
|
1301
|
+
[...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])].filter((route) => route.provider !== "signaliz").map((route) => route.provider)
|
|
1302
|
+
);
|
|
1303
|
+
for (const provider of providers) {
|
|
1304
|
+
try {
|
|
1305
|
+
await this.callMcp("discover_capabilities", {
|
|
1306
|
+
query: `campaign builder ${provider} ${request.goal}`,
|
|
1307
|
+
category: "campaign"
|
|
1308
|
+
});
|
|
1309
|
+
} catch (error) {
|
|
1310
|
+
warnings.push(`Capability discovery for ${provider} failed: ${errorMessage(error)}`);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
async callMcp(tool, args) {
|
|
1315
|
+
return this.client.mcp("tools/call", { name: tool, arguments: compact(args) });
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
function createCampaignBuilderAgentPlan(request, context = {}) {
|
|
1319
|
+
const defaults = mergeDefaults(request.signalizDefaults);
|
|
1320
|
+
const targetCount = request.targetCount ?? numberOrUndefined2(context.scopeBuildArgs?.target_count) ?? 100;
|
|
1321
|
+
const campaignName = request.campaignName ?? stringValue(context.scopeBuildArgs?.name) ?? titleFromGoal(request.goal);
|
|
1322
|
+
const workspaceContext = context.workspaceContext ?? request.workspaceContext ?? {};
|
|
1323
|
+
const memory = normalizeMemory(request);
|
|
1324
|
+
const routes = normalizeRoutes(request);
|
|
1325
|
+
const estimatedCredits = estimateCredits(request, defaults, targetCount);
|
|
1326
|
+
const buildRequest = createBuildRequest(request, defaults, targetCount, campaignName, context.scopeBuildArgs, routes, memory, context.scopeBrainPreflight);
|
|
1327
|
+
const brainPreflight = asRecord(buildRequest.brainPreflight);
|
|
1328
|
+
const approvals = deriveApprovals(request, routes, memory, estimatedCredits, defaults.delivery?.approvalRequired !== false);
|
|
1329
|
+
return {
|
|
1330
|
+
planId: `cbp_${hashString(JSON.stringify({ goal: request.goal, campaignName, targetCount, routes }))}`,
|
|
1331
|
+
campaignName,
|
|
1332
|
+
goal: request.goal,
|
|
1333
|
+
targetCount,
|
|
1334
|
+
workspaceContext,
|
|
1335
|
+
memory,
|
|
1336
|
+
defaults: {
|
|
1337
|
+
requireVerifiedEmail: defaults.requireVerifiedEmail,
|
|
1338
|
+
dedupKeys: defaults.dedupKeys,
|
|
1339
|
+
allowDownscale: defaults.allowDownscale
|
|
1340
|
+
},
|
|
1341
|
+
routes,
|
|
1342
|
+
approvals,
|
|
1343
|
+
buildRequest,
|
|
1344
|
+
brainPreflight,
|
|
1345
|
+
mcpFlow: createMcpFlow(request, buildRequest, routes, memory, approvals),
|
|
1346
|
+
estimatedCredits,
|
|
1347
|
+
warnings: context.warnings ?? []
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
function getMissingCampaignBuilderApprovals(plan, approval) {
|
|
1351
|
+
if (approval.planId !== plan.planId) {
|
|
1352
|
+
return plan.approvals;
|
|
1353
|
+
}
|
|
1354
|
+
const approvedTypes = new Set(approval.approvedTypes);
|
|
1355
|
+
const approvedRoutes = new Set(approval.approvedRouteIds ?? []);
|
|
1356
|
+
return plan.approvals.filter((required) => {
|
|
1357
|
+
if (!required.blocking) return false;
|
|
1358
|
+
if (!approvedTypes.has(required.type)) return true;
|
|
1359
|
+
if (required.routeId && !approvedRoutes.has(required.routeId)) return true;
|
|
1360
|
+
if (required.type === "spend" && required.estimatedCredits && approval.spendLimitCredits !== void 0) {
|
|
1361
|
+
return approval.spendLimitCredits < required.estimatedCredits;
|
|
1362
|
+
}
|
|
1363
|
+
return false;
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
function mergeDefaults(overrides) {
|
|
1367
|
+
return {
|
|
1368
|
+
...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS,
|
|
1369
|
+
...overrides,
|
|
1370
|
+
signals: { ...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS.signals, ...overrides?.signals },
|
|
1371
|
+
qualification: { ...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS.qualification, ...overrides?.qualification },
|
|
1372
|
+
copy: { ...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS.copy, ...overrides?.copy },
|
|
1373
|
+
delivery: { ...DEFAULT_SIGNALIZ_CAMPAIGN_BUILDER_DEFAULTS.delivery, ...overrides?.delivery }
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function normalizeMemory(request) {
|
|
1377
|
+
const configured = request.memory ?? {};
|
|
1378
|
+
const queries = configured.queries && configured.queries.length > 0 ? configured.queries : [{
|
|
1379
|
+
query: request.goal,
|
|
1380
|
+
scopes: ["workspace", configured.useNetworkPatterns ? "network_patterns" : "operator_notes"],
|
|
1381
|
+
topK: 8,
|
|
1382
|
+
rationale: "Seed the campaign plan with prior ICP, angle, source, and reply-performance patterns."
|
|
1383
|
+
}];
|
|
1384
|
+
return {
|
|
1385
|
+
enabled: configured.enabled !== false,
|
|
1386
|
+
queries,
|
|
1387
|
+
useWorkspaceHistory: configured.useWorkspaceHistory !== false,
|
|
1388
|
+
useNetworkPatterns: configured.useNetworkPatterns === true,
|
|
1389
|
+
privacyMode: configured.privacyMode ?? (configured.useNetworkPatterns ? "anonymized_patterns" : "workspace_only")
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
function normalizeRoutes(request) {
|
|
1393
|
+
const routes = [
|
|
1394
|
+
{
|
|
1395
|
+
id: "signaliz-source",
|
|
1396
|
+
layer: "source",
|
|
1397
|
+
provider: "signaliz",
|
|
1398
|
+
mode: "required",
|
|
1399
|
+
toolName: "generate_leads",
|
|
1400
|
+
rationale: "Use Signaliz fresh workspace acquisition as the default source of truth."
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
id: "signaliz-verify",
|
|
1404
|
+
layer: "qualification",
|
|
1405
|
+
provider: "signaliz",
|
|
1406
|
+
mode: "required",
|
|
1407
|
+
toolName: "find_and_verify_emails",
|
|
1408
|
+
rationale: "Require verified contactability before sequence delivery."
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
id: "signaliz-signals",
|
|
1412
|
+
layer: "enrichment",
|
|
1413
|
+
provider: "signaliz",
|
|
1414
|
+
mode: "if_available",
|
|
1415
|
+
toolName: "enrich_company_signals",
|
|
1416
|
+
rationale: "Attach current buying signals and evidence for qualification and copy."
|
|
1417
|
+
}
|
|
1418
|
+
];
|
|
1419
|
+
routes.push(...routesFromCustomerTools(request.customerTools ?? []));
|
|
1420
|
+
routes.push(...request.integrations ?? []);
|
|
1421
|
+
return routes.map((route, index) => ({
|
|
1422
|
+
...route,
|
|
1423
|
+
id: route.id ?? `${route.provider}-${route.layer}-${index + 1}`,
|
|
1424
|
+
mode: route.mode ?? "if_available"
|
|
1425
|
+
}));
|
|
1426
|
+
}
|
|
1427
|
+
function routesFromCustomerTools(tools) {
|
|
1428
|
+
return tools.flatMap(
|
|
1429
|
+
(tool) => tool.useForLayers.map((layer) => ({
|
|
1430
|
+
layer,
|
|
1431
|
+
provider: tool.provider,
|
|
1432
|
+
mode: tool.mode ?? "if_available",
|
|
1433
|
+
mcpServerName: tool.mcpServerName,
|
|
1434
|
+
label: tool.label,
|
|
1435
|
+
approvalRequired: tool.approvalRequired,
|
|
1436
|
+
gtmLayers: tool.gtmLayerCapabilities,
|
|
1437
|
+
routingPolicy: tool.routingPolicy,
|
|
1438
|
+
providerCapability: tool.providerCapability,
|
|
1439
|
+
config: {
|
|
1440
|
+
...tool.config,
|
|
1441
|
+
available_tools: tool.availableTools
|
|
1442
|
+
},
|
|
1443
|
+
rationale: `${tool.label ?? tool.provider} is customer-provided for ${layer}.`
|
|
1444
|
+
}))
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
function createBuildRequest(request, defaults, targetCount, campaignName, scopeBuildArgs, routes = [], memory, scopeBrainPreflight) {
|
|
1448
|
+
const buildRequest = {
|
|
1449
|
+
name: campaignName,
|
|
1450
|
+
prompt: request.goal,
|
|
1451
|
+
description: buildDescription(request),
|
|
1452
|
+
targetCount,
|
|
1453
|
+
dryRun: true,
|
|
1454
|
+
allowDownscale: defaults.allowDownscale,
|
|
1455
|
+
confirmSpend: false,
|
|
1456
|
+
dedupKeys: defaults.dedupKeys,
|
|
1457
|
+
icp: {
|
|
1458
|
+
...request.icp,
|
|
1459
|
+
geographies: request.icp?.geographies ?? request.constraints?.geographies,
|
|
1460
|
+
exclusions: [...request.icp?.exclusions ?? [], ...request.constraints?.exclusions ?? []],
|
|
1461
|
+
requireVerifiedEmail: request.icp?.requireVerifiedEmail ?? defaults.requireVerifiedEmail
|
|
1462
|
+
},
|
|
1463
|
+
policy: {
|
|
1464
|
+
maxCredits: defaults.maxCredits,
|
|
1465
|
+
verifyEmails: defaults.requireVerifiedEmail
|
|
1466
|
+
},
|
|
1467
|
+
signals: defaults.signals,
|
|
1468
|
+
qualification: defaults.qualification,
|
|
1469
|
+
copy: defaults.copy,
|
|
1470
|
+
delivery: defaults.delivery,
|
|
1471
|
+
enhancers: enhancerConfig(request)
|
|
1472
|
+
};
|
|
1473
|
+
const scoped = asRecord(scopeBuildArgs);
|
|
1474
|
+
buildRequest.gtmCampaignId = request.gtmCampaignId ?? stringValue(scoped.gtm_campaign_id ?? scoped.gtmCampaignId);
|
|
1475
|
+
if (typeof scoped.name === "string") buildRequest.name = scoped.name;
|
|
1476
|
+
if (typeof scoped.prompt === "string") buildRequest.prompt = scoped.prompt;
|
|
1477
|
+
if (typeof scoped.target_count === "number") buildRequest.targetCount = scoped.target_count;
|
|
1478
|
+
const brainDefaults = asRecord(request.brainDefaults ?? scoped.brain_defaults ?? scoped.brainDefaults);
|
|
1479
|
+
if (Object.keys(brainDefaults).length > 0) buildRequest.brainDefaults = brainDefaults;
|
|
1480
|
+
const deliveryRisk = asRecord(request.deliveryRisk ?? scoped.delivery_risk ?? scoped.deliveryRisk);
|
|
1481
|
+
if (Object.keys(deliveryRisk).length > 0) buildRequest.deliveryRisk = deliveryRisk;
|
|
1482
|
+
const scopedBrainPreflight = asRecord(scoped.brain_preflight);
|
|
1483
|
+
const providedBrainPreflight = Object.keys(scopedBrainPreflight).length > 0 ? scopedBrainPreflight : asRecord(scopeBrainPreflight);
|
|
1484
|
+
buildRequest.brainPreflight = Object.keys(providedBrainPreflight).length > 0 ? providedBrainPreflight : createBrainPreflight(request, buildRequest, routes, memory ?? normalizeMemory(request));
|
|
1485
|
+
return buildRequest;
|
|
1486
|
+
}
|
|
1487
|
+
function createBrainPreflight(request, buildRequest, routes, memory) {
|
|
1488
|
+
const layers = uniqueStrings([
|
|
1489
|
+
"icp",
|
|
1490
|
+
"email_finding",
|
|
1491
|
+
"email_verification",
|
|
1492
|
+
...routes.flatMap(gtmLayersForRoute),
|
|
1493
|
+
buildRequest.delivery?.destinationType === "webhook" ? "destination_export" : void 0,
|
|
1494
|
+
["instantly", "smartlead", "heyreach"].some((provider) => routes.some((route) => route.provider === provider)) ? "sender" : void 0,
|
|
1495
|
+
memory.enabled ? "feedback" : void 0
|
|
1496
|
+
]);
|
|
1497
|
+
const providerChain = uniqueStrings(["signaliz", ...routes.map((route) => route.provider)]);
|
|
1498
|
+
const targetIcp = compact({
|
|
1499
|
+
personas: buildRequest.icp?.personas,
|
|
1500
|
+
industries: buildRequest.icp?.industries,
|
|
1501
|
+
company_sizes: buildRequest.icp?.companySizes,
|
|
1502
|
+
geographies: buildRequest.icp?.geographies,
|
|
1503
|
+
keywords: buildRequest.icp?.keywords,
|
|
1504
|
+
exclusions: buildRequest.icp?.exclusions,
|
|
1505
|
+
require_verified_email: buildRequest.icp?.requireVerifiedEmail
|
|
1506
|
+
});
|
|
1507
|
+
const learningArgs = compact({
|
|
1508
|
+
campaign_brief: request.goal,
|
|
1509
|
+
target_icp: targetIcp,
|
|
1510
|
+
layers,
|
|
1511
|
+
provider_chain: providerChain,
|
|
1512
|
+
lead_source: providerChain[0] ?? "signaliz",
|
|
1513
|
+
include_memory: memory.enabled,
|
|
1514
|
+
include_network: memory.useNetworkPatterns,
|
|
1515
|
+
write_mode: "dry_run",
|
|
1516
|
+
limit: 25
|
|
1517
|
+
});
|
|
1518
|
+
const defaultsArgs = compact({
|
|
1519
|
+
campaign_brief: request.goal,
|
|
1520
|
+
target_icp: targetIcp,
|
|
1521
|
+
layers,
|
|
1522
|
+
include_global: memory.useNetworkPatterns,
|
|
1523
|
+
include_memory: memory.enabled,
|
|
1524
|
+
write_campaign: false,
|
|
1525
|
+
limit: 25
|
|
1526
|
+
});
|
|
1527
|
+
const riskArgs = compact({
|
|
1528
|
+
provider_chain: providerChain,
|
|
1529
|
+
lead_source: providerChain[0] ?? "signaliz",
|
|
1530
|
+
target_icp: targetIcp,
|
|
1531
|
+
include_global: memory.useNetworkPatterns,
|
|
1532
|
+
limit: 25
|
|
1533
|
+
});
|
|
1534
|
+
return {
|
|
1535
|
+
required: true,
|
|
1536
|
+
policy: "Run read-only GTM Brain preflight before build_campaign so learned defaults, memory, and deliverability risk stay attached to the build.",
|
|
1537
|
+
layers,
|
|
1538
|
+
target_icp: targetIcp,
|
|
1539
|
+
provider_chain: providerChain,
|
|
1540
|
+
lead_source: providerChain[0] ?? "signaliz",
|
|
1541
|
+
tool_sequence: [
|
|
1542
|
+
{ tool: "gtm_brain_learning_cycle_plan", purpose: "Plan the Brain learning loop for this campaign.", arguments: learningArgs },
|
|
1543
|
+
{ tool: "gtm_brain_seed_defaults", purpose: "Seed campaign defaults from workspace memory and safe aggregate patterns.", arguments: defaultsArgs },
|
|
1544
|
+
{ tool: "gtm_brain_delivery_risk", purpose: "Check deliverability risk before launch or external writes.", arguments: riskArgs }
|
|
1545
|
+
]
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
function gtmLayersForBuilderLayer(layer) {
|
|
1549
|
+
const map = {
|
|
1550
|
+
workspace_context: ["customer_data"],
|
|
1551
|
+
memory: ["feedback"],
|
|
1552
|
+
source: ["find_company", "find_people", "lead_generation"],
|
|
1553
|
+
enrichment: ["company_enrichment"],
|
|
1554
|
+
qualification: ["qualification"],
|
|
1555
|
+
copy: ["copy_enrichment"],
|
|
1556
|
+
delivery: ["destination_export"],
|
|
1557
|
+
feedback: ["feedback"],
|
|
1558
|
+
approval: ["approval"]
|
|
1559
|
+
};
|
|
1560
|
+
return map[layer] ?? ["custom"];
|
|
1561
|
+
}
|
|
1562
|
+
function gtmLayersForRoute(route) {
|
|
1563
|
+
const explicitLayers = uniqueStrings([
|
|
1564
|
+
route.gtmLayer,
|
|
1565
|
+
...route.gtmLayers ?? [],
|
|
1566
|
+
...route.providerCapability?.layerCapabilities ?? []
|
|
1567
|
+
]);
|
|
1568
|
+
return explicitLayers.length > 0 ? explicitLayers : gtmLayersForBuilderLayer(route.layer);
|
|
1569
|
+
}
|
|
1570
|
+
function enhancerConfig(request) {
|
|
1571
|
+
const routes = [...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])];
|
|
1572
|
+
const octave = routes.find((route) => route.provider === "octave");
|
|
1573
|
+
const clay = routes.find((route) => route.provider === "clay_webhook");
|
|
1574
|
+
if (!octave && !clay) return void 0;
|
|
1575
|
+
return {
|
|
1576
|
+
octave: octave ? {
|
|
1577
|
+
enabled: octave.mode !== "disabled",
|
|
1578
|
+
mode: octave.mode === "required" ? "required" : "if_available",
|
|
1579
|
+
copyAgentId: stringValue(octave.config?.copy_agent_id ?? octave.config?.copyAgentId),
|
|
1580
|
+
qualificationAgentId: stringValue(octave.config?.qualification_agent_id ?? octave.config?.qualificationAgentId)
|
|
1581
|
+
} : void 0,
|
|
1582
|
+
clay: clay ? {
|
|
1583
|
+
enabled: clay.mode !== "disabled",
|
|
1584
|
+
mode: clay.mode === "required" ? "required" : "if_available",
|
|
1585
|
+
tableId: stringValue(clay.config?.table_id ?? clay.config?.tableId),
|
|
1586
|
+
enrichmentFields: arrayOfStrings(clay.config?.enrichment_fields ?? clay.config?.enrichmentFields)
|
|
1587
|
+
} : void 0
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
function deriveApprovals(request, routes, memory, estimatedCredits, deliveryApprovalRequired) {
|
|
1591
|
+
const policy = request.approvalPolicy ?? {};
|
|
1592
|
+
const requireFor = new Set(policy.requireApprovalFor ?? ["spend", "external_write", "customer_tool", "delivery", "launch"]);
|
|
1593
|
+
const approvals = [];
|
|
1594
|
+
if (memory.enabled && memory.useNetworkPatterns && requireFor.has("memory_retrieval")) {
|
|
1595
|
+
approvals.push({
|
|
1596
|
+
id: "approval-memory-network",
|
|
1597
|
+
type: "memory_retrieval",
|
|
1598
|
+
label: "Use anonymized network memory",
|
|
1599
|
+
reason: "The plan will consult cross-workspace patterns instead of only private workspace history.",
|
|
1600
|
+
blocking: true
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
if (estimatedCredits > (policy.maxCreditsWithoutApproval ?? 0) && requireFor.has("spend")) {
|
|
1604
|
+
approvals.push({
|
|
1605
|
+
id: "approval-spend",
|
|
1606
|
+
type: "spend",
|
|
1607
|
+
label: "Approve campaign spend",
|
|
1608
|
+
reason: `Estimated campaign work may use up to ${estimatedCredits} credits.`,
|
|
1609
|
+
blocking: true,
|
|
1610
|
+
estimatedCredits
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1613
|
+
for (const route of routes) {
|
|
1614
|
+
const isCustomerTool = route.provider !== "signaliz";
|
|
1615
|
+
const isWriteLayer = route.layer === "delivery" || route.layer === "feedback";
|
|
1616
|
+
if (isCustomerTool && route.approvalRequired !== false && requireFor.has("customer_tool")) {
|
|
1617
|
+
approvals.push({
|
|
1618
|
+
id: `approval-tool-${route.id}`,
|
|
1619
|
+
type: "customer_tool",
|
|
1620
|
+
label: `Use ${route.label ?? route.provider}`,
|
|
1621
|
+
reason: route.rationale ?? `${route.provider} is part of the campaign plan.`,
|
|
1622
|
+
blocking: route.mode === "required" || policy.requireHumanApproval === true,
|
|
1623
|
+
routeId: route.id,
|
|
1624
|
+
provider: route.provider
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
if (isWriteLayer && route.provider !== "csv" && requireFor.has("external_write")) {
|
|
1628
|
+
approvals.push({
|
|
1629
|
+
id: `approval-write-${route.id}`,
|
|
1630
|
+
type: "external_write",
|
|
1631
|
+
label: `Approve ${route.provider} write`,
|
|
1632
|
+
reason: "External delivery, sync, sequencer, or feedback writes must be explicitly approved.",
|
|
1633
|
+
blocking: true,
|
|
1634
|
+
routeId: route.id,
|
|
1635
|
+
provider: route.provider
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
if (deliveryApprovalRequired && requireFor.has("delivery")) {
|
|
1640
|
+
approvals.push({
|
|
1641
|
+
id: "approval-delivery",
|
|
1642
|
+
type: "delivery",
|
|
1643
|
+
label: "Approve delivery destination",
|
|
1644
|
+
reason: "Delivery remains gated until the destination, field map, suppression rules, and send limits are reviewed.",
|
|
1645
|
+
blocking: true
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
if (requireFor.has("launch")) {
|
|
1649
|
+
approvals.push({
|
|
1650
|
+
id: "approval-launch",
|
|
1651
|
+
type: "launch",
|
|
1652
|
+
label: "Launch campaign build",
|
|
1653
|
+
reason: "The dry-run plan must be accepted before spendful build execution.",
|
|
1654
|
+
blocking: true
|
|
1655
|
+
});
|
|
1656
|
+
}
|
|
1657
|
+
return dedupeApprovals(approvals);
|
|
1658
|
+
}
|
|
1659
|
+
function createMcpFlow(request, buildRequest, routes, memory, approvals) {
|
|
1660
|
+
const steps = [
|
|
1661
|
+
{
|
|
1662
|
+
id: "workspace-context",
|
|
1663
|
+
phase: "workspace_context",
|
|
1664
|
+
tool: "get_workspace",
|
|
1665
|
+
arguments: {},
|
|
1666
|
+
readOnly: true,
|
|
1667
|
+
approvalRequired: false
|
|
1668
|
+
}
|
|
1669
|
+
];
|
|
1670
|
+
if (memory.enabled) {
|
|
1671
|
+
for (const [index, query] of memory.queries.entries()) {
|
|
1672
|
+
steps.push({
|
|
1673
|
+
id: `memory-${index + 1}`,
|
|
1674
|
+
phase: "memory",
|
|
1675
|
+
tool: "gtm_memory_search",
|
|
1676
|
+
arguments: buildGtmMemorySearchArgs(request, routes, query),
|
|
1677
|
+
readOnly: true,
|
|
1678
|
+
approvalRequired: memory.useNetworkPatterns
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
for (const route of routes) {
|
|
1683
|
+
steps.push({
|
|
1684
|
+
id: `route-${route.id}`,
|
|
1685
|
+
phase: route.layer,
|
|
1686
|
+
tool: route.toolName ?? "discover_capabilities",
|
|
1687
|
+
arguments: {
|
|
1688
|
+
provider: route.provider,
|
|
1689
|
+
mcp_server_name: route.mcpServerName,
|
|
1690
|
+
mode: route.mode,
|
|
1691
|
+
config: route.config
|
|
1692
|
+
},
|
|
1693
|
+
readOnly: !["delivery", "feedback"].includes(route.layer),
|
|
1694
|
+
approvalRequired: route.approvalRequired === true || route.layer === "delivery" || route.layer === "feedback"
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
steps.push({
|
|
1698
|
+
id: "scope-campaign",
|
|
1699
|
+
phase: "plan",
|
|
1700
|
+
tool: "scope_campaign",
|
|
1701
|
+
arguments: {
|
|
1702
|
+
prompt: request.goal,
|
|
1703
|
+
client_name: request.clientName,
|
|
1704
|
+
client_context: request.clientContext,
|
|
1705
|
+
target_count: request.targetCount
|
|
1706
|
+
},
|
|
1707
|
+
readOnly: true,
|
|
1708
|
+
approvalRequired: false
|
|
1709
|
+
});
|
|
1710
|
+
const brainPreflight = asRecord(buildRequest.brainPreflight);
|
|
1711
|
+
const brainToolSequence = Array.isArray(brainPreflight.tool_sequence) ? brainPreflight.tool_sequence.map((step) => asRecord(step)).filter((step) => typeof step.tool === "string") : [];
|
|
1712
|
+
for (const [index, brainStep] of brainToolSequence.entries()) {
|
|
1713
|
+
steps.push({
|
|
1714
|
+
id: `brain-preflight-${index + 1}`,
|
|
1715
|
+
phase: "plan",
|
|
1716
|
+
tool: String(brainStep.tool),
|
|
1717
|
+
arguments: asRecord(brainStep.arguments),
|
|
1718
|
+
readOnly: true,
|
|
1719
|
+
approvalRequired: memory.useNetworkPatterns === true
|
|
1720
|
+
});
|
|
1721
|
+
}
|
|
1722
|
+
if (buildRequest.gtmCampaignId) {
|
|
1723
|
+
steps.push({
|
|
1724
|
+
id: "dry-run-prepare",
|
|
1725
|
+
phase: "plan",
|
|
1726
|
+
tool: "gtm_campaign_build_execution_prepare",
|
|
1727
|
+
arguments: buildExecutionPrepareArgs(buildRequest, true, false),
|
|
1728
|
+
readOnly: true,
|
|
1729
|
+
approvalRequired: false
|
|
1730
|
+
});
|
|
1731
|
+
}
|
|
1732
|
+
steps.push({
|
|
1733
|
+
id: "dry-run-build",
|
|
1734
|
+
phase: "plan",
|
|
1735
|
+
tool: "build_campaign",
|
|
1736
|
+
arguments: {
|
|
1737
|
+
...buildCampaignArgs({ ...buildRequest, dryRun: true, confirmSpend: false }),
|
|
1738
|
+
dry_run: true
|
|
1739
|
+
},
|
|
1740
|
+
readOnly: true,
|
|
1741
|
+
approvalRequired: false
|
|
1742
|
+
});
|
|
1743
|
+
if (buildRequest.gtmCampaignId) {
|
|
1744
|
+
steps.push({
|
|
1745
|
+
id: "execution-prepare",
|
|
1746
|
+
phase: "launch",
|
|
1747
|
+
tool: "gtm_campaign_build_execution_prepare",
|
|
1748
|
+
arguments: buildExecutionPrepareArgs(buildRequest, false, true),
|
|
1749
|
+
readOnly: true,
|
|
1750
|
+
approvalRequired: approvals.some((approval) => approval.blocking)
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
steps.push({
|
|
1754
|
+
id: "approved-build",
|
|
1755
|
+
phase: "launch",
|
|
1756
|
+
tool: "build_campaign",
|
|
1757
|
+
arguments: {
|
|
1758
|
+
...buildCampaignArgs({ ...buildRequest, dryRun: false, confirmSpend: true }),
|
|
1759
|
+
required_approvals: approvals.map((approval) => approval.id)
|
|
1760
|
+
},
|
|
1761
|
+
readOnly: false,
|
|
1762
|
+
approvalRequired: approvals.some((approval) => approval.blocking)
|
|
1763
|
+
});
|
|
1764
|
+
return steps.map((step) => ({ ...step, arguments: compact(step.arguments) }));
|
|
1765
|
+
}
|
|
1766
|
+
function buildGtmMemorySearchArgs(request, routes, query) {
|
|
1767
|
+
const layers = uniqueStrings(routes.flatMap(gtmLayersForRoute));
|
|
1768
|
+
const providerChain = uniqueStrings(routes.map((route) => route.provider));
|
|
1769
|
+
return compact({
|
|
1770
|
+
query: query.query,
|
|
1771
|
+
limit: query.topK,
|
|
1772
|
+
target_icp: request.icp ? buildGtmTargetIcpContext(request.icp) : void 0,
|
|
1773
|
+
layers: layers.length > 0 ? layers : void 0,
|
|
1774
|
+
provider_chain: providerChain.length > 0 ? providerChain : void 0,
|
|
1775
|
+
days: 180
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
function buildGtmTargetIcpContext(icp) {
|
|
1779
|
+
return compact({
|
|
1780
|
+
roles: icp.personas,
|
|
1781
|
+
personas: icp.personas,
|
|
1782
|
+
industries: icp.industries,
|
|
1783
|
+
company_sizes: icp.companySizes,
|
|
1784
|
+
geographies: icp.geographies,
|
|
1785
|
+
keywords: icp.keywords,
|
|
1786
|
+
exclusions: icp.exclusions,
|
|
1787
|
+
require_verified_email: icp.requireVerifiedEmail
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1790
|
+
function buildCampaignArgs(request) {
|
|
1791
|
+
const args = {
|
|
1792
|
+
name: request.name,
|
|
1793
|
+
prompt: request.prompt
|
|
1794
|
+
};
|
|
1795
|
+
if (request.description) args.description = request.description;
|
|
1796
|
+
if (request.targetCount) args.target_count = request.targetCount;
|
|
1797
|
+
if (request.dryRun !== void 0) args.dry_run = request.dryRun;
|
|
1798
|
+
if (request.allowDownscale !== void 0) args.allow_downscale = request.allowDownscale;
|
|
1799
|
+
if (request.confirmSpend !== void 0) args.confirm_spend = request.confirmSpend;
|
|
1800
|
+
if (request.dedupKeys) args.dedup_keys = request.dedupKeys;
|
|
1801
|
+
if (request.brainPreflight) args.brain_preflight = request.brainPreflight;
|
|
1802
|
+
if (request.brainDefaults) args.brain_defaults = request.brainDefaults;
|
|
1803
|
+
if (request.deliveryRisk) args.delivery_risk = request.deliveryRisk;
|
|
1804
|
+
if (request.icp) {
|
|
1805
|
+
args.icp = compact({
|
|
1806
|
+
personas: request.icp.personas,
|
|
1807
|
+
industries: request.icp.industries,
|
|
1808
|
+
company_sizes: request.icp.companySizes,
|
|
1809
|
+
geographies: request.icp.geographies,
|
|
1810
|
+
keywords: request.icp.keywords,
|
|
1811
|
+
exclusions: request.icp.exclusions,
|
|
1812
|
+
require_verified_email: request.icp.requireVerifiedEmail
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
if (request.policy) {
|
|
1816
|
+
args.policy = compact({
|
|
1817
|
+
max_credits: request.policy.maxCredits,
|
|
1818
|
+
verify_emails: request.policy.verifyEmails,
|
|
1819
|
+
model: request.policy.model
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
if (request.signals) {
|
|
1823
|
+
args.signals = compact({
|
|
1824
|
+
enabled: request.signals.enabled,
|
|
1825
|
+
types: request.signals.types,
|
|
1826
|
+
custom_prompt: request.signals.customPrompt,
|
|
1827
|
+
confidence_threshold: request.signals.confidenceThreshold,
|
|
1828
|
+
lookback_days: request.signals.lookbackDays
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
if (request.qualification) {
|
|
1832
|
+
args.qualification = compact({
|
|
1833
|
+
enabled: request.qualification.enabled,
|
|
1834
|
+
model: request.qualification.model
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1837
|
+
if (request.copy) {
|
|
1838
|
+
args.copy = compact({
|
|
1839
|
+
enabled: request.copy.enabled,
|
|
1840
|
+
tone: request.copy.tone,
|
|
1841
|
+
max_body_words: request.copy.maxBodyWords,
|
|
1842
|
+
sender_context: request.copy.senderContext,
|
|
1843
|
+
offer_context: request.copy.offerContext,
|
|
1844
|
+
model: request.copy.model
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
if (request.delivery) {
|
|
1848
|
+
args.delivery = compact({
|
|
1849
|
+
enabled: request.delivery.enabled,
|
|
1850
|
+
destination_type: request.delivery.destinationType,
|
|
1851
|
+
approval_required: request.delivery.approvalRequired,
|
|
1852
|
+
include_disqualified: request.delivery.includeDisqualified,
|
|
1853
|
+
destination_config: request.delivery.destinationConfig
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1856
|
+
if (request.enhancers) {
|
|
1857
|
+
args.enhancers = compact({
|
|
1858
|
+
clay: request.enhancers.clay && compact({
|
|
1859
|
+
enabled: request.enhancers.clay.enabled,
|
|
1860
|
+
mode: request.enhancers.clay.mode,
|
|
1861
|
+
table_id: request.enhancers.clay.tableId,
|
|
1862
|
+
enrichment_fields: request.enhancers.clay.enrichmentFields,
|
|
1863
|
+
api_key_env: request.enhancers.clay.apiKeyEnv
|
|
1864
|
+
}),
|
|
1865
|
+
octave: request.enhancers.octave && compact({
|
|
1866
|
+
enabled: request.enhancers.octave.enabled,
|
|
1867
|
+
mode: request.enhancers.octave.mode,
|
|
1868
|
+
copy_agent_id: request.enhancers.octave.copyAgentId,
|
|
1869
|
+
qualification_agent_id: request.enhancers.octave.qualificationAgentId,
|
|
1870
|
+
api_key_env: request.enhancers.octave.apiKeyEnv
|
|
1871
|
+
})
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
return compact(args);
|
|
1875
|
+
}
|
|
1876
|
+
function buildExecutionPrepareArgs(request, dryRun, confirmSpend) {
|
|
1877
|
+
const buildArgs2 = buildCampaignArgs(request);
|
|
1878
|
+
return compact({
|
|
1879
|
+
campaign_id: request.gtmCampaignId,
|
|
1880
|
+
target_count: buildArgs2.target_count,
|
|
1881
|
+
allow_downscale: buildArgs2.allow_downscale,
|
|
1882
|
+
dry_run: dryRun,
|
|
1883
|
+
confirm_spend: confirmSpend,
|
|
1884
|
+
include_brain_context: true,
|
|
1885
|
+
require_delivery_risk_clearance: true,
|
|
1886
|
+
delivery_risk: buildArgs2.delivery_risk,
|
|
1887
|
+
dedup_keys: buildArgs2.dedup_keys,
|
|
1888
|
+
policy: buildArgs2.policy,
|
|
1889
|
+
signals: buildArgs2.signals,
|
|
1890
|
+
qualification: buildArgs2.qualification,
|
|
1891
|
+
copy: buildArgs2.copy,
|
|
1892
|
+
delivery: buildArgs2.delivery,
|
|
1893
|
+
enhancers: buildArgs2.enhancers
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
function mapBuildResult(data, dryRun) {
|
|
1897
|
+
return {
|
|
1898
|
+
campaignBuildId: data.campaign_build_id ?? null,
|
|
1899
|
+
campaignId: data.campaign_id ?? null,
|
|
1900
|
+
campaignObject: data.campaign_object ?? null,
|
|
1901
|
+
status: dryRun || data.dry_run ? "dry_run" : data.status ?? "queued",
|
|
1902
|
+
currentPhase: dryRun || data.dry_run ? "plan" : data.current_phase ?? "acquisition",
|
|
1903
|
+
nextPollAfterSeconds: data.next_poll_after_seconds ?? 10,
|
|
1904
|
+
message: data.message ?? data.summary ?? "",
|
|
1905
|
+
dryRun: dryRun || data.dry_run === true,
|
|
1906
|
+
requestedTargetCount: data.requested_target_count,
|
|
1907
|
+
plannedTargetCount: data.planned_target_count,
|
|
1908
|
+
estimatedCredits: data.estimated_credits,
|
|
1909
|
+
estimatedDurationSeconds: data.estimated_duration_seconds,
|
|
1910
|
+
targetLimitApplied: data.target_limit_applied,
|
|
1911
|
+
targetLimitReason: data.target_limit_reason,
|
|
1912
|
+
maxSupportedTargetCount: data.max_supported_target_count,
|
|
1913
|
+
brainContext: data.brain_context ?? {},
|
|
1914
|
+
providerRoute: mapProviderRoute2(data)
|
|
1915
|
+
};
|
|
1916
|
+
}
|
|
1917
|
+
function mapProviderRoute2(data) {
|
|
1918
|
+
const brainContext = asRecord(data?.brain_context);
|
|
1919
|
+
const plan = nullableRecord(data?.provider_route_plan) ?? nullableRecord(brainContext.provider_route_plan);
|
|
1920
|
+
const summary = nullableRecord(data?.provider_route_summary) ?? nullableRecord(brainContext.provider_route_summary) ?? nullableRecord(plan?.summary);
|
|
1921
|
+
const blockers = arrayOfStrings(data?.provider_route_blockers ?? brainContext.provider_route_blockers ?? plan?.blockers) ?? [];
|
|
1922
|
+
const warnings = arrayOfStrings(data?.provider_route_warnings ?? brainContext.provider_route_warnings ?? plan?.warnings) ?? [];
|
|
1923
|
+
const ready = typeof data?.provider_route_ready === "boolean" ? data.provider_route_ready : typeof brainContext.provider_route_ready === "boolean" ? brainContext.provider_route_ready : typeof plan?.ready === "boolean" ? plan.ready : null;
|
|
1924
|
+
const label = typeof data?.provider_route_label === "string" ? data.provider_route_label : typeof brainContext.provider_route_label === "string" ? brainContext.provider_route_label : providerRouteLabel2(summary, ready);
|
|
1925
|
+
if (!plan && !summary && ready === null && blockers.length === 0 && warnings.length === 0 && !label) {
|
|
1926
|
+
return null;
|
|
1927
|
+
}
|
|
1928
|
+
return {
|
|
1929
|
+
plan,
|
|
1930
|
+
summary,
|
|
1931
|
+
ready,
|
|
1932
|
+
label: label || "attached",
|
|
1933
|
+
blockers,
|
|
1934
|
+
warnings
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
function nullableRecord(value) {
|
|
1938
|
+
const record = asRecord(value);
|
|
1939
|
+
return Object.keys(record).length > 0 ? record : null;
|
|
1940
|
+
}
|
|
1941
|
+
function providerRouteLabel2(summary, ready) {
|
|
1942
|
+
if (!summary) return ready === true ? "ready" : ready === false ? "blocked" : "";
|
|
1943
|
+
const totalLayers = numberOrNull2(summary.total_layers);
|
|
1944
|
+
const readyLayers = numberOrNull2(summary.ready_layers);
|
|
1945
|
+
const customProviderLayers = numberOrNull2(summary.custom_provider_layers);
|
|
1946
|
+
const signalizDefaultLayers = numberOrNull2(summary.signaliz_default_layers);
|
|
1947
|
+
const fallbackLayers = numberOrNull2(summary.fallback_layers);
|
|
1948
|
+
const blockedLayers = numberOrNull2(summary.blocked_layers);
|
|
1949
|
+
return [
|
|
1950
|
+
totalLayers === null || readyLayers === null ? ready === true ? "ready" : ready === false ? "blocked" : null : `${readyLayers}/${totalLayers} layers ready`,
|
|
1951
|
+
customProviderLayers !== null ? `${customProviderLayers} custom` : null,
|
|
1952
|
+
signalizDefaultLayers !== null ? `${signalizDefaultLayers} Signaliz default` : null,
|
|
1953
|
+
fallbackLayers !== null ? `${fallbackLayers} fallback` : null,
|
|
1954
|
+
blockedLayers !== null ? `${blockedLayers} blocked` : null
|
|
1955
|
+
].filter(Boolean).join(", ");
|
|
1956
|
+
}
|
|
1957
|
+
function numberOrNull2(value) {
|
|
1958
|
+
const parsed = Number(value);
|
|
1959
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1960
|
+
}
|
|
1961
|
+
function estimateCredits(request, defaults, targetCount) {
|
|
1962
|
+
if (typeof defaults.maxCredits === "number") return defaults.maxCredits;
|
|
1963
|
+
const signalCredits = defaults.signals?.enabled === false ? 0 : targetCount * 2;
|
|
1964
|
+
const copyCredits = defaults.copy?.enabled === false ? 0 : targetCount;
|
|
1965
|
+
const requiredCustomerToolPremium = [...request.integrations ?? [], ...routesFromCustomerTools(request.customerTools ?? [])].filter((route) => route.mode === "required" && ["octave", "ai_ark", "clay_webhook"].includes(route.provider)).length * Math.ceil(targetCount / 25);
|
|
1966
|
+
return signalCredits + copyCredits + requiredCustomerToolPremium;
|
|
1967
|
+
}
|
|
1968
|
+
function buildDescription(request) {
|
|
1969
|
+
const parts = [
|
|
1970
|
+
request.clientName ? `Client: ${request.clientName}` : void 0,
|
|
1971
|
+
request.clientContext ? `Context: ${request.clientContext}` : void 0,
|
|
1972
|
+
request.constraints?.deliverabilityNotes?.length ? `Deliverability: ${request.constraints.deliverabilityNotes.join("; ")}` : void 0,
|
|
1973
|
+
"Agent-built campaign plan layered on Signaliz kernel and existing MCP tools."
|
|
1974
|
+
];
|
|
1975
|
+
return parts.filter(Boolean).join("\n");
|
|
1976
|
+
}
|
|
1977
|
+
function dedupeApprovals(approvals) {
|
|
1978
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1979
|
+
return approvals.filter((approval) => {
|
|
1980
|
+
const key = `${approval.type}:${approval.routeId ?? approval.provider ?? approval.id}`;
|
|
1981
|
+
if (seen.has(key)) return false;
|
|
1982
|
+
seen.add(key);
|
|
1983
|
+
return true;
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
function compact(record) {
|
|
1987
|
+
return Object.fromEntries(
|
|
1988
|
+
Object.entries(record).filter(([, value]) => value !== void 0 && value !== null && value !== "")
|
|
1989
|
+
);
|
|
1990
|
+
}
|
|
1991
|
+
function asRecord(value) {
|
|
1992
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1993
|
+
}
|
|
1994
|
+
function stringValue(value) {
|
|
1995
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1996
|
+
}
|
|
1997
|
+
function numberOrUndefined2(value) {
|
|
1998
|
+
const parsed = Number(value);
|
|
1999
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
2000
|
+
}
|
|
2001
|
+
function arrayOfStrings(value) {
|
|
2002
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : void 0;
|
|
2003
|
+
}
|
|
2004
|
+
function uniqueStrings(values) {
|
|
2005
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2006
|
+
const out = [];
|
|
2007
|
+
for (const value of values) {
|
|
2008
|
+
if (!value) continue;
|
|
2009
|
+
const key = value.trim();
|
|
2010
|
+
if (!key || seen.has(key)) continue;
|
|
2011
|
+
seen.add(key);
|
|
2012
|
+
out.push(key);
|
|
2013
|
+
}
|
|
2014
|
+
return out;
|
|
2015
|
+
}
|
|
2016
|
+
function titleFromGoal(goal) {
|
|
2017
|
+
const words = goal.replace(/[^a-zA-Z0-9 ]/g, " ").trim().split(/\s+/).slice(0, 7);
|
|
2018
|
+
return words.length > 0 ? words.map((word) => word[0]?.toUpperCase() + word.slice(1)).join(" ") : "Agent Built Campaign";
|
|
2019
|
+
}
|
|
2020
|
+
function hashString(input) {
|
|
2021
|
+
let hash = 0;
|
|
2022
|
+
for (let i = 0; i < input.length; i++) {
|
|
2023
|
+
hash = (hash << 5) - hash + input.charCodeAt(i) | 0;
|
|
2024
|
+
}
|
|
2025
|
+
return Math.abs(hash).toString(36);
|
|
2026
|
+
}
|
|
2027
|
+
function errorMessage(error) {
|
|
2028
|
+
return error instanceof Error ? error.message : String(error);
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
// src/resources/icps.ts
|
|
2032
|
+
var Icps = class {
|
|
2033
|
+
constructor(client) {
|
|
2034
|
+
this.client = client;
|
|
2035
|
+
}
|
|
2036
|
+
/** List all ICPs in the workspace */
|
|
2037
|
+
async list(opts) {
|
|
2038
|
+
const data = await this.client.mcp("tools/call", {
|
|
2039
|
+
name: "list_icps",
|
|
2040
|
+
arguments: {
|
|
2041
|
+
include_source_playbook_data: opts?.includeSourcePlaybookData ?? opts?.includeOctaveData ?? false
|
|
2042
|
+
}
|
|
2043
|
+
});
|
|
2044
|
+
return data.icps ?? [];
|
|
2045
|
+
}
|
|
2046
|
+
/** Get full ICP details by ID */
|
|
2047
|
+
async get(icpId) {
|
|
2048
|
+
return this.client.mcp("tools/call", {
|
|
2049
|
+
name: "get_icp",
|
|
2050
|
+
arguments: { icp_id: icpId }
|
|
2051
|
+
});
|
|
2052
|
+
}
|
|
2053
|
+
/** Import connected source playbooks as ICPs */
|
|
2054
|
+
async importFromPlaybooks(playbookIds) {
|
|
2055
|
+
return this.client.mcp("tools/call", {
|
|
2056
|
+
name: "import_icps_from_playbooks",
|
|
2057
|
+
arguments: playbookIds?.length ? { playbook_ids: playbookIds } : {}
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
/** @deprecated Use importFromPlaybooks. */
|
|
2061
|
+
async importFromOctave(playbookIds) {
|
|
2062
|
+
return this.importFromPlaybooks(playbookIds);
|
|
2063
|
+
}
|
|
2064
|
+
};
|
|
2065
|
+
|
|
2066
|
+
// src/resources/leads.ts
|
|
2067
|
+
var Leads = class {
|
|
2068
|
+
constructor(client) {
|
|
2069
|
+
this.client = client;
|
|
2070
|
+
}
|
|
2071
|
+
/**
|
|
2072
|
+
* Generate B2B leads from a natural-language prompt.
|
|
2073
|
+
* Returns a job_id — poll with `runs.get(jobId)` or `check_job_status`.
|
|
2074
|
+
*/
|
|
2075
|
+
async generate(params) {
|
|
2076
|
+
const data = await this.client.mcp("tools/call", {
|
|
2077
|
+
name: "generate_leads",
|
|
2078
|
+
arguments: {
|
|
2079
|
+
prompt: params.prompt,
|
|
2080
|
+
max_leads: params.maxLeads,
|
|
2081
|
+
verify_emails: params.verifyEmails,
|
|
2082
|
+
file_name: params.fileName,
|
|
2083
|
+
model: params.model,
|
|
2084
|
+
company_domains: params.companyDomains,
|
|
2085
|
+
completeness_mode: params.completenessMode,
|
|
2086
|
+
lookalike_expansion: params.lookalikeExpansion,
|
|
2087
|
+
confirm_spend: params.confirmSpend
|
|
2088
|
+
}
|
|
2089
|
+
});
|
|
2090
|
+
return mapJobResult(data);
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Generate local business leads via Google Maps + email scraping.
|
|
2094
|
+
* Returns a job_id — poll with `runs.get(jobId)` or `check_job_status`.
|
|
2095
|
+
*/
|
|
2096
|
+
async generateLocal(params) {
|
|
2097
|
+
const data = await this.client.mcp("tools/call", {
|
|
2098
|
+
name: "generate_local_leads",
|
|
2099
|
+
arguments: {
|
|
2100
|
+
prompt: params.prompt,
|
|
2101
|
+
target_verified: params.targetVerified ?? params.maxLeads,
|
|
2102
|
+
verify_emails: params.verifyEmails,
|
|
2103
|
+
file_name: params.fileName,
|
|
2104
|
+
confirm_spend: params.confirmSpend
|
|
2105
|
+
}
|
|
2106
|
+
});
|
|
2107
|
+
return mapJobResult(data);
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* List curated native GTM data sources with data-cost guardrails.
|
|
2111
|
+
*/
|
|
2112
|
+
async listNativeGtmCapabilities(category) {
|
|
2113
|
+
const data = await this.client.mcp("tools/call", {
|
|
2114
|
+
name: "list_native_gtm_capabilities",
|
|
2115
|
+
arguments: category ? { category } : {}
|
|
2116
|
+
});
|
|
2117
|
+
return data.capabilities ?? [];
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Run a curated native GTM capability. Returns a job_id; poll with `runs.get(jobId)`
|
|
2121
|
+
* or `checkStatus(jobId)`.
|
|
2122
|
+
*/
|
|
2123
|
+
async runNativeGtmCapability(params) {
|
|
2124
|
+
const data = await this.client.mcp("tools/call", {
|
|
2125
|
+
name: "run_native_gtm_capability",
|
|
2126
|
+
arguments: {
|
|
2127
|
+
capability: params.capability,
|
|
2128
|
+
query: params.query,
|
|
2129
|
+
urls: params.urls,
|
|
2130
|
+
place_ids: params.placeIds,
|
|
2131
|
+
max_results: params.maxResults,
|
|
2132
|
+
mode: params.mode,
|
|
2133
|
+
since: params.since,
|
|
2134
|
+
location: params.location,
|
|
2135
|
+
country_code: params.countryCode,
|
|
2136
|
+
confirm_spend: params.confirmSpend
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2139
|
+
return mapJobResult(data);
|
|
2140
|
+
}
|
|
2141
|
+
/**
|
|
2142
|
+
* Free-text router: pass an intent like "pull youtube subscribers of @joshwhitfieldai"
|
|
2143
|
+
* and get back the top GTM capability matches with suggested args ready to run.
|
|
2144
|
+
*/
|
|
2145
|
+
async findGtmCapability(intent) {
|
|
2146
|
+
const data = await this.client.mcp("tools/call", {
|
|
2147
|
+
name: "find_gtm_capability",
|
|
2148
|
+
arguments: { intent }
|
|
2149
|
+
});
|
|
2150
|
+
return { matches: data.matches ?? [], intent: data.intent ?? intent };
|
|
2151
|
+
}
|
|
2152
|
+
/**
|
|
2153
|
+
* Check the status of a lead generation job.
|
|
2154
|
+
*/
|
|
2155
|
+
async checkStatus(jobId) {
|
|
2156
|
+
return this.client.mcp("tools/call", {
|
|
2157
|
+
name: "check_job_status",
|
|
2158
|
+
arguments: { job_id: jobId }
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
function mapJobResult(data) {
|
|
2163
|
+
return {
|
|
2164
|
+
jobId: data.job_id,
|
|
2165
|
+
status: data.status,
|
|
2166
|
+
capability: data.capability,
|
|
2167
|
+
prompt: data.prompt,
|
|
2168
|
+
source: data.source,
|
|
2169
|
+
targetVerified: data.target_verified,
|
|
2170
|
+
maxLeads: data.max_leads ?? data.max_results,
|
|
2171
|
+
verifyEmails: data.verify_emails ?? false,
|
|
2172
|
+
message: data.message,
|
|
2173
|
+
estimatedTimeSeconds: data.estimated_time_seconds
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
// src/resources/execution-reference.ts
|
|
2178
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2179
|
+
var PREFIXED_RE = /^(op|routine|tick|routine_tick|trigger|trigger_run|run|dataplane|dataplane_run|queue|queue_job|job|event|execution_event|replay|replay_run):(.+)$/i;
|
|
2180
|
+
var FIELD_KIND_MAP = {
|
|
2181
|
+
op_id: "op",
|
|
2182
|
+
opId: "op",
|
|
2183
|
+
routine_id: "routine",
|
|
2184
|
+
routineId: "routine",
|
|
2185
|
+
tick_id: "routine_tick",
|
|
2186
|
+
tickId: "routine_tick",
|
|
2187
|
+
routineTickId: "routine_tick",
|
|
2188
|
+
run_id: "trigger_run",
|
|
2189
|
+
runId: "trigger_run",
|
|
2190
|
+
trigger_run_id: "trigger_run",
|
|
2191
|
+
triggerRunId: "trigger_run",
|
|
2192
|
+
dataplane_run_id: "dataplane_run",
|
|
2193
|
+
dataplaneRunId: "dataplane_run",
|
|
2194
|
+
job_id: "queue_job",
|
|
2195
|
+
jobId: "queue_job",
|
|
2196
|
+
queue_job_id: "queue_job",
|
|
2197
|
+
queueJobId: "queue_job",
|
|
2198
|
+
execution_event_id: "execution_event",
|
|
2199
|
+
executionEventId: "execution_event",
|
|
2200
|
+
event_id: "execution_event",
|
|
2201
|
+
eventId: "execution_event",
|
|
2202
|
+
replay_run_id: "replay_run",
|
|
2203
|
+
replayRunId: "replay_run"
|
|
2204
|
+
};
|
|
2205
|
+
var PREFIX_KIND_MAP = {
|
|
2206
|
+
op: "op",
|
|
2207
|
+
routine: "routine",
|
|
2208
|
+
tick: "routine_tick",
|
|
2209
|
+
routine_tick: "routine_tick",
|
|
2210
|
+
trigger: "trigger_run",
|
|
2211
|
+
trigger_run: "trigger_run",
|
|
2212
|
+
run: "trigger_run",
|
|
2213
|
+
dataplane: "dataplane_run",
|
|
2214
|
+
dataplane_run: "dataplane_run",
|
|
2215
|
+
queue: "queue_job",
|
|
2216
|
+
queue_job: "queue_job",
|
|
2217
|
+
job: "queue_job",
|
|
2218
|
+
event: "execution_event",
|
|
2219
|
+
execution_event: "execution_event",
|
|
2220
|
+
replay: "replay_run",
|
|
2221
|
+
replay_run: "replay_run"
|
|
2222
|
+
};
|
|
2223
|
+
function normalizeExecutionReference(input) {
|
|
2224
|
+
const original = typeof input === "string" ? input : input.id;
|
|
2225
|
+
const trimmed = original.trim();
|
|
2226
|
+
const sourceField = typeof input === "string" ? void 0 : input.source_field;
|
|
2227
|
+
const explicitKind = typeof input === "string" ? void 0 : input.kind;
|
|
2228
|
+
const prefixed = trimmed.match(PREFIXED_RE);
|
|
2229
|
+
const kind = explicitKind ?? kindFromPrefix(prefixed?.[1]) ?? kindFromField(sourceField) ?? inferKind(trimmed);
|
|
2230
|
+
const id = prefixed?.[2]?.trim() || trimmed;
|
|
2231
|
+
return {
|
|
2232
|
+
kind,
|
|
2233
|
+
id,
|
|
2234
|
+
original,
|
|
2235
|
+
label: labelFor(kind),
|
|
2236
|
+
query_field: queryFieldFor(kind),
|
|
2237
|
+
status_command: statusCommandFor(kind, id),
|
|
2238
|
+
replay_command: replayCommandFor(kind, id)
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
function collectExecutionReferences(payload) {
|
|
2242
|
+
const refs = [];
|
|
2243
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2244
|
+
for (const [field, value] of Object.entries(payload)) {
|
|
2245
|
+
if (!Object.prototype.hasOwnProperty.call(FIELD_KIND_MAP, field)) continue;
|
|
2246
|
+
if (typeof value !== "string" || value.trim().length === 0) continue;
|
|
2247
|
+
const ref = normalizeExecutionReference({ id: value, source_field: field });
|
|
2248
|
+
const key = `${ref.kind}:${ref.id}`;
|
|
2249
|
+
if (seen.has(key)) continue;
|
|
2250
|
+
seen.add(key);
|
|
2251
|
+
refs.push(ref);
|
|
2252
|
+
}
|
|
2253
|
+
return refs;
|
|
2254
|
+
}
|
|
2255
|
+
function kindFromPrefix(prefix) {
|
|
2256
|
+
if (!prefix) return void 0;
|
|
2257
|
+
return PREFIX_KIND_MAP[prefix.toLowerCase()];
|
|
2258
|
+
}
|
|
2259
|
+
function kindFromField(field) {
|
|
2260
|
+
if (!field) return void 0;
|
|
2261
|
+
return FIELD_KIND_MAP[field];
|
|
2262
|
+
}
|
|
2263
|
+
function inferKind(value) {
|
|
2264
|
+
if (value.startsWith("run_")) return "trigger_run";
|
|
2265
|
+
if (UUID_RE.test(value)) return "dataplane_run";
|
|
2266
|
+
return "unknown";
|
|
2267
|
+
}
|
|
2268
|
+
function labelFor(kind) {
|
|
2269
|
+
switch (kind) {
|
|
2270
|
+
case "op":
|
|
2271
|
+
return "Op";
|
|
2272
|
+
case "routine":
|
|
2273
|
+
return "Routine";
|
|
2274
|
+
case "routine_tick":
|
|
2275
|
+
return "Routine tick";
|
|
2276
|
+
case "trigger_run":
|
|
2277
|
+
return "Trigger.dev run";
|
|
2278
|
+
case "dataplane_run":
|
|
2279
|
+
return "Dataplane run";
|
|
2280
|
+
case "queue_job":
|
|
2281
|
+
return "Queue job";
|
|
2282
|
+
case "execution_event":
|
|
2283
|
+
return "Execution event";
|
|
2284
|
+
case "replay_run":
|
|
2285
|
+
return "Replay run";
|
|
2286
|
+
case "unknown":
|
|
2287
|
+
default:
|
|
2288
|
+
return "Execution reference";
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
function queryFieldFor(kind) {
|
|
2292
|
+
switch (kind) {
|
|
2293
|
+
case "op":
|
|
2294
|
+
return "op_id";
|
|
2295
|
+
case "routine":
|
|
2296
|
+
return "routine_id";
|
|
2297
|
+
case "routine_tick":
|
|
2298
|
+
return "tick_id";
|
|
2299
|
+
case "trigger_run":
|
|
2300
|
+
return "run_id";
|
|
2301
|
+
case "dataplane_run":
|
|
2302
|
+
return "run_id";
|
|
2303
|
+
case "queue_job":
|
|
2304
|
+
return "job_id";
|
|
2305
|
+
case "execution_event":
|
|
2306
|
+
return "execution_event_id";
|
|
2307
|
+
case "replay_run":
|
|
2308
|
+
return "replay_run_id";
|
|
2309
|
+
case "unknown":
|
|
2310
|
+
default:
|
|
2311
|
+
return "id";
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
function statusCommandFor(kind, id) {
|
|
2315
|
+
switch (kind) {
|
|
2316
|
+
case "op":
|
|
2317
|
+
return `signaliz status ${id}`;
|
|
2318
|
+
case "trigger_run":
|
|
2319
|
+
case "dataplane_run":
|
|
2320
|
+
case "replay_run":
|
|
2321
|
+
return `signaliz watch ${id}`;
|
|
2322
|
+
case "queue_job":
|
|
2323
|
+
return `signaliz queue --job-id ${id}`;
|
|
2324
|
+
case "routine":
|
|
2325
|
+
return `signaliz routine ${id}`;
|
|
2326
|
+
default:
|
|
2327
|
+
return void 0;
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
function replayCommandFor(kind, id) {
|
|
2331
|
+
if (kind !== "execution_event") return void 0;
|
|
2332
|
+
return `signaliz replay ${id}`;
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
// src/resources/ops.ts
|
|
2336
|
+
function asRecord2(value) {
|
|
2337
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2338
|
+
}
|
|
2339
|
+
function stringValue2(value, fallback = "") {
|
|
2340
|
+
return typeof value === "string" ? value : fallback;
|
|
2341
|
+
}
|
|
2342
|
+
function optionalString(value) {
|
|
2343
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2344
|
+
}
|
|
2345
|
+
function numberValue(value) {
|
|
2346
|
+
const parsed = Number(value);
|
|
2347
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
2348
|
+
}
|
|
2349
|
+
var Ops = class {
|
|
2350
|
+
constructor(client) {
|
|
2351
|
+
this.client = client;
|
|
2352
|
+
}
|
|
2353
|
+
async plan(params) {
|
|
2354
|
+
const body = typeof params === "string" ? { prompt: params } : buildOpsPlanBody(params);
|
|
2355
|
+
return normalizeOpsPlanResult(await this.call("ops_plan", body));
|
|
2356
|
+
}
|
|
2357
|
+
async autopilot(params = {}) {
|
|
2358
|
+
const data = await this.call("ops_autopilot", {
|
|
2359
|
+
window_hours: params.windowHours,
|
|
2360
|
+
output_format: "json"
|
|
2361
|
+
});
|
|
2362
|
+
return normalizeOpsAutopilotResult(data);
|
|
2363
|
+
}
|
|
2364
|
+
async create(params) {
|
|
2365
|
+
const body = typeof params === "string" ? { prompt: params } : buildOpsCreateBody(params);
|
|
2366
|
+
return normalizeOpsCreateResult(withExecutionRefs(await this.call("ops_create", body)));
|
|
2367
|
+
}
|
|
2368
|
+
async execute(params) {
|
|
2369
|
+
const body = typeof params === "string" ? { prompt: params } : buildOpsExecuteBody(params);
|
|
2370
|
+
return normalizeOpsExecuteResult(withExecutionRefs(await this.call("ops_execute", body)));
|
|
2371
|
+
}
|
|
2372
|
+
async run(params) {
|
|
2373
|
+
const body = typeof params === "string" ? { op_id: params } : buildOpsRunBody(params);
|
|
2374
|
+
return normalizeOpsRunResult(withExecutionRefs(await this.call("ops_run", body)));
|
|
2375
|
+
}
|
|
2376
|
+
async status(params) {
|
|
2377
|
+
const body = typeof params === "string" ? { op_id: params } : buildOpsStatusBody(params);
|
|
2378
|
+
return normalizeOpsStatusResult(withExecutionRefs(await this.call("ops_status", body)));
|
|
2379
|
+
}
|
|
2380
|
+
async results(params) {
|
|
2381
|
+
const body = typeof params === "string" ? { op_id: params } : buildOpsResultsBody(params);
|
|
2382
|
+
return normalizeOpsResultsResult(withExecutionRefs(await this.call("ops_results", body)));
|
|
2383
|
+
}
|
|
2384
|
+
async proof(params = {}) {
|
|
2385
|
+
const data = await this.call("ops_proof", {
|
|
2386
|
+
window_hours: params.windowHours,
|
|
2387
|
+
output_format: "json"
|
|
2388
|
+
});
|
|
2389
|
+
return normalizeOpsProofResult(data);
|
|
2390
|
+
}
|
|
2391
|
+
async debug(params) {
|
|
2392
|
+
const options = typeof params === "string" ? { op_id: params } : buildOpsDebugOptions(params);
|
|
2393
|
+
const diagnosticErrors = [];
|
|
2394
|
+
const status = await this.status(options.op_id);
|
|
2395
|
+
const refs = /* @__PURE__ */ new Map();
|
|
2396
|
+
const addRefs = (items) => {
|
|
2397
|
+
for (const ref of items ?? []) refs.set(`${ref.kind}:${ref.id}`, ref);
|
|
2398
|
+
};
|
|
2399
|
+
const recordError = (step, err) => {
|
|
2400
|
+
diagnosticErrors.push({
|
|
2401
|
+
step,
|
|
2402
|
+
message: err instanceof Error ? err.message : String(err)
|
|
2403
|
+
});
|
|
2404
|
+
};
|
|
2405
|
+
addRefs(status.execution_refs);
|
|
2406
|
+
if (status.latest_run && typeof status.latest_run === "object") {
|
|
2407
|
+
addRefs(collectExecutionReferences(status.latest_run));
|
|
2408
|
+
}
|
|
2409
|
+
const runRefs = Array.from(refs.values()).filter((ref) => ref.kind === "trigger_run" || ref.kind === "dataplane_run" || ref.kind === "replay_run");
|
|
2410
|
+
const runStatuses = [];
|
|
2411
|
+
for (const ref of runRefs) {
|
|
2412
|
+
try {
|
|
2413
|
+
const result = await this.getTriggerRunStatus(ref.id);
|
|
2414
|
+
const runs = "runs" in result ? result.runs : [result];
|
|
2415
|
+
runStatuses.push(...runs);
|
|
2416
|
+
for (const run of runs) addRefs(run.execution_refs);
|
|
2417
|
+
} catch (err) {
|
|
2418
|
+
recordError(`run-status:${ref.id}`, err);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
let queue;
|
|
2422
|
+
if (options.include_queue !== false) {
|
|
2423
|
+
try {
|
|
2424
|
+
queue = await this.getQueueStatus({ summary: true });
|
|
2425
|
+
addRefs(queue.execution_refs);
|
|
2426
|
+
} catch (err) {
|
|
2427
|
+
recordError("queue", err);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
let dashboardRecent;
|
|
2431
|
+
if (options.include_dashboard !== false) {
|
|
2432
|
+
try {
|
|
2433
|
+
dashboardRecent = await this.getDashboard({
|
|
2434
|
+
section: "recent",
|
|
2435
|
+
limit: options.dashboard_limit ?? 10,
|
|
2436
|
+
timeRangeDays: options.time_range_days
|
|
2437
|
+
});
|
|
2438
|
+
} catch (err) {
|
|
2439
|
+
recordError("dashboard:recent", err);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
let results;
|
|
2443
|
+
if (options.include_results) {
|
|
2444
|
+
try {
|
|
2445
|
+
results = await this.results({
|
|
2446
|
+
op_id: options.op_id,
|
|
2447
|
+
limit: options.results_limit ?? 25,
|
|
2448
|
+
include_failed_runs: true
|
|
2449
|
+
});
|
|
2450
|
+
addRefs(results.execution_refs);
|
|
2451
|
+
} catch (err) {
|
|
2452
|
+
recordError("results", err);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
const executionRefs = Array.from(refs.values());
|
|
2456
|
+
const replayCandidates = executionRefs.filter((ref) => ref.kind === "execution_event");
|
|
2457
|
+
const nextActions = buildDebugNextActions(status, executionRefs, diagnosticErrors);
|
|
2458
|
+
return normalizeOpsDebugResult({
|
|
2459
|
+
success: diagnosticErrors.length === 0,
|
|
2460
|
+
op_id: options.op_id,
|
|
2461
|
+
checked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2462
|
+
diagnosis: buildDebugDiagnosis(status, runStatuses, queue, diagnosticErrors),
|
|
2463
|
+
status,
|
|
2464
|
+
execution_refs: executionRefs,
|
|
2465
|
+
run_statuses: runStatuses,
|
|
2466
|
+
queue,
|
|
2467
|
+
dashboard_recent: dashboardRecent,
|
|
2468
|
+
results,
|
|
2469
|
+
replay_candidates: replayCandidates,
|
|
2470
|
+
next_actions: nextActions,
|
|
2471
|
+
diagnostic_errors: diagnosticErrors
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
async quickstartWorkflow(workflowType = "email_verification") {
|
|
2475
|
+
const workflow = normalizeOpsQuickstartWorkflow(await this.call("quickstart_workflow", { workflow_type: workflowType }));
|
|
2476
|
+
assertQuickstartWorkflowCoherent(workflow, workflowType);
|
|
2477
|
+
return workflow;
|
|
2478
|
+
}
|
|
2479
|
+
async approve(params) {
|
|
2480
|
+
return normalizeOpsApproveResult(await this.call("ops_approve", buildApproveBody(params)));
|
|
2481
|
+
}
|
|
2482
|
+
async createRoutine(params) {
|
|
2483
|
+
return normalizeOpsRoutine(await this.call("create_routine", buildCreateRoutineBody(params)));
|
|
2484
|
+
}
|
|
2485
|
+
async listRoutines(params = {}) {
|
|
2486
|
+
const data = await this.call("list_routines", { ...params, format: "json" });
|
|
2487
|
+
const nextCursor = data.next_cursor ?? data.nextCursor ?? null;
|
|
2488
|
+
const hasMore = data.has_more ?? data.hasMore ?? false;
|
|
2489
|
+
return {
|
|
2490
|
+
routines: Array.isArray(data.routines ?? data) ? (data.routines ?? data).map(normalizeOpsRoutine) : [],
|
|
2491
|
+
total: data.total,
|
|
2492
|
+
next_cursor: nextCursor,
|
|
2493
|
+
nextCursor,
|
|
2494
|
+
has_more: hasMore,
|
|
2495
|
+
hasMore
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
async getRoutine(routineId) {
|
|
2499
|
+
return normalizeOpsRoutine(await this.call("get_routine", { routine_id: routineId }));
|
|
2500
|
+
}
|
|
2501
|
+
async updateRoutine(params) {
|
|
2502
|
+
return normalizeOpsRoutine(await this.call("update_routine", buildRoutineBody(params)));
|
|
2503
|
+
}
|
|
2504
|
+
async runRoutineNow(params) {
|
|
2505
|
+
const body = typeof params === "string" ? { routine_id: params } : buildRoutineBody(params);
|
|
2506
|
+
return normalizeOpsRoutineRunResult(await this.call("run_routine_now", body));
|
|
2507
|
+
}
|
|
2508
|
+
async deleteRoutine(routineId, permanent = false) {
|
|
2509
|
+
return normalizeOpsRoutineDeleteResult(await this.call("delete_routine", { routine_id: routineId, confirm: true, permanent }));
|
|
2510
|
+
}
|
|
2511
|
+
async listOutputSinks(params = {}) {
|
|
2512
|
+
const data = await this.call("list_output_sinks", buildListOutputSinksBody(params));
|
|
2513
|
+
const sinks = data.sinks ?? data ?? [];
|
|
2514
|
+
return Array.isArray(sinks) ? sinks.map(normalizeOpsSink) : [];
|
|
2515
|
+
}
|
|
2516
|
+
async getReadiness(params = {}) {
|
|
2517
|
+
const data = await this.call("get_ops_readiness", {
|
|
2518
|
+
window_hours: params.windowHours,
|
|
2519
|
+
include_details: params.includeDetails,
|
|
2520
|
+
run_acquisition_probe: params.runAcquisitionProbe,
|
|
2521
|
+
output_format: "json"
|
|
2522
|
+
});
|
|
2523
|
+
const summary = asRecord2(data.summary);
|
|
2524
|
+
const checks = Array.isArray(data.checks) ? data.checks : [];
|
|
2525
|
+
const checkedAt = stringValue2(data.checked_at ?? data.checkedAt, (/* @__PURE__ */ new Date()).toISOString());
|
|
2526
|
+
const nextActions = Array.isArray(data.next_actions) ? data.next_actions.map(String) : Array.isArray(data.nextActions) ? data.nextActions.map(String) : [];
|
|
2527
|
+
return {
|
|
2528
|
+
status: data.status === "ready" || data.status === "blocked" ? data.status : "degraded",
|
|
2529
|
+
checked_at: checkedAt,
|
|
2530
|
+
checkedAt,
|
|
2531
|
+
credits_used: 0,
|
|
2532
|
+
creditsUsed: 0,
|
|
2533
|
+
credits_charged: 0,
|
|
2534
|
+
creditsCharged: 0,
|
|
2535
|
+
summary: {
|
|
2536
|
+
active_connections: numberValue(summary.active_connections ?? summary.activeConnections),
|
|
2537
|
+
activeConnections: numberValue(summary.active_connections ?? summary.activeConnections),
|
|
2538
|
+
failing_connections: numberValue(summary.failing_connections ?? summary.failingConnections),
|
|
2539
|
+
failingConnections: numberValue(summary.failing_connections ?? summary.failingConnections),
|
|
2540
|
+
active_routines: numberValue(summary.active_routines ?? summary.activeRoutines),
|
|
2541
|
+
activeRoutines: numberValue(summary.active_routines ?? summary.activeRoutines),
|
|
2542
|
+
recent_failed_ticks: numberValue(summary.recent_failed_ticks ?? summary.recentFailedTicks),
|
|
2543
|
+
recentFailedTicks: numberValue(summary.recent_failed_ticks ?? summary.recentFailedTicks),
|
|
2544
|
+
queued_deliveries: numberValue(summary.queued_deliveries ?? summary.queuedDeliveries),
|
|
2545
|
+
queuedDeliveries: numberValue(summary.queued_deliveries ?? summary.queuedDeliveries),
|
|
2546
|
+
pending_approvals: numberValue(summary.pending_approvals ?? summary.pendingApprovals),
|
|
2547
|
+
pendingApprovals: numberValue(summary.pending_approvals ?? summary.pendingApprovals),
|
|
2548
|
+
lead_records: numberValue(summary.lead_records ?? summary.leadRecords),
|
|
2549
|
+
leadRecords: numberValue(summary.lead_records ?? summary.leadRecords),
|
|
2550
|
+
recent_acquisition_failures: numberValue(summary.recent_acquisition_failures ?? summary.recentAcquisitionFailures),
|
|
2551
|
+
recentAcquisitionFailures: numberValue(summary.recent_acquisition_failures ?? summary.recentAcquisitionFailures),
|
|
2552
|
+
acquisition_probe_status: optionalString(summary.acquisition_probe_status ?? summary.acquisitionProbeStatus),
|
|
2553
|
+
acquisitionProbeStatus: optionalString(summary.acquisition_probe_status ?? summary.acquisitionProbeStatus)
|
|
2554
|
+
},
|
|
2555
|
+
checks: checks.map((rawCheck) => {
|
|
2556
|
+
const check = asRecord2(rawCheck);
|
|
2557
|
+
const nextAction = optionalString(check.next_action ?? check.nextAction);
|
|
2558
|
+
return {
|
|
2559
|
+
id: String(check.id ?? ""),
|
|
2560
|
+
label: String(check.label ?? check.id ?? ""),
|
|
2561
|
+
status: check.status === "fail" ? "fail" : check.status === "warn" ? "warn" : "pass",
|
|
2562
|
+
detail: String(check.detail ?? ""),
|
|
2563
|
+
next_action: nextAction,
|
|
2564
|
+
nextAction
|
|
2565
|
+
};
|
|
2566
|
+
}),
|
|
2567
|
+
next_actions: nextActions,
|
|
2568
|
+
nextActions,
|
|
2569
|
+
raw: data
|
|
2570
|
+
};
|
|
2571
|
+
}
|
|
2572
|
+
async doctor(params = {}) {
|
|
2573
|
+
return this.getReadiness(params);
|
|
2574
|
+
}
|
|
2575
|
+
async createOutputSink(params) {
|
|
2576
|
+
const data = await this.call("create_output_sink", buildCreateOutputSinkBody(params));
|
|
2577
|
+
return normalizeOpsSink(data.sink ?? data);
|
|
2578
|
+
}
|
|
2579
|
+
async attachSinkToRoutine(params) {
|
|
2580
|
+
return normalizeOpsRoutineSinkResult(await this.call("attach_sink_to_routine", buildRoutineSinkBody(params)));
|
|
2581
|
+
}
|
|
2582
|
+
async getRoutineTicks(params) {
|
|
2583
|
+
return normalizeOpsRoutineTicksResult(await this.call("get_routine_ticks", buildRoutineBody(params)));
|
|
2584
|
+
}
|
|
2585
|
+
async getLastTickItems(params) {
|
|
2586
|
+
return normalizeOpsRoutineTickItemsResult(await this.call("get_last_tick_items", buildRoutineBody(params)));
|
|
2587
|
+
}
|
|
2588
|
+
async getTriggerRunStatus(params) {
|
|
2589
|
+
const body = typeof params === "string" ? { run_id: params } : {
|
|
2590
|
+
run_id: params.run_id ?? params.runId,
|
|
2591
|
+
run_ids: params.run_ids ?? params.runIds
|
|
2592
|
+
};
|
|
2593
|
+
const result = await this.client.post("trigger-run-status", body);
|
|
2594
|
+
if ("runs" in result) {
|
|
2595
|
+
return {
|
|
2596
|
+
...result,
|
|
2597
|
+
runs: result.runs.map((run) => normalizeOpsTriggerRunStatus(withExecutionRefs(run)))
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
return normalizeOpsTriggerRunStatus(withExecutionRefs(result));
|
|
2601
|
+
}
|
|
2602
|
+
async getQueueStatus(params = {}) {
|
|
2603
|
+
return normalizeOpsQueueStatus(withExecutionRefs(await this.client.get("check-queue-status", {
|
|
2604
|
+
job_id: params.job_id ?? params.jobId,
|
|
2605
|
+
idempotency_key: params.idempotency_key ?? params.idempotencyKey,
|
|
2606
|
+
summary: params.summary
|
|
2607
|
+
})));
|
|
2608
|
+
}
|
|
2609
|
+
async replayFromCheckpoint(executionEventId) {
|
|
2610
|
+
const result = await this.client.post("replay-from-checkpoint", { execution_event_id: executionEventId });
|
|
2611
|
+
const normalized = normalizeOpsReplayResult(withExecutionRefs(result));
|
|
2612
|
+
return {
|
|
2613
|
+
...normalized,
|
|
2614
|
+
execution_refs: [
|
|
2615
|
+
...normalized.execution_refs ?? [],
|
|
2616
|
+
normalizeExecutionReference({ id: executionEventId, source_field: "execution_event_id" })
|
|
2617
|
+
]
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
normalizeExecutionReference(input) {
|
|
2621
|
+
return normalizeExecutionReference(input);
|
|
2622
|
+
}
|
|
2623
|
+
collectExecutionReferences(payload) {
|
|
2624
|
+
return collectExecutionReferences(payload);
|
|
2625
|
+
}
|
|
2626
|
+
async getDashboard(params = {}) {
|
|
2627
|
+
return normalizeOpsDashboardResult(await this.client.post("ops-dashboard", params));
|
|
2628
|
+
}
|
|
2629
|
+
async call(name, args) {
|
|
2630
|
+
return this.client.mcp("tools/call", {
|
|
2631
|
+
name,
|
|
2632
|
+
arguments: args
|
|
2633
|
+
});
|
|
2634
|
+
}
|
|
2635
|
+
};
|
|
2636
|
+
function withExecutionRefs(result) {
|
|
2637
|
+
return {
|
|
2638
|
+
...result,
|
|
2639
|
+
execution_refs: mergeExecutionRefs(result)
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
function mergeExecutionRefs(result) {
|
|
2643
|
+
const refs = /* @__PURE__ */ new Map();
|
|
2644
|
+
const add = (ref) => refs.set(`${ref.kind}:${ref.id}`, ref);
|
|
2645
|
+
if (Array.isArray(result.execution_refs)) {
|
|
2646
|
+
for (const raw of result.execution_refs) {
|
|
2647
|
+
if (raw && typeof raw === "object") {
|
|
2648
|
+
const ref = raw;
|
|
2649
|
+
if (typeof ref.id === "string" && typeof ref.kind === "string") add(ref);
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
for (const ref of collectExecutionReferences(result)) add(ref);
|
|
2654
|
+
return Array.from(refs.values());
|
|
2655
|
+
}
|
|
2656
|
+
function normalizeOpsPrimitiveRetryPolicy(policy = {}) {
|
|
2657
|
+
return {
|
|
2658
|
+
...policy,
|
|
2659
|
+
max_retries: policy.max_retries ?? policy.maxRetries ?? 0,
|
|
2660
|
+
maxRetries: policy.maxRetries ?? policy.max_retries ?? 0,
|
|
2661
|
+
initial_delay_ms: policy.initial_delay_ms ?? policy.initialDelayMs ?? 0,
|
|
2662
|
+
initialDelayMs: policy.initialDelayMs ?? policy.initial_delay_ms ?? 0,
|
|
2663
|
+
max_delay_ms: policy.max_delay_ms ?? policy.maxDelayMs ?? 0,
|
|
2664
|
+
maxDelayMs: policy.maxDelayMs ?? policy.max_delay_ms ?? 0,
|
|
2665
|
+
backoff_multiplier: policy.backoff_multiplier ?? policy.backoffMultiplier ?? 0,
|
|
2666
|
+
backoffMultiplier: policy.backoffMultiplier ?? policy.backoff_multiplier ?? 0,
|
|
2667
|
+
jitter: policy.jitter ?? false,
|
|
2668
|
+
retryable_errors: policy.retryable_errors ?? policy.retryableErrors ?? [],
|
|
2669
|
+
retryableErrors: policy.retryableErrors ?? policy.retryable_errors ?? [],
|
|
2670
|
+
respect_retry_after: policy.respect_retry_after ?? policy.respectRetryAfter ?? false,
|
|
2671
|
+
respectRetryAfter: policy.respectRetryAfter ?? policy.respect_retry_after ?? false
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
function normalizeOpsPrimitiveConcurrencyPolicy(policy = {}) {
|
|
2675
|
+
return {
|
|
2676
|
+
...policy,
|
|
2677
|
+
workspace_key: policy.workspace_key ?? policy.workspaceKey ?? "",
|
|
2678
|
+
workspaceKey: policy.workspaceKey ?? policy.workspace_key ?? "",
|
|
2679
|
+
provider_key: policy.provider_key ?? policy.providerKey,
|
|
2680
|
+
providerKey: policy.providerKey ?? policy.provider_key,
|
|
2681
|
+
max_concurrency: policy.max_concurrency ?? policy.maxConcurrency ?? 0,
|
|
2682
|
+
maxConcurrency: policy.maxConcurrency ?? policy.max_concurrency ?? 0
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2685
|
+
function normalizeOpsPrimitiveDeadLetterPolicy(policy = {}) {
|
|
2686
|
+
return {
|
|
2687
|
+
...policy,
|
|
2688
|
+
enabled: policy.enabled ?? false,
|
|
2689
|
+
queue: policy.queue ?? "",
|
|
2690
|
+
include_input_hash: policy.include_input_hash ?? policy.includeInputHash ?? false,
|
|
2691
|
+
includeInputHash: policy.includeInputHash ?? policy.include_input_hash ?? false,
|
|
2692
|
+
include_execution_refs: policy.include_execution_refs ?? policy.includeExecutionRefs ?? false,
|
|
2693
|
+
includeExecutionRefs: policy.includeExecutionRefs ?? policy.include_execution_refs ?? false
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
function normalizeOpsPrimitiveObservabilityPolicy(policy = {}) {
|
|
2697
|
+
return {
|
|
2698
|
+
...policy,
|
|
2699
|
+
emits_execution_refs: policy.emits_execution_refs ?? policy.emitsExecutionRefs ?? false,
|
|
2700
|
+
emitsExecutionRefs: policy.emitsExecutionRefs ?? policy.emits_execution_refs ?? false,
|
|
2701
|
+
emits_progress_events: policy.emits_progress_events ?? policy.emitsProgressEvents ?? false,
|
|
2702
|
+
emitsProgressEvents: policy.emitsProgressEvents ?? policy.emits_progress_events ?? false,
|
|
2703
|
+
event_fields: policy.event_fields ?? policy.eventFields ?? [],
|
|
2704
|
+
eventFields: policy.eventFields ?? policy.event_fields ?? []
|
|
2705
|
+
};
|
|
2706
|
+
}
|
|
2707
|
+
function normalizeOpsPrimitive(primitive) {
|
|
2708
|
+
return {
|
|
2709
|
+
...primitive,
|
|
2710
|
+
permission_level: primitive.permission_level ?? primitive.permissionLevel,
|
|
2711
|
+
permissionLevel: primitive.permissionLevel ?? primitive.permission_level,
|
|
2712
|
+
workspace_scope: primitive.workspace_scope ?? primitive.workspaceScope,
|
|
2713
|
+
workspaceScope: primitive.workspaceScope ?? primitive.workspace_scope,
|
|
2714
|
+
input_schema: primitive.input_schema ?? primitive.inputSchema,
|
|
2715
|
+
inputSchema: primitive.inputSchema ?? primitive.input_schema,
|
|
2716
|
+
output_schema: primitive.output_schema ?? primitive.outputSchema,
|
|
2717
|
+
outputSchema: primitive.outputSchema ?? primitive.output_schema,
|
|
2718
|
+
retry_policy: normalizeOpsPrimitiveRetryPolicy(primitive.retry_policy ?? primitive.retryPolicy),
|
|
2719
|
+
retryPolicy: normalizeOpsPrimitiveRetryPolicy(primitive.retryPolicy ?? primitive.retry_policy),
|
|
2720
|
+
concurrency_policy: normalizeOpsPrimitiveConcurrencyPolicy(primitive.concurrency_policy ?? primitive.concurrencyPolicy),
|
|
2721
|
+
concurrencyPolicy: normalizeOpsPrimitiveConcurrencyPolicy(primitive.concurrencyPolicy ?? primitive.concurrency_policy),
|
|
2722
|
+
rate_limit_key: primitive.rate_limit_key ?? primitive.rateLimitKey,
|
|
2723
|
+
rateLimitKey: primitive.rateLimitKey ?? primitive.rate_limit_key,
|
|
2724
|
+
idempotency_key_fields: primitive.idempotency_key_fields ?? primitive.idempotencyKeyFields ?? [],
|
|
2725
|
+
idempotencyKeyFields: primitive.idempotencyKeyFields ?? primitive.idempotency_key_fields ?? [],
|
|
2726
|
+
dead_letter_policy: normalizeOpsPrimitiveDeadLetterPolicy(primitive.dead_letter_policy ?? primitive.deadLetterPolicy),
|
|
2727
|
+
deadLetterPolicy: normalizeOpsPrimitiveDeadLetterPolicy(primitive.deadLetterPolicy ?? primitive.dead_letter_policy),
|
|
2728
|
+
observability: normalizeOpsPrimitiveObservabilityPolicy(primitive.observability)
|
|
2729
|
+
};
|
|
2730
|
+
}
|
|
2731
|
+
function normalizeOpsPlanResult(result) {
|
|
2732
|
+
const primitiveGraph = result.primitive_graph ?? result.primitiveGraph;
|
|
2733
|
+
return {
|
|
2734
|
+
...result,
|
|
2735
|
+
plan_id: result.plan_id ?? result.planId,
|
|
2736
|
+
planId: result.planId ?? result.plan_id,
|
|
2737
|
+
target_count: result.target_count ?? result.targetCount,
|
|
2738
|
+
targetCount: result.targetCount ?? result.target_count,
|
|
2739
|
+
estimated_credits: result.estimated_credits ?? result.estimatedCredits,
|
|
2740
|
+
estimatedCredits: result.estimatedCredits ?? result.estimated_credits,
|
|
2741
|
+
approval_required: result.approval_required ?? result.approvalRequired,
|
|
2742
|
+
approvalRequired: result.approvalRequired ?? result.approval_required,
|
|
2743
|
+
expected_output: result.expected_output ?? result.expectedOutput,
|
|
2744
|
+
expectedOutput: result.expectedOutput ?? result.expected_output,
|
|
2745
|
+
next_action: result.next_action ?? result.nextAction,
|
|
2746
|
+
nextAction: result.nextAction ?? result.next_action,
|
|
2747
|
+
ui_summary: result.ui_summary ?? result.uiSummary,
|
|
2748
|
+
uiSummary: result.uiSummary ?? result.ui_summary,
|
|
2749
|
+
review_steps: result.review_steps ?? result.reviewSteps,
|
|
2750
|
+
reviewSteps: result.reviewSteps ?? result.review_steps,
|
|
2751
|
+
fix_actions: result.fix_actions ?? result.fixActions,
|
|
2752
|
+
fixActions: result.fixActions ?? result.fix_actions,
|
|
2753
|
+
destination_status: result.destination_status ?? result.destinationStatus,
|
|
2754
|
+
destinationStatus: result.destinationStatus ?? result.destination_status,
|
|
2755
|
+
primitive_graph: primitiveGraph?.map(normalizeOpsPrimitive),
|
|
2756
|
+
primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive)
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
function normalizeOpsCreateResult(result) {
|
|
2760
|
+
return {
|
|
2761
|
+
...result,
|
|
2762
|
+
op_id: result.op_id ?? result.opId,
|
|
2763
|
+
opId: result.opId ?? result.op_id,
|
|
2764
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
2765
|
+
routineId: result.routineId ?? result.routine_id,
|
|
2766
|
+
run_id: result.run_id ?? result.runId,
|
|
2767
|
+
runId: result.runId ?? result.run_id,
|
|
2768
|
+
next_action: result.next_action ?? result.nextAction,
|
|
2769
|
+
nextAction: result.nextAction ?? result.next_action,
|
|
2770
|
+
results_count: result.results_count ?? result.resultsCount,
|
|
2771
|
+
resultsCount: result.resultsCount ?? result.results_count,
|
|
2772
|
+
results_url: result.results_url ?? result.resultsUrl,
|
|
2773
|
+
resultsUrl: result.resultsUrl ?? result.results_url,
|
|
2774
|
+
delivery_status: result.delivery_status ?? result.deliveryStatus,
|
|
2775
|
+
deliveryStatus: result.deliveryStatus ?? result.delivery_status,
|
|
2776
|
+
estimated_credits: result.estimated_credits ?? result.estimatedCredits,
|
|
2777
|
+
estimatedCredits: result.estimatedCredits ?? result.estimated_credits,
|
|
2778
|
+
plan: result.plan ? normalizeOpsPlanResult(result.plan) : result.plan
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2781
|
+
function normalizeOpsExecuteResult(result) {
|
|
2782
|
+
const created = normalizeOpsCreateResult(result);
|
|
2783
|
+
return {
|
|
2784
|
+
...created,
|
|
2785
|
+
error_code: result.error_code ?? result.errorCode,
|
|
2786
|
+
errorCode: result.errorCode ?? result.error_code,
|
|
2787
|
+
approval_required: result.approval_required ?? result.approvalRequired,
|
|
2788
|
+
approvalRequired: result.approvalRequired ?? result.approval_required,
|
|
2789
|
+
retry_arguments: result.retry_arguments ?? result.retryArguments,
|
|
2790
|
+
retryArguments: result.retryArguments ?? result.retry_arguments,
|
|
2791
|
+
next_step: result.next_step ?? result.nextStep,
|
|
2792
|
+
nextStep: result.nextStep ?? result.next_step,
|
|
2793
|
+
next_steps: result.next_steps ?? result.nextSteps,
|
|
2794
|
+
nextSteps: result.nextSteps ?? result.next_steps,
|
|
2795
|
+
blockers: result.blockers
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
function normalizeOpsDebugDiagnosis(diagnosis) {
|
|
2799
|
+
return {
|
|
2800
|
+
...diagnosis,
|
|
2801
|
+
queue_pending: diagnosis.queue_pending ?? diagnosis.queuePending,
|
|
2802
|
+
queuePending: diagnosis.queuePending ?? diagnosis.queue_pending,
|
|
2803
|
+
queue_processing: diagnosis.queue_processing ?? diagnosis.queueProcessing,
|
|
2804
|
+
queueProcessing: diagnosis.queueProcessing ?? diagnosis.queue_processing,
|
|
2805
|
+
queue_failed_last_hour: diagnosis.queue_failed_last_hour ?? diagnosis.queueFailedLastHour,
|
|
2806
|
+
queueFailedLastHour: diagnosis.queueFailedLastHour ?? diagnosis.queue_failed_last_hour,
|
|
2807
|
+
provider_pressure: diagnosis.provider_pressure ?? diagnosis.providerPressure,
|
|
2808
|
+
providerPressure: diagnosis.providerPressure ?? diagnosis.provider_pressure,
|
|
2809
|
+
failed_run_count: diagnosis.failed_run_count ?? diagnosis.failedRunCount,
|
|
2810
|
+
failedRunCount: diagnosis.failedRunCount ?? diagnosis.failed_run_count,
|
|
2811
|
+
primary_error: diagnosis.primary_error ?? diagnosis.primaryError,
|
|
2812
|
+
primaryError: diagnosis.primaryError ?? diagnosis.primary_error
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
function normalizeOpsDebugResult(result) {
|
|
2816
|
+
return {
|
|
2817
|
+
...result,
|
|
2818
|
+
op_id: result.op_id ?? result.opId,
|
|
2819
|
+
opId: result.opId ?? result.op_id,
|
|
2820
|
+
checked_at: result.checked_at ?? result.checkedAt,
|
|
2821
|
+
checkedAt: result.checkedAt ?? result.checked_at,
|
|
2822
|
+
diagnosis: normalizeOpsDebugDiagnosis(result.diagnosis),
|
|
2823
|
+
execution_refs: result.execution_refs ?? result.executionRefs ?? [],
|
|
2824
|
+
executionRefs: result.executionRefs ?? result.execution_refs ?? [],
|
|
2825
|
+
run_statuses: result.run_statuses ?? result.runStatuses ?? [],
|
|
2826
|
+
runStatuses: result.runStatuses ?? result.run_statuses ?? [],
|
|
2827
|
+
dashboard_recent: result.dashboard_recent ?? result.dashboardRecent,
|
|
2828
|
+
dashboardRecent: result.dashboardRecent ?? result.dashboard_recent,
|
|
2829
|
+
replay_candidates: result.replay_candidates ?? result.replayCandidates ?? [],
|
|
2830
|
+
replayCandidates: result.replayCandidates ?? result.replay_candidates ?? [],
|
|
2831
|
+
next_actions: result.next_actions ?? result.nextActions ?? [],
|
|
2832
|
+
nextActions: result.nextActions ?? result.next_actions ?? [],
|
|
2833
|
+
diagnostic_errors: result.diagnostic_errors ?? result.diagnosticErrors ?? [],
|
|
2834
|
+
diagnosticErrors: result.diagnosticErrors ?? result.diagnostic_errors ?? []
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function normalizeOpsQuickstartStep(step) {
|
|
2838
|
+
return {
|
|
2839
|
+
...step,
|
|
2840
|
+
primitive_id: step.primitive_id ?? step.primitiveId,
|
|
2841
|
+
primitiveId: step.primitiveId ?? step.primitive_id,
|
|
2842
|
+
primitive_version: step.primitive_version ?? step.primitiveVersion,
|
|
2843
|
+
primitiveVersion: step.primitiveVersion ?? step.primitive_version
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
function normalizeOpsQuickstartWorkflow(result) {
|
|
2847
|
+
const primitiveGraph = result.primitive_graph ?? result.primitiveGraph;
|
|
2848
|
+
return {
|
|
2849
|
+
...result,
|
|
2850
|
+
workflow_type: result.workflow_type ?? result.workflowType,
|
|
2851
|
+
workflowType: result.workflowType ?? result.workflow_type,
|
|
2852
|
+
requested_workflow_type: result.requested_workflow_type ?? result.requestedWorkflowType,
|
|
2853
|
+
requestedWorkflowType: result.requestedWorkflowType ?? result.requested_workflow_type,
|
|
2854
|
+
credits_required: result.credits_required ?? result.creditsRequired,
|
|
2855
|
+
creditsRequired: result.creditsRequired ?? result.credits_required,
|
|
2856
|
+
steps: (result.steps ?? []).map(normalizeOpsQuickstartStep),
|
|
2857
|
+
primitive_graph: primitiveGraph?.map(normalizeOpsPrimitive),
|
|
2858
|
+
primitiveGraph: primitiveGraph?.map(normalizeOpsPrimitive),
|
|
2859
|
+
available_types: result.available_types ?? result.availableTypes ?? [],
|
|
2860
|
+
availableTypes: result.availableTypes ?? result.available_types ?? []
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2863
|
+
function assertQuickstartWorkflowCoherent(workflow, requestedWorkflowType) {
|
|
2864
|
+
if (!workflow.available_types.length) return;
|
|
2865
|
+
if (workflow.available_types.includes(workflow.workflow_type)) return;
|
|
2866
|
+
throw new SignalizError({
|
|
2867
|
+
code: "QUICKSTART_TEMPLATE_DRIFT",
|
|
2868
|
+
errorType: "validation",
|
|
2869
|
+
message: `quickstart_workflow returned workflow_type "${workflow.workflow_type}" for requested type "${requestedWorkflowType}", but available_types did not include it`,
|
|
2870
|
+
details: {
|
|
2871
|
+
requested_workflow_type: requestedWorkflowType,
|
|
2872
|
+
workflow_type: workflow.workflow_type,
|
|
2873
|
+
available_types: workflow.available_types
|
|
2874
|
+
}
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
function normalizeOpsRunResult(result) {
|
|
2878
|
+
return {
|
|
2879
|
+
...result,
|
|
2880
|
+
op_id: result.op_id ?? result.opId,
|
|
2881
|
+
opId: result.opId ?? result.op_id,
|
|
2882
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
2883
|
+
routineId: result.routineId ?? result.routine_id,
|
|
2884
|
+
run_id: result.run_id ?? result.runId,
|
|
2885
|
+
runId: result.runId ?? result.run_id,
|
|
2886
|
+
next_action: result.next_action ?? result.nextAction,
|
|
2887
|
+
nextAction: result.nextAction ?? result.next_action,
|
|
2888
|
+
results_count: result.results_count ?? result.resultsCount,
|
|
2889
|
+
resultsCount: result.resultsCount ?? result.results_count,
|
|
2890
|
+
results_url: result.results_url ?? result.resultsUrl,
|
|
2891
|
+
resultsUrl: result.resultsUrl ?? result.results_url,
|
|
2892
|
+
delivery_status: result.delivery_status ?? result.deliveryStatus,
|
|
2893
|
+
deliveryStatus: result.deliveryStatus ?? result.delivery_status
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
function normalizeOpsStatusResult(result) {
|
|
2897
|
+
return {
|
|
2898
|
+
...normalizeOpsRunResult(result),
|
|
2899
|
+
estimated_credits: result.estimated_credits ?? result.estimatedCredits,
|
|
2900
|
+
estimatedCredits: result.estimatedCredits ?? result.estimated_credits,
|
|
2901
|
+
latest_run: result.latest_run ?? result.latestRun,
|
|
2902
|
+
latestRun: result.latestRun ?? result.latest_run,
|
|
2903
|
+
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
function normalizeOpsResultsResult(result) {
|
|
2907
|
+
const nextCursor = result.next_cursor ?? result.nextCursor ?? null;
|
|
2908
|
+
const hasMore = result.has_more ?? result.hasMore ?? false;
|
|
2909
|
+
return {
|
|
2910
|
+
...result,
|
|
2911
|
+
op_id: result.op_id ?? result.opId,
|
|
2912
|
+
opId: result.opId ?? result.op_id,
|
|
2913
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
2914
|
+
routineId: result.routineId ?? result.routine_id,
|
|
2915
|
+
run_id: result.run_id ?? result.runId,
|
|
2916
|
+
runId: result.runId ?? result.run_id,
|
|
2917
|
+
results_count: result.results_count ?? result.resultsCount,
|
|
2918
|
+
resultsCount: result.resultsCount ?? result.results_count,
|
|
2919
|
+
results_total: result.results_total ?? result.resultsTotal,
|
|
2920
|
+
resultsTotal: result.resultsTotal ?? result.results_total,
|
|
2921
|
+
next_cursor: nextCursor,
|
|
2922
|
+
nextCursor,
|
|
2923
|
+
has_more: hasMore,
|
|
2924
|
+
hasMore,
|
|
2925
|
+
next_action: result.next_action ?? result.nextAction,
|
|
2926
|
+
nextAction: result.nextAction ?? result.next_action,
|
|
2927
|
+
results_url: result.results_url ?? result.resultsUrl,
|
|
2928
|
+
resultsUrl: result.resultsUrl ?? result.results_url,
|
|
2929
|
+
delivery_status: result.delivery_status ?? result.deliveryStatus,
|
|
2930
|
+
deliveryStatus: result.deliveryStatus ?? result.delivery_status
|
|
2931
|
+
};
|
|
2932
|
+
}
|
|
2933
|
+
function normalizeOpsProofResult(data) {
|
|
2934
|
+
const summary = asRecord2(data.summary);
|
|
2935
|
+
const destinations = Array.isArray(data.destinations) ? data.destinations.map((rawDestination) => {
|
|
2936
|
+
const destination = asRecord2(rawDestination);
|
|
2937
|
+
return {
|
|
2938
|
+
type: stringValue2(destination.type),
|
|
2939
|
+
label: stringValue2(destination.label, stringValue2(destination.type)),
|
|
2940
|
+
connected: Boolean(destination.connected),
|
|
2941
|
+
healthy: Boolean(destination.healthy),
|
|
2942
|
+
delivered: numberValue(destination.delivered),
|
|
2943
|
+
failed: numberValue(destination.failed),
|
|
2944
|
+
proof: stringValue2(destination.proof, "connected")
|
|
2945
|
+
};
|
|
2946
|
+
}) : [];
|
|
2947
|
+
const checkedAt = optionalString(data.checked_at ?? data.checkedAt);
|
|
2948
|
+
const nextActions = Array.isArray(data.next_actions) ? data.next_actions.map(String) : Array.isArray(data.nextActions) ? data.nextActions.map(String) : [];
|
|
2949
|
+
const blockers = Array.isArray(data.blockers) ? data.blockers.map(String) : [];
|
|
2950
|
+
const queryErrors = Array.isArray(data.query_errors) ? data.query_errors.map(String) : Array.isArray(data.queryErrors) ? data.queryErrors.map(String) : [];
|
|
2951
|
+
return {
|
|
2952
|
+
...data,
|
|
2953
|
+
status: stringValue2(data.status, stringValue2(data.proof_state ?? data.proofState, "unproven")),
|
|
2954
|
+
proof_state: stringValue2(data.proof_state ?? data.proofState, stringValue2(data.status, "unproven")),
|
|
2955
|
+
proofState: stringValue2(data.proofState ?? data.proof_state, stringValue2(data.status, "unproven")),
|
|
2956
|
+
checked_at: checkedAt,
|
|
2957
|
+
checkedAt,
|
|
2958
|
+
window_hours: numberValue(data.window_hours ?? data.windowHours),
|
|
2959
|
+
windowHours: numberValue(data.window_hours ?? data.windowHours),
|
|
2960
|
+
label: stringValue2(data.label, "Ops proof"),
|
|
2961
|
+
ui_summary: optionalString(data.ui_summary ?? data.uiSummary),
|
|
2962
|
+
uiSummary: optionalString(data.ui_summary ?? data.uiSummary),
|
|
2963
|
+
founder_verdict: optionalString(data.founder_verdict ?? data.founderVerdict),
|
|
2964
|
+
founderVerdict: optionalString(data.founder_verdict ?? data.founderVerdict),
|
|
2965
|
+
summary: {
|
|
2966
|
+
connected_destinations: numberValue(summary.connected_destinations ?? summary.connectedDestinations),
|
|
2967
|
+
connectedDestinations: numberValue(summary.connected_destinations ?? summary.connectedDestinations),
|
|
2968
|
+
healthy_destinations: numberValue(summary.healthy_destinations ?? summary.healthyDestinations),
|
|
2969
|
+
healthyDestinations: numberValue(summary.healthy_destinations ?? summary.healthyDestinations),
|
|
2970
|
+
failing_destinations: numberValue(summary.failing_destinations ?? summary.failingDestinations),
|
|
2971
|
+
failingDestinations: numberValue(summary.failing_destinations ?? summary.failingDestinations),
|
|
2972
|
+
deliveries_30d: numberValue(summary.deliveries_30d ?? summary.deliveries30d),
|
|
2973
|
+
deliveries30d: numberValue(summary.deliveries_30d ?? summary.deliveries30d),
|
|
2974
|
+
delivered_30d: numberValue(summary.delivered_30d ?? summary.delivered30d),
|
|
2975
|
+
delivered30d: numberValue(summary.delivered_30d ?? summary.delivered30d),
|
|
2976
|
+
failed_30d: numberValue(summary.failed_30d ?? summary.failed30d),
|
|
2977
|
+
failed30d: numberValue(summary.failed_30d ?? summary.failed30d),
|
|
2978
|
+
external_delivered_30d: numberValue(summary.external_delivered_30d ?? summary.externalDelivered30d),
|
|
2979
|
+
externalDelivered30d: numberValue(summary.external_delivered_30d ?? summary.externalDelivered30d),
|
|
2980
|
+
nango_proofs_30d: numberValue(summary.nango_proofs_30d ?? summary.nangoProofs30d),
|
|
2981
|
+
nangoProofs30d: numberValue(summary.nango_proofs_30d ?? summary.nangoProofs30d),
|
|
2982
|
+
nango_failures_30d: numberValue(summary.nango_failures_30d ?? summary.nangoFailures30d),
|
|
2983
|
+
nangoFailures30d: numberValue(summary.nango_failures_30d ?? summary.nangoFailures30d),
|
|
2984
|
+
airbyte_configured: numberValue(summary.airbyte_configured ?? summary.airbyteConfigured),
|
|
2985
|
+
airbyteConfigured: numberValue(summary.airbyte_configured ?? summary.airbyteConfigured),
|
|
2986
|
+
airbyte_proofs_30d: numberValue(summary.airbyte_proofs_30d ?? summary.airbyteProofs30d),
|
|
2987
|
+
airbyteProofs30d: numberValue(summary.airbyte_proofs_30d ?? summary.airbyteProofs30d),
|
|
2988
|
+
airbyte_failures_30d: numberValue(summary.airbyte_failures_30d ?? summary.airbyteFailures30d),
|
|
2989
|
+
airbyteFailures30d: numberValue(summary.airbyte_failures_30d ?? summary.airbyteFailures30d)
|
|
2990
|
+
},
|
|
2991
|
+
destinations,
|
|
2992
|
+
blockers,
|
|
2993
|
+
next_action: optionalString(data.next_action ?? data.nextAction),
|
|
2994
|
+
nextAction: optionalString(data.next_action ?? data.nextAction),
|
|
2995
|
+
next_actions: nextActions,
|
|
2996
|
+
nextActions,
|
|
2997
|
+
estimated_credits: numberValue(data.estimated_credits ?? data.estimatedCredits),
|
|
2998
|
+
estimatedCredits: numberValue(data.estimated_credits ?? data.estimatedCredits),
|
|
2999
|
+
approval_required: Boolean(data.approval_required ?? data.approvalRequired),
|
|
3000
|
+
approvalRequired: Boolean(data.approval_required ?? data.approvalRequired),
|
|
3001
|
+
credits_charged: 0,
|
|
3002
|
+
creditsCharged: 0,
|
|
3003
|
+
proof_mode: data.proof_mode !== false,
|
|
3004
|
+
proofMode: data.proof_mode !== false,
|
|
3005
|
+
query_errors: queryErrors,
|
|
3006
|
+
queryErrors,
|
|
3007
|
+
raw: data
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
function normalizeOpsAutopilotMotion(rawMotion) {
|
|
3011
|
+
const motion = asRecord2(rawMotion);
|
|
3012
|
+
const targetCount = numberValue(motion.target_count ?? motion.targetCount);
|
|
3013
|
+
const estimatedCredits = numberValue(motion.estimated_credits ?? motion.estimatedCredits);
|
|
3014
|
+
const mcpSequence = Array.isArray(motion.mcp_sequence) ? motion.mcp_sequence : Array.isArray(motion.mcpSequence) ? motion.mcpSequence : [];
|
|
3015
|
+
return {
|
|
3016
|
+
...motion,
|
|
3017
|
+
id: stringValue2(motion.id),
|
|
3018
|
+
blueprint: stringValue2(motion.blueprint, "build_leads"),
|
|
3019
|
+
title: stringValue2(motion.title),
|
|
3020
|
+
outcome: stringValue2(motion.outcome),
|
|
3021
|
+
prompt: stringValue2(motion.prompt),
|
|
3022
|
+
target_count: targetCount,
|
|
3023
|
+
targetCount,
|
|
3024
|
+
cadence: stringValue2(motion.cadence, "manual"),
|
|
3025
|
+
destinations: Array.isArray(motion.destinations) ? motion.destinations.map(String) : [],
|
|
3026
|
+
estimated_credits: estimatedCredits,
|
|
3027
|
+
estimatedCredits,
|
|
3028
|
+
proof_gate: optionalString(motion.proof_gate ?? motion.proofGate),
|
|
3029
|
+
proofGate: optionalString(motion.proof_gate ?? motion.proofGate),
|
|
3030
|
+
why_now: optionalString(motion.why_now ?? motion.whyNow),
|
|
3031
|
+
whyNow: optionalString(motion.why_now ?? motion.whyNow),
|
|
3032
|
+
agent_prompt: optionalString(motion.agent_prompt ?? motion.agentPrompt),
|
|
3033
|
+
agentPrompt: optionalString(motion.agent_prompt ?? motion.agentPrompt),
|
|
3034
|
+
cli_command: optionalString(motion.cli_command ?? motion.cliCommand),
|
|
3035
|
+
cliCommand: optionalString(motion.cli_command ?? motion.cliCommand),
|
|
3036
|
+
mcp_sequence: mcpSequence,
|
|
3037
|
+
mcpSequence
|
|
3038
|
+
};
|
|
3039
|
+
}
|
|
3040
|
+
function normalizeOpsAutopilotResult(result) {
|
|
3041
|
+
const primary = normalizeOpsAutopilotMotion(result.primary_motion ?? result.primaryMotion);
|
|
3042
|
+
const motions = Array.isArray(result.motions) ? result.motions.map(normalizeOpsAutopilotMotion) : [];
|
|
3043
|
+
const queryErrors = Array.isArray(result.query_errors) ? result.query_errors.map(String) : Array.isArray(result.queryErrors) ? result.queryErrors.map(String) : [];
|
|
3044
|
+
return {
|
|
3045
|
+
...result,
|
|
3046
|
+
stage: stringValue2(result.stage, "prove"),
|
|
3047
|
+
headline: stringValue2(result.headline, "Ops Autopilot"),
|
|
3048
|
+
verdict: stringValue2(result.verdict),
|
|
3049
|
+
next_action: stringValue2(result.next_action ?? result.nextAction),
|
|
3050
|
+
nextAction: stringValue2(result.next_action ?? result.nextAction),
|
|
3051
|
+
primary_motion: primary,
|
|
3052
|
+
primaryMotion: primary,
|
|
3053
|
+
motions,
|
|
3054
|
+
scale_rule: optionalString(result.scale_rule ?? result.scaleRule),
|
|
3055
|
+
scaleRule: optionalString(result.scale_rule ?? result.scaleRule),
|
|
3056
|
+
agent_handoff: optionalString(result.agent_handoff ?? result.agentHandoff),
|
|
3057
|
+
agentHandoff: optionalString(result.agent_handoff ?? result.agentHandoff),
|
|
3058
|
+
proof_state: optionalString(result.proof_state ?? result.proofState),
|
|
3059
|
+
proofState: optionalString(result.proof_state ?? result.proofState),
|
|
3060
|
+
proof_summary: result.proof_summary ?? result.proofSummary,
|
|
3061
|
+
proofSummary: result.proof_summary ?? result.proofSummary,
|
|
3062
|
+
next_step: result.next_step ?? result.nextStep,
|
|
3063
|
+
nextStep: result.next_step ?? result.nextStep,
|
|
3064
|
+
query_errors: queryErrors,
|
|
3065
|
+
queryErrors,
|
|
3066
|
+
credits_charged: 0,
|
|
3067
|
+
creditsCharged: 0
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
3070
|
+
function normalizeOpsTriggerRunStatus(result) {
|
|
3071
|
+
const runId = result.run_id ?? result.runId;
|
|
3072
|
+
return {
|
|
3073
|
+
...result,
|
|
3074
|
+
run_id: runId,
|
|
3075
|
+
runId,
|
|
3076
|
+
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
|
|
3077
|
+
};
|
|
3078
|
+
}
|
|
3079
|
+
function normalizeOpsQueueStatus(result) {
|
|
3080
|
+
const summary = result.summary;
|
|
3081
|
+
const producerEnvelope = normalizeOpsQueueProducerEnvelope(result.producer_envelope ?? result.producerEnvelope);
|
|
3082
|
+
const job = result.job ? {
|
|
3083
|
+
...result.job,
|
|
3084
|
+
id: result.job.id ?? result.job.jobId,
|
|
3085
|
+
jobId: result.job.jobId ?? result.job.id,
|
|
3086
|
+
function_name: result.job.function_name ?? result.job.functionName,
|
|
3087
|
+
functionName: result.job.functionName ?? result.job.function_name,
|
|
3088
|
+
estimated_wait_ms: result.job.estimated_wait_ms ?? result.job.estimatedWaitMs,
|
|
3089
|
+
estimatedWaitMs: result.job.estimatedWaitMs ?? result.job.estimated_wait_ms,
|
|
3090
|
+
error_message: result.job.error_message ?? result.job.errorMessage,
|
|
3091
|
+
errorMessage: result.job.errorMessage ?? result.job.error_message
|
|
3092
|
+
} : void 0;
|
|
3093
|
+
if (!summary) {
|
|
3094
|
+
return {
|
|
3095
|
+
...result,
|
|
3096
|
+
producer_envelope: producerEnvelope,
|
|
3097
|
+
producerEnvelope,
|
|
3098
|
+
job,
|
|
3099
|
+
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
|
|
3100
|
+
};
|
|
3101
|
+
}
|
|
3102
|
+
const queue = summary.queue;
|
|
3103
|
+
const normalizedQueue = queue ? {
|
|
3104
|
+
...queue,
|
|
3105
|
+
completed_last_hour: queue.completed_last_hour ?? queue.completedLastHour,
|
|
3106
|
+
completedLastHour: queue.completedLastHour ?? queue.completed_last_hour,
|
|
3107
|
+
failed_last_hour: queue.failed_last_hour ?? queue.failedLastHour,
|
|
3108
|
+
failedLastHour: queue.failedLastHour ?? queue.failed_last_hour,
|
|
3109
|
+
pending_by_function: queue.pending_by_function ?? queue.pendingByFunction,
|
|
3110
|
+
pendingByFunction: queue.pendingByFunction ?? queue.pending_by_function
|
|
3111
|
+
} : void 0;
|
|
3112
|
+
return {
|
|
3113
|
+
...result,
|
|
3114
|
+
producer_envelope: producerEnvelope,
|
|
3115
|
+
producerEnvelope,
|
|
3116
|
+
job,
|
|
3117
|
+
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0,
|
|
3118
|
+
summary: {
|
|
3119
|
+
...summary,
|
|
3120
|
+
queue: normalizedQueue,
|
|
3121
|
+
provider_stats: summary.provider_stats ?? summary.providerStats,
|
|
3122
|
+
providerStats: summary.providerStats ?? summary.provider_stats,
|
|
3123
|
+
redis_status: summary.redis_status ?? summary.redisStatus,
|
|
3124
|
+
redisStatus: summary.redisStatus ?? summary.redis_status,
|
|
3125
|
+
recent_events: summary.recent_events ?? summary.recentEvents,
|
|
3126
|
+
recentEvents: summary.recentEvents ?? summary.recent_events
|
|
3127
|
+
}
|
|
3128
|
+
};
|
|
3129
|
+
}
|
|
3130
|
+
function normalizeOpsQueueProducerEnvelope(envelope) {
|
|
3131
|
+
if (!envelope) return void 0;
|
|
3132
|
+
return {
|
|
3133
|
+
...envelope,
|
|
3134
|
+
schema_version: envelope.schema_version ?? envelope.schemaVersion,
|
|
3135
|
+
schemaVersion: envelope.schemaVersion ?? envelope.schema_version,
|
|
3136
|
+
queue_name: envelope.queue_name ?? envelope.queueName,
|
|
3137
|
+
queueName: envelope.queueName ?? envelope.queue_name,
|
|
3138
|
+
status_source: envelope.status_source ?? envelope.statusSource,
|
|
3139
|
+
statusSource: envelope.statusSource ?? envelope.status_source,
|
|
3140
|
+
idempotency_key: envelope.idempotency_key ?? envelope.idempotencyKey ?? null,
|
|
3141
|
+
idempotencyKey: envelope.idempotencyKey ?? envelope.idempotency_key ?? null,
|
|
3142
|
+
job_id: envelope.job_id ?? envelope.jobId ?? null,
|
|
3143
|
+
jobId: envelope.jobId ?? envelope.job_id ?? null,
|
|
3144
|
+
summary_requested: envelope.summary_requested ?? envelope.summaryRequested,
|
|
3145
|
+
summaryRequested: envelope.summaryRequested ?? envelope.summary_requested,
|
|
3146
|
+
retry_after_ms: envelope.retry_after_ms ?? envelope.retryAfterMs,
|
|
3147
|
+
retryAfterMs: envelope.retryAfterMs ?? envelope.retry_after_ms,
|
|
3148
|
+
poll_after_seconds: envelope.poll_after_seconds ?? envelope.pollAfterSeconds,
|
|
3149
|
+
pollAfterSeconds: envelope.pollAfterSeconds ?? envelope.poll_after_seconds,
|
|
3150
|
+
emitted_at: envelope.emitted_at ?? envelope.emittedAt,
|
|
3151
|
+
emittedAt: envelope.emittedAt ?? envelope.emitted_at
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
function normalizeOpsReplayResult(result) {
|
|
3155
|
+
const replayRunId = result.replay_run_id ?? result.replayRunId ?? "";
|
|
3156
|
+
const originalRunId = result.original_run_id ?? result.originalRunId ?? "";
|
|
3157
|
+
const startFromNode = result.start_from_node ?? result.startFromNode ?? 0;
|
|
3158
|
+
const totalNodes = result.total_nodes ?? result.totalNodes ?? 0;
|
|
3159
|
+
return {
|
|
3160
|
+
...result,
|
|
3161
|
+
replay_run_id: replayRunId,
|
|
3162
|
+
replayRunId,
|
|
3163
|
+
original_run_id: originalRunId,
|
|
3164
|
+
originalRunId,
|
|
3165
|
+
start_from_node: startFromNode,
|
|
3166
|
+
startFromNode,
|
|
3167
|
+
total_nodes: totalNodes,
|
|
3168
|
+
totalNodes,
|
|
3169
|
+
diagnosis: result.diagnosis ? normalizeOpsDebugDiagnosis(result.diagnosis) : void 0
|
|
3170
|
+
};
|
|
3171
|
+
}
|
|
3172
|
+
function normalizeOpsApproveResult(result) {
|
|
3173
|
+
return {
|
|
3174
|
+
...result,
|
|
3175
|
+
token_id: result.token_id ?? result.tokenId,
|
|
3176
|
+
tokenId: result.tokenId ?? result.token_id,
|
|
3177
|
+
token_ids: result.token_ids ?? result.tokenIds,
|
|
3178
|
+
tokenIds: result.tokenIds ?? result.token_ids,
|
|
3179
|
+
reviewer_notes: result.reviewer_notes ?? result.reviewerNotes,
|
|
3180
|
+
reviewerNotes: result.reviewerNotes ?? result.reviewer_notes
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3183
|
+
function normalizeOpsDashboardResult(result) {
|
|
3184
|
+
return {
|
|
3185
|
+
...result,
|
|
3186
|
+
today_executions: result.today_executions ?? result.todayExecutions,
|
|
3187
|
+
todayExecutions: result.todayExecutions ?? result.today_executions,
|
|
3188
|
+
today_credits: result.today_credits ?? result.todayCredits,
|
|
3189
|
+
todayCredits: result.todayCredits ?? result.today_credits,
|
|
3190
|
+
month_executions: result.month_executions ?? result.monthExecutions,
|
|
3191
|
+
monthExecutions: result.monthExecutions ?? result.month_executions,
|
|
3192
|
+
month_credits: result.month_credits ?? result.monthCredits,
|
|
3193
|
+
monthCredits: result.monthCredits ?? result.month_credits,
|
|
3194
|
+
avg_execution_time_ms: result.avg_execution_time_ms ?? result.avgExecutionTimeMs,
|
|
3195
|
+
avgExecutionTimeMs: result.avgExecutionTimeMs ?? result.avg_execution_time_ms
|
|
3196
|
+
};
|
|
3197
|
+
}
|
|
3198
|
+
function normalizeOpsSink(sink) {
|
|
3199
|
+
return {
|
|
3200
|
+
...sink,
|
|
3201
|
+
id: sink.id ?? sink.sink_id ?? sink.sinkId,
|
|
3202
|
+
sink_id: sink.sink_id ?? sink.sinkId ?? sink.id,
|
|
3203
|
+
sinkId: sink.sinkId ?? sink.sink_id ?? sink.id,
|
|
3204
|
+
connection_id: sink.connection_id ?? sink.connectionId,
|
|
3205
|
+
connectionId: sink.connectionId ?? sink.connection_id,
|
|
3206
|
+
connector_id: sink.connector_id ?? sink.connectorId,
|
|
3207
|
+
connectorId: sink.connectorId ?? sink.connector_id,
|
|
3208
|
+
sync_status: sink.sync_status ?? sink.syncStatus,
|
|
3209
|
+
syncStatus: sink.syncStatus ?? sink.sync_status,
|
|
3210
|
+
last_synced_at: sink.last_synced_at ?? sink.lastSyncedAt,
|
|
3211
|
+
lastSyncedAt: sink.lastSyncedAt ?? sink.last_synced_at
|
|
3212
|
+
};
|
|
3213
|
+
}
|
|
3214
|
+
function normalizeOpsRoutine(routine) {
|
|
3215
|
+
const outputSinks = routine.output_sinks ?? routine.outputSinks;
|
|
3216
|
+
return withExecutionRefs({
|
|
3217
|
+
...routine,
|
|
3218
|
+
id: routine.id ?? routine.routine_id ?? routine.routineId,
|
|
3219
|
+
routine_id: routine.routine_id ?? routine.routineId ?? routine.id,
|
|
3220
|
+
routineId: routine.routineId ?? routine.routine_id ?? routine.id,
|
|
3221
|
+
last_tick_at: routine.last_tick_at ?? routine.lastTickAt,
|
|
3222
|
+
lastTickAt: routine.lastTickAt ?? routine.last_tick_at,
|
|
3223
|
+
next_tick_at: routine.next_tick_at ?? routine.nextTickAt,
|
|
3224
|
+
nextTickAt: routine.nextTickAt ?? routine.next_tick_at,
|
|
3225
|
+
output_sinks: outputSinks?.map(normalizeOpsSink),
|
|
3226
|
+
outputSinks: outputSinks?.map(normalizeOpsSink)
|
|
3227
|
+
});
|
|
3228
|
+
}
|
|
3229
|
+
function normalizeOpsRoutineRunResult(result) {
|
|
3230
|
+
return withExecutionRefs({
|
|
3231
|
+
...result,
|
|
3232
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
3233
|
+
routineId: result.routineId ?? result.routine_id,
|
|
3234
|
+
tick_id: result.tick_id ?? result.tickId,
|
|
3235
|
+
tickId: result.tickId ?? result.tick_id,
|
|
3236
|
+
run_id: result.run_id ?? result.runId,
|
|
3237
|
+
runId: result.runId ?? result.run_id,
|
|
3238
|
+
next_action: result.next_action ?? result.nextAction,
|
|
3239
|
+
nextAction: result.nextAction ?? result.next_action
|
|
3240
|
+
});
|
|
3241
|
+
}
|
|
3242
|
+
function normalizeOpsRoutineDeleteResult(result) {
|
|
3243
|
+
return withExecutionRefs({
|
|
3244
|
+
...result,
|
|
3245
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
3246
|
+
routineId: result.routineId ?? result.routine_id,
|
|
3247
|
+
next_action: result.next_action ?? result.nextAction,
|
|
3248
|
+
nextAction: result.nextAction ?? result.next_action
|
|
3249
|
+
});
|
|
3250
|
+
}
|
|
3251
|
+
function normalizeOpsRoutineSinkResult(result) {
|
|
3252
|
+
return withExecutionRefs({
|
|
3253
|
+
...result,
|
|
3254
|
+
routine_id: result.routine_id ?? result.routineId,
|
|
3255
|
+
routineId: result.routineId ?? result.routine_id,
|
|
3256
|
+
sink_id: result.sink_id ?? result.sinkId,
|
|
3257
|
+
sinkId: result.sinkId ?? result.sink_id,
|
|
3258
|
+
next_action: result.next_action ?? result.nextAction,
|
|
3259
|
+
nextAction: result.nextAction ?? result.next_action,
|
|
3260
|
+
routine: result.routine ? normalizeOpsRoutine(result.routine) : result.routine,
|
|
3261
|
+
sink: result.sink ? normalizeOpsSink(result.sink) : result.sink
|
|
3262
|
+
});
|
|
3263
|
+
}
|
|
3264
|
+
function normalizeOpsRoutineTick(tick) {
|
|
3265
|
+
return withExecutionRefs({
|
|
3266
|
+
...tick,
|
|
3267
|
+
id: tick.id ?? tick.tick_id ?? tick.tickId,
|
|
3268
|
+
tick_id: tick.tick_id ?? tick.tickId ?? tick.id,
|
|
3269
|
+
tickId: tick.tickId ?? tick.tick_id ?? tick.id,
|
|
3270
|
+
routine_id: tick.routine_id ?? tick.routineId,
|
|
3271
|
+
routineId: tick.routineId ?? tick.routine_id,
|
|
3272
|
+
started_at: tick.started_at ?? tick.startedAt,
|
|
3273
|
+
startedAt: tick.startedAt ?? tick.started_at,
|
|
3274
|
+
completed_at: tick.completed_at ?? tick.completedAt,
|
|
3275
|
+
completedAt: tick.completedAt ?? tick.completed_at,
|
|
3276
|
+
error_message: tick.error_message ?? tick.errorMessage,
|
|
3277
|
+
errorMessage: tick.errorMessage ?? tick.error_message
|
|
3278
|
+
});
|
|
3279
|
+
}
|
|
3280
|
+
function normalizeOpsRoutineTicksResult(result) {
|
|
3281
|
+
const ticks = Array.isArray(result.ticks ?? result.items) ? (result.ticks ?? result.items ?? []).map(normalizeOpsRoutineTick) : [];
|
|
3282
|
+
const nextCursor = result.next_cursor ?? result.nextCursor ?? null;
|
|
3283
|
+
const hasMore = result.has_more ?? result.hasMore ?? false;
|
|
3284
|
+
return {
|
|
3285
|
+
...result,
|
|
3286
|
+
ticks,
|
|
3287
|
+
items: result.items ? ticks : result.items,
|
|
3288
|
+
next_cursor: nextCursor,
|
|
3289
|
+
nextCursor,
|
|
3290
|
+
has_more: hasMore,
|
|
3291
|
+
hasMore
|
|
3292
|
+
};
|
|
3293
|
+
}
|
|
3294
|
+
function normalizeOpsRoutineTickItem(item) {
|
|
3295
|
+
return withExecutionRefs({
|
|
3296
|
+
...item,
|
|
3297
|
+
id: item.id ?? item.item_id ?? item.itemId,
|
|
3298
|
+
item_id: item.item_id ?? item.itemId ?? item.id,
|
|
3299
|
+
itemId: item.itemId ?? item.item_id ?? item.id,
|
|
3300
|
+
tick_id: item.tick_id ?? item.tickId,
|
|
3301
|
+
tickId: item.tickId ?? item.tick_id,
|
|
3302
|
+
routine_id: item.routine_id ?? item.routineId,
|
|
3303
|
+
routineId: item.routineId ?? item.routine_id,
|
|
3304
|
+
error_message: item.error_message ?? item.errorMessage,
|
|
3305
|
+
errorMessage: item.errorMessage ?? item.error_message
|
|
3306
|
+
});
|
|
3307
|
+
}
|
|
3308
|
+
function normalizeOpsRoutineTickItemsResult(result) {
|
|
3309
|
+
const items = Array.isArray(result.items ?? result.rows) ? (result.items ?? result.rows ?? []).map(normalizeOpsRoutineTickItem) : [];
|
|
3310
|
+
const nextCursor = result.next_cursor ?? result.nextCursor ?? null;
|
|
3311
|
+
const hasMore = result.has_more ?? result.hasMore ?? false;
|
|
3312
|
+
return {
|
|
3313
|
+
...result,
|
|
3314
|
+
items,
|
|
3315
|
+
rows: result.rows ? items : result.rows,
|
|
3316
|
+
next_cursor: nextCursor,
|
|
3317
|
+
nextCursor,
|
|
3318
|
+
has_more: hasMore,
|
|
3319
|
+
hasMore
|
|
3320
|
+
};
|
|
3321
|
+
}
|
|
3322
|
+
function buildOpsPlanBody(params) {
|
|
3323
|
+
const { targetCount, companyDomains, customAiPrompt, signalPrompt, outputPrompt, ...rest } = params;
|
|
3324
|
+
return {
|
|
3325
|
+
...rest,
|
|
3326
|
+
target_count: rest.target_count ?? targetCount,
|
|
3327
|
+
company_domains: rest.company_domains ?? companyDomains,
|
|
3328
|
+
custom_ai_prompt: rest.custom_ai_prompt ?? customAiPrompt,
|
|
3329
|
+
signal_prompt: rest.signal_prompt ?? signalPrompt,
|
|
3330
|
+
output_prompt: rest.output_prompt ?? outputPrompt
|
|
3331
|
+
};
|
|
3332
|
+
}
|
|
3333
|
+
function buildOpsCreateBody(params) {
|
|
3334
|
+
const { confirmSpend, ...rest } = params;
|
|
3335
|
+
return {
|
|
3336
|
+
...buildOpsPlanBody(rest),
|
|
3337
|
+
confirm_spend: rest.confirm_spend ?? confirmSpend
|
|
3338
|
+
};
|
|
3339
|
+
}
|
|
3340
|
+
function buildOpsExecuteBody(params) {
|
|
3341
|
+
const { autoRun, dryRun, outputFormat, ...rest } = params;
|
|
3342
|
+
return {
|
|
3343
|
+
...buildOpsCreateBody(rest),
|
|
3344
|
+
auto_run: rest.auto_run ?? autoRun,
|
|
3345
|
+
dry_run: rest.dry_run ?? dryRun,
|
|
3346
|
+
output_format: rest.output_format ?? outputFormat
|
|
3347
|
+
};
|
|
3348
|
+
}
|
|
3349
|
+
function buildOpsRunBody(params) {
|
|
3350
|
+
const { opId, ...rest } = params;
|
|
3351
|
+
return {
|
|
3352
|
+
...rest,
|
|
3353
|
+
op_id: rest.op_id ?? opId
|
|
3354
|
+
};
|
|
3355
|
+
}
|
|
3356
|
+
function buildOpsStatusBody(params) {
|
|
3357
|
+
const { opId, ...rest } = params;
|
|
3358
|
+
return {
|
|
3359
|
+
...rest,
|
|
3360
|
+
op_id: rest.op_id ?? opId
|
|
3361
|
+
};
|
|
3362
|
+
}
|
|
3363
|
+
function buildOpsResultsBody(params) {
|
|
3364
|
+
const { opId, nextCursor, includeFailedRuns, ...rest } = params;
|
|
3365
|
+
return {
|
|
3366
|
+
...rest,
|
|
3367
|
+
op_id: rest.op_id ?? opId,
|
|
3368
|
+
cursor: rest.cursor ?? nextCursor,
|
|
3369
|
+
include_failed_runs: rest.include_failed_runs ?? includeFailedRuns
|
|
3370
|
+
};
|
|
3371
|
+
}
|
|
3372
|
+
function buildOpsDebugOptions(params) {
|
|
3373
|
+
const {
|
|
3374
|
+
opId,
|
|
3375
|
+
includeResults,
|
|
3376
|
+
resultsLimit,
|
|
3377
|
+
includeQueue,
|
|
3378
|
+
includeDashboard,
|
|
3379
|
+
dashboardLimit,
|
|
3380
|
+
timeRangeDays,
|
|
3381
|
+
...rest
|
|
3382
|
+
} = params;
|
|
3383
|
+
const op_id = rest.op_id ?? opId;
|
|
3384
|
+
if (!op_id) throw new Error("ops.debug requires op_id or opId");
|
|
3385
|
+
return {
|
|
3386
|
+
...rest,
|
|
3387
|
+
op_id,
|
|
3388
|
+
include_results: rest.include_results ?? includeResults,
|
|
3389
|
+
results_limit: rest.results_limit ?? resultsLimit,
|
|
3390
|
+
include_queue: rest.include_queue ?? includeQueue,
|
|
3391
|
+
include_dashboard: rest.include_dashboard ?? includeDashboard,
|
|
3392
|
+
dashboard_limit: rest.dashboard_limit ?? dashboardLimit,
|
|
3393
|
+
time_range_days: rest.time_range_days ?? timeRangeDays
|
|
3394
|
+
};
|
|
3395
|
+
}
|
|
3396
|
+
function buildCreateRoutineBody(params) {
|
|
3397
|
+
const { outputSinks, wakeOnEvents, ...rest } = params;
|
|
3398
|
+
const sinks = rest.output_sinks ?? outputSinks;
|
|
3399
|
+
return {
|
|
3400
|
+
...rest,
|
|
3401
|
+
output_sinks: Array.isArray(sinks) ? sinks.map(normalizeOpsSinkRequest) : sinks,
|
|
3402
|
+
wake_on_events: rest.wake_on_events ?? wakeOnEvents
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
function buildRoutineBody(params) {
|
|
3406
|
+
const { routineId, ...rest } = params;
|
|
3407
|
+
return {
|
|
3408
|
+
...rest,
|
|
3409
|
+
routine_id: rest.routine_id ?? routineId
|
|
3410
|
+
};
|
|
3411
|
+
}
|
|
3412
|
+
function buildRoutineSinkBody(params) {
|
|
3413
|
+
const { routineId, sinkId, ...rest } = params;
|
|
3414
|
+
return {
|
|
3415
|
+
...rest,
|
|
3416
|
+
routine_id: rest.routine_id ?? routineId,
|
|
3417
|
+
sink_id: rest.sink_id ?? sinkId
|
|
3418
|
+
};
|
|
3419
|
+
}
|
|
3420
|
+
function buildListOutputSinksBody(params) {
|
|
3421
|
+
const { includeInactive, ...rest } = params;
|
|
3422
|
+
return {
|
|
3423
|
+
...rest,
|
|
3424
|
+
include_inactive: rest.include_inactive ?? includeInactive
|
|
3425
|
+
};
|
|
3426
|
+
}
|
|
3427
|
+
function buildCreateOutputSinkBody(params) {
|
|
3428
|
+
const { connectionId, webhookUrl, ...rest } = params;
|
|
3429
|
+
return {
|
|
3430
|
+
...rest,
|
|
3431
|
+
connection_id: rest.connection_id ?? connectionId,
|
|
3432
|
+
webhook_url: rest.webhook_url ?? webhookUrl
|
|
3433
|
+
};
|
|
3434
|
+
}
|
|
3435
|
+
function normalizeOpsSinkRequest(sink) {
|
|
3436
|
+
const {
|
|
3437
|
+
sinkId,
|
|
3438
|
+
connectionId,
|
|
3439
|
+
connectorId,
|
|
3440
|
+
connectorName,
|
|
3441
|
+
deliveryMode,
|
|
3442
|
+
providerConfigKey,
|
|
3443
|
+
integrationId,
|
|
3444
|
+
nangoConnectionId,
|
|
3445
|
+
actionName,
|
|
3446
|
+
nangoAction,
|
|
3447
|
+
proxyPath,
|
|
3448
|
+
nangoProxyPath,
|
|
3449
|
+
fieldMap,
|
|
3450
|
+
requiredFields,
|
|
3451
|
+
writeConfirmed,
|
|
3452
|
+
agentWriteConfirmed,
|
|
3453
|
+
config,
|
|
3454
|
+
...rest
|
|
3455
|
+
} = sink;
|
|
3456
|
+
const normalizedConfig = normalizeOpsSinkConfigRequest(config);
|
|
3457
|
+
const connection_id = rest.connection_id ?? connectionId;
|
|
3458
|
+
const connector_id = rest.connector_id ?? connectorId;
|
|
3459
|
+
const delivery_mode = rest.delivery_mode ?? deliveryMode;
|
|
3460
|
+
const provider_config_key = rest.provider_config_key ?? providerConfigKey;
|
|
3461
|
+
const integration_id = rest.integration_id ?? integrationId;
|
|
3462
|
+
const nango_connection_id = rest.nango_connection_id ?? nangoConnectionId;
|
|
3463
|
+
const action_name = rest.action_name ?? actionName;
|
|
3464
|
+
const nango_action = rest.nango_action ?? nangoAction;
|
|
3465
|
+
const proxy_path = rest.proxy_path ?? proxyPath;
|
|
3466
|
+
const nango_proxy_path = rest.nango_proxy_path ?? nangoProxyPath;
|
|
3467
|
+
const field_map = rest.field_map ?? fieldMap;
|
|
3468
|
+
const required_fields = rest.required_fields ?? requiredFields;
|
|
3469
|
+
const write_confirmed = rest.write_confirmed ?? writeConfirmed;
|
|
3470
|
+
const agent_write_confirmed = rest.agent_write_confirmed ?? agentWriteConfirmed;
|
|
3471
|
+
if (connection_id !== void 0 && normalizedConfig.connection_id === void 0) normalizedConfig.connection_id = connection_id;
|
|
3472
|
+
if (connector_id !== void 0 && normalizedConfig.connector_id === void 0) normalizedConfig.connector_id = connector_id;
|
|
3473
|
+
if (delivery_mode !== void 0 && normalizedConfig.delivery_mode === void 0) normalizedConfig.delivery_mode = delivery_mode;
|
|
3474
|
+
if (provider_config_key !== void 0 && normalizedConfig.provider_config_key === void 0) normalizedConfig.provider_config_key = provider_config_key;
|
|
3475
|
+
if (integration_id !== void 0 && normalizedConfig.integration_id === void 0) normalizedConfig.integration_id = integration_id;
|
|
3476
|
+
if (nango_connection_id !== void 0 && normalizedConfig.nango_connection_id === void 0) normalizedConfig.nango_connection_id = nango_connection_id;
|
|
3477
|
+
if (action_name !== void 0 && normalizedConfig.action_name === void 0) normalizedConfig.action_name = action_name;
|
|
3478
|
+
if (nango_action !== void 0 && normalizedConfig.nango_action === void 0) normalizedConfig.nango_action = nango_action;
|
|
3479
|
+
if (proxy_path !== void 0 && normalizedConfig.proxy_path === void 0) normalizedConfig.proxy_path = proxy_path;
|
|
3480
|
+
if (nango_proxy_path !== void 0 && normalizedConfig.nango_proxy_path === void 0) normalizedConfig.nango_proxy_path = nango_proxy_path;
|
|
3481
|
+
if (field_map !== void 0 && normalizedConfig.field_map === void 0) normalizedConfig.field_map = field_map;
|
|
3482
|
+
if (required_fields !== void 0 && normalizedConfig.required_fields === void 0) normalizedConfig.required_fields = required_fields;
|
|
3483
|
+
if (write_confirmed !== void 0 && normalizedConfig.write_confirmed === void 0) normalizedConfig.write_confirmed = write_confirmed;
|
|
3484
|
+
if (agent_write_confirmed !== void 0 && normalizedConfig.agent_write_confirmed === void 0) normalizedConfig.agent_write_confirmed = agent_write_confirmed;
|
|
3485
|
+
if (sink.type === "nango" && normalizedConfig.integration_platform === void 0) normalizedConfig.integration_platform = "nango";
|
|
3486
|
+
return {
|
|
3487
|
+
...rest,
|
|
3488
|
+
sink_id: rest.sink_id ?? sinkId,
|
|
3489
|
+
connection_id,
|
|
3490
|
+
connector_id,
|
|
3491
|
+
connector_name: rest.connector_name ?? connectorName,
|
|
3492
|
+
delivery_mode,
|
|
3493
|
+
provider_config_key,
|
|
3494
|
+
integration_id,
|
|
3495
|
+
nango_connection_id,
|
|
3496
|
+
action_name,
|
|
3497
|
+
nango_action,
|
|
3498
|
+
proxy_path,
|
|
3499
|
+
nango_proxy_path,
|
|
3500
|
+
field_map,
|
|
3501
|
+
required_fields,
|
|
3502
|
+
write_confirmed,
|
|
3503
|
+
agent_write_confirmed,
|
|
3504
|
+
config: normalizedConfig
|
|
3505
|
+
};
|
|
3506
|
+
}
|
|
3507
|
+
function normalizeOpsSinkConfigRequest(config) {
|
|
3508
|
+
const out = { ...config ?? {} };
|
|
3509
|
+
if (out.connection_id === void 0 && out.connectionId !== void 0) out.connection_id = out.connectionId;
|
|
3510
|
+
if (out.connector_id === void 0 && out.connectorId !== void 0) out.connector_id = out.connectorId;
|
|
3511
|
+
if (out.connector_name === void 0 && out.connectorName !== void 0) out.connector_name = out.connectorName;
|
|
3512
|
+
if (out.delivery_mode === void 0 && out.deliveryMode !== void 0) out.delivery_mode = out.deliveryMode;
|
|
3513
|
+
if (out.provider_config_key === void 0 && out.providerConfigKey !== void 0) out.provider_config_key = out.providerConfigKey;
|
|
3514
|
+
if (out.integration_id === void 0 && out.integrationId !== void 0) out.integration_id = out.integrationId;
|
|
3515
|
+
if (out.nango_connection_id === void 0 && out.nangoConnectionId !== void 0) out.nango_connection_id = out.nangoConnectionId;
|
|
3516
|
+
if (out.action_name === void 0 && out.actionName !== void 0) out.action_name = out.actionName;
|
|
3517
|
+
if (out.nango_action === void 0 && out.nangoAction !== void 0) out.nango_action = out.nangoAction;
|
|
3518
|
+
if (out.proxy_path === void 0 && out.proxyPath !== void 0) out.proxy_path = out.proxyPath;
|
|
3519
|
+
if (out.nango_proxy_path === void 0 && out.nangoProxyPath !== void 0) out.nango_proxy_path = out.nangoProxyPath;
|
|
3520
|
+
if (out.field_map === void 0 && out.fieldMap !== void 0) out.field_map = out.fieldMap;
|
|
3521
|
+
if (out.required_fields === void 0 && out.requiredFields !== void 0) out.required_fields = out.requiredFields;
|
|
3522
|
+
if (out.write_confirmed === void 0 && out.writeConfirmed !== void 0) out.write_confirmed = out.writeConfirmed;
|
|
3523
|
+
if (out.agent_write_confirmed === void 0 && out.agentWriteConfirmed !== void 0) out.agent_write_confirmed = out.agentWriteConfirmed;
|
|
3524
|
+
return out;
|
|
3525
|
+
}
|
|
3526
|
+
function buildApproveBody(params) {
|
|
3527
|
+
const { tokenId, tokenIds, reviewerNotes, ...rest } = params;
|
|
3528
|
+
return {
|
|
3529
|
+
...rest,
|
|
3530
|
+
token_id: rest.token_id ?? tokenId,
|
|
3531
|
+
token_ids: rest.token_ids ?? tokenIds,
|
|
3532
|
+
reviewer_notes: rest.reviewer_notes ?? reviewerNotes
|
|
3533
|
+
};
|
|
3534
|
+
}
|
|
3535
|
+
function buildDebugNextActions(status, refs, errors) {
|
|
3536
|
+
const actions = /* @__PURE__ */ new Set();
|
|
3537
|
+
if (status.next_action) actions.add(status.next_action);
|
|
3538
|
+
for (const ref of refs) {
|
|
3539
|
+
if (ref.status_command) actions.add(ref.status_command);
|
|
3540
|
+
if (ref.replay_command) actions.add(ref.replay_command);
|
|
3541
|
+
}
|
|
3542
|
+
if (errors.length > 0) actions.add("Review diagnostic_errors before replaying or changing the Op prompt.");
|
|
3543
|
+
if (refs.some((ref) => ref.kind === "queue_job")) actions.add("Inspect queue pressure before retrying provider-backed work.");
|
|
3544
|
+
return Array.from(actions);
|
|
3545
|
+
}
|
|
3546
|
+
function buildDebugDiagnosis(status, runStatuses, queue, errors) {
|
|
3547
|
+
const backendDiagnosis = status.diagnosis ? normalizeOpsDebugDiagnosis(status.diagnosis) : void 0;
|
|
3548
|
+
const queueSummary = queue?.summary?.queue ?? queue?.queue;
|
|
3549
|
+
const queuePending = queueSummary?.pending ?? 0;
|
|
3550
|
+
const queueProcessing = queueSummary?.processing ?? 0;
|
|
3551
|
+
const queueFailedLastHour = queue?.summary?.queue?.failed_last_hour ?? queue?.summary?.queue?.failedLastHour ?? 0;
|
|
3552
|
+
const failedRuns = runStatuses.filter((run) => /fail|error|cancel/i.test(run.status || ""));
|
|
3553
|
+
const primaryRunError = failedRuns.map((run) => run.error).find((error) => error !== void 0);
|
|
3554
|
+
const primaryError = errors[0]?.message || stringifyDebugError(primaryRunError);
|
|
3555
|
+
const providerPressure = queuePending >= 100 ? "high" : queuePending >= 10 ? "medium" : queuePending > 0 || queueProcessing > 0 ? "low" : "none";
|
|
3556
|
+
const statusText = `${status.status || ""} ${status.phase || ""}`.toLowerCase();
|
|
3557
|
+
const state = errors.length > 0 ? "degraded" : failedRuns.length > 0 || statusText.includes("failed") || statusText.includes("error") ? "failed" : statusText.includes("running") || statusText.includes("pending") || statusText.includes("queued") || queueProcessing > 0 ? "running" : statusText.includes("complete") || statusText.includes("success") ? "healthy" : backendDiagnosis?.state ?? "unknown";
|
|
3558
|
+
const retryable = state === "failed" && (failedRuns.length > 0 || backendDiagnosis?.retryable === true || Boolean(status.execution_refs?.some((ref) => ref.replay_command)));
|
|
3559
|
+
const summary = [
|
|
3560
|
+
`State ${state}`,
|
|
3561
|
+
`retry ${retryable ? "available" : "not indicated"}`,
|
|
3562
|
+
`queue ${queuePending} pending/${queueProcessing} processing`,
|
|
3563
|
+
`provider pressure ${providerPressure}`
|
|
3564
|
+
].join("; ");
|
|
3565
|
+
return {
|
|
3566
|
+
state,
|
|
3567
|
+
retryable,
|
|
3568
|
+
queue_pending: queuePending,
|
|
3569
|
+
queue_processing: queueProcessing,
|
|
3570
|
+
queue_failed_last_hour: queueFailedLastHour,
|
|
3571
|
+
provider_pressure: providerPressure,
|
|
3572
|
+
failed_run_count: failedRuns.length || backendDiagnosis?.failed_run_count || 0,
|
|
3573
|
+
primary_error: primaryError ?? backendDiagnosis?.primary_error,
|
|
3574
|
+
summary
|
|
3575
|
+
};
|
|
3576
|
+
}
|
|
3577
|
+
function stringifyDebugError(error) {
|
|
3578
|
+
if (error === void 0 || error === null) return void 0;
|
|
3579
|
+
if (typeof error === "string") return error;
|
|
3580
|
+
if (error instanceof Error) return error.message;
|
|
3581
|
+
try {
|
|
3582
|
+
return JSON.stringify(error);
|
|
3583
|
+
} catch {
|
|
3584
|
+
return String(error);
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
|
|
3588
|
+
// src/resources/ai.ts
|
|
3589
|
+
function toSnakeConfig(params) {
|
|
3590
|
+
return {
|
|
3591
|
+
system_prompt: params.systemPrompt || params.system_prompt || "You are a senior business research analyst. Use multi-model evidence carefully and return concise structured enrichment.",
|
|
3592
|
+
user_template: params.userTemplate || params.user_template || params.prompt,
|
|
3593
|
+
model: params.model,
|
|
3594
|
+
temperature: params.temperature,
|
|
3595
|
+
max_concurrency: params.maxConcurrency || params.max_concurrency,
|
|
3596
|
+
max_tokens: params.maxTokens || params.max_tokens,
|
|
3597
|
+
output_fields: params.outputFields || params.output_fields || [{ name: "response", type: "text", description: "Structured enrichment result" }],
|
|
3598
|
+
attachments: params.attachments,
|
|
3599
|
+
attachment_fields: params.attachmentFields || params.attachment_fields,
|
|
3600
|
+
pdf_engine: params.pdfEngine || params.pdf_engine,
|
|
3601
|
+
fusion: params.fusion
|
|
3602
|
+
};
|
|
3603
|
+
}
|
|
3604
|
+
function recordsFromParams(params) {
|
|
3605
|
+
const records = params.records || params.inputs;
|
|
3606
|
+
if (records?.length) return { records };
|
|
3607
|
+
if (params.input) return { input: params.input };
|
|
3608
|
+
return { input: {} };
|
|
3609
|
+
}
|
|
3610
|
+
var Ai = class {
|
|
3611
|
+
constructor(client) {
|
|
3612
|
+
this.client = client;
|
|
3613
|
+
}
|
|
3614
|
+
/**
|
|
3615
|
+
* Run Custom AI Enrichment - Multi Model.
|
|
3616
|
+
*
|
|
3617
|
+
* Uses OpenRouter Fusion for multi-model analysis with web search/fetch enabled
|
|
3618
|
+
* inside Fusion, then synthesizes the requested structured output fields.
|
|
3619
|
+
*/
|
|
3620
|
+
async multiModel(params) {
|
|
3621
|
+
if (!params.model) {
|
|
3622
|
+
throw new Error('model is required. Use an OpenRouter id such as "anthropic/claude-sonnet-4" or "google/gemini-2.5-flash".');
|
|
3623
|
+
}
|
|
3624
|
+
if (!params.prompt && !params.userTemplate && !params.user_template) {
|
|
3625
|
+
throw new Error("prompt or userTemplate is required.");
|
|
3626
|
+
}
|
|
3627
|
+
const data = await this.client.post("custom-ai-multi-model", {
|
|
3628
|
+
...recordsFromParams(params),
|
|
3629
|
+
config: toSnakeConfig(params)
|
|
3630
|
+
});
|
|
3631
|
+
return {
|
|
3632
|
+
success: data.success ?? false,
|
|
3633
|
+
capability: data.capability ?? "custom_ai_multi_model",
|
|
3634
|
+
displayName: data.display_name ?? "Custom AI Enrichment - Multi Model",
|
|
3635
|
+
results: data.results ?? [],
|
|
3636
|
+
creditsUsed: data.total_credits_used ?? data.credits_used ?? 0,
|
|
3637
|
+
model: data.model,
|
|
3638
|
+
fusion: data.fusion,
|
|
3639
|
+
multimodalCount: data.multimodal_count ?? 0,
|
|
3640
|
+
tokensUsed: data.tokens_used ?? 0,
|
|
3641
|
+
costUsd: data.cost_usd ?? 0,
|
|
3642
|
+
billingMetadata: data.billing_metadata,
|
|
3643
|
+
raw: data
|
|
3644
|
+
};
|
|
3645
|
+
}
|
|
3646
|
+
};
|
|
3647
|
+
|
|
3648
|
+
// src/resources/gtm-kernel.ts
|
|
3649
|
+
var GtmKernel = class {
|
|
3650
|
+
constructor(client) {
|
|
3651
|
+
this.client = client;
|
|
3652
|
+
}
|
|
3653
|
+
/** Load workspace context for an agent session: campaigns, memory, Brain, connections, and Signaliz primitives. */
|
|
3654
|
+
async context(options = {}) {
|
|
3655
|
+
return this.callMcp("gtm_workspace_context", {
|
|
3656
|
+
include_campaigns: options.includeCampaigns,
|
|
3657
|
+
include_memory: options.includeMemory,
|
|
3658
|
+
include_brain: options.includeBrain,
|
|
3659
|
+
include_connections: options.includeConnections,
|
|
3660
|
+
limit: options.limit
|
|
3661
|
+
});
|
|
3662
|
+
}
|
|
3663
|
+
/** Inspect whether the workspace has the Kernel + Brain substrate pieces needed to build, run, and improve campaigns. */
|
|
3664
|
+
async bootstrapStatus(options = {}) {
|
|
3665
|
+
return this.callMcp("gtm_workspace_bootstrap_status", {
|
|
3666
|
+
campaign_id: options.campaignId,
|
|
3667
|
+
days: options.days,
|
|
3668
|
+
min_sample_size: options.minSampleSize,
|
|
3669
|
+
include_connections: options.includeConnections,
|
|
3670
|
+
include_samples: options.includeSamples,
|
|
3671
|
+
limit: options.limit
|
|
3672
|
+
});
|
|
3673
|
+
}
|
|
3674
|
+
/** Discover existing provider campaigns, starting with live/Kernel-linked Instantly campaigns, before audit or import preview. */
|
|
3675
|
+
async discoverExistingCampaigns(options = {}) {
|
|
3676
|
+
return this.callMcp("gtm_existing_campaign_discover", {
|
|
3677
|
+
provider: options.provider,
|
|
3678
|
+
integration_id: options.integrationId,
|
|
3679
|
+
search: options.search,
|
|
3680
|
+
limit: options.limit,
|
|
3681
|
+
include_kernel_linked: options.includeKernelLinked,
|
|
3682
|
+
include_provider_live: options.includeProviderLive
|
|
3683
|
+
});
|
|
3684
|
+
}
|
|
3685
|
+
/** Run a read-only existing campaign audit with completeness, recommendations, safe next MCP JSON, and approval boundaries. */
|
|
3686
|
+
async auditExistingCampaign(options) {
|
|
3687
|
+
return this.callMcp("gtm_existing_campaign_audit", {
|
|
3688
|
+
campaign_id: options.campaignId,
|
|
3689
|
+
provider: options.provider,
|
|
3690
|
+
provider_campaign_id: options.providerCampaignId,
|
|
3691
|
+
campaign_name: options.campaignName,
|
|
3692
|
+
days: options.days,
|
|
3693
|
+
include_route_preview: options.includeRoutePreview,
|
|
3694
|
+
include_memory: options.includeMemory,
|
|
3695
|
+
include_brain: options.includeBrain
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3698
|
+
/** Discover the first matching existing provider campaign, then run the same read-only audit against that match. */
|
|
3699
|
+
async auditExistingCampaignBySearch(options) {
|
|
3700
|
+
const discovery = await this.discoverExistingCampaigns({
|
|
3701
|
+
provider: options.provider,
|
|
3702
|
+
integrationId: options.integrationId,
|
|
3703
|
+
search: options.search,
|
|
3704
|
+
limit: 1,
|
|
3705
|
+
includeKernelLinked: options.includeKernelLinked,
|
|
3706
|
+
includeProviderLive: options.includeProviderLive
|
|
3707
|
+
});
|
|
3708
|
+
const match = discovery.campaigns?.[0];
|
|
3709
|
+
const campaignId = match?.linked_kernel_campaign_id || void 0;
|
|
3710
|
+
const providerCampaignId = match?.provider_campaign_id || void 0;
|
|
3711
|
+
if (!campaignId && !providerCampaignId) {
|
|
3712
|
+
throw new Error(`No existing ${options.provider || discovery.provider || "provider"} campaign matched "${options.search}"`);
|
|
3713
|
+
}
|
|
3714
|
+
return this.auditExistingCampaign({
|
|
3715
|
+
provider: options.provider || discovery.provider || match?.provider,
|
|
3716
|
+
campaignId,
|
|
3717
|
+
providerCampaignId,
|
|
3718
|
+
campaignName: match?.name || match?.linked_kernel_campaign_name || void 0,
|
|
3719
|
+
days: options.days,
|
|
3720
|
+
includeRoutePreview: options.includeRoutePreview,
|
|
3721
|
+
includeMemory: options.includeMemory,
|
|
3722
|
+
includeBrain: options.includeBrain
|
|
3723
|
+
});
|
|
3724
|
+
}
|
|
3725
|
+
/** Create a first-class GTM campaign object in the current workspace. */
|
|
3726
|
+
async createCampaign(input) {
|
|
3727
|
+
return this.callMcp("gtm_campaign_create", campaignCreateArgs(input));
|
|
3728
|
+
}
|
|
3729
|
+
/** Backfill historical campaigns, provider links, feedback, and memory into the GTM Kernel substrate. */
|
|
3730
|
+
async importCampaignHistory(input) {
|
|
3731
|
+
return this.callMcp("gtm_campaign_history_import", {
|
|
3732
|
+
source: input.source,
|
|
3733
|
+
dry_run: input.dryRun,
|
|
3734
|
+
create_memory: input.createMemory,
|
|
3735
|
+
campaigns: input.campaigns.map(campaignHistoryImportCampaignArgs)
|
|
3736
|
+
});
|
|
3737
|
+
}
|
|
3738
|
+
/** Queue a Trigger-backed campaign history import for larger CMM/client backfills. */
|
|
3739
|
+
async importCampaignHistoryRun(input) {
|
|
3740
|
+
return this.callMcp("gtm_campaign_history_import_run", {
|
|
3741
|
+
source: input.source,
|
|
3742
|
+
dry_run: input.dryRun,
|
|
3743
|
+
create_memory: input.createMemory,
|
|
3744
|
+
campaigns: input.campaigns?.map(campaignHistoryImportCampaignArgs),
|
|
3745
|
+
batches: input.batches?.map((batch) => ({
|
|
3746
|
+
batch_id: batch.batchId,
|
|
3747
|
+
campaigns: batch.campaigns.map(campaignHistoryImportCampaignArgs)
|
|
3748
|
+
})),
|
|
3749
|
+
batch_size: input.batchSize,
|
|
3750
|
+
continue_on_error: input.continueOnError,
|
|
3751
|
+
run_brain_cycle: input.runBrainCycle,
|
|
3752
|
+
brain_cycle_write_mode: input.brainCycleWriteMode,
|
|
3753
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3754
|
+
brain_cycle_days: input.brainCycleDays,
|
|
3755
|
+
brain_cycle_network_days: input.brainCycleNetworkDays,
|
|
3756
|
+
brain_cycle_min_sample_size: input.brainCycleMinSampleSize,
|
|
3757
|
+
brain_cycle_limit: input.brainCycleLimit
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3760
|
+
/** Preview a provider-neutral history import payload derived from an existing campaign build. */
|
|
3761
|
+
async previewCampaignBuildBackfill(options) {
|
|
3762
|
+
return this.callMcp("gtm_campaign_build_backfill_preview", {
|
|
3763
|
+
campaign_build_id: options.campaignBuildId,
|
|
3764
|
+
include_sample_rows: options.includeSampleRows,
|
|
3765
|
+
include_copy_samples: options.includeCopySamples,
|
|
3766
|
+
sample_row_limit: options.sampleRowLimit,
|
|
3767
|
+
create_memory: options.createMemory,
|
|
3768
|
+
include_payload: options.includePayload
|
|
3769
|
+
});
|
|
3770
|
+
}
|
|
3771
|
+
/** Queue campaign-build history backfills through the Trigger-backed history import runner. */
|
|
3772
|
+
async runCampaignBuildBackfill(input) {
|
|
3773
|
+
return this.callMcp("gtm_campaign_build_backfill_run", {
|
|
3774
|
+
campaign_build_ids: input.campaignBuildIds,
|
|
3775
|
+
source: input.source,
|
|
3776
|
+
dry_run: input.dryRun,
|
|
3777
|
+
create_memory: input.createMemory,
|
|
3778
|
+
include_sample_rows: input.includeSampleRows,
|
|
3779
|
+
include_copy_samples: input.includeCopySamples,
|
|
3780
|
+
include_payload: input.includePayload,
|
|
3781
|
+
sample_row_limit: input.sampleRowLimit,
|
|
3782
|
+
batch_size: input.batchSize,
|
|
3783
|
+
continue_on_error: input.continueOnError,
|
|
3784
|
+
run_brain_cycle: input.runBrainCycle,
|
|
3785
|
+
brain_cycle_write_mode: input.brainCycleWriteMode,
|
|
3786
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3787
|
+
brain_cycle_days: input.brainCycleDays,
|
|
3788
|
+
brain_cycle_network_days: input.brainCycleNetworkDays,
|
|
3789
|
+
brain_cycle_min_sample_size: input.brainCycleMinSampleSize,
|
|
3790
|
+
brain_cycle_limit: input.brainCycleLimit
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3793
|
+
/** Inspect Campaign Builder to Kernel backfill status for one build. */
|
|
3794
|
+
async campaignBuildBackfillStatus(options) {
|
|
3795
|
+
return this.callMcp("gtm_campaign_build_backfill_status", {
|
|
3796
|
+
campaign_build_id: options.campaignBuildId,
|
|
3797
|
+
include_phases: options.includePhases,
|
|
3798
|
+
include_linked_campaign: options.includeLinkedCampaign
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3801
|
+
/** List first-class GTM campaign objects in the current workspace. */
|
|
3802
|
+
async listCampaigns(options = {}) {
|
|
3803
|
+
return this.callMcp("gtm_campaign_list", {
|
|
3804
|
+
status: options.status,
|
|
3805
|
+
provider: options.provider,
|
|
3806
|
+
search: options.search,
|
|
3807
|
+
limit: options.limit,
|
|
3808
|
+
include_archived: options.includeArchived
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
/** Get one campaign with provider links, logs, feedback summary, memory, and Brain patterns. */
|
|
3812
|
+
async getCampaign(campaignId, options = {}) {
|
|
3813
|
+
return this.callMcp("gtm_campaign_get", {
|
|
3814
|
+
campaign_id: campaignId,
|
|
3815
|
+
log_limit: options.logLimit,
|
|
3816
|
+
memory_limit: options.memoryLimit
|
|
3817
|
+
});
|
|
3818
|
+
}
|
|
3819
|
+
/** Inspect campaign execution state, linked build progress, provider readiness, feedback, memory, and next actions. */
|
|
3820
|
+
async campaignExecutionStatus(options) {
|
|
3821
|
+
return this.callMcp("gtm_campaign_execution_status", {
|
|
3822
|
+
campaign_id: options.campaignId,
|
|
3823
|
+
campaign_build_id: options.campaignBuildId,
|
|
3824
|
+
include_provider_readiness: options.includeProviderReadiness,
|
|
3825
|
+
include_feedback: options.includeFeedback,
|
|
3826
|
+
include_memory: options.includeMemory,
|
|
3827
|
+
include_recent_log: options.includeRecentLog,
|
|
3828
|
+
log_limit: options.logLimit,
|
|
3829
|
+
memory_limit: options.memoryLimit
|
|
3830
|
+
});
|
|
3831
|
+
}
|
|
3832
|
+
/** Inspect whether a campaign/build is ready for Brain learning and return exact learning-cycle args. */
|
|
3833
|
+
async campaignLearningStatus(options) {
|
|
3834
|
+
return this.callMcp("gtm_campaign_learning_status", {
|
|
3835
|
+
campaign_id: options.campaignId,
|
|
3836
|
+
campaign_build_id: options.campaignBuildId,
|
|
3837
|
+
days: options.days,
|
|
3838
|
+
network_days: options.networkDays,
|
|
3839
|
+
min_sample_size: options.minSampleSize,
|
|
3840
|
+
min_workspace_count: options.minWorkspaceCount,
|
|
3841
|
+
min_privacy_k: options.minPrivacyK,
|
|
3842
|
+
include_memory: options.includeMemory,
|
|
3843
|
+
include_network: options.includeNetwork,
|
|
3844
|
+
write_mode: options.writeMode,
|
|
3845
|
+
limit: options.limit
|
|
3846
|
+
});
|
|
3847
|
+
}
|
|
3848
|
+
/** Update a first-class GTM campaign and append the associated campaign log entry. */
|
|
3849
|
+
async updateCampaign(input) {
|
|
3850
|
+
return this.callMcp("gtm_campaign_update", campaignUpdateArgs(input));
|
|
3851
|
+
}
|
|
3852
|
+
/** Append an auditable campaign action with actor, rationale, payload, and optional idempotency key. */
|
|
3853
|
+
async logCampaign(campaignId, input) {
|
|
3854
|
+
return this.callMcp("gtm_campaign_log", campaignLogArgs({ ...input, campaignId }));
|
|
3855
|
+
}
|
|
3856
|
+
/** Ingest provider-neutral feedback from Instantly, Smartlead, HeyReach, webhook, or a custom MCP. */
|
|
3857
|
+
async ingestFeedback(input) {
|
|
3858
|
+
return this.callMcp("gtm_feedback_ingest", {
|
|
3859
|
+
source: input.source,
|
|
3860
|
+
campaign_id: input.campaignId,
|
|
3861
|
+
campaign_build_id: input.campaignBuildId,
|
|
3862
|
+
provider_campaign_id: input.providerCampaignId,
|
|
3863
|
+
events: input.events,
|
|
3864
|
+
provider_payload: input.providerPayload,
|
|
3865
|
+
create_memory: input.createMemory,
|
|
3866
|
+
write_routine_outcomes: input.writeRoutineOutcomes
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
/** Normalize Instantly webhook/pull payloads and ingest row-level feedback through the GTM Kernel. */
|
|
3870
|
+
async syncInstantlyFeedback(input) {
|
|
3871
|
+
return this.callMcp("gtm_instantly_feedback_sync", {
|
|
3872
|
+
campaign_id: input.campaignId,
|
|
3873
|
+
campaign_build_id: input.campaignBuildId,
|
|
3874
|
+
provider_campaign_id: input.providerCampaignId,
|
|
3875
|
+
instantly_campaign_id: input.instantlyCampaignId,
|
|
3876
|
+
sync_mode: input.syncMode,
|
|
3877
|
+
events: input.events,
|
|
3878
|
+
provider_payload: input.providerPayload,
|
|
3879
|
+
cursor: input.cursor,
|
|
3880
|
+
since: input.since,
|
|
3881
|
+
until: input.until,
|
|
3882
|
+
aggregate_snapshot: input.aggregateSnapshot,
|
|
3883
|
+
create_memory: input.createMemory,
|
|
3884
|
+
write_routine_outcomes: input.writeRoutineOutcomes
|
|
3885
|
+
});
|
|
3886
|
+
}
|
|
3887
|
+
/** Start a background Instantly webhook-events pull and route results into the GTM feedback loop. */
|
|
3888
|
+
async pullInstantlyFeedback(input) {
|
|
3889
|
+
return this.callMcp("gtm_instantly_feedback_pull", {
|
|
3890
|
+
campaign_id: input.campaignId,
|
|
3891
|
+
campaign_build_id: input.campaignBuildId,
|
|
3892
|
+
provider_link_id: input.providerLinkId,
|
|
3893
|
+
provider_campaign_id: input.providerCampaignId,
|
|
3894
|
+
instantly_campaign_id: input.instantlyCampaignId,
|
|
3895
|
+
integration_id: input.integrationId,
|
|
3896
|
+
cursor: input.cursor,
|
|
3897
|
+
from: input.from,
|
|
3898
|
+
to: input.to,
|
|
3899
|
+
limit: input.limit,
|
|
3900
|
+
max_pages: input.maxPages,
|
|
3901
|
+
create_memory: input.createMemory,
|
|
3902
|
+
write_routine_outcomes: input.writeRoutineOutcomes,
|
|
3903
|
+
dry_run: input.dryRun,
|
|
3904
|
+
run_brain_cycle: input.runBrainCycle,
|
|
3905
|
+
brain_cycle_write_mode: input.brainCycleWriteMode,
|
|
3906
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3907
|
+
brain_cycle_min_ingested: input.brainCycleMinIngested,
|
|
3908
|
+
brain_cycle_min_interval_minutes: input.brainCycleMinIntervalMinutes
|
|
3909
|
+
});
|
|
3910
|
+
}
|
|
3911
|
+
/** Prepare a secure Instantly feedback webhook URL for a campaign provider link. */
|
|
3912
|
+
async prepareInstantlyFeedbackWebhook(input) {
|
|
3913
|
+
return this.callMcp("gtm_instantly_feedback_webhook_prepare", {
|
|
3914
|
+
campaign_id: input.campaignId,
|
|
3915
|
+
campaign_build_id: input.campaignBuildId,
|
|
3916
|
+
provider_link_id: input.providerLinkId,
|
|
3917
|
+
provider_campaign_id: input.providerCampaignId,
|
|
3918
|
+
instantly_campaign_id: input.instantlyCampaignId,
|
|
3919
|
+
integration_id: input.integrationId,
|
|
3920
|
+
provider_workspace_id: input.providerWorkspaceId,
|
|
3921
|
+
provider_account_id: input.providerAccountId,
|
|
3922
|
+
rotate_secret: input.rotateSecret,
|
|
3923
|
+
run_brain_cycle: input.runBrainCycle,
|
|
3924
|
+
brain_cycle_write_mode: input.brainCycleWriteMode,
|
|
3925
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3926
|
+
brain_cycle_min_ingested: input.brainCycleMinIngested,
|
|
3927
|
+
brain_cycle_min_interval_minutes: input.brainCycleMinIntervalMinutes
|
|
3928
|
+
});
|
|
3929
|
+
}
|
|
3930
|
+
/** Preview anonymized Instantly workspace sources registered for Kernel import. */
|
|
3931
|
+
async previewKernelImport(input = {}) {
|
|
3932
|
+
return this.callMcp("gtm_kernel_import_preview", {
|
|
3933
|
+
source_ids: input.sourceIds,
|
|
3934
|
+
include_leads: input.includeLeads,
|
|
3935
|
+
include_replies: input.includeReplies,
|
|
3936
|
+
include_private_copy: input.includePrivateCopy,
|
|
3937
|
+
max_pages: input.maxPages,
|
|
3938
|
+
limit: input.limit
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
/** Queue the read-only Instantly-to-GTM Kernel import. Live writes require writeApproved. */
|
|
3942
|
+
async runKernelImport(input = {}) {
|
|
3943
|
+
return this.callMcp("gtm_kernel_import_run", {
|
|
3944
|
+
source_ids: input.sourceIds,
|
|
3945
|
+
dry_run: input.dryRun,
|
|
3946
|
+
write_approved: input.writeApproved,
|
|
3947
|
+
include_leads: input.includeLeads,
|
|
3948
|
+
include_replies: input.includeReplies,
|
|
3949
|
+
include_private_copy: input.includePrivateCopy,
|
|
3950
|
+
private_copy_approved: input.privateCopyApproved,
|
|
3951
|
+
promote_global_patterns: input.promoteGlobalPatterns,
|
|
3952
|
+
min_global_privacy_k: input.minGlobalPrivacyK,
|
|
3953
|
+
max_pages: input.maxPages,
|
|
3954
|
+
limit: input.limit
|
|
3955
|
+
});
|
|
3956
|
+
}
|
|
3957
|
+
/** Queue Brain distillation over imported Instantly memory with abstracted-only outputs. */
|
|
3958
|
+
async runBrainDistillation(input = {}) {
|
|
3959
|
+
return this.callMcp("gtm_brain_distill_run", {
|
|
3960
|
+
source_ids: input.sourceIds,
|
|
3961
|
+
write_mode: input.writeMode,
|
|
3962
|
+
write_approved: input.writeApproved,
|
|
3963
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3964
|
+
days: input.days,
|
|
3965
|
+
network_days: input.networkDays,
|
|
3966
|
+
min_sample_size: input.minSampleSize,
|
|
3967
|
+
min_workspace_count: input.minWorkspaceCount,
|
|
3968
|
+
min_privacy_k: input.minPrivacyK
|
|
3969
|
+
});
|
|
3970
|
+
}
|
|
3971
|
+
/** Prepare a provider-agnostic feedback webhook URL for Smartlead, HeyReach, Airbyte, or custom sender events. */
|
|
3972
|
+
async prepareFeedbackWebhook(input) {
|
|
3973
|
+
return this.callMcp("gtm_feedback_webhook_prepare", {
|
|
3974
|
+
provider: input.provider,
|
|
3975
|
+
campaign_id: input.campaignId,
|
|
3976
|
+
campaign_build_id: input.campaignBuildId,
|
|
3977
|
+
provider_link_id: input.providerLinkId,
|
|
3978
|
+
provider_campaign_id: input.providerCampaignId,
|
|
3979
|
+
integration_id: input.integrationId,
|
|
3980
|
+
provider_workspace_id: input.providerWorkspaceId,
|
|
3981
|
+
provider_account_id: input.providerAccountId,
|
|
3982
|
+
rotate_secret: input.rotateSecret,
|
|
3983
|
+
run_brain_cycle: input.runBrainCycle,
|
|
3984
|
+
brain_cycle_write_mode: input.brainCycleWriteMode,
|
|
3985
|
+
brain_cycle_phases: input.brainCyclePhases,
|
|
3986
|
+
brain_cycle_min_ingested: input.brainCycleMinIngested,
|
|
3987
|
+
brain_cycle_min_interval_minutes: input.brainCycleMinIntervalMinutes
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
/** Search ranked workspace campaign memory instead of dumping raw history. */
|
|
3991
|
+
async searchMemory(options = {}) {
|
|
3992
|
+
return this.callMcp("gtm_memory_search", {
|
|
3993
|
+
query: options.query,
|
|
3994
|
+
campaign_id: options.campaignId,
|
|
3995
|
+
memory_type: options.memoryType,
|
|
3996
|
+
keywords: options.keywords,
|
|
3997
|
+
outcome_type: options.outcomeType,
|
|
3998
|
+
target_icp: options.targetIcp,
|
|
3999
|
+
layers: options.layers,
|
|
4000
|
+
provider_chain: options.providerChain,
|
|
4001
|
+
dimension_filters: options.dimensionFilters,
|
|
4002
|
+
require_dimension_match: options.requireDimensionMatch,
|
|
4003
|
+
days: options.days,
|
|
4004
|
+
limit: options.limit
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
4007
|
+
/** Retrieve evidence-backed workspace and privacy-safe aggregate Brain patterns. */
|
|
4008
|
+
async brainPatterns(options = {}) {
|
|
4009
|
+
return this.callMcp("gtm_brain_patterns", {
|
|
4010
|
+
campaign_id: options.campaignId,
|
|
4011
|
+
pattern_type: options.patternType,
|
|
4012
|
+
segment_key: options.segmentKey,
|
|
4013
|
+
include_global: options.includeGlobal,
|
|
4014
|
+
min_confidence: options.minConfidence,
|
|
4015
|
+
limit: options.limit
|
|
4016
|
+
});
|
|
4017
|
+
}
|
|
4018
|
+
/** Plan the closed-loop Brain learning sequence without recursively executing Edge Functions. */
|
|
4019
|
+
async learningCyclePlan(input = {}) {
|
|
4020
|
+
return this.callMcp("gtm_brain_learning_cycle_plan", {
|
|
4021
|
+
campaign_id: input.campaignId,
|
|
4022
|
+
campaign_brief: input.campaignBrief,
|
|
4023
|
+
target_icp: input.targetIcp,
|
|
4024
|
+
layers: input.layers,
|
|
4025
|
+
provider_chain: input.providerChain,
|
|
4026
|
+
lead_source: input.leadSource,
|
|
4027
|
+
days: input.days,
|
|
4028
|
+
network_days: input.networkDays,
|
|
4029
|
+
min_sample_size: input.minSampleSize,
|
|
4030
|
+
min_workspace_count: input.minWorkspaceCount,
|
|
4031
|
+
min_privacy_k: input.minPrivacyK,
|
|
4032
|
+
include_memory: input.includeMemory,
|
|
4033
|
+
include_network: input.includeNetwork,
|
|
4034
|
+
write_mode: input.writeMode,
|
|
4035
|
+
limit: input.limit
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
4038
|
+
/** Queue the closed-loop Brain learning sequence in Trigger. */
|
|
4039
|
+
async learningCycleRun(input = {}) {
|
|
4040
|
+
return this.callMcp("gtm_brain_learning_cycle_run", {
|
|
4041
|
+
campaign_id: input.campaignId,
|
|
4042
|
+
campaign_brief: input.campaignBrief,
|
|
4043
|
+
target_icp: input.targetIcp,
|
|
4044
|
+
layers: input.layers,
|
|
4045
|
+
provider_chain: input.providerChain,
|
|
4046
|
+
lead_source: input.leadSource,
|
|
4047
|
+
days: input.days,
|
|
4048
|
+
network_days: input.networkDays,
|
|
4049
|
+
min_sample_size: input.minSampleSize,
|
|
4050
|
+
min_workspace_count: input.minWorkspaceCount,
|
|
4051
|
+
min_privacy_k: input.minPrivacyK,
|
|
4052
|
+
include_memory: input.includeMemory,
|
|
4053
|
+
include_network: input.includeNetwork,
|
|
4054
|
+
write_mode: input.writeMode,
|
|
4055
|
+
phases: input.phases,
|
|
4056
|
+
continue_on_error: input.continueOnError,
|
|
4057
|
+
limit: input.limit
|
|
4058
|
+
});
|
|
4059
|
+
}
|
|
4060
|
+
/** Seed campaign defaults from active Brain patterns and ranked workspace memory. */
|
|
4061
|
+
async seedBrainDefaults(input = {}) {
|
|
4062
|
+
return this.callMcp("gtm_brain_seed_defaults", {
|
|
4063
|
+
campaign_id: input.campaignId,
|
|
4064
|
+
campaign_brief: input.campaignBrief,
|
|
4065
|
+
target_icp: input.targetIcp,
|
|
4066
|
+
layers: input.layers,
|
|
4067
|
+
include_global: input.includeGlobal,
|
|
4068
|
+
include_memory: input.includeMemory,
|
|
4069
|
+
min_confidence: input.minConfidence,
|
|
4070
|
+
write_campaign: input.writeCampaign,
|
|
4071
|
+
limit: input.limit
|
|
4072
|
+
});
|
|
4073
|
+
}
|
|
4074
|
+
/** Extract within-workspace Brain V1 patterns from feedback, provider links, campaigns, and memory. */
|
|
4075
|
+
async extractBrainPatterns(input = {}) {
|
|
4076
|
+
return this.callMcp("gtm_brain_extract_patterns", {
|
|
4077
|
+
campaign_id: input.campaignId,
|
|
4078
|
+
days: input.days,
|
|
4079
|
+
pattern_types: input.patternTypes,
|
|
4080
|
+
min_sample_size: input.minSampleSize,
|
|
4081
|
+
include_memory: input.includeMemory,
|
|
4082
|
+
write_patterns: input.writePatterns,
|
|
4083
|
+
dry_run: input.dryRun,
|
|
4084
|
+
replace_existing: input.replaceExisting,
|
|
4085
|
+
limit: input.limit
|
|
4086
|
+
});
|
|
4087
|
+
}
|
|
4088
|
+
/** Aggregate opted-in workspace Brain patterns into privacy-safe global defaults. */
|
|
4089
|
+
async aggregateBrainPatterns(input = {}) {
|
|
4090
|
+
return this.callMcp("gtm_brain_aggregate_patterns", {
|
|
4091
|
+
days: input.days,
|
|
4092
|
+
pattern_types: input.patternTypes,
|
|
4093
|
+
min_workspace_count: input.minWorkspaceCount,
|
|
4094
|
+
min_privacy_k: input.minPrivacyK,
|
|
4095
|
+
min_confidence: input.minConfidence,
|
|
4096
|
+
include_low_confidence: input.includeLowConfidence,
|
|
4097
|
+
write_patterns: input.writePatterns,
|
|
4098
|
+
dry_run: input.dryRun,
|
|
4099
|
+
replace_existing: input.replaceExisting,
|
|
4100
|
+
limit: input.limit
|
|
4101
|
+
});
|
|
4102
|
+
}
|
|
4103
|
+
/** Aggregate opted-in workspace deliverability calibrations into privacy-safe global calibration rows. */
|
|
4104
|
+
async aggregateBrainCalibrations(input = {}) {
|
|
4105
|
+
return this.callMcp("gtm_brain_aggregate_calibrations", {
|
|
4106
|
+
days: input.days,
|
|
4107
|
+
dimension_types: input.dimensionTypes,
|
|
4108
|
+
min_workspace_count: input.minWorkspaceCount,
|
|
4109
|
+
min_privacy_k: input.minPrivacyK,
|
|
4110
|
+
min_confidence: input.minConfidence,
|
|
4111
|
+
include_low_confidence: input.includeLowConfidence,
|
|
4112
|
+
write_calibrations: input.writeCalibrations,
|
|
4113
|
+
dry_run: input.dryRun,
|
|
4114
|
+
replace_existing: input.replaceExisting,
|
|
4115
|
+
limit: input.limit
|
|
4116
|
+
});
|
|
4117
|
+
}
|
|
4118
|
+
/** Calibrate workspace deliverability predictions against actual bounce feedback. */
|
|
4119
|
+
async calibrateDeliverability(input = {}) {
|
|
4120
|
+
return this.callMcp("gtm_brain_calibrate_deliverability", {
|
|
4121
|
+
campaign_id: input.campaignId,
|
|
4122
|
+
days: input.days,
|
|
4123
|
+
dimension_types: input.dimensionTypes,
|
|
4124
|
+
min_sample_size: input.minSampleSize,
|
|
4125
|
+
dry_run: input.dryRun,
|
|
4126
|
+
write_calibrations: input.writeCalibrations,
|
|
4127
|
+
write_patterns: input.writePatterns,
|
|
4128
|
+
replace_existing: input.replaceExisting,
|
|
4129
|
+
limit: input.limit
|
|
4130
|
+
});
|
|
4131
|
+
}
|
|
4132
|
+
/** Estimate pre-send delivery risk from campaign context, lead samples, and Brain calibrations. */
|
|
4133
|
+
async deliveryRisk(input = {}) {
|
|
4134
|
+
return this.callMcp("gtm_brain_delivery_risk", {
|
|
4135
|
+
campaign_id: input.campaignId,
|
|
4136
|
+
provider_chain: input.providerChain,
|
|
4137
|
+
lead_source: input.leadSource,
|
|
4138
|
+
target_icp: input.targetIcp,
|
|
4139
|
+
lead_samples: input.leadSamples,
|
|
4140
|
+
include_global: input.includeGlobal,
|
|
4141
|
+
min_confidence: input.minConfidence,
|
|
4142
|
+
limit: input.limit
|
|
4143
|
+
});
|
|
4144
|
+
}
|
|
4145
|
+
/** Rank provider-chain, ICP, source, copy, and sequence failure patterns without writing raw lead data. */
|
|
4146
|
+
async failurePatterns(options = {}) {
|
|
4147
|
+
return this.callMcp("gtm_brain_failure_patterns", {
|
|
4148
|
+
campaign_id: options.campaignId,
|
|
4149
|
+
days: options.days,
|
|
4150
|
+
min_sample_size: options.minSampleSize,
|
|
4151
|
+
dimensions: options.dimensions,
|
|
4152
|
+
include_existing_patterns: options.includeExistingPatterns,
|
|
4153
|
+
include_global: options.includeGlobal,
|
|
4154
|
+
limit: options.limit
|
|
4155
|
+
});
|
|
4156
|
+
}
|
|
4157
|
+
/** List provider presets agents can wire into GTM campaign layers, including BYO and Signaliz fallback options. */
|
|
4158
|
+
async providerCatalog(options = {}) {
|
|
4159
|
+
return this.callMcp("gtm_provider_catalog", {
|
|
4160
|
+
provider_id: options.providerId,
|
|
4161
|
+
layer: options.layer,
|
|
4162
|
+
include_planned: options.includePlanned,
|
|
4163
|
+
include_layer_catalog: options.includeLayerCatalog
|
|
4164
|
+
});
|
|
4165
|
+
}
|
|
4166
|
+
/** Inspect GTM integration activation cards for UI and agent routing without writing state. */
|
|
4167
|
+
async integrationsActivationStatus(options = {}) {
|
|
4168
|
+
return this.callMcp("gtm_integrations_activation_status", {
|
|
4169
|
+
campaign_id: options.campaignId,
|
|
4170
|
+
layer: options.layer,
|
|
4171
|
+
include_planned: options.includePlanned,
|
|
4172
|
+
include_connections: options.includeConnections
|
|
4173
|
+
});
|
|
4174
|
+
}
|
|
4175
|
+
/** Compose Memory, Brain defaults, failure intelligence, and provider routes into a read-only campaign build plan. */
|
|
4176
|
+
async campaignBuildPlan(input = {}) {
|
|
4177
|
+
return this.callMcp("gtm_campaign_build_plan", {
|
|
4178
|
+
campaign_id: input.campaignId,
|
|
4179
|
+
campaign_build_id: input.campaignBuildId,
|
|
4180
|
+
campaign_brief: input.campaignBrief,
|
|
4181
|
+
target_icp: input.targetIcp,
|
|
4182
|
+
lead_count: input.leadCount,
|
|
4183
|
+
layers: input.layers,
|
|
4184
|
+
preferred_providers: input.preferredProviders,
|
|
4185
|
+
memory_dimension_filters: input.memoryDimensionFilters,
|
|
4186
|
+
require_memory_dimension_match: input.requireMemoryDimensionMatch,
|
|
4187
|
+
include_memory: input.includeMemory,
|
|
4188
|
+
include_brain: input.includeBrain,
|
|
4189
|
+
include_provider_routes: input.includeProviderRoutes,
|
|
4190
|
+
include_failure_patterns: input.includeFailurePatterns,
|
|
4191
|
+
include_planned_providers: input.includePlannedProviders,
|
|
4192
|
+
days: input.days,
|
|
4193
|
+
limit: input.limit
|
|
4194
|
+
});
|
|
4195
|
+
}
|
|
4196
|
+
/** Persist a reviewed campaign build plan into a campaign object and audit log. Dry-run first by default. */
|
|
4197
|
+
async commitCampaignBuildPlan(input = {}) {
|
|
4198
|
+
return this.callMcp("gtm_campaign_build_plan_commit", {
|
|
4199
|
+
campaign_id: input.campaignId,
|
|
4200
|
+
campaign_build_id: input.campaignBuildId,
|
|
4201
|
+
name: input.name,
|
|
4202
|
+
campaign_brief: input.campaignBrief,
|
|
4203
|
+
target_icp: input.targetIcp,
|
|
4204
|
+
lead_count: input.leadCount,
|
|
4205
|
+
layers: input.layers,
|
|
4206
|
+
preferred_providers: input.preferredProviders,
|
|
4207
|
+
plan_snapshot: input.planSnapshot,
|
|
4208
|
+
sequences: input.sequences,
|
|
4209
|
+
lead_list_refs: input.leadListRefs,
|
|
4210
|
+
send_config: input.sendConfig,
|
|
4211
|
+
brain_config: input.brainConfig,
|
|
4212
|
+
metadata: input.metadata,
|
|
4213
|
+
status: input.status,
|
|
4214
|
+
approval_required: input.approvalRequired,
|
|
4215
|
+
actor_type: input.actorType,
|
|
4216
|
+
actor_id: input.actorId,
|
|
4217
|
+
rationale: input.rationale,
|
|
4218
|
+
idempotency_key: input.idempotencyKey,
|
|
4219
|
+
dry_run: input.dryRun,
|
|
4220
|
+
confirm: input.confirm
|
|
4221
|
+
});
|
|
4222
|
+
}
|
|
4223
|
+
/** Derive exact build_campaign arguments from a committed campaign object without creating a build. */
|
|
4224
|
+
async prepareCampaignBuildExecution(input) {
|
|
4225
|
+
return this.callMcp("gtm_campaign_build_execution_prepare", {
|
|
4226
|
+
campaign_id: input.campaignId,
|
|
4227
|
+
target_count: input.targetCount,
|
|
4228
|
+
allow_downscale: input.allowDownscale,
|
|
4229
|
+
dry_run: input.dryRun,
|
|
4230
|
+
confirm_spend: input.confirmSpend,
|
|
4231
|
+
include_brain_context: input.includeBrainContext,
|
|
4232
|
+
require_delivery_risk_clearance: input.requireDeliveryRiskClearance,
|
|
4233
|
+
delivery_risk: input.deliveryRisk,
|
|
4234
|
+
dedup_keys: input.dedupKeys,
|
|
4235
|
+
policy: input.policy,
|
|
4236
|
+
signals: input.signals,
|
|
4237
|
+
qualification: input.qualification,
|
|
4238
|
+
copy: input.copy,
|
|
4239
|
+
delivery: input.delivery,
|
|
4240
|
+
enhancers: input.enhancers
|
|
4241
|
+
});
|
|
4242
|
+
}
|
|
4243
|
+
/** Prepare exact recipe, route, preview, and delivery arguments for a provider without writing state. */
|
|
4244
|
+
async prepareProviderRecipe(input) {
|
|
4245
|
+
return this.callMcp("gtm_provider_recipe_prepare", {
|
|
4246
|
+
provider_id: input.providerId,
|
|
4247
|
+
provider_name: input.providerName,
|
|
4248
|
+
description: input.description,
|
|
4249
|
+
layer_capabilities: input.layerCapabilities,
|
|
4250
|
+
invocation_type: input.invocationType,
|
|
4251
|
+
auth_strategy: input.authStrategy,
|
|
4252
|
+
endpoint_url: input.endpointUrl,
|
|
4253
|
+
http_method: input.httpMethod,
|
|
4254
|
+
secret_ref: input.secretRef,
|
|
4255
|
+
workspace_integration_id: input.workspaceIntegrationId,
|
|
4256
|
+
workspace_mcp_server_id: input.workspaceMcpServerId,
|
|
4257
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
4258
|
+
request_template: input.requestTemplate,
|
|
4259
|
+
response_mapping: input.responseMapping,
|
|
4260
|
+
input_schema: input.inputSchema,
|
|
4261
|
+
output_schema: input.outputSchema,
|
|
4262
|
+
readiness: input.readiness,
|
|
4263
|
+
metadata: input.metadata,
|
|
4264
|
+
layer: input.layer,
|
|
4265
|
+
campaign_id: input.campaignId,
|
|
4266
|
+
use_signaliz_fallback: input.useSignalizFallback,
|
|
4267
|
+
priority: input.priority,
|
|
4268
|
+
status: input.status,
|
|
4269
|
+
sample_records: input.sampleRecords,
|
|
4270
|
+
context: input.context
|
|
4271
|
+
});
|
|
4272
|
+
}
|
|
4273
|
+
/** Prepare exact Clay webhook recipe, route, preview, and delivery arguments without writing state. */
|
|
4274
|
+
async prepareClayWebhook(input = {}) {
|
|
4275
|
+
return this.callMcp("gtm_clay_webhook_prepare", {
|
|
4276
|
+
endpoint_url: input.endpointUrl,
|
|
4277
|
+
secret_ref: input.secretRef,
|
|
4278
|
+
layer: input.layer,
|
|
4279
|
+
campaign_id: input.campaignId,
|
|
4280
|
+
use_signaliz_fallback: input.useSignalizFallback,
|
|
4281
|
+
priority: input.priority,
|
|
4282
|
+
status: input.status,
|
|
4283
|
+
sample_records: input.sampleRecords,
|
|
4284
|
+
context: input.context
|
|
4285
|
+
});
|
|
4286
|
+
}
|
|
4287
|
+
/** Dry-run or confirm a one-call provider route activation across one or more GTM layers. */
|
|
4288
|
+
async activateProviderRoute(input) {
|
|
4289
|
+
return this.callMcp("gtm_provider_route_activate", {
|
|
4290
|
+
provider_id: input.providerId,
|
|
4291
|
+
provider_name: input.providerName,
|
|
4292
|
+
description: input.description,
|
|
4293
|
+
layer: input.layer,
|
|
4294
|
+
layers: input.layers,
|
|
4295
|
+
campaign_id: input.campaignId,
|
|
4296
|
+
invocation_type: input.invocationType,
|
|
4297
|
+
auth_strategy: input.authStrategy,
|
|
4298
|
+
endpoint_url: input.endpointUrl,
|
|
4299
|
+
http_method: input.httpMethod,
|
|
4300
|
+
secret_ref: input.secretRef,
|
|
4301
|
+
workspace_integration_id: input.workspaceIntegrationId,
|
|
4302
|
+
workspace_mcp_server_id: input.workspaceMcpServerId,
|
|
4303
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
4304
|
+
use_signaliz_fallback: input.useSignalizFallback,
|
|
4305
|
+
priority: input.priority,
|
|
4306
|
+
route_config: input.routeConfig,
|
|
4307
|
+
request_template: input.requestTemplate,
|
|
4308
|
+
response_mapping: input.responseMapping,
|
|
4309
|
+
input_schema: input.inputSchema,
|
|
4310
|
+
output_schema: input.outputSchema,
|
|
4311
|
+
readiness: input.readiness,
|
|
4312
|
+
metadata: input.metadata,
|
|
4313
|
+
status: input.status,
|
|
4314
|
+
route_status: input.routeStatus,
|
|
4315
|
+
replace_existing_routes: input.replaceExistingRoutes,
|
|
4316
|
+
dry_run: input.dryRun,
|
|
4317
|
+
confirm: input.confirm,
|
|
4318
|
+
sample_records: input.sampleRecords,
|
|
4319
|
+
context: input.context
|
|
4320
|
+
});
|
|
4321
|
+
}
|
|
4322
|
+
/** List Signaliz-managed integrations, external MCP servers, app connections, recipes, and layer routes. */
|
|
4323
|
+
async listConnections(options = {}) {
|
|
4324
|
+
return this.callMcp("gtm_connections_list", {
|
|
4325
|
+
kind: options.kind,
|
|
4326
|
+
include_disconnected: options.includeDisconnected
|
|
4327
|
+
});
|
|
4328
|
+
}
|
|
4329
|
+
/** Register a workspace connection for the Kernel connection layer. */
|
|
4330
|
+
async registerConnection(input) {
|
|
4331
|
+
return this.callMcp("gtm_connection_register", {
|
|
4332
|
+
connection_kind: input.connectionKind,
|
|
4333
|
+
name: input.name,
|
|
4334
|
+
server_url: input.serverUrl,
|
|
4335
|
+
auth_type: input.authType,
|
|
4336
|
+
auth_config: input.authConfig,
|
|
4337
|
+
enabled_tools: input.enabledTools,
|
|
4338
|
+
preset_id: input.presetId,
|
|
4339
|
+
vendor_id: input.vendorId,
|
|
4340
|
+
service_category: input.serviceCategory,
|
|
4341
|
+
connection_type: input.connectionType,
|
|
4342
|
+
status: input.status,
|
|
4343
|
+
metadata: input.metadata
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4346
|
+
/** Create a reusable integration recipe for BYO providers such as Clay webhooks, Apollo, AI Ark, Octave, or Airbyte. */
|
|
4347
|
+
async createIntegrationRecipe(input) {
|
|
4348
|
+
return this.callMcp("gtm_integration_recipe_create", {
|
|
4349
|
+
provider_id: input.providerId,
|
|
4350
|
+
provider_name: input.providerName,
|
|
4351
|
+
description: input.description,
|
|
4352
|
+
layer_capabilities: input.layerCapabilities,
|
|
4353
|
+
invocation_type: input.invocationType,
|
|
4354
|
+
auth_strategy: input.authStrategy,
|
|
4355
|
+
workspace_integration_id: input.workspaceIntegrationId,
|
|
4356
|
+
workspace_mcp_server_id: input.workspaceMcpServerId,
|
|
4357
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
4358
|
+
endpoint_url: input.endpointUrl,
|
|
4359
|
+
http_method: input.httpMethod,
|
|
4360
|
+
request_template: input.requestTemplate,
|
|
4361
|
+
response_mapping: input.responseMapping,
|
|
4362
|
+
input_schema: input.inputSchema,
|
|
4363
|
+
output_schema: input.outputSchema,
|
|
4364
|
+
readiness: input.readiness,
|
|
4365
|
+
metadata: input.metadata,
|
|
4366
|
+
status: input.status
|
|
4367
|
+
});
|
|
4368
|
+
}
|
|
4369
|
+
/** Set a workspace or campaign provider route for one GTM layer. */
|
|
4370
|
+
async setLayerRoute(input) {
|
|
4371
|
+
return this.callMcp("gtm_layer_route_set", {
|
|
4372
|
+
layer: input.layer,
|
|
4373
|
+
provider_id: input.providerId,
|
|
4374
|
+
campaign_id: input.campaignId,
|
|
4375
|
+
recipe_id: input.recipeId,
|
|
4376
|
+
priority: input.priority,
|
|
4377
|
+
use_signaliz_fallback: input.useSignalizFallback,
|
|
4378
|
+
route_config: input.routeConfig,
|
|
4379
|
+
status: input.status
|
|
4380
|
+
});
|
|
4381
|
+
}
|
|
4382
|
+
/** Get effective layer routes, including Signaliz fallback availability. */
|
|
4383
|
+
async getLayerRoutes(options = {}) {
|
|
4384
|
+
return this.callMcp("gtm_layer_routes_get", {
|
|
4385
|
+
campaign_id: options.campaignId,
|
|
4386
|
+
layer: options.layer
|
|
4387
|
+
});
|
|
4388
|
+
}
|
|
4389
|
+
/** Preview one effective layer route before external delivery or provider execution. */
|
|
4390
|
+
async previewLayerRoute(input) {
|
|
4391
|
+
return this.callMcp("gtm_layer_route_preview", {
|
|
4392
|
+
layer: input.layer,
|
|
4393
|
+
campaign_id: input.campaignId,
|
|
4394
|
+
sample_records: input.sampleRecords,
|
|
4395
|
+
context: input.context
|
|
4396
|
+
});
|
|
4397
|
+
}
|
|
4398
|
+
/** List Nango-backed action tools for a workspace connection without executing them. */
|
|
4399
|
+
async listNangoTools(options = {}) {
|
|
4400
|
+
return this.callMcp("nango_mcp_tools_list", {
|
|
4401
|
+
workspace_connection_id: options.workspaceConnectionId,
|
|
4402
|
+
connection_id: options.connectionId,
|
|
4403
|
+
provider_config_key: options.providerConfigKey,
|
|
4404
|
+
integration_id: options.integrationId,
|
|
4405
|
+
nango_connection_id: options.nangoConnectionId,
|
|
4406
|
+
format: options.format,
|
|
4407
|
+
include_raw: options.includeRaw
|
|
4408
|
+
});
|
|
4409
|
+
}
|
|
4410
|
+
/** Dry-run or execute a Nango-backed action tool through the approval-aware MCP bridge. */
|
|
4411
|
+
async callNangoTool(input) {
|
|
4412
|
+
return this.callMcp("nango_mcp_tool_call", {
|
|
4413
|
+
workspace_connection_id: input.workspaceConnectionId,
|
|
4414
|
+
connection_id: input.connectionId,
|
|
4415
|
+
provider_config_key: input.providerConfigKey,
|
|
4416
|
+
integration_id: input.integrationId,
|
|
4417
|
+
nango_connection_id: input.nangoConnectionId,
|
|
4418
|
+
action_name: input.actionName,
|
|
4419
|
+
tool_name: input.toolName,
|
|
4420
|
+
input: input.input,
|
|
4421
|
+
async: input.async,
|
|
4422
|
+
max_retries: input.maxRetries,
|
|
4423
|
+
dry_run: input.dryRun,
|
|
4424
|
+
confirm: input.confirm,
|
|
4425
|
+
confirm_write: input.confirmWrite
|
|
4426
|
+
});
|
|
4427
|
+
}
|
|
4428
|
+
/** Poll an async Nango action result by action id or status URL. */
|
|
4429
|
+
async getNangoActionResult(input) {
|
|
4430
|
+
return this.callMcp("nango_mcp_action_result_get", {
|
|
4431
|
+
action_id: input.actionId,
|
|
4432
|
+
status_url: input.statusUrl
|
|
4433
|
+
});
|
|
4434
|
+
}
|
|
4435
|
+
/** Deliver approved campaign-layer records to a webhook recipe, starting with Clay-style webhooks. */
|
|
4436
|
+
async deliverWebhook(input) {
|
|
4437
|
+
return this.callMcp("gtm_webhook_deliver", {
|
|
4438
|
+
recipe_id: input.recipeId,
|
|
4439
|
+
campaign_id: input.campaignId,
|
|
4440
|
+
layer: input.layer,
|
|
4441
|
+
records: input.records,
|
|
4442
|
+
context: input.context,
|
|
4443
|
+
idempotency_key: input.idempotencyKey
|
|
4444
|
+
});
|
|
4445
|
+
}
|
|
4446
|
+
async callMcp(tool, args) {
|
|
4447
|
+
return this.client.mcp("tools/call", { name: tool, arguments: compact2(args) });
|
|
4448
|
+
}
|
|
4449
|
+
};
|
|
4450
|
+
function campaignCreateArgs(input) {
|
|
4451
|
+
return {
|
|
4452
|
+
name: input.name,
|
|
4453
|
+
description: input.description,
|
|
4454
|
+
source: input.source,
|
|
4455
|
+
status: input.status,
|
|
4456
|
+
campaign_build_id: input.campaignBuildId,
|
|
4457
|
+
campaign_builder_job_id: input.campaignBuilderJobId,
|
|
4458
|
+
routine_id: input.routineId,
|
|
4459
|
+
target_icp: input.targetIcp,
|
|
4460
|
+
sequences: input.sequences,
|
|
4461
|
+
lead_list_refs: input.leadListRefs,
|
|
4462
|
+
send_config: input.sendConfig,
|
|
4463
|
+
provider_links: input.providerLinks?.map(providerLinkArgs),
|
|
4464
|
+
brain_config: input.brainConfig,
|
|
4465
|
+
metadata: input.metadata,
|
|
4466
|
+
log: input.log ? campaignLogArgs(input.log) : void 0
|
|
4467
|
+
};
|
|
4468
|
+
}
|
|
4469
|
+
function campaignHistoryImportCampaignArgs(input) {
|
|
4470
|
+
return {
|
|
4471
|
+
campaign_id: input.campaignId,
|
|
4472
|
+
idempotency_key: input.idempotencyKey,
|
|
4473
|
+
name: input.name,
|
|
4474
|
+
description: input.description,
|
|
4475
|
+
source: input.source,
|
|
4476
|
+
status: input.status,
|
|
4477
|
+
campaign_build_id: input.campaignBuildId,
|
|
4478
|
+
campaign_builder_job_id: input.campaignBuilderJobId,
|
|
4479
|
+
routine_id: input.routineId,
|
|
4480
|
+
target_icp: input.targetIcp,
|
|
4481
|
+
sequences: input.sequences,
|
|
4482
|
+
lead_list_refs: input.leadListRefs,
|
|
4483
|
+
send_config: input.sendConfig,
|
|
4484
|
+
performance_metrics: input.performanceMetrics,
|
|
4485
|
+
brain_config: input.brainConfig,
|
|
4486
|
+
memory_summary: input.memorySummary,
|
|
4487
|
+
metadata: input.metadata,
|
|
4488
|
+
provider_links: input.providerLinks?.map(providerLinkArgs),
|
|
4489
|
+
feedback_events: input.feedbackEvents,
|
|
4490
|
+
memory_items: input.memoryItems?.map(campaignHistoryMemoryArgs),
|
|
4491
|
+
started_at: input.startedAt,
|
|
4492
|
+
completed_at: input.completedAt,
|
|
4493
|
+
summary: input.summary,
|
|
4494
|
+
memory_summary_text: input.memorySummaryText
|
|
4495
|
+
};
|
|
4496
|
+
}
|
|
4497
|
+
function campaignHistoryMemoryArgs(input) {
|
|
4498
|
+
return {
|
|
4499
|
+
idempotency_key: input.idempotencyKey,
|
|
4500
|
+
memory_type: input.memoryType,
|
|
4501
|
+
title: input.title,
|
|
4502
|
+
content: input.content,
|
|
4503
|
+
keywords: input.keywords,
|
|
4504
|
+
dimensions: input.dimensions,
|
|
4505
|
+
outcome_type: input.outcomeType,
|
|
4506
|
+
outcome_value: input.outcomeValue,
|
|
4507
|
+
sample_size: input.sampleSize,
|
|
4508
|
+
confidence: input.confidence,
|
|
4509
|
+
shareable: input.shareable,
|
|
4510
|
+
redaction_state: input.redactionState,
|
|
4511
|
+
metadata: input.metadata,
|
|
4512
|
+
recency_at: input.recencyAt
|
|
4513
|
+
};
|
|
4514
|
+
}
|
|
4515
|
+
function campaignUpdateArgs(input) {
|
|
4516
|
+
return {
|
|
4517
|
+
campaign_id: input.campaignId,
|
|
4518
|
+
name: input.name,
|
|
4519
|
+
description: input.description,
|
|
4520
|
+
status: input.status,
|
|
4521
|
+
target_icp: input.targetIcp,
|
|
4522
|
+
sequences: input.sequences,
|
|
4523
|
+
lead_list_refs: input.leadListRefs,
|
|
4524
|
+
send_config: input.sendConfig,
|
|
4525
|
+
performance_metrics: input.performanceMetrics,
|
|
4526
|
+
brain_config: input.brainConfig,
|
|
4527
|
+
memory_summary: input.memorySummary,
|
|
4528
|
+
metadata: input.metadata,
|
|
4529
|
+
provider_links: input.providerLinks?.map(providerLinkArgs),
|
|
4530
|
+
log: input.log ? campaignLogArgs(input.log) : void 0
|
|
4531
|
+
};
|
|
4532
|
+
}
|
|
4533
|
+
function campaignLogArgs(input) {
|
|
4534
|
+
return {
|
|
4535
|
+
campaign_id: input.campaignId,
|
|
4536
|
+
actor_type: input.actorType,
|
|
4537
|
+
actor_id: input.actorId,
|
|
4538
|
+
action: input.action,
|
|
4539
|
+
rationale: input.rationale,
|
|
4540
|
+
payload: input.payload,
|
|
4541
|
+
idempotency_key: input.idempotencyKey
|
|
4542
|
+
};
|
|
4543
|
+
}
|
|
4544
|
+
function providerLinkArgs(input) {
|
|
4545
|
+
return {
|
|
4546
|
+
provider: input.provider,
|
|
4547
|
+
provider_campaign_id: input.providerCampaignId,
|
|
4548
|
+
integration_id: input.integrationId,
|
|
4549
|
+
provider_workspace_id: input.providerWorkspaceId,
|
|
4550
|
+
provider_account_id: input.providerAccountId,
|
|
4551
|
+
status: input.status,
|
|
4552
|
+
metadata: input.metadata
|
|
4553
|
+
};
|
|
4554
|
+
}
|
|
4555
|
+
function compact2(value) {
|
|
4556
|
+
if (Array.isArray(value)) return value.map((item) => compact2(item)).filter((item) => item !== void 0);
|
|
4557
|
+
if (!value || typeof value !== "object") return value;
|
|
4558
|
+
const out = {};
|
|
4559
|
+
for (const [key, child] of Object.entries(value)) {
|
|
4560
|
+
if (child === void 0) continue;
|
|
4561
|
+
const compacted = compact2(child);
|
|
4562
|
+
if (compacted === void 0) continue;
|
|
4563
|
+
out[key] = compacted;
|
|
4564
|
+
}
|
|
4565
|
+
return out;
|
|
4566
|
+
}
|
|
4567
|
+
|
|
4568
|
+
// src/index.ts
|
|
4569
|
+
function inferMcpToolCategory(toolName) {
|
|
4570
|
+
if (typeof toolName !== "string" || !toolName) return void 0;
|
|
4571
|
+
if (toolName.startsWith("ops_") || toolName === "get_ops_readiness" || toolName === "get_gtm_ops_readiness" || toolName.startsWith("gtm_") || [
|
|
4572
|
+
"list_routines",
|
|
4573
|
+
"create_routine",
|
|
4574
|
+
"update_routine",
|
|
4575
|
+
"run_routine_now",
|
|
4576
|
+
"get_routine",
|
|
4577
|
+
"get_routine_ticks",
|
|
4578
|
+
"get_tick_items",
|
|
4579
|
+
"get_last_tick_items",
|
|
4580
|
+
"chain_routines",
|
|
4581
|
+
"get_chain_status",
|
|
4582
|
+
"launch_campaign",
|
|
4583
|
+
"quickstart_gtm_book",
|
|
4584
|
+
"list_campaigns",
|
|
4585
|
+
"campaign_performance",
|
|
4586
|
+
"tune_campaign",
|
|
4587
|
+
"emit_event",
|
|
4588
|
+
"approvals_list",
|
|
4589
|
+
"list_output_sinks",
|
|
4590
|
+
"create_output_sink",
|
|
4591
|
+
"update_output_sink",
|
|
4592
|
+
"delete_output_sink",
|
|
4593
|
+
"attach_sink_to_routine"
|
|
4594
|
+
].includes(toolName)) {
|
|
4595
|
+
return "ops";
|
|
4596
|
+
}
|
|
4597
|
+
if ([
|
|
4598
|
+
"find_emails_with_verification",
|
|
4599
|
+
"verify_email",
|
|
4600
|
+
"enrich_company_signals",
|
|
4601
|
+
"company_intelligence",
|
|
4602
|
+
"find_contacts_with_email",
|
|
4603
|
+
"execute_primitive"
|
|
4604
|
+
].includes(toolName)) {
|
|
4605
|
+
return "enrichment";
|
|
4606
|
+
}
|
|
4607
|
+
if (toolName.includes("icp")) return "icp";
|
|
4608
|
+
if (toolName.startsWith("ai_clean_")) return "data_cleaning";
|
|
4609
|
+
if (toolName.includes("system") || toolName.includes("workflow")) return "automation";
|
|
4610
|
+
if (toolName.includes("agent") || toolName.includes("platform_health") || toolName === "discover_capabilities") return "observability";
|
|
4611
|
+
return void 0;
|
|
4612
|
+
}
|
|
4613
|
+
function asRecord3(value) {
|
|
4614
|
+
return value && typeof value === "object" ? value : void 0;
|
|
4615
|
+
}
|
|
4616
|
+
function asStringArray(value) {
|
|
4617
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : void 0;
|
|
4618
|
+
}
|
|
4619
|
+
function asObjectSchema(value) {
|
|
4620
|
+
return asRecord3(value);
|
|
4621
|
+
}
|
|
4622
|
+
var Signaliz = class {
|
|
4623
|
+
constructor(config) {
|
|
4624
|
+
this.client = new HttpClient(config);
|
|
4625
|
+
this.emails = new Emails(this.client);
|
|
4626
|
+
this.signals = new Signals(this.client);
|
|
4627
|
+
this.systems = new Systems(this.client);
|
|
4628
|
+
this.runs = new Runs(this.client);
|
|
4629
|
+
this.http = new Http(this.client);
|
|
4630
|
+
this.campaigns = new Campaigns(this.client);
|
|
4631
|
+
this.campaignBuilderAgent = new CampaignBuilderAgent(this.client);
|
|
4632
|
+
this.icps = new Icps(this.client);
|
|
4633
|
+
this.leads = new Leads(this.client);
|
|
4634
|
+
this.ops = new Ops(this.client);
|
|
4635
|
+
this.ai = new Ai(this.client);
|
|
4636
|
+
this.gtm = new GtmKernel(this.client);
|
|
4637
|
+
}
|
|
4638
|
+
/** Get current workspace info including credits */
|
|
4639
|
+
async getWorkspace() {
|
|
4640
|
+
const data = await this.client.mcp("tools/call", {
|
|
4641
|
+
name: "get_workspace",
|
|
4642
|
+
arguments: {}
|
|
4643
|
+
});
|
|
4644
|
+
return {
|
|
4645
|
+
id: data.workspace_id ?? data.id,
|
|
4646
|
+
name: data.workspace_name ?? data.name ?? "Unknown",
|
|
4647
|
+
creditsRemaining: data.credits_remaining ?? data.credit_balance ?? data.credits ?? 0,
|
|
4648
|
+
plan: data.plan ?? data.plan_name ?? "unknown"
|
|
4649
|
+
};
|
|
4650
|
+
}
|
|
4651
|
+
/** Get MCP platform health and recent latency/error-rate signals */
|
|
4652
|
+
async getPlatformHealth() {
|
|
4653
|
+
const data = await this.client.mcp("tools/call", {
|
|
4654
|
+
name: "get_platform_health",
|
|
4655
|
+
arguments: {}
|
|
4656
|
+
});
|
|
4657
|
+
return {
|
|
4658
|
+
status: data.status ?? "unknown",
|
|
4659
|
+
period: data.period,
|
|
4660
|
+
totalRequests: data.total_requests ?? data.totalRequests ?? 0,
|
|
4661
|
+
errorRate: data.error_rate ?? data.errorRate ?? "0%",
|
|
4662
|
+
latency: {
|
|
4663
|
+
p50: data.latency?.p50 ?? 0,
|
|
4664
|
+
p95: data.latency?.p95 ?? 0,
|
|
4665
|
+
p99: data.latency?.p99 ?? 0,
|
|
4666
|
+
sampleCount: data.latency?.sample_count ?? data.latency?.sampleCount,
|
|
4667
|
+
source: data.latency?.source
|
|
4668
|
+
}
|
|
4669
|
+
};
|
|
4670
|
+
}
|
|
4671
|
+
/** Alias for getPlatformHealth, useful in health-check scripts */
|
|
4672
|
+
async health() {
|
|
4673
|
+
return this.getPlatformHealth();
|
|
4674
|
+
}
|
|
4675
|
+
/** List all available MCP tools */
|
|
4676
|
+
async listTools() {
|
|
4677
|
+
const data = await this.client.mcp("tools/list", {});
|
|
4678
|
+
const tools = data?.tools ?? data ?? [];
|
|
4679
|
+
return tools.map((t) => ({
|
|
4680
|
+
name: typeof t.name === "string" ? t.name : "",
|
|
4681
|
+
description: String(t.description ?? "").slice(0, 120),
|
|
4682
|
+
category: typeof t.annotations?.category === "string" ? t.annotations.category : inferMcpToolCategory(t.name),
|
|
4683
|
+
costCredits: typeof t.annotations?.cost_credits === "number" ? t.annotations.cost_credits : void 0,
|
|
4684
|
+
contractVersion: typeof (t.annotations?.contract_version ?? t.annotations?.contract?.contract_version) === "string" ? t.annotations?.contract_version ?? t.annotations?.contract?.contract_version : void 0,
|
|
4685
|
+
permissionLevel: typeof (t.annotations?.permission_level ?? t.annotations?.contract?.permission_level) === "string" ? t.annotations?.permission_level ?? t.annotations?.contract?.permission_level : void 0,
|
|
4686
|
+
authScopes: asStringArray(t.annotations?.auth_scopes ?? t.annotations?.contract?.auth_scopes),
|
|
4687
|
+
idempotent: typeof (t.annotations?.idempotentHint ?? t.annotations?.idempotent ?? t.annotations?.contract?.idempotent) === "boolean" ? t.annotations?.idempotentHint ?? t.annotations?.idempotent ?? t.annotations?.contract?.idempotent : void 0,
|
|
4688
|
+
destructive: typeof (t.annotations?.destructiveHint ?? t.annotations?.destructive ?? t.annotations?.contract?.destructive) === "boolean" ? t.annotations?.destructiveHint ?? t.annotations?.destructive ?? t.annotations?.contract?.destructive : void 0,
|
|
4689
|
+
retryable: typeof (t.annotations?.retryable ?? t.annotations?.contract?.retryable) === "boolean" ? t.annotations?.retryable ?? t.annotations?.contract?.retryable : void 0,
|
|
4690
|
+
rateLimitKey: typeof (t.annotations?.rate_limit_key ?? t.annotations?.contract?.rate_limit_key) === "string" ? t.annotations?.rate_limit_key ?? t.annotations?.contract?.rate_limit_key : void 0,
|
|
4691
|
+
observability: asRecord3(t.annotations?.observability ?? t.annotations?.contract?.observability),
|
|
4692
|
+
inputSchema: asObjectSchema(t.inputSchema ?? t.input_schema ?? t.annotations?.contract?.input_schema),
|
|
4693
|
+
outputSchema: asObjectSchema(t.outputSchema ?? t.output_schema ?? t.annotations?.contract?.output_schema),
|
|
4694
|
+
annotations: asRecord3(t.annotations)
|
|
4695
|
+
}));
|
|
4696
|
+
}
|
|
4697
|
+
/** Discover tools by natural language query */
|
|
4698
|
+
async discover(query, category) {
|
|
4699
|
+
const data = await this.client.mcp("tools/call", {
|
|
4700
|
+
name: "discover_capabilities",
|
|
4701
|
+
arguments: { query, category }
|
|
4702
|
+
});
|
|
4703
|
+
return (data.matches ?? []).map((m) => ({
|
|
4704
|
+
name: m.tool,
|
|
4705
|
+
description: m.description,
|
|
4706
|
+
category: m.category,
|
|
4707
|
+
costCredits: m.cost_credits,
|
|
4708
|
+
contractVersion: m.contract_version ?? m.contract?.contract_version,
|
|
4709
|
+
permissionLevel: m.permission_level ?? m.contract?.permission_level,
|
|
4710
|
+
authScopes: m.auth_scopes ?? m.contract?.auth_scopes,
|
|
4711
|
+
idempotent: m.idempotent ?? m.contract?.idempotent,
|
|
4712
|
+
destructive: m.destructive ?? m.contract?.destructive,
|
|
4713
|
+
retryable: m.retryable ?? m.contract?.retryable,
|
|
4714
|
+
rateLimitKey: m.rate_limit_key ?? m.contract?.rate_limit_key,
|
|
4715
|
+
observability: m.observability ?? m.contract?.observability,
|
|
4716
|
+
inputSchema: m.input_schema ?? m.inputSchema ?? m.contract?.input_schema,
|
|
4717
|
+
outputSchema: m.output_schema ?? m.outputSchema ?? m.contract?.output_schema,
|
|
4718
|
+
annotations: m.annotations
|
|
4719
|
+
}));
|
|
4720
|
+
}
|
|
4721
|
+
};
|
|
4722
|
+
|
|
4723
|
+
// src/mcp-config.ts
|
|
4724
|
+
function detectAgent() {
|
|
4725
|
+
const home = os.homedir();
|
|
4726
|
+
const claudePath = path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
4727
|
+
if (fs.existsSync(path.dirname(claudePath))) {
|
|
4728
|
+
return { name: "Claude Desktop", configPath: claudePath, wrapperKey: "mcpServers" };
|
|
4729
|
+
}
|
|
4730
|
+
const cursorPath = path.join(process.cwd(), ".cursor", "mcp.json");
|
|
4731
|
+
if (fs.existsSync(path.dirname(cursorPath))) {
|
|
4732
|
+
return { name: "Cursor", configPath: cursorPath, wrapperKey: "mcpServers" };
|
|
4733
|
+
}
|
|
4734
|
+
return {
|
|
4735
|
+
name: "generic MCP client",
|
|
4736
|
+
configPath: path.join(process.cwd(), ".mcp", "config.json"),
|
|
4737
|
+
wrapperKey: "mcpServers"
|
|
4738
|
+
};
|
|
4739
|
+
}
|
|
4740
|
+
function prompt(question) {
|
|
4741
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
4742
|
+
return new Promise((resolve) => {
|
|
4743
|
+
rl.question(question, (answer) => {
|
|
4744
|
+
rl.close();
|
|
4745
|
+
resolve(answer.trim());
|
|
4746
|
+
});
|
|
4747
|
+
});
|
|
4748
|
+
}
|
|
4749
|
+
function generateMcpConfig(apiKey) {
|
|
4750
|
+
return {
|
|
4751
|
+
signaliz: {
|
|
4752
|
+
command: "npx",
|
|
4753
|
+
args: ["-y", "@signaliz/mcp-server@latest"],
|
|
4754
|
+
env: {
|
|
4755
|
+
SIGNALIZ_API_KEY: apiKey,
|
|
4756
|
+
SIGNALIZ_API_URL: "https://api.signaliz.com/functions/v1"
|
|
4757
|
+
}
|
|
603
4758
|
}
|
|
604
4759
|
};
|
|
605
4760
|
}
|