@agent-nexus/cli 0.1.12 → 0.1.13
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 +589 -16
- 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.13",
|
|
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,11 +787,9 @@ var ChannelsResource = class extends BaseResource {
|
|
|
790
787
|
);
|
|
791
788
|
}
|
|
792
789
|
async listTemplateApprovals(params) {
|
|
793
|
-
return this.http.request(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
{ query: params }
|
|
797
|
-
);
|
|
790
|
+
return this.http.request("GET", "/channels/whatsapp-templates/approvals", {
|
|
791
|
+
query: params
|
|
792
|
+
});
|
|
798
793
|
}
|
|
799
794
|
async submitTemplateApproval(body) {
|
|
800
795
|
return this.http.request(
|
|
@@ -2061,6 +2056,64 @@ var ToolDiscoveryResource = class extends BaseResource {
|
|
|
2061
2056
|
);
|
|
2062
2057
|
}
|
|
2063
2058
|
};
|
|
2059
|
+
var TracingResource = class extends BaseResource {
|
|
2060
|
+
// ── Traces ──────────────────────────────────────────────────────────────
|
|
2061
|
+
async listTraces(params) {
|
|
2062
|
+
const { data, meta } = await this.http.requestWithMeta(
|
|
2063
|
+
"GET",
|
|
2064
|
+
"/tracing/traces",
|
|
2065
|
+
{ query: params }
|
|
2066
|
+
);
|
|
2067
|
+
return { data, meta };
|
|
2068
|
+
}
|
|
2069
|
+
async getTrace(traceId) {
|
|
2070
|
+
return this.http.request("GET", `/tracing/traces/${traceId}`);
|
|
2071
|
+
}
|
|
2072
|
+
async deleteTrace(traceId) {
|
|
2073
|
+
return this.http.request("DELETE", `/tracing/traces/${traceId}`);
|
|
2074
|
+
}
|
|
2075
|
+
// ── Generations ─────────────────────────────────────────────────────────
|
|
2076
|
+
async listGenerations(params) {
|
|
2077
|
+
const { data, meta } = await this.http.requestWithMeta(
|
|
2078
|
+
"GET",
|
|
2079
|
+
"/tracing/generations",
|
|
2080
|
+
{ query: params }
|
|
2081
|
+
);
|
|
2082
|
+
return { data, meta };
|
|
2083
|
+
}
|
|
2084
|
+
async getGeneration(generationId) {
|
|
2085
|
+
return this.http.request("GET", `/tracing/generations/${generationId}`);
|
|
2086
|
+
}
|
|
2087
|
+
// ── Models ──────────────────────────────────────────────────────────────
|
|
2088
|
+
async listModels() {
|
|
2089
|
+
return this.http.request("GET", "/tracing/models");
|
|
2090
|
+
}
|
|
2091
|
+
// ── Analytics ───────────────────────────────────────────────────────────
|
|
2092
|
+
async getSummary(params) {
|
|
2093
|
+
return this.http.request("GET", "/tracing/analytics/summary", {
|
|
2094
|
+
query: params
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
async getCostBreakdown(params) {
|
|
2098
|
+
return this.http.request("GET", "/tracing/analytics/cost-breakdown", {
|
|
2099
|
+
query: params
|
|
2100
|
+
});
|
|
2101
|
+
}
|
|
2102
|
+
async getTimeline(params) {
|
|
2103
|
+
return this.http.request("GET", "/tracing/analytics/timeline", {
|
|
2104
|
+
query: params
|
|
2105
|
+
});
|
|
2106
|
+
}
|
|
2107
|
+
// ── Export ──────────────────────────────────────────────────────────────
|
|
2108
|
+
async exportTrace(traceId, params) {
|
|
2109
|
+
return this.http.request("POST", `/tracing/traces/${traceId}/export`, {
|
|
2110
|
+
body: params
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
async bulkExport(params) {
|
|
2114
|
+
return this.http.request("POST", "/tracing/export", { body: params });
|
|
2115
|
+
}
|
|
2116
|
+
};
|
|
2064
2117
|
var WorkflowExecutionsResource = class extends BaseResource {
|
|
2065
2118
|
async list(params) {
|
|
2066
2119
|
const { data, meta } = await this.http.requestWithMeta("GET", "/workflows/executions", {
|
|
@@ -2533,6 +2586,7 @@ var NexusClient = class {
|
|
|
2533
2586
|
this.phoneNumbers = new PhoneNumbersResource(http);
|
|
2534
2587
|
this.tickets = new TicketsResource(http);
|
|
2535
2588
|
this.channels = new ChannelsResource(http);
|
|
2589
|
+
this.tracing = new TracingResource(http);
|
|
2536
2590
|
}
|
|
2537
2591
|
};
|
|
2538
2592
|
|
|
@@ -3663,6 +3717,41 @@ function openUrl(url) {
|
|
|
3663
3717
|
var import_node_child_process2 = require("child_process");
|
|
3664
3718
|
var import_node_fs2 = require("fs");
|
|
3665
3719
|
init_output();
|
|
3720
|
+
var VARIABLE_PATTERN = /\{\{\d+\}\}/g;
|
|
3721
|
+
function warnIfHighVariableDensity(types) {
|
|
3722
|
+
let warned = false;
|
|
3723
|
+
function checkField(text, fieldLabel) {
|
|
3724
|
+
const matches = text.match(VARIABLE_PATTERN) ?? [];
|
|
3725
|
+
if (matches.length === 0) return;
|
|
3726
|
+
const variableCharsLength = matches.reduce((sum, m) => sum + m.length, 0);
|
|
3727
|
+
const staticLength = text.length - variableCharsLength;
|
|
3728
|
+
if (staticLength < matches.length * 3) {
|
|
3729
|
+
console.warn(
|
|
3730
|
+
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."`
|
|
3731
|
+
);
|
|
3732
|
+
warned = true;
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
for (const [typeKey, typeValue] of Object.entries(types)) {
|
|
3736
|
+
if (!typeValue || typeof typeValue !== "object") continue;
|
|
3737
|
+
const tv = typeValue;
|
|
3738
|
+
if (typeof tv.body === "string") checkField(tv.body, `${typeKey} body`);
|
|
3739
|
+
if (typeof tv.title === "string") checkField(tv.title, `${typeKey} title`);
|
|
3740
|
+
if (typeof tv.subtitle === "string") checkField(tv.subtitle, `${typeKey} subtitle`);
|
|
3741
|
+
if (Array.isArray(tv.cards)) {
|
|
3742
|
+
tv.cards.forEach((card, i) => {
|
|
3743
|
+
if (typeof card?.body === "string") checkField(card.body, `${typeKey} card[${i}] body`);
|
|
3744
|
+
if (typeof card?.title === "string") checkField(card.title, `${typeKey} card[${i}] title`);
|
|
3745
|
+
});
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
if (warned) {
|
|
3749
|
+
console.warn(
|
|
3750
|
+
color.yellow(" Tip:") + " Add more descriptive static text around {{N}} placeholders to avoid Meta rejection.\n"
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
return warned;
|
|
3754
|
+
}
|
|
3666
3755
|
function openUrl2(url) {
|
|
3667
3756
|
const platform = process.platform;
|
|
3668
3757
|
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
@@ -3914,6 +4003,7 @@ Examples:
|
|
|
3914
4003
|
return;
|
|
3915
4004
|
}
|
|
3916
4005
|
}
|
|
4006
|
+
warnIfHighVariableDensity(types);
|
|
3917
4007
|
const client = createClient(program2.optsWithGlobals());
|
|
3918
4008
|
const result = await client.channels.createWhatsAppTemplate({
|
|
3919
4009
|
connectionId: opts.connectionId,
|
|
@@ -3945,6 +4035,44 @@ Examples:
|
|
|
3945
4035
|
{ key: "status", label: "Status" }
|
|
3946
4036
|
]);
|
|
3947
4037
|
printSuccess("Template submitted for Meta approval.");
|
|
4038
|
+
const pollMaxMs = 3e4;
|
|
4039
|
+
const pollIntervalMs = 5e3;
|
|
4040
|
+
const pollStart = Date.now();
|
|
4041
|
+
let resolved = false;
|
|
4042
|
+
console.log("Checking approval status...");
|
|
4043
|
+
while (Date.now() - pollStart < pollMaxMs) {
|
|
4044
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
4045
|
+
try {
|
|
4046
|
+
const approvals = await client.channels.listTemplateApprovals({
|
|
4047
|
+
connectionId: opts.connectionId
|
|
4048
|
+
});
|
|
4049
|
+
const approvalsArr = approvals?.data ?? approvals;
|
|
4050
|
+
const items = Array.isArray(approvalsArr) ? approvalsArr : [approvalsArr];
|
|
4051
|
+
const match = items.find((a) => a.sid === data.id);
|
|
4052
|
+
if (match?.approvalRequests?.status) {
|
|
4053
|
+
const status = match.approvalRequests.status;
|
|
4054
|
+
if (status === "rejected") {
|
|
4055
|
+
console.log(color.red(`\u2717 Template rejected by Meta: ${status}`));
|
|
4056
|
+
if (match.approvalRequests.rejection_reason) {
|
|
4057
|
+
console.log(` Reason: ${match.approvalRequests.rejection_reason}`);
|
|
4058
|
+
}
|
|
4059
|
+
resolved = true;
|
|
4060
|
+
process.exitCode = 1;
|
|
4061
|
+
break;
|
|
4062
|
+
} else if (status === "approved") {
|
|
4063
|
+
console.log(color.green(`\u2713 Template approved by Meta.`));
|
|
4064
|
+
resolved = true;
|
|
4065
|
+
break;
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
} catch {
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
if (!resolved) {
|
|
4072
|
+
console.log(
|
|
4073
|
+
`Status still pending. Check later: ${color.dim("nexus channel whatsapp-template approvals")}`
|
|
4074
|
+
);
|
|
4075
|
+
}
|
|
3948
4076
|
}
|
|
3949
4077
|
} catch (err) {
|
|
3950
4078
|
process.exitCode = handleError(err);
|
|
@@ -4799,12 +4927,25 @@ Examples:
|
|
|
4799
4927
|
process.exitCode = handleError(err);
|
|
4800
4928
|
}
|
|
4801
4929
|
});
|
|
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(
|
|
4930
|
+
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(
|
|
4931
|
+
"--variables <json>",
|
|
4932
|
+
'Variables JSON: {"1":{"description":"Name","isBodyVariable":true}}'
|
|
4933
|
+
).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(
|
|
4934
|
+
"--carousel-template-group <json>",
|
|
4935
|
+
"Carousel template group JSON with size variants (carousel only)"
|
|
4936
|
+
).option(
|
|
4937
|
+
"--single-item-card-template-id <id>",
|
|
4938
|
+
"Fallback card template ID for single-item carousels"
|
|
4939
|
+
).option(
|
|
4940
|
+
"--single-item-card-template-group <json>",
|
|
4941
|
+
"Single-item card template group JSON for multi-language fallback"
|
|
4942
|
+
).addHelpText(
|
|
4803
4943
|
"after",
|
|
4804
4944
|
`
|
|
4805
4945
|
Examples:
|
|
4806
4946
|
$ 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}}'
|
|
4947
|
+
$ nexus deployment template attach dep-123 --template-id HX456 --name order --description "Order confirmation" --variables '{"1":{"description":"Customer name","isBodyVariable":true}}'
|
|
4948
|
+
$ 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
4949
|
).action(async (deploymentId, opts) => {
|
|
4809
4950
|
try {
|
|
4810
4951
|
let variables;
|
|
@@ -4817,6 +4958,26 @@ Examples:
|
|
|
4817
4958
|
return;
|
|
4818
4959
|
}
|
|
4819
4960
|
}
|
|
4961
|
+
let carouselTemplateGroup;
|
|
4962
|
+
if (opts.carouselTemplateGroup) {
|
|
4963
|
+
try {
|
|
4964
|
+
carouselTemplateGroup = JSON.parse(opts.carouselTemplateGroup);
|
|
4965
|
+
} catch {
|
|
4966
|
+
console.error("Error: --carousel-template-group must be valid JSON.");
|
|
4967
|
+
process.exitCode = 1;
|
|
4968
|
+
return;
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
let singleItemCardTemplateGroup;
|
|
4972
|
+
if (opts.singleItemCardTemplateGroup) {
|
|
4973
|
+
try {
|
|
4974
|
+
singleItemCardTemplateGroup = JSON.parse(opts.singleItemCardTemplateGroup);
|
|
4975
|
+
} catch {
|
|
4976
|
+
console.error("Error: --single-item-card-template-group must be valid JSON.");
|
|
4977
|
+
process.exitCode = 1;
|
|
4978
|
+
return;
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4820
4981
|
const client = createClient(program2.optsWithGlobals());
|
|
4821
4982
|
const result = await client.deployments.attachDeploymentTemplate(deploymentId, {
|
|
4822
4983
|
templateId: opts.templateId,
|
|
@@ -4824,7 +4985,11 @@ Examples:
|
|
|
4824
4985
|
description: opts.description,
|
|
4825
4986
|
variables,
|
|
4826
4987
|
type: opts.type,
|
|
4827
|
-
enableMultiLanguage: opts.enableMultiLanguage
|
|
4988
|
+
enableMultiLanguage: opts.enableMultiLanguage,
|
|
4989
|
+
enableDynamicSize: opts.enableDynamicSize,
|
|
4990
|
+
carouselTemplateGroup,
|
|
4991
|
+
singleItemCardTemplateId: opts.singleItemCardTemplateId,
|
|
4992
|
+
singleItemCardTemplateGroup
|
|
4828
4993
|
});
|
|
4829
4994
|
const data = result?.data ?? result;
|
|
4830
4995
|
printRecord(data, [
|
|
@@ -4838,12 +5003,22 @@ Examples:
|
|
|
4838
5003
|
process.exitCode = handleError(err);
|
|
4839
5004
|
}
|
|
4840
5005
|
});
|
|
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").
|
|
5006
|
+
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(
|
|
5007
|
+
"--carousel-template-group <json>",
|
|
5008
|
+
"Carousel template group JSON with size variants (carousel only)"
|
|
5009
|
+
).option(
|
|
5010
|
+
"--single-item-card-template-id <id>",
|
|
5011
|
+
"Fallback card template ID for single-item carousels"
|
|
5012
|
+
).option(
|
|
5013
|
+
"--single-item-card-template-group <json>",
|
|
5014
|
+
"Single-item card template group JSON for multi-language fallback"
|
|
5015
|
+
).addHelpText(
|
|
4842
5016
|
"after",
|
|
4843
5017
|
`
|
|
4844
5018
|
Examples:
|
|
4845
5019
|
$ nexus deployment template update dep-123 HX456 --name "Updated Welcome"
|
|
4846
|
-
$ nexus deployment template update dep-123 HX456 --variables '{"1":{"description":"Full name"}}'
|
|
5020
|
+
$ nexus deployment template update dep-123 HX456 --variables '{"1":{"description":"Full name"}}'
|
|
5021
|
+
$ nexus deployment template update dep-123 HX456 --enable-dynamic-size --carousel-template-group '{"baseName":"products","availableTemplates":[...]}'`
|
|
4847
5022
|
).action(async (deploymentId, templateId, opts) => {
|
|
4848
5023
|
try {
|
|
4849
5024
|
const body = {};
|
|
@@ -4851,6 +5026,10 @@ Examples:
|
|
|
4851
5026
|
if (opts.description !== void 0) body.description = opts.description;
|
|
4852
5027
|
if (opts.enableMultiLanguage !== void 0)
|
|
4853
5028
|
body.enableMultiLanguage = opts.enableMultiLanguage;
|
|
5029
|
+
if (opts.enableDynamicSize !== void 0)
|
|
5030
|
+
body.enableDynamicSize = opts.enableDynamicSize;
|
|
5031
|
+
if (opts.singleItemCardTemplateId !== void 0)
|
|
5032
|
+
body.singleItemCardTemplateId = opts.singleItemCardTemplateId;
|
|
4854
5033
|
if (opts.variables) {
|
|
4855
5034
|
try {
|
|
4856
5035
|
body.variables = JSON.parse(opts.variables);
|
|
@@ -4860,6 +5039,24 @@ Examples:
|
|
|
4860
5039
|
return;
|
|
4861
5040
|
}
|
|
4862
5041
|
}
|
|
5042
|
+
if (opts.carouselTemplateGroup) {
|
|
5043
|
+
try {
|
|
5044
|
+
body.carouselTemplateGroup = JSON.parse(opts.carouselTemplateGroup);
|
|
5045
|
+
} catch {
|
|
5046
|
+
console.error("Error: --carousel-template-group must be valid JSON.");
|
|
5047
|
+
process.exitCode = 1;
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
5050
|
+
}
|
|
5051
|
+
if (opts.singleItemCardTemplateGroup) {
|
|
5052
|
+
try {
|
|
5053
|
+
body.singleItemCardTemplateGroup = JSON.parse(opts.singleItemCardTemplateGroup);
|
|
5054
|
+
} catch {
|
|
5055
|
+
console.error("Error: --single-item-card-template-group must be valid JSON.");
|
|
5056
|
+
process.exitCode = 1;
|
|
5057
|
+
return;
|
|
5058
|
+
}
|
|
5059
|
+
}
|
|
4863
5060
|
const client = createClient(program2.optsWithGlobals());
|
|
4864
5061
|
const result = await client.deployments.updateDeploymentTemplate(
|
|
4865
5062
|
deploymentId,
|
|
@@ -4886,7 +5083,10 @@ Examples:
|
|
|
4886
5083
|
output: process.stdout
|
|
4887
5084
|
});
|
|
4888
5085
|
const answer = await new Promise((resolve) => {
|
|
4889
|
-
rl.question(
|
|
5086
|
+
rl.question(
|
|
5087
|
+
`Detach template ${templateId} from deployment ${deploymentId}? (y/N) `,
|
|
5088
|
+
resolve
|
|
5089
|
+
);
|
|
4890
5090
|
});
|
|
4891
5091
|
rl.close();
|
|
4892
5092
|
if (answer.toLowerCase() !== "y") {
|
|
@@ -12537,6 +12737,378 @@ Examples:
|
|
|
12537
12737
|
});
|
|
12538
12738
|
}
|
|
12539
12739
|
|
|
12740
|
+
// src/commands/tracing.ts
|
|
12741
|
+
init_output();
|
|
12742
|
+
function registerTracingCommands(program2) {
|
|
12743
|
+
const tracing = program2.command("tracing").description("View LLM traces and analytics");
|
|
12744
|
+
addPaginationOptions(
|
|
12745
|
+
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").option("--start-date <iso>", "Filter from date (ISO 8601)").option("--end-date <iso>", "Filter to date (ISO 8601)").option(
|
|
12746
|
+
"--sort-by <field>",
|
|
12747
|
+
"Sort by field (startedAt, totalCostUsd, totalDurationMs)",
|
|
12748
|
+
"startedAt"
|
|
12749
|
+
).option("--order <dir>", "Sort order (asc, desc)", "desc").addHelpText(
|
|
12750
|
+
"after",
|
|
12751
|
+
`
|
|
12752
|
+
Examples:
|
|
12753
|
+
$ nexus tracing traces
|
|
12754
|
+
$ nexus tracing traces --status FAILED --limit 10
|
|
12755
|
+
$ nexus tracing traces --agent-id abc --start-date 2026-03-01 --json`
|
|
12756
|
+
)
|
|
12757
|
+
).action(async (opts) => {
|
|
12758
|
+
try {
|
|
12759
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12760
|
+
const { data, meta } = await client.tracing.listTraces({
|
|
12761
|
+
...getPaginationParams(opts),
|
|
12762
|
+
status: opts.status,
|
|
12763
|
+
agentId: opts.agentId,
|
|
12764
|
+
workflowId: opts.workflowId,
|
|
12765
|
+
model: opts.model,
|
|
12766
|
+
startDate: opts.startDate,
|
|
12767
|
+
endDate: opts.endDate,
|
|
12768
|
+
sortBy: opts.sortBy,
|
|
12769
|
+
order: opts.order
|
|
12770
|
+
});
|
|
12771
|
+
printList(data, meta, [
|
|
12772
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12773
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12774
|
+
{ key: "agentName", label: "AGENT", width: 20 },
|
|
12775
|
+
{ key: "workflowName", label: "WORKFLOW", width: 20 },
|
|
12776
|
+
{
|
|
12777
|
+
key: "totalCostUsd",
|
|
12778
|
+
label: "COST ($)",
|
|
12779
|
+
width: 10,
|
|
12780
|
+
format: (v) => v != null ? `$${Number(v).toFixed(4)}` : "-"
|
|
12781
|
+
},
|
|
12782
|
+
{
|
|
12783
|
+
key: "totalDurationMs",
|
|
12784
|
+
label: "DURATION",
|
|
12785
|
+
width: 10,
|
|
12786
|
+
format: (v) => v != null ? `${Number(v)}ms` : "-"
|
|
12787
|
+
},
|
|
12788
|
+
{ key: "generationCount", label: "GENS", width: 5 },
|
|
12789
|
+
{ key: "startedAt", label: "STARTED", width: 20 }
|
|
12790
|
+
]);
|
|
12791
|
+
} catch (err) {
|
|
12792
|
+
process.exitCode = handleError(err);
|
|
12793
|
+
}
|
|
12794
|
+
});
|
|
12795
|
+
tracing.command("trace").description("Get trace details with generations").argument("<id>", "Trace ID").addHelpText(
|
|
12796
|
+
"after",
|
|
12797
|
+
`
|
|
12798
|
+
Examples:
|
|
12799
|
+
$ nexus tracing trace abc-123
|
|
12800
|
+
$ nexus tracing trace abc-123 --json`
|
|
12801
|
+
).action(async (id) => {
|
|
12802
|
+
try {
|
|
12803
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12804
|
+
const trace = await client.tracing.getTrace(id);
|
|
12805
|
+
printRecord(trace, [
|
|
12806
|
+
{ key: "id", label: "ID" },
|
|
12807
|
+
{ key: "status", label: "Status" },
|
|
12808
|
+
{ key: "agentName", label: "Agent" },
|
|
12809
|
+
{ key: "workflowName", label: "Workflow" },
|
|
12810
|
+
{ key: "totalCostUsd", label: "Cost ($)", format: (v) => v != null ? `$${Number(v).toFixed(4)}` : "-" },
|
|
12811
|
+
{ key: "totalInputTokens", label: "Input Tokens" },
|
|
12812
|
+
{ key: "totalOutputTokens", label: "Output Tokens" },
|
|
12813
|
+
{ key: "totalDurationMs", label: "Duration (ms)" },
|
|
12814
|
+
{ key: "startedAt", label: "Started" },
|
|
12815
|
+
{ key: "completedAt", label: "Completed" }
|
|
12816
|
+
]);
|
|
12817
|
+
const gens = trace.generations;
|
|
12818
|
+
if (gens && gens.length > 0) {
|
|
12819
|
+
console.log(`
|
|
12820
|
+
${color.bold("Generations")} (${gens.length}):
|
|
12821
|
+
`);
|
|
12822
|
+
printList(gens, void 0, [
|
|
12823
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12824
|
+
{ key: "modelName", label: "MODEL", width: 25 },
|
|
12825
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12826
|
+
{
|
|
12827
|
+
key: "costUsd",
|
|
12828
|
+
label: "COST ($)",
|
|
12829
|
+
width: 10,
|
|
12830
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
12831
|
+
},
|
|
12832
|
+
{
|
|
12833
|
+
key: "durationMs",
|
|
12834
|
+
label: "DURATION",
|
|
12835
|
+
width: 10,
|
|
12836
|
+
format: (v) => v != null ? `${v}ms` : "-"
|
|
12837
|
+
}
|
|
12838
|
+
]);
|
|
12839
|
+
}
|
|
12840
|
+
} catch (err) {
|
|
12841
|
+
process.exitCode = handleError(err);
|
|
12842
|
+
}
|
|
12843
|
+
});
|
|
12844
|
+
tracing.command("delete").description("Delete a trace and its generations").argument("<id>", "Trace ID").addHelpText(
|
|
12845
|
+
"after",
|
|
12846
|
+
`
|
|
12847
|
+
Examples:
|
|
12848
|
+
$ nexus tracing delete abc-123`
|
|
12849
|
+
).action(async (id) => {
|
|
12850
|
+
try {
|
|
12851
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12852
|
+
await client.tracing.deleteTrace(id);
|
|
12853
|
+
printSuccess("Trace deleted.", { id });
|
|
12854
|
+
} catch (err) {
|
|
12855
|
+
process.exitCode = handleError(err);
|
|
12856
|
+
}
|
|
12857
|
+
});
|
|
12858
|
+
addPaginationOptions(
|
|
12859
|
+
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").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").option("--end-date <iso>", "Filter to date").option("--min-cost <usd>", "Minimum cost in USD").option("--max-cost <usd>", "Maximum cost in USD").addHelpText(
|
|
12860
|
+
"after",
|
|
12861
|
+
`
|
|
12862
|
+
Examples:
|
|
12863
|
+
$ nexus tracing generations
|
|
12864
|
+
$ nexus tracing generations --provider ANTHROPIC --status FAILED
|
|
12865
|
+
$ nexus tracing generations --trace-id abc-123 --json`
|
|
12866
|
+
)
|
|
12867
|
+
).action(async (opts) => {
|
|
12868
|
+
try {
|
|
12869
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12870
|
+
const { data, meta } = await client.tracing.listGenerations({
|
|
12871
|
+
...getPaginationParams(opts),
|
|
12872
|
+
traceId: opts.traceId,
|
|
12873
|
+
provider: opts.provider,
|
|
12874
|
+
modelName: opts.model,
|
|
12875
|
+
status: opts.status,
|
|
12876
|
+
agentId: opts.agentId,
|
|
12877
|
+
taskId: opts.taskId,
|
|
12878
|
+
startDate: opts.startDate,
|
|
12879
|
+
endDate: opts.endDate,
|
|
12880
|
+
minCostUsd: opts.minCost ? parseFloat(opts.minCost) : void 0,
|
|
12881
|
+
maxCostUsd: opts.maxCost ? parseFloat(opts.maxCost) : void 0
|
|
12882
|
+
});
|
|
12883
|
+
printList(data, meta, [
|
|
12884
|
+
{ key: "id", label: "ID", width: 36 },
|
|
12885
|
+
{ key: "traceId", label: "TRACE", width: 36 },
|
|
12886
|
+
{ key: "modelName", label: "MODEL", width: 25 },
|
|
12887
|
+
{ key: "status", label: "STATUS", width: 12, format: formatStatus },
|
|
12888
|
+
{
|
|
12889
|
+
key: "costUsd",
|
|
12890
|
+
label: "COST ($)",
|
|
12891
|
+
width: 10,
|
|
12892
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
12893
|
+
},
|
|
12894
|
+
{
|
|
12895
|
+
key: "durationMs",
|
|
12896
|
+
label: "DURATION",
|
|
12897
|
+
width: 10,
|
|
12898
|
+
format: (v) => v != null ? `${v}ms` : "-"
|
|
12899
|
+
}
|
|
12900
|
+
]);
|
|
12901
|
+
} catch (err) {
|
|
12902
|
+
process.exitCode = handleError(err);
|
|
12903
|
+
}
|
|
12904
|
+
});
|
|
12905
|
+
tracing.command("generation").description("Get generation details including prompt and response").argument("<id>", "Generation ID").addHelpText(
|
|
12906
|
+
"after",
|
|
12907
|
+
`
|
|
12908
|
+
Examples:
|
|
12909
|
+
$ nexus tracing generation gen-123
|
|
12910
|
+
$ nexus tracing generation gen-123 --json`
|
|
12911
|
+
).action(async (id) => {
|
|
12912
|
+
try {
|
|
12913
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12914
|
+
const gen = await client.tracing.getGeneration(id);
|
|
12915
|
+
printRecord(gen, [
|
|
12916
|
+
{ key: "id", label: "ID" },
|
|
12917
|
+
{ key: "traceId", label: "Trace ID" },
|
|
12918
|
+
{ key: "provider", label: "Provider" },
|
|
12919
|
+
{ key: "modelName", label: "Model" },
|
|
12920
|
+
{ key: "status", label: "Status" },
|
|
12921
|
+
{ key: "inputTokens", label: "Input Tokens" },
|
|
12922
|
+
{ key: "outputTokens", label: "Output Tokens" },
|
|
12923
|
+
{
|
|
12924
|
+
key: "costUsd",
|
|
12925
|
+
label: "Cost ($)",
|
|
12926
|
+
format: (v) => v != null ? `$${Number(v).toFixed(6)}` : "-"
|
|
12927
|
+
},
|
|
12928
|
+
{ key: "durationMs", label: "Duration (ms)" },
|
|
12929
|
+
{ key: "temperature", label: "Temperature" },
|
|
12930
|
+
{ key: "taskName", label: "Task" },
|
|
12931
|
+
{ key: "startedAt", label: "Started" },
|
|
12932
|
+
{ key: "completedAt", label: "Completed" },
|
|
12933
|
+
{ key: "errorMessage", label: "Error" }
|
|
12934
|
+
]);
|
|
12935
|
+
} catch (err) {
|
|
12936
|
+
process.exitCode = handleError(err);
|
|
12937
|
+
}
|
|
12938
|
+
});
|
|
12939
|
+
tracing.command("models").description("List distinct model names used in traces").addHelpText(
|
|
12940
|
+
"after",
|
|
12941
|
+
`
|
|
12942
|
+
Examples:
|
|
12943
|
+
$ nexus tracing models`
|
|
12944
|
+
).action(async () => {
|
|
12945
|
+
try {
|
|
12946
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12947
|
+
const models = await client.tracing.listModels();
|
|
12948
|
+
if (Array.isArray(models) && models.length > 0) {
|
|
12949
|
+
for (const m of models) console.log(m);
|
|
12950
|
+
} else {
|
|
12951
|
+
console.log("No models found.");
|
|
12952
|
+
}
|
|
12953
|
+
} catch (err) {
|
|
12954
|
+
process.exitCode = handleError(err);
|
|
12955
|
+
}
|
|
12956
|
+
});
|
|
12957
|
+
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(
|
|
12958
|
+
"after",
|
|
12959
|
+
`
|
|
12960
|
+
Examples:
|
|
12961
|
+
$ nexus tracing summary
|
|
12962
|
+
$ nexus tracing summary --start-date 2026-03-01 --end-date 2026-03-30
|
|
12963
|
+
$ nexus tracing summary --json`
|
|
12964
|
+
).action(async (opts) => {
|
|
12965
|
+
try {
|
|
12966
|
+
const client = createClient(program2.optsWithGlobals());
|
|
12967
|
+
const summary = await client.tracing.getSummary({
|
|
12968
|
+
startDate: opts.startDate,
|
|
12969
|
+
endDate: opts.endDate
|
|
12970
|
+
});
|
|
12971
|
+
printRecord(summary, [
|
|
12972
|
+
{ key: "totalTraces", label: "Total Traces" },
|
|
12973
|
+
{ key: "completedTraces", label: "Completed" },
|
|
12974
|
+
{ key: "failedTraces", label: "Failed" },
|
|
12975
|
+
{ key: "inProgressTraces", label: "In Progress" },
|
|
12976
|
+
{
|
|
12977
|
+
key: "totalCostUsd",
|
|
12978
|
+
label: "Total Cost ($)",
|
|
12979
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
12980
|
+
},
|
|
12981
|
+
{ key: "totalInputTokens", label: "Input Tokens" },
|
|
12982
|
+
{ key: "totalOutputTokens", label: "Output Tokens" },
|
|
12983
|
+
{
|
|
12984
|
+
key: "avgDurationMs",
|
|
12985
|
+
label: "Avg Duration",
|
|
12986
|
+
format: (v) => v != null ? `${Number(v).toFixed(0)}ms` : "-"
|
|
12987
|
+
},
|
|
12988
|
+
{ key: "distinctModelCount", label: "Distinct Models" }
|
|
12989
|
+
]);
|
|
12990
|
+
} catch (err) {
|
|
12991
|
+
process.exitCode = handleError(err);
|
|
12992
|
+
}
|
|
12993
|
+
});
|
|
12994
|
+
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(
|
|
12995
|
+
"after",
|
|
12996
|
+
`
|
|
12997
|
+
Examples:
|
|
12998
|
+
$ nexus tracing cost-breakdown
|
|
12999
|
+
$ nexus tracing cost-breakdown --group-by agent
|
|
13000
|
+
$ nexus tracing cost-breakdown --group-by workflow --json`
|
|
13001
|
+
).action(async (opts) => {
|
|
13002
|
+
try {
|
|
13003
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13004
|
+
const result = await client.tracing.getCostBreakdown({
|
|
13005
|
+
groupBy: opts.groupBy,
|
|
13006
|
+
startDate: opts.startDate,
|
|
13007
|
+
endDate: opts.endDate
|
|
13008
|
+
});
|
|
13009
|
+
const entries = result.entries ?? [];
|
|
13010
|
+
printList(entries, void 0, [
|
|
13011
|
+
{ key: "groupKey", label: "KEY", width: 36 },
|
|
13012
|
+
{ key: "groupLabel", label: "LABEL", width: 25 },
|
|
13013
|
+
{
|
|
13014
|
+
key: "totalCostUsd",
|
|
13015
|
+
label: "COST ($)",
|
|
13016
|
+
width: 12,
|
|
13017
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
13018
|
+
},
|
|
13019
|
+
{ key: "traceCount", label: "TRACES", width: 8 },
|
|
13020
|
+
{ key: "generationCount", label: "GENS", width: 8 },
|
|
13021
|
+
{ key: "totalInputTokens", label: "IN TOKENS", width: 12 },
|
|
13022
|
+
{ key: "totalOutputTokens", label: "OUT TOKENS", width: 12 }
|
|
13023
|
+
]);
|
|
13024
|
+
} catch (err) {
|
|
13025
|
+
process.exitCode = handleError(err);
|
|
13026
|
+
}
|
|
13027
|
+
});
|
|
13028
|
+
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(
|
|
13029
|
+
"after",
|
|
13030
|
+
`
|
|
13031
|
+
Examples:
|
|
13032
|
+
$ nexus tracing timeline
|
|
13033
|
+
$ nexus tracing timeline --granularity hour --start-date 2026-03-29 --json`
|
|
13034
|
+
).action(async (opts) => {
|
|
13035
|
+
try {
|
|
13036
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13037
|
+
const result = await client.tracing.getTimeline({
|
|
13038
|
+
granularity: opts.granularity,
|
|
13039
|
+
startDate: opts.startDate,
|
|
13040
|
+
endDate: opts.endDate
|
|
13041
|
+
});
|
|
13042
|
+
const points = result.points ?? [];
|
|
13043
|
+
printList(points, void 0, [
|
|
13044
|
+
{ key: "date", label: "DATE", width: 22 },
|
|
13045
|
+
{ key: "traceCount", label: "TRACES", width: 8 },
|
|
13046
|
+
{ key: "generationCount", label: "GENS", width: 8 },
|
|
13047
|
+
{
|
|
13048
|
+
key: "totalCostUsd",
|
|
13049
|
+
label: "COST ($)",
|
|
13050
|
+
width: 12,
|
|
13051
|
+
format: (v) => `$${Number(v).toFixed(4)}`
|
|
13052
|
+
},
|
|
13053
|
+
{
|
|
13054
|
+
key: "avgDurationMs",
|
|
13055
|
+
label: "AVG DUR",
|
|
13056
|
+
width: 10,
|
|
13057
|
+
format: (v) => v != null ? `${Number(v).toFixed(0)}ms` : "-"
|
|
13058
|
+
}
|
|
13059
|
+
]);
|
|
13060
|
+
} catch (err) {
|
|
13061
|
+
process.exitCode = handleError(err);
|
|
13062
|
+
}
|
|
13063
|
+
});
|
|
13064
|
+
tracing.command("export").description("Export a single trace").argument("<id>", "Trace ID").option("--format <fmt>", "Output format (json, csv)", "json").addHelpText(
|
|
13065
|
+
"after",
|
|
13066
|
+
`
|
|
13067
|
+
Examples:
|
|
13068
|
+
$ nexus tracing export abc-123
|
|
13069
|
+
$ nexus tracing export abc-123 --format csv > trace.csv`
|
|
13070
|
+
).action(async (id, opts) => {
|
|
13071
|
+
try {
|
|
13072
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13073
|
+
const result = await client.tracing.exportTrace(id, { format: opts.format });
|
|
13074
|
+
console.log(result.content);
|
|
13075
|
+
} catch (err) {
|
|
13076
|
+
process.exitCode = handleError(err);
|
|
13077
|
+
}
|
|
13078
|
+
});
|
|
13079
|
+
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(
|
|
13080
|
+
"after",
|
|
13081
|
+
`
|
|
13082
|
+
Examples:
|
|
13083
|
+
$ nexus tracing export-bulk --format csv > traces.csv
|
|
13084
|
+
$ nexus tracing export-bulk --status FAILED --limit 50`
|
|
13085
|
+
).action(async (opts) => {
|
|
13086
|
+
try {
|
|
13087
|
+
const client = createClient(program2.optsWithGlobals());
|
|
13088
|
+
const result = await client.tracing.bulkExport({
|
|
13089
|
+
format: opts.format,
|
|
13090
|
+
status: opts.status,
|
|
13091
|
+
agentId: opts.agentId,
|
|
13092
|
+
workflowId: opts.workflowId,
|
|
13093
|
+
startDate: opts.startDate,
|
|
13094
|
+
endDate: opts.endDate,
|
|
13095
|
+
limit: parseInt(opts.limit, 10)
|
|
13096
|
+
});
|
|
13097
|
+
console.log(result.content);
|
|
13098
|
+
} catch (err) {
|
|
13099
|
+
process.exitCode = handleError(err);
|
|
13100
|
+
}
|
|
13101
|
+
});
|
|
13102
|
+
}
|
|
13103
|
+
function formatStatus(v) {
|
|
13104
|
+
const s = String(v);
|
|
13105
|
+
if (s === "COMPLETED") return color.green(s);
|
|
13106
|
+
if (s === "FAILED") return color.red(s);
|
|
13107
|
+
if (s === "IN_PROGRESS" || s === "RUNNING") return color.yellow(s);
|
|
13108
|
+
if (s === "PENDING") return color.dim(s);
|
|
13109
|
+
return s;
|
|
13110
|
+
}
|
|
13111
|
+
|
|
12540
13112
|
// src/commands/upgrade.ts
|
|
12541
13113
|
var import_node_child_process3 = require("child_process");
|
|
12542
13114
|
init_output();
|
|
@@ -13586,6 +14158,7 @@ registerModelCommands(program);
|
|
|
13586
14158
|
registerCustomModelCommands(program);
|
|
13587
14159
|
registerPhoneNumberCommands(program);
|
|
13588
14160
|
registerChannelCommands(program);
|
|
14161
|
+
registerTracingCommands(program);
|
|
13589
14162
|
registerUpgradeCommand(program);
|
|
13590
14163
|
registerDocsCommand(program);
|
|
13591
14164
|
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.13",
|
|
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.15"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"gen:docs": "tsx scripts/bundle-docs.ts",
|