@agent-nexus/cli 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +693 -15
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -166,7 +166,7 @@ var require_package = __commonJS({
|
|
|
166
166
|
"package.json"(exports2, module2) {
|
|
167
167
|
module2.exports = {
|
|
168
168
|
name: "@agent-nexus/cli",
|
|
169
|
-
version: "0.1.
|
|
169
|
+
version: "0.1.14",
|
|
170
170
|
description: "Official CLI for the Nexus AI agent platform.",
|
|
171
171
|
license: "MIT",
|
|
172
172
|
keywords: [
|
|
@@ -778,10 +778,7 @@ var ChannelsResource = class extends BaseResource {
|
|
|
778
778
|
return this.http.request("POST", "/channels/whatsapp-templates", { body });
|
|
779
779
|
}
|
|
780
780
|
async getWhatsAppTemplate(templateId) {
|
|
781
|
-
return this.http.request(
|
|
782
|
-
"GET",
|
|
783
|
-
`/channels/whatsapp-templates/${templateId}`
|
|
784
|
-
);
|
|
781
|
+
return this.http.request("GET", `/channels/whatsapp-templates/${templateId}`);
|
|
785
782
|
}
|
|
786
783
|
async deleteWhatsAppTemplate(templateId) {
|
|
787
784
|
return this.http.request(
|
|
@@ -790,19 +787,34 @@ var ChannelsResource = class extends BaseResource {
|
|
|
790
787
|
);
|
|
791
788
|
}
|
|
792
789
|
async listTemplateApprovals(params) {
|
|
790
|
+
return this.http.request("GET", "/channels/whatsapp-templates/approvals", {
|
|
791
|
+
query: params
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
async submitTemplateApproval(body) {
|
|
793
795
|
return this.http.request(
|
|
794
|
-
"
|
|
796
|
+
"POST",
|
|
795
797
|
"/channels/whatsapp-templates/approvals",
|
|
796
|
-
{
|
|
798
|
+
{ body }
|
|
797
799
|
);
|
|
798
800
|
}
|
|
799
|
-
|
|
801
|
+
// ===========================================================================
|
|
802
|
+
// WhatsApp Template Test-Send
|
|
803
|
+
// ===========================================================================
|
|
804
|
+
async testSendWhatsAppTemplate(templateId, body) {
|
|
800
805
|
return this.http.request(
|
|
801
806
|
"POST",
|
|
802
|
-
|
|
807
|
+
`/channels/whatsapp-templates/${templateId}/test-send`,
|
|
803
808
|
{ body }
|
|
804
809
|
);
|
|
805
810
|
}
|
|
811
|
+
async getTestSendStatus(templateId, messageSid, params) {
|
|
812
|
+
return this.http.request(
|
|
813
|
+
"GET",
|
|
814
|
+
`/channels/whatsapp-templates/${templateId}/test-send/${messageSid}/status`,
|
|
815
|
+
{ query: params }
|
|
816
|
+
);
|
|
817
|
+
}
|
|
806
818
|
};
|
|
807
819
|
var CloudImportsResource = class extends BaseResource {
|
|
808
820
|
// Google Drive
|
|
@@ -2061,6 +2073,64 @@ var ToolDiscoveryResource = class extends BaseResource {
|
|
|
2061
2073
|
);
|
|
2062
2074
|
}
|
|
2063
2075
|
};
|
|
2076
|
+
var TracingResource = class extends BaseResource {
|
|
2077
|
+
// ── Traces ──────────────────────────────────────────────────────────────
|
|
2078
|
+
async listTraces(params) {
|
|
2079
|
+
const { data, meta } = await this.http.requestWithMeta(
|
|
2080
|
+
"GET",
|
|
2081
|
+
"/tracing/traces",
|
|
2082
|
+
{ query: params }
|
|
2083
|
+
);
|
|
2084
|
+
return { data, meta };
|
|
2085
|
+
}
|
|
2086
|
+
async getTrace(traceId) {
|
|
2087
|
+
return this.http.request("GET", `/tracing/traces/${traceId}`);
|
|
2088
|
+
}
|
|
2089
|
+
async deleteTrace(traceId) {
|
|
2090
|
+
return this.http.request("DELETE", `/tracing/traces/${traceId}`);
|
|
2091
|
+
}
|
|
2092
|
+
// ── Generations ─────────────────────────────────────────────────────────
|
|
2093
|
+
async listGenerations(params) {
|
|
2094
|
+
const { data, meta } = await this.http.requestWithMeta(
|
|
2095
|
+
"GET",
|
|
2096
|
+
"/tracing/generations",
|
|
2097
|
+
{ query: params }
|
|
2098
|
+
);
|
|
2099
|
+
return { data, meta };
|
|
2100
|
+
}
|
|
2101
|
+
async getGeneration(generationId) {
|
|
2102
|
+
return this.http.request("GET", `/tracing/generations/${generationId}`);
|
|
2103
|
+
}
|
|
2104
|
+
// ── Models ──────────────────────────────────────────────────────────────
|
|
2105
|
+
async listModels() {
|
|
2106
|
+
return this.http.request("GET", "/tracing/models");
|
|
2107
|
+
}
|
|
2108
|
+
// ── Analytics ───────────────────────────────────────────────────────────
|
|
2109
|
+
async getSummary(params) {
|
|
2110
|
+
return this.http.request("GET", "/tracing/analytics/summary", {
|
|
2111
|
+
query: params
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
async getCostBreakdown(params) {
|
|
2115
|
+
return this.http.request("GET", "/tracing/analytics/cost-breakdown", {
|
|
2116
|
+
query: params
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
async getTimeline(params) {
|
|
2120
|
+
return this.http.request("GET", "/tracing/analytics/timeline", {
|
|
2121
|
+
query: params
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
// ── Export ──────────────────────────────────────────────────────────────
|
|
2125
|
+
async exportTrace(traceId, params) {
|
|
2126
|
+
return this.http.request("POST", `/tracing/traces/${traceId}/export`, {
|
|
2127
|
+
body: params
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
async bulkExport(params) {
|
|
2131
|
+
return this.http.request("POST", "/tracing/export", { body: params });
|
|
2132
|
+
}
|
|
2133
|
+
};
|
|
2064
2134
|
var WorkflowExecutionsResource = class extends BaseResource {
|
|
2065
2135
|
async list(params) {
|
|
2066
2136
|
const { data, meta } = await this.http.requestWithMeta("GET", "/workflows/executions", {
|
|
@@ -2533,6 +2603,7 @@ var NexusClient = class {
|
|
|
2533
2603
|
this.phoneNumbers = new PhoneNumbersResource(http);
|
|
2534
2604
|
this.tickets = new TicketsResource(http);
|
|
2535
2605
|
this.channels = new ChannelsResource(http);
|
|
2606
|
+
this.tracing = new TracingResource(http);
|
|
2536
2607
|
}
|
|
2537
2608
|
};
|
|
2538
2609
|
|
|
@@ -3663,6 +3734,41 @@ function openUrl(url) {
|
|
|
3663
3734
|
var import_node_child_process2 = require("child_process");
|
|
3664
3735
|
var import_node_fs2 = require("fs");
|
|
3665
3736
|
init_output();
|
|
3737
|
+
var VARIABLE_PATTERN = /\{\{\d+\}\}/g;
|
|
3738
|
+
function warnIfHighVariableDensity(types) {
|
|
3739
|
+
let warned = false;
|
|
3740
|
+
function checkField(text, fieldLabel) {
|
|
3741
|
+
const matches = text.match(VARIABLE_PATTERN) ?? [];
|
|
3742
|
+
if (matches.length === 0) return;
|
|
3743
|
+
const variableCharsLength = matches.reduce((sum, m) => sum + m.length, 0);
|
|
3744
|
+
const staticLength = text.length - variableCharsLength;
|
|
3745
|
+
if (staticLength < matches.length * 3) {
|
|
3746
|
+
console.warn(
|
|
3747
|
+
color.yellow("\u26A0 Warning:") + ` ${fieldLabel} has very high variable density (${staticLength} static chars, ${matches.length} variable(s)). Meta may reject this with "too many variables for its length."`
|
|
3748
|
+
);
|
|
3749
|
+
warned = true;
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
for (const [typeKey, typeValue] of Object.entries(types)) {
|
|
3753
|
+
if (!typeValue || typeof typeValue !== "object") continue;
|
|
3754
|
+
const tv = typeValue;
|
|
3755
|
+
if (typeof tv.body === "string") checkField(tv.body, `${typeKey} body`);
|
|
3756
|
+
if (typeof tv.title === "string") checkField(tv.title, `${typeKey} title`);
|
|
3757
|
+
if (typeof tv.subtitle === "string") checkField(tv.subtitle, `${typeKey} subtitle`);
|
|
3758
|
+
if (Array.isArray(tv.cards)) {
|
|
3759
|
+
tv.cards.forEach((card, i) => {
|
|
3760
|
+
if (typeof card?.body === "string") checkField(card.body, `${typeKey} card[${i}] body`);
|
|
3761
|
+
if (typeof card?.title === "string") checkField(card.title, `${typeKey} card[${i}] title`);
|
|
3762
|
+
});
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
if (warned) {
|
|
3766
|
+
console.warn(
|
|
3767
|
+
color.yellow(" Tip:") + " Add more descriptive static text around {{N}} placeholders to avoid Meta rejection.\n"
|
|
3768
|
+
);
|
|
3769
|
+
}
|
|
3770
|
+
return warned;
|
|
3771
|
+
}
|
|
3666
3772
|
function openUrl2(url) {
|
|
3667
3773
|
const platform = process.platform;
|
|
3668
3774
|
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
@@ -3914,6 +4020,7 @@ Examples:
|
|
|
3914
4020
|
return;
|
|
3915
4021
|
}
|
|
3916
4022
|
}
|
|
4023
|
+
warnIfHighVariableDensity(types);
|
|
3917
4024
|
const client = createClient(program2.optsWithGlobals());
|
|
3918
4025
|
const result = await client.channels.createWhatsAppTemplate({
|
|
3919
4026
|
connectionId: opts.connectionId,
|
|
@@ -3945,6 +4052,44 @@ Examples:
|
|
|
3945
4052
|
{ key: "status", label: "Status" }
|
|
3946
4053
|
]);
|
|
3947
4054
|
printSuccess("Template submitted for Meta approval.");
|
|
4055
|
+
const pollMaxMs = 3e4;
|
|
4056
|
+
const pollIntervalMs = 5e3;
|
|
4057
|
+
const pollStart = Date.now();
|
|
4058
|
+
let resolved = false;
|
|
4059
|
+
console.log("Checking approval status...");
|
|
4060
|
+
while (Date.now() - pollStart < pollMaxMs) {
|
|
4061
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
4062
|
+
try {
|
|
4063
|
+
const approvals = await client.channels.listTemplateApprovals({
|
|
4064
|
+
connectionId: opts.connectionId
|
|
4065
|
+
});
|
|
4066
|
+
const approvalsArr = approvals?.data ?? approvals;
|
|
4067
|
+
const items = Array.isArray(approvalsArr) ? approvalsArr : [approvalsArr];
|
|
4068
|
+
const match = items.find((a) => a.sid === data.id);
|
|
4069
|
+
if (match?.approvalRequests?.status) {
|
|
4070
|
+
const status = match.approvalRequests.status;
|
|
4071
|
+
if (status === "rejected") {
|
|
4072
|
+
console.log(color.red(`\u2717 Template rejected by Meta: ${status}`));
|
|
4073
|
+
if (match.approvalRequests.rejection_reason) {
|
|
4074
|
+
console.log(` Reason: ${match.approvalRequests.rejection_reason}`);
|
|
4075
|
+
}
|
|
4076
|
+
resolved = true;
|
|
4077
|
+
process.exitCode = 1;
|
|
4078
|
+
break;
|
|
4079
|
+
} else if (status === "approved") {
|
|
4080
|
+
console.log(color.green(`\u2713 Template approved by Meta.`));
|
|
4081
|
+
resolved = true;
|
|
4082
|
+
break;
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
} catch {
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
if (!resolved) {
|
|
4089
|
+
console.log(
|
|
4090
|
+
`Status still pending. Check later: ${color.dim("nexus channel whatsapp-template approvals")}`
|
|
4091
|
+
);
|
|
4092
|
+
}
|
|
3948
4093
|
}
|
|
3949
4094
|
} catch (err) {
|
|
3950
4095
|
process.exitCode = handleError(err);
|
|
@@ -4069,6 +4214,83 @@ Next: Attach to deployment: ${color.dim("nexus deployment template attach <depId
|
|
|
4069
4214
|
process.exitCode = handleError(err);
|
|
4070
4215
|
}
|
|
4071
4216
|
});
|
|
4217
|
+
waTemplate.command("test-send").description(
|
|
4218
|
+
"Test-send a WhatsApp template to a phone number via the real Twilio/Meta pipeline"
|
|
4219
|
+
).requiredOption("--connection-id <id>", "Messaging connection ID").requiredOption("--template-id <id>", "Template ID (Twilio content SID)").requiredOption("--to <phone>", "Recipient phone number in E.164 format (e.g., +1234567890)").option("--variables <json>", `Template variables as JSON (e.g., '{"1": "Hello"}')`).option("--wait", "Poll delivery status until resolved (up to 2 minutes)").addHelpText(
|
|
4220
|
+
"after",
|
|
4221
|
+
`
|
|
4222
|
+
Examples:
|
|
4223
|
+
$ nexus channel whatsapp-template test-send --connection-id abc --template-id HX123 --to +1234567890
|
|
4224
|
+
$ nexus channel whatsapp-template test-send --connection-id abc --template-id HX123 --to +1234567890 --variables '{"1": "Sneakers"}' --wait`
|
|
4225
|
+
).action(async (opts) => {
|
|
4226
|
+
try {
|
|
4227
|
+
const client = createClient(program2.optsWithGlobals());
|
|
4228
|
+
let variables;
|
|
4229
|
+
if (opts.variables) {
|
|
4230
|
+
try {
|
|
4231
|
+
variables = JSON.parse(opts.variables);
|
|
4232
|
+
} catch {
|
|
4233
|
+
console.error(`Invalid JSON for --variables. Example: '{"1": "Hello"}'`);
|
|
4234
|
+
process.exitCode = 1;
|
|
4235
|
+
return;
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
const result = await client.channels.testSendWhatsAppTemplate(opts.templateId, {
|
|
4239
|
+
connectionId: opts.connectionId,
|
|
4240
|
+
to: opts.to,
|
|
4241
|
+
variables
|
|
4242
|
+
});
|
|
4243
|
+
const data = result?.data ?? result;
|
|
4244
|
+
printRecord(data, [
|
|
4245
|
+
{ key: "messageSid", label: "Message SID" },
|
|
4246
|
+
{ key: "status", label: "Status" },
|
|
4247
|
+
{ key: "to", label: "To" },
|
|
4248
|
+
{ key: "from", label: "From" },
|
|
4249
|
+
{ key: "sentAt", label: "Sent At" }
|
|
4250
|
+
]);
|
|
4251
|
+
printSuccess("Template test-send initiated.");
|
|
4252
|
+
if (opts.wait) {
|
|
4253
|
+
const maxWaitMs = 12e4;
|
|
4254
|
+
const intervalMs = 5e3;
|
|
4255
|
+
const startTime = Date.now();
|
|
4256
|
+
let lastStatus = data.status;
|
|
4257
|
+
console.log("Polling delivery status...");
|
|
4258
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
4259
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
4260
|
+
try {
|
|
4261
|
+
const statusResult = await client.channels.getTestSendStatus(
|
|
4262
|
+
opts.templateId,
|
|
4263
|
+
data.messageSid,
|
|
4264
|
+
{ connectionId: opts.connectionId }
|
|
4265
|
+
);
|
|
4266
|
+
const statusData = statusResult?.data ?? statusResult;
|
|
4267
|
+
lastStatus = statusData.status;
|
|
4268
|
+
if (["delivered", "read"].includes(lastStatus)) {
|
|
4269
|
+
console.log(color.green(`\u2713 Message ${lastStatus}.`));
|
|
4270
|
+
break;
|
|
4271
|
+
} else if (["failed", "undelivered"].includes(lastStatus)) {
|
|
4272
|
+
console.log(color.red(`\u2717 Message ${lastStatus}.`));
|
|
4273
|
+
if (statusData.errorCode) {
|
|
4274
|
+
console.log(
|
|
4275
|
+
` Error ${statusData.errorCode}: ${statusData.errorMessage ?? "Unknown error"}`
|
|
4276
|
+
);
|
|
4277
|
+
}
|
|
4278
|
+
process.exitCode = 1;
|
|
4279
|
+
break;
|
|
4280
|
+
}
|
|
4281
|
+
} catch {
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
if (!["delivered", "read", "failed", "undelivered"].includes(lastStatus)) {
|
|
4285
|
+
console.log(
|
|
4286
|
+
`Status still '${lastStatus}' after 2m. The message may still be in transit.`
|
|
4287
|
+
);
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
} catch (err) {
|
|
4291
|
+
process.exitCode = handleError(err);
|
|
4292
|
+
}
|
|
4293
|
+
});
|
|
4072
4294
|
}
|
|
4073
4295
|
|
|
4074
4296
|
// src/commands/collection.ts
|
|
@@ -4799,12 +5021,25 @@ Examples:
|
|
|
4799
5021
|
process.exitCode = handleError(err);
|
|
4800
5022
|
}
|
|
4801
5023
|
});
|
|
4802
|
-
depTemplate.command("attach").description("Attach a WhatsApp template to a deployment").argument("<deploymentId>", "Deployment ID").requiredOption("--template-id <id>", "Template ID (Twilio SID)").requiredOption("--name <name>", "Display name for this template").requiredOption("--description <text>", "Description of what this template does").option(
|
|
5024
|
+
depTemplate.command("attach").description("Attach a WhatsApp template to a deployment").argument("<deploymentId>", "Deployment ID").requiredOption("--template-id <id>", "Template ID (Twilio SID)").requiredOption("--name <name>", "Display name for this template").requiredOption("--description <text>", "Description of what this template does").option(
|
|
5025
|
+
"--variables <json>",
|
|
5026
|
+
'Variables JSON: {"1":{"description":"Name","isBodyVariable":true}}'
|
|
5027
|
+
).option("--type <type>", "Template type: template, card, or carousel", "template").option("--enable-multi-language", "Enable multi-language support").option("--enable-dynamic-size", "Enable dynamic carousel size (carousel only)").option(
|
|
5028
|
+
"--carousel-template-group <json>",
|
|
5029
|
+
"Carousel template group JSON with size variants (carousel only)"
|
|
5030
|
+
).option(
|
|
5031
|
+
"--single-item-card-template-id <id>",
|
|
5032
|
+
"Fallback card template ID for single-item carousels"
|
|
5033
|
+
).option(
|
|
5034
|
+
"--single-item-card-template-group <json>",
|
|
5035
|
+
"Single-item card template group JSON for multi-language fallback"
|
|
5036
|
+
).addHelpText(
|
|
4803
5037
|
"after",
|
|
4804
5038
|
`
|
|
4805
5039
|
Examples:
|
|
4806
5040
|
$ nexus deployment template attach dep-123 --template-id HX456 --name welcome --description "Welcome message"
|
|
4807
|
-
$ nexus deployment template attach dep-123 --template-id HX456 --name order --description "Order confirmation" --variables '{"1":{"description":"Customer name","isBodyVariable":true}}'
|
|
5041
|
+
$ nexus deployment template attach dep-123 --template-id HX456 --name order --description "Order confirmation" --variables '{"1":{"description":"Customer name","isBodyVariable":true}}'
|
|
5042
|
+
$ nexus deployment template attach dep-123 --template-id HX456 --name products --description "Product carousel" --type carousel --enable-dynamic-size --carousel-template-group '{"baseName":"products","availableTemplates":[{"language":"en","carouselSize":3,"templateId":"HX111"},{"language":"en","carouselSize":5,"templateId":"HX222"}],"minCarouselSize":3,"maxCarouselSize":5}'`
|
|
4808
5043
|
).action(async (deploymentId, opts) => {
|
|
4809
5044
|
try {
|
|
4810
5045
|
let variables;
|
|
@@ -4817,6 +5052,26 @@ Examples:
|
|
|
4817
5052
|
return;
|
|
4818
5053
|
}
|
|
4819
5054
|
}
|
|
5055
|
+
let carouselTemplateGroup;
|
|
5056
|
+
if (opts.carouselTemplateGroup) {
|
|
5057
|
+
try {
|
|
5058
|
+
carouselTemplateGroup = JSON.parse(opts.carouselTemplateGroup);
|
|
5059
|
+
} catch {
|
|
5060
|
+
console.error("Error: --carousel-template-group must be valid JSON.");
|
|
5061
|
+
process.exitCode = 1;
|
|
5062
|
+
return;
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5065
|
+
let singleItemCardTemplateGroup;
|
|
5066
|
+
if (opts.singleItemCardTemplateGroup) {
|
|
5067
|
+
try {
|
|
5068
|
+
singleItemCardTemplateGroup = JSON.parse(opts.singleItemCardTemplateGroup);
|
|
5069
|
+
} catch {
|
|
5070
|
+
console.error("Error: --single-item-card-template-group must be valid JSON.");
|
|
5071
|
+
process.exitCode = 1;
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
4820
5075
|
const client = createClient(program2.optsWithGlobals());
|
|
4821
5076
|
const result = await client.deployments.attachDeploymentTemplate(deploymentId, {
|
|
4822
5077
|
templateId: opts.templateId,
|
|
@@ -4824,7 +5079,11 @@ Examples:
|
|
|
4824
5079
|
description: opts.description,
|
|
4825
5080
|
variables,
|
|
4826
5081
|
type: opts.type,
|
|
4827
|
-
enableMultiLanguage: opts.enableMultiLanguage
|
|
5082
|
+
enableMultiLanguage: opts.enableMultiLanguage,
|
|
5083
|
+
enableDynamicSize: opts.enableDynamicSize,
|
|
5084
|
+
carouselTemplateGroup,
|
|
5085
|
+
singleItemCardTemplateId: opts.singleItemCardTemplateId,
|
|
5086
|
+
singleItemCardTemplateGroup
|
|
4828
5087
|
});
|
|
4829
5088
|
const data = result?.data ?? result;
|
|
4830
5089
|
printRecord(data, [
|
|
@@ -4838,12 +5097,22 @@ Examples:
|
|
|
4838
5097
|
process.exitCode = handleError(err);
|
|
4839
5098
|
}
|
|
4840
5099
|
});
|
|
4841
|
-
depTemplate.command("update").description("Update a template's configuration on a deployment").argument("<deploymentId>", "Deployment ID").argument("<templateId>", "Template ID (Twilio SID)").option("--name <name>", "New display name").option("--description <text>", "New description").option("--variables <json>", "Updated variables JSON").option("--enable-multi-language", "Enable multi-language support").option("--no-multi-language", "Disable multi-language support").
|
|
5100
|
+
depTemplate.command("update").description("Update a template's configuration on a deployment").argument("<deploymentId>", "Deployment ID").argument("<templateId>", "Template ID (Twilio SID)").option("--name <name>", "New display name").option("--description <text>", "New description").option("--variables <json>", "Updated variables JSON").option("--enable-multi-language", "Enable multi-language support").option("--no-multi-language", "Disable multi-language support").option("--enable-dynamic-size", "Enable dynamic carousel size (carousel only)").option("--no-dynamic-size", "Disable dynamic carousel size").option(
|
|
5101
|
+
"--carousel-template-group <json>",
|
|
5102
|
+
"Carousel template group JSON with size variants (carousel only)"
|
|
5103
|
+
).option(
|
|
5104
|
+
"--single-item-card-template-id <id>",
|
|
5105
|
+
"Fallback card template ID for single-item carousels"
|
|
5106
|
+
).option(
|
|
5107
|
+
"--single-item-card-template-group <json>",
|
|
5108
|
+
"Single-item card template group JSON for multi-language fallback"
|
|
5109
|
+
).addHelpText(
|
|
4842
5110
|
"after",
|
|
4843
5111
|
`
|
|
4844
5112
|
Examples:
|
|
4845
5113
|
$ nexus deployment template update dep-123 HX456 --name "Updated Welcome"
|
|
4846
|
-
$ nexus deployment template update dep-123 HX456 --variables '{"1":{"description":"Full name"}}'
|
|
5114
|
+
$ nexus deployment template update dep-123 HX456 --variables '{"1":{"description":"Full name"}}'
|
|
5115
|
+
$ nexus deployment template update dep-123 HX456 --enable-dynamic-size --carousel-template-group '{"baseName":"products","availableTemplates":[...]}'`
|
|
4847
5116
|
).action(async (deploymentId, templateId, opts) => {
|
|
4848
5117
|
try {
|
|
4849
5118
|
const body = {};
|
|
@@ -4851,6 +5120,9 @@ Examples:
|
|
|
4851
5120
|
if (opts.description !== void 0) body.description = opts.description;
|
|
4852
5121
|
if (opts.enableMultiLanguage !== void 0)
|
|
4853
5122
|
body.enableMultiLanguage = opts.enableMultiLanguage;
|
|
5123
|
+
if (opts.enableDynamicSize !== void 0) body.enableDynamicSize = opts.enableDynamicSize;
|
|
5124
|
+
if (opts.singleItemCardTemplateId !== void 0)
|
|
5125
|
+
body.singleItemCardTemplateId = opts.singleItemCardTemplateId;
|
|
4854
5126
|
if (opts.variables) {
|
|
4855
5127
|
try {
|
|
4856
5128
|
body.variables = JSON.parse(opts.variables);
|
|
@@ -4860,6 +5132,24 @@ Examples:
|
|
|
4860
5132
|
return;
|
|
4861
5133
|
}
|
|
4862
5134
|
}
|
|
5135
|
+
if (opts.carouselTemplateGroup) {
|
|
5136
|
+
try {
|
|
5137
|
+
body.carouselTemplateGroup = JSON.parse(opts.carouselTemplateGroup);
|
|
5138
|
+
} catch {
|
|
5139
|
+
console.error("Error: --carousel-template-group must be valid JSON.");
|
|
5140
|
+
process.exitCode = 1;
|
|
5141
|
+
return;
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
if (opts.singleItemCardTemplateGroup) {
|
|
5145
|
+
try {
|
|
5146
|
+
body.singleItemCardTemplateGroup = JSON.parse(opts.singleItemCardTemplateGroup);
|
|
5147
|
+
} catch {
|
|
5148
|
+
console.error("Error: --single-item-card-template-group must be valid JSON.");
|
|
5149
|
+
process.exitCode = 1;
|
|
5150
|
+
return;
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
4863
5153
|
const client = createClient(program2.optsWithGlobals());
|
|
4864
5154
|
const result = await client.deployments.updateDeploymentTemplate(
|
|
4865
5155
|
deploymentId,
|
|
@@ -4886,7 +5176,10 @@ Examples:
|
|
|
4886
5176
|
output: process.stdout
|
|
4887
5177
|
});
|
|
4888
5178
|
const answer = await new Promise((resolve) => {
|
|
4889
|
-
rl.question(
|
|
5179
|
+
rl.question(
|
|
5180
|
+
`Detach template ${templateId} from deployment ${deploymentId}? (y/N) `,
|
|
5181
|
+
resolve
|
|
5182
|
+
);
|
|
4890
5183
|
});
|
|
4891
5184
|
rl.close();
|
|
4892
5185
|
if (answer.toLowerCase() !== "y") {
|
|
@@ -12537,6 +12830,390 @@ Examples:
|
|
|
12537
12830
|
});
|
|
12538
12831
|
}
|
|
12539
12832
|
|
|
12833
|
+
// src/commands/tracing.ts
|
|
12834
|
+
init_output();
|
|
12835
|
+
function registerTracingCommands(program2) {
|
|
12836
|
+
const tracing = program2.command("tracing").description("View LLM traces and analytics");
|
|
12837
|
+
addPaginationOptions(
|
|
12838
|
+
tracing.command("traces").description("List LLM traces").option("--status <status>", "Filter by status (IN_PROGRESS, COMPLETED, FAILED)").option("--agent-id <id>", "Filter by agent ID").option("--workflow-id <id>", "Filter by workflow ID").option("--model <name>", "Filter by model name (max 255 chars)").option("--start-date <iso>", "Filter from date (ISO 8601, e.g. 2026-03-01)").option("--end-date <iso>", "Filter to date (ISO 8601, e.g. 2026-03-01)").option(
|
|
12839
|
+
"--sort-by <field>",
|
|
12840
|
+
"Sort by field (startedAt, totalCostUsd, totalDurationMs)",
|
|
12841
|
+
"startedAt"
|
|
12842
|
+
).option("--order <dir>", "Sort order (asc, desc)", "desc").addHelpText(
|
|
12843
|
+
"after",
|
|
12844
|
+
`
|
|
12845
|
+
Examples:
|
|
12846
|
+
$ nexus tracing traces
|
|
12847
|
+
$ nexus tracing traces --status FAILED --limit 10
|
|
12848
|
+
$ nexus tracing traces --agent-id abc --start-date 2026-03-01 --json`
|
|
12849
|
+
)
|
|
12850
|
+
).action(async (opts) => {
|
|
12851
|
+
try {
|
|
12852
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12853
|
+
const { data, meta } = await client.tracing.listTraces({
|
|
12854
|
+
...getPaginationParams(opts),
|
|
12855
|
+
status: opts.status,
|
|
12856
|
+
agentId: opts.agentId,
|
|
12857
|
+
workflowId: opts.workflowId,
|
|
12858
|
+
model: opts.model,
|
|
12859
|
+
startDate: opts.startDate,
|
|
12860
|
+
endDate: opts.endDate,
|
|
12861
|
+
sortBy: opts.sortBy,
|
|
12862
|
+
order: opts.order
|
|
12863
|
+
});
|
|
12864
|
+
printList(
|
|
12865
|
+
data,
|
|
12866
|
+
meta,
|
|
12867
|
+
[
|
|
12868
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12869
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12870
|
+
{ key: "agentName", label: "AGENT", width: 20 },
|
|
12871
|
+
{ key: "workflowName", label: "WORKFLOW", width: 20 },
|
|
12872
|
+
{
|
|
12873
|
+
key: "totalCostUsd",
|
|
12874
|
+
label: "COST ($)",
|
|
12875
|
+
width: 10,
|
|
12876
|
+
format: (v) => v != null ? `$${Number(v).toFixed(4)}` : "-"
|
|
12877
|
+
},
|
|
12878
|
+
{
|
|
12879
|
+
key: "totalDurationMs",
|
|
12880
|
+
label: "DURATION",
|
|
12881
|
+
width: 10,
|
|
12882
|
+
format: (v) => v != null ? `${Number(v)}ms` : "-"
|
|
12883
|
+
},
|
|
12884
|
+
{ key: "generationCount", label: "GENS", width: 5 },
|
|
12885
|
+
{ key: "startedAt", label: "STARTED", width: 20 }
|
|
12886
|
+
]
|
|
12887
|
+
);
|
|
12888
|
+
} catch (err) {
|
|
12889
|
+
process.exitCode = handleError(err);
|
|
12890
|
+
}
|
|
12891
|
+
});
|
|
12892
|
+
tracing.command("trace").description("Get trace details with generations").argument("<id>", "Trace ID").addHelpText(
|
|
12893
|
+
"after",
|
|
12894
|
+
`
|
|
12895
|
+
Examples:
|
|
12896
|
+
$ nexus tracing trace abc-123
|
|
12897
|
+
$ nexus tracing trace abc-123 --json`
|
|
12898
|
+
).action(async (id) => {
|
|
12899
|
+
try {
|
|
12900
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12901
|
+
const trace = await client.tracing.getTrace(id);
|
|
12902
|
+
printRecord(trace, [
|
|
12903
|
+
{ key: "id", label: "ID" },
|
|
12904
|
+
{ key: "status", label: "Status" },
|
|
12905
|
+
{ key: "agentName", label: "Agent" },
|
|
12906
|
+
{ key: "workflowName", label: "Workflow" },
|
|
12907
|
+
{
|
|
12908
|
+
key: "totalCostUsd",
|
|
12909
|
+
label: "Cost ($)",
|
|
12910
|
+
format: (v) => v != null ? `$${Number(v).toFixed(4)}` : "-"
|
|
12911
|
+
},
|
|
12912
|
+
{ key: "totalInputTokens", label: "Input Tokens" },
|
|
12913
|
+
{ key: "totalOutputTokens", label: "Output Tokens" },
|
|
12914
|
+
{ key: "totalDurationMs", label: "Duration (ms)" },
|
|
12915
|
+
{ key: "startedAt", label: "Started" },
|
|
12916
|
+
{ key: "completedAt", label: "Completed" }
|
|
12917
|
+
]);
|
|
12918
|
+
const gens = trace.generations;
|
|
12919
|
+
if (gens && gens.length > 0) {
|
|
12920
|
+
console.log(`
|
|
12921
|
+
${color.bold("Generations")} (${gens.length}):
|
|
12922
|
+
`);
|
|
12923
|
+
printList(gens, void 0, [
|
|
12924
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12925
|
+
{ key: "modelName", label: "MODEL", width: 25 },
|
|
12926
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12927
|
+
{
|
|
12928
|
+
key: "costUsd",
|
|
12929
|
+
label: "COST ($)",
|
|
12930
|
+
width: 10,
|
|
12931
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
12932
|
+
},
|
|
12933
|
+
{
|
|
12934
|
+
key: "durationMs",
|
|
12935
|
+
label: "DURATION",
|
|
12936
|
+
width: 10,
|
|
12937
|
+
format: (v) => v != null ? `${v}ms` : "-"
|
|
12938
|
+
}
|
|
12939
|
+
]);
|
|
12940
|
+
}
|
|
12941
|
+
} catch (err) {
|
|
12942
|
+
process.exitCode = handleError(err);
|
|
12943
|
+
}
|
|
12944
|
+
});
|
|
12945
|
+
tracing.command("delete").description("Delete a trace and its generations").argument("<id>", "Trace ID").addHelpText(
|
|
12946
|
+
"after",
|
|
12947
|
+
`
|
|
12948
|
+
Examples:
|
|
12949
|
+
$ nexus tracing delete abc-123`
|
|
12950
|
+
).action(async (id) => {
|
|
12951
|
+
try {
|
|
12952
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12953
|
+
await client.tracing.deleteTrace(id);
|
|
12954
|
+
printSuccess("Trace deleted.", { id });
|
|
12955
|
+
} catch (err) {
|
|
12956
|
+
process.exitCode = handleError(err);
|
|
12957
|
+
}
|
|
12958
|
+
});
|
|
12959
|
+
addPaginationOptions(
|
|
12960
|
+
tracing.command("generations").description("List LLM generations across traces").option("--trace-id <id>", "Filter by trace ID").option("--provider <provider>", "Filter by provider (OPEN_AI, ANTHROPIC, GOOGLE_AI)").option("--model <name>", "Filter by model name (max 255 chars)").option("--status <status>", "Filter by status (PENDING, RUNNING, COMPLETED, FAILED)").option("--agent-id <id>", "Filter by agent ID").option("--task-id <id>", "Filter by task ID").option("--start-date <iso>", "Filter from date (ISO 8601, e.g. 2026-03-01)").option("--end-date <iso>", "Filter to date (ISO 8601, e.g. 2026-03-01)").option("--min-cost <usd>", "Minimum cost in USD").option("--max-cost <usd>", "Maximum cost in USD").addHelpText(
|
|
12961
|
+
"after",
|
|
12962
|
+
`
|
|
12963
|
+
Examples:
|
|
12964
|
+
$ nexus tracing generations
|
|
12965
|
+
$ nexus tracing generations --provider ANTHROPIC --status FAILED
|
|
12966
|
+
$ nexus tracing generations --trace-id abc-123 --json`
|
|
12967
|
+
)
|
|
12968
|
+
).action(async (opts) => {
|
|
12969
|
+
try {
|
|
12970
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12971
|
+
const { data, meta } = await client.tracing.listGenerations({
|
|
12972
|
+
...getPaginationParams(opts),
|
|
12973
|
+
traceId: opts.traceId,
|
|
12974
|
+
provider: opts.provider,
|
|
12975
|
+
modelName: opts.model,
|
|
12976
|
+
status: opts.status,
|
|
12977
|
+
agentId: opts.agentId,
|
|
12978
|
+
taskId: opts.taskId,
|
|
12979
|
+
startDate: opts.startDate,
|
|
12980
|
+
endDate: opts.endDate,
|
|
12981
|
+
minCostUsd: opts.minCost ? parseFloat(opts.minCost) : void 0,
|
|
12982
|
+
maxCostUsd: opts.maxCost ? parseFloat(opts.maxCost) : void 0
|
|
12983
|
+
});
|
|
12984
|
+
printList(
|
|
12985
|
+
data,
|
|
12986
|
+
meta,
|
|
12987
|
+
[
|
|
12988
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12989
|
+
{ key: "traceId", label: "TRACE", width: 36 },
|
|
12990
|
+
{ key: "modelName", label: "MODEL", width: 25 },
|
|
12991
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12992
|
+
{
|
|
12993
|
+
key: "costUsd",
|
|
12994
|
+
label: "COST ($)",
|
|
12995
|
+
width: 10,
|
|
12996
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
12997
|
+
},
|
|
12998
|
+
{
|
|
12999
|
+
key: "durationMs",
|
|
13000
|
+
label: "DURATION",
|
|
13001
|
+
width: 10,
|
|
13002
|
+
format: (v) => v != null ? `${v}ms` : "-"
|
|
13003
|
+
}
|
|
13004
|
+
]
|
|
13005
|
+
);
|
|
13006
|
+
} catch (err) {
|
|
13007
|
+
process.exitCode = handleError(err);
|
|
13008
|
+
}
|
|
13009
|
+
});
|
|
13010
|
+
tracing.command("generation").description("Get generation details including prompt and response").argument("<id>", "Generation ID").addHelpText(
|
|
13011
|
+
"after",
|
|
13012
|
+
`
|
|
13013
|
+
Examples:
|
|
13014
|
+
$ nexus tracing generation gen-123
|
|
13015
|
+
$ nexus tracing generation gen-123 --json`
|
|
13016
|
+
).action(async (id) => {
|
|
13017
|
+
try {
|
|
13018
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13019
|
+
const gen = await client.tracing.getGeneration(id);
|
|
13020
|
+
printRecord(gen, [
|
|
13021
|
+
{ key: "id", label: "ID" },
|
|
13022
|
+
{ key: "traceId", label: "Trace ID" },
|
|
13023
|
+
{ key: "provider", label: "Provider" },
|
|
13024
|
+
{ key: "modelName", label: "Model" },
|
|
13025
|
+
{ key: "status", label: "Status" },
|
|
13026
|
+
{ key: "inputTokens", label: "Input Tokens" },
|
|
13027
|
+
{ key: "outputTokens", label: "Output Tokens" },
|
|
13028
|
+
{
|
|
13029
|
+
key: "costUsd",
|
|
13030
|
+
label: "Cost ($)",
|
|
13031
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
13032
|
+
},
|
|
13033
|
+
{ key: "durationMs", label: "Duration (ms)" },
|
|
13034
|
+
{ key: "temperature", label: "Temperature" },
|
|
13035
|
+
{ key: "taskName", label: "Task" },
|
|
13036
|
+
{ key: "startedAt", label: "Started" },
|
|
13037
|
+
{ key: "completedAt", label: "Completed" },
|
|
13038
|
+
{ key: "errorMessage", label: "Error" }
|
|
13039
|
+
]);
|
|
13040
|
+
} catch (err) {
|
|
13041
|
+
process.exitCode = handleError(err);
|
|
13042
|
+
}
|
|
13043
|
+
});
|
|
13044
|
+
tracing.command("models").description("List distinct model names used in traces").addHelpText(
|
|
13045
|
+
"after",
|
|
13046
|
+
`
|
|
13047
|
+
Examples:
|
|
13048
|
+
$ nexus tracing models`
|
|
13049
|
+
).action(async () => {
|
|
13050
|
+
try {
|
|
13051
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13052
|
+
const models = await client.tracing.listModels();
|
|
13053
|
+
if (Array.isArray(models) && models.length > 0) {
|
|
13054
|
+
for (const m of models) console.log(m);
|
|
13055
|
+
} else {
|
|
13056
|
+
console.log("No models found.");
|
|
13057
|
+
}
|
|
13058
|
+
} catch (err) {
|
|
13059
|
+
process.exitCode = handleError(err);
|
|
13060
|
+
}
|
|
13061
|
+
});
|
|
13062
|
+
tracing.command("summary").description("Get tracing analytics summary").option("--start-date <iso>", "Period start (ISO 8601)").option("--end-date <iso>", "Period end (ISO 8601)").addHelpText(
|
|
13063
|
+
"after",
|
|
13064
|
+
`
|
|
13065
|
+
Examples:
|
|
13066
|
+
$ nexus tracing summary
|
|
13067
|
+
$ nexus tracing summary --start-date 2026-03-01 --end-date 2026-03-30
|
|
13068
|
+
$ nexus tracing summary --json`
|
|
13069
|
+
).action(async (opts) => {
|
|
13070
|
+
try {
|
|
13071
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13072
|
+
const summary = await client.tracing.getSummary({
|
|
13073
|
+
startDate: opts.startDate,
|
|
13074
|
+
endDate: opts.endDate
|
|
13075
|
+
});
|
|
13076
|
+
printRecord(summary, [
|
|
13077
|
+
{ key: "totalTraces", label: "Total Traces" },
|
|
13078
|
+
{ key: "completedTraces", label: "Completed" },
|
|
13079
|
+
{ key: "failedTraces", label: "Failed" },
|
|
13080
|
+
{ key: "inProgressTraces", label: "In Progress" },
|
|
13081
|
+
{
|
|
13082
|
+
key: "totalCostUsd",
|
|
13083
|
+
label: "Total Cost ($)",
|
|
13084
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
13085
|
+
},
|
|
13086
|
+
{ key: "totalInputTokens", label: "Input Tokens" },
|
|
13087
|
+
{ key: "totalOutputTokens", label: "Output Tokens" },
|
|
13088
|
+
{
|
|
13089
|
+
key: "avgDurationMs",
|
|
13090
|
+
label: "Avg Duration",
|
|
13091
|
+
format: (v) => v != null ? `${Number(v).toFixed(0)}ms` : "-"
|
|
13092
|
+
},
|
|
13093
|
+
{ key: "distinctModelCount", label: "Distinct Models" }
|
|
13094
|
+
]);
|
|
13095
|
+
} catch (err) {
|
|
13096
|
+
process.exitCode = handleError(err);
|
|
13097
|
+
}
|
|
13098
|
+
});
|
|
13099
|
+
tracing.command("cost-breakdown").description("Get cost breakdown by model, agent, or workflow").option("--group-by <key>", "Group by (model, agent, workflow)", "model").option("--start-date <iso>", "Period start").option("--end-date <iso>", "Period end").addHelpText(
|
|
13100
|
+
"after",
|
|
13101
|
+
`
|
|
13102
|
+
Examples:
|
|
13103
|
+
$ nexus tracing cost-breakdown
|
|
13104
|
+
$ nexus tracing cost-breakdown --group-by agent
|
|
13105
|
+
$ nexus tracing cost-breakdown --group-by workflow --json`
|
|
13106
|
+
).action(async (opts) => {
|
|
13107
|
+
try {
|
|
13108
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13109
|
+
const result = await client.tracing.getCostBreakdown({
|
|
13110
|
+
groupBy: opts.groupBy,
|
|
13111
|
+
startDate: opts.startDate,
|
|
13112
|
+
endDate: opts.endDate
|
|
13113
|
+
});
|
|
13114
|
+
const entries = result.entries ?? [];
|
|
13115
|
+
printList(entries, void 0, [
|
|
13116
|
+
{ key: "groupKey", label: "KEY", width: 36 },
|
|
13117
|
+
{ key: "groupLabel", label: "LABEL", width: 25 },
|
|
13118
|
+
{
|
|
13119
|
+
key: "totalCostUsd",
|
|
13120
|
+
label: "COST ($)",
|
|
13121
|
+
width: 12,
|
|
13122
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
13123
|
+
},
|
|
13124
|
+
{ key: "traceCount", label: "TRACES", width: 8 },
|
|
13125
|
+
{ key: "generationCount", label: "GENS", width: 8 },
|
|
13126
|
+
{ key: "totalInputTokens", label: "IN TOKENS", width: 12 },
|
|
13127
|
+
{ key: "totalOutputTokens", label: "OUT TOKENS", width: 12 }
|
|
13128
|
+
]);
|
|
13129
|
+
} catch (err) {
|
|
13130
|
+
process.exitCode = handleError(err);
|
|
13131
|
+
}
|
|
13132
|
+
});
|
|
13133
|
+
tracing.command("timeline").description("Get tracing timeline data").option("--granularity <g>", "Granularity (hour, day, week)", "day").option("--start-date <iso>", "Period start").option("--end-date <iso>", "Period end").addHelpText(
|
|
13134
|
+
"after",
|
|
13135
|
+
`
|
|
13136
|
+
Examples:
|
|
13137
|
+
$ nexus tracing timeline
|
|
13138
|
+
$ nexus tracing timeline --granularity hour --start-date 2026-03-29 --json`
|
|
13139
|
+
).action(async (opts) => {
|
|
13140
|
+
try {
|
|
13141
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13142
|
+
const result = await client.tracing.getTimeline({
|
|
13143
|
+
granularity: opts.granularity,
|
|
13144
|
+
startDate: opts.startDate,
|
|
13145
|
+
endDate: opts.endDate
|
|
13146
|
+
});
|
|
13147
|
+
const points = result.points ?? [];
|
|
13148
|
+
printList(points, void 0, [
|
|
13149
|
+
{ key: "date", label: "DATE", width: 22 },
|
|
13150
|
+
{ key: "traceCount", label: "TRACES", width: 8 },
|
|
13151
|
+
{ key: "generationCount", label: "GENS", width: 8 },
|
|
13152
|
+
{
|
|
13153
|
+
key: "totalCostUsd",
|
|
13154
|
+
label: "COST ($)",
|
|
13155
|
+
width: 12,
|
|
13156
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
13157
|
+
},
|
|
13158
|
+
{
|
|
13159
|
+
key: "avgDurationMs",
|
|
13160
|
+
label: "AVG DUR",
|
|
13161
|
+
width: 10,
|
|
13162
|
+
format: (v) => v != null ? `${Number(v).toFixed(0)}ms` : "-"
|
|
13163
|
+
}
|
|
13164
|
+
]);
|
|
13165
|
+
} catch (err) {
|
|
13166
|
+
process.exitCode = handleError(err);
|
|
13167
|
+
}
|
|
13168
|
+
});
|
|
13169
|
+
tracing.command("export").description("Export a single trace").argument("<id>", "Trace ID").option("--format <fmt>", "Output format (json, csv)", "json").addHelpText(
|
|
13170
|
+
"after",
|
|
13171
|
+
`
|
|
13172
|
+
Examples:
|
|
13173
|
+
$ nexus tracing export abc-123
|
|
13174
|
+
$ nexus tracing export abc-123 --format csv > trace.csv`
|
|
13175
|
+
).action(async (id, opts) => {
|
|
13176
|
+
try {
|
|
13177
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13178
|
+
const result = await client.tracing.exportTrace(id, { format: opts.format });
|
|
13179
|
+
console.log(result.content);
|
|
13180
|
+
} catch (err) {
|
|
13181
|
+
process.exitCode = handleError(err);
|
|
13182
|
+
}
|
|
13183
|
+
});
|
|
13184
|
+
tracing.command("export-bulk").description("Bulk export traces (max 1000)").option("--format <fmt>", "Output format (json, csv)", "json").option("--status <status>", "Filter by status").option("--agent-id <id>", "Filter by agent ID").option("--workflow-id <id>", "Filter by workflow ID").option("--start-date <iso>", "Filter from date").option("--end-date <iso>", "Filter to date").option("--limit <n>", "Max traces to export", "100").addHelpText(
|
|
13185
|
+
"after",
|
|
13186
|
+
`
|
|
13187
|
+
Examples:
|
|
13188
|
+
$ nexus tracing export-bulk --format csv > traces.csv
|
|
13189
|
+
$ nexus tracing export-bulk --status FAILED --limit 50`
|
|
13190
|
+
).action(async (opts) => {
|
|
13191
|
+
try {
|
|
13192
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13193
|
+
const result = await client.tracing.bulkExport({
|
|
13194
|
+
format: opts.format,
|
|
13195
|
+
status: opts.status,
|
|
13196
|
+
agentId: opts.agentId,
|
|
13197
|
+
workflowId: opts.workflowId,
|
|
13198
|
+
startDate: opts.startDate,
|
|
13199
|
+
endDate: opts.endDate,
|
|
13200
|
+
limit: parseInt(opts.limit, 10)
|
|
13201
|
+
});
|
|
13202
|
+
console.log(result.content);
|
|
13203
|
+
} catch (err) {
|
|
13204
|
+
process.exitCode = handleError(err);
|
|
13205
|
+
}
|
|
13206
|
+
});
|
|
13207
|
+
}
|
|
13208
|
+
function formatStatus(v) {
|
|
13209
|
+
const s = String(v);
|
|
13210
|
+
if (s === "COMPLETED") return color.green(s);
|
|
13211
|
+
if (s === "FAILED") return color.red(s);
|
|
13212
|
+
if (s === "IN_PROGRESS" || s === "RUNNING") return color.yellow(s);
|
|
13213
|
+
if (s === "PENDING") return color.dim(s);
|
|
13214
|
+
return s;
|
|
13215
|
+
}
|
|
13216
|
+
|
|
12540
13217
|
// src/commands/upgrade.ts
|
|
12541
13218
|
var import_node_child_process3 = require("child_process");
|
|
12542
13219
|
init_output();
|
|
@@ -13586,6 +14263,7 @@ registerModelCommands(program);
|
|
|
13586
14263
|
registerCustomModelCommands(program);
|
|
13587
14264
|
registerPhoneNumberCommands(program);
|
|
13588
14265
|
registerChannelCommands(program);
|
|
14266
|
+
registerTracingCommands(program);
|
|
13589
14267
|
registerUpgradeCommand(program);
|
|
13590
14268
|
registerDocsCommand(program);
|
|
13591
14269
|
if (process.argv.length <= 2) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-nexus/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Official CLI for the Nexus AI agent platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@types/node": "24.6.2",
|
|
36
36
|
"tsup": "^8.5.0",
|
|
37
37
|
"typescript": "^5.8.3",
|
|
38
|
-
"@agent-nexus/sdk": "0.1.
|
|
38
|
+
"@agent-nexus/sdk": "0.1.16"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"gen:docs": "tsx scripts/bundle-docs.ts",
|