olakai-cli 0.1.2 → 0.1.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 +73 -1
- package/dist/index.js +754 -0
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -404,6 +404,262 @@ async function deleteWorkflow(id) {
|
|
|
404
404
|
throw new Error(error.error || "Failed to delete workflow");
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
|
+
async function listKpis(options) {
|
|
408
|
+
const token = getValidToken();
|
|
409
|
+
if (!token) {
|
|
410
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
411
|
+
}
|
|
412
|
+
const params = new URLSearchParams();
|
|
413
|
+
if (options?.agentId) {
|
|
414
|
+
params.set("agentId", options.agentId);
|
|
415
|
+
}
|
|
416
|
+
if (options?.includeInactive) {
|
|
417
|
+
params.set("includeInactive", "true");
|
|
418
|
+
}
|
|
419
|
+
const url = `${getBaseUrl()}/api/config/kpis${params.toString() ? `?${params}` : ""}`;
|
|
420
|
+
const response = await fetch(url, {
|
|
421
|
+
headers: {
|
|
422
|
+
Authorization: `Bearer ${token}`
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
if (!response.ok) {
|
|
426
|
+
if (response.status === 401) {
|
|
427
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
428
|
+
}
|
|
429
|
+
const error = await response.json();
|
|
430
|
+
throw new Error(error.error || "Failed to list KPIs");
|
|
431
|
+
}
|
|
432
|
+
const data = await response.json();
|
|
433
|
+
return data.kpiDefinitions;
|
|
434
|
+
}
|
|
435
|
+
async function getKpi(id) {
|
|
436
|
+
const token = getValidToken();
|
|
437
|
+
if (!token) {
|
|
438
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
439
|
+
}
|
|
440
|
+
const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {
|
|
441
|
+
headers: {
|
|
442
|
+
Authorization: `Bearer ${token}`
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
if (!response.ok) {
|
|
446
|
+
if (response.status === 401) {
|
|
447
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
448
|
+
}
|
|
449
|
+
if (response.status === 404) {
|
|
450
|
+
throw new Error("KPI definition not found");
|
|
451
|
+
}
|
|
452
|
+
const error = await response.json();
|
|
453
|
+
throw new Error(error.error || "Failed to get KPI");
|
|
454
|
+
}
|
|
455
|
+
return await response.json();
|
|
456
|
+
}
|
|
457
|
+
async function createKpi(payload) {
|
|
458
|
+
const token = getValidToken();
|
|
459
|
+
if (!token) {
|
|
460
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
461
|
+
}
|
|
462
|
+
const response = await fetch(`${getBaseUrl()}/api/config/kpis`, {
|
|
463
|
+
method: "POST",
|
|
464
|
+
headers: {
|
|
465
|
+
Authorization: `Bearer ${token}`,
|
|
466
|
+
"Content-Type": "application/json"
|
|
467
|
+
},
|
|
468
|
+
body: JSON.stringify(payload)
|
|
469
|
+
});
|
|
470
|
+
if (!response.ok) {
|
|
471
|
+
if (response.status === 401) {
|
|
472
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
473
|
+
}
|
|
474
|
+
if (response.status === 409) {
|
|
475
|
+
throw new Error("A KPI definition with this name already exists");
|
|
476
|
+
}
|
|
477
|
+
const error = await response.json();
|
|
478
|
+
throw new Error(error.error || "Failed to create KPI");
|
|
479
|
+
}
|
|
480
|
+
return await response.json();
|
|
481
|
+
}
|
|
482
|
+
async function updateKpi(id, payload) {
|
|
483
|
+
const token = getValidToken();
|
|
484
|
+
if (!token) {
|
|
485
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
486
|
+
}
|
|
487
|
+
const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {
|
|
488
|
+
method: "PUT",
|
|
489
|
+
headers: {
|
|
490
|
+
Authorization: `Bearer ${token}`,
|
|
491
|
+
"Content-Type": "application/json"
|
|
492
|
+
},
|
|
493
|
+
body: JSON.stringify(payload)
|
|
494
|
+
});
|
|
495
|
+
if (!response.ok) {
|
|
496
|
+
if (response.status === 401) {
|
|
497
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
498
|
+
}
|
|
499
|
+
if (response.status === 404) {
|
|
500
|
+
throw new Error("KPI definition not found");
|
|
501
|
+
}
|
|
502
|
+
if (response.status === 409) {
|
|
503
|
+
throw new Error("A KPI definition with this name already exists");
|
|
504
|
+
}
|
|
505
|
+
const error = await response.json();
|
|
506
|
+
throw new Error(error.error || "Failed to update KPI");
|
|
507
|
+
}
|
|
508
|
+
return await response.json();
|
|
509
|
+
}
|
|
510
|
+
async function deleteKpi(id) {
|
|
511
|
+
const token = getValidToken();
|
|
512
|
+
if (!token) {
|
|
513
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
514
|
+
}
|
|
515
|
+
const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {
|
|
516
|
+
method: "DELETE",
|
|
517
|
+
headers: {
|
|
518
|
+
Authorization: `Bearer ${token}`
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
if (!response.ok) {
|
|
522
|
+
if (response.status === 401) {
|
|
523
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
524
|
+
}
|
|
525
|
+
if (response.status === 404) {
|
|
526
|
+
throw new Error("KPI definition not found");
|
|
527
|
+
}
|
|
528
|
+
const error = await response.json();
|
|
529
|
+
throw new Error(error.error || "Failed to delete KPI");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
async function getKpiContextVariables(agentId) {
|
|
533
|
+
const token = getValidToken();
|
|
534
|
+
if (!token) {
|
|
535
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
536
|
+
}
|
|
537
|
+
const params = new URLSearchParams();
|
|
538
|
+
if (agentId) {
|
|
539
|
+
params.set("agentId", agentId);
|
|
540
|
+
}
|
|
541
|
+
const url = `${getBaseUrl()}/api/config/kpis/context-variables${params.toString() ? `?${params}` : ""}`;
|
|
542
|
+
const response = await fetch(url, {
|
|
543
|
+
headers: {
|
|
544
|
+
Authorization: `Bearer ${token}`
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
if (!response.ok) {
|
|
548
|
+
if (response.status === 401) {
|
|
549
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
550
|
+
}
|
|
551
|
+
const error = await response.json();
|
|
552
|
+
throw new Error(error.error || "Failed to get context variables");
|
|
553
|
+
}
|
|
554
|
+
const data = await response.json();
|
|
555
|
+
return data.contextVariables;
|
|
556
|
+
}
|
|
557
|
+
async function validateKpiFormula(formula, agentId) {
|
|
558
|
+
const token = getValidToken();
|
|
559
|
+
if (!token) {
|
|
560
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
561
|
+
}
|
|
562
|
+
const response = await fetch(`${getBaseUrl()}/api/config/kpis/validate`, {
|
|
563
|
+
method: "POST",
|
|
564
|
+
headers: {
|
|
565
|
+
Authorization: `Bearer ${token}`,
|
|
566
|
+
"Content-Type": "application/json"
|
|
567
|
+
},
|
|
568
|
+
body: JSON.stringify({ formula, agentId })
|
|
569
|
+
});
|
|
570
|
+
if (!response.ok) {
|
|
571
|
+
if (response.status === 401) {
|
|
572
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
573
|
+
}
|
|
574
|
+
const error = await response.json();
|
|
575
|
+
throw new Error(error.error || "Failed to validate formula");
|
|
576
|
+
}
|
|
577
|
+
return await response.json();
|
|
578
|
+
}
|
|
579
|
+
async function listActivity(options = {}) {
|
|
580
|
+
const token = getValidToken();
|
|
581
|
+
if (!token) {
|
|
582
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
583
|
+
}
|
|
584
|
+
const params = new URLSearchParams();
|
|
585
|
+
if (options.agentId) params.set("agentId", options.agentId);
|
|
586
|
+
if (options.workflowId) params.set("workflowId", options.workflowId);
|
|
587
|
+
if (options.since) params.set("since", options.since);
|
|
588
|
+
if (options.until) params.set("until", options.until);
|
|
589
|
+
if (options.limit !== void 0) params.set("limit", String(options.limit));
|
|
590
|
+
if (options.offset !== void 0) params.set("offset", String(options.offset));
|
|
591
|
+
if (options.includeContent) params.set("includeContent", "true");
|
|
592
|
+
if (options.includeAnalytics) params.set("includeAnalytics", "true");
|
|
593
|
+
const url = `${getBaseUrl()}/api/activity/prompts${params.toString() ? `?${params}` : ""}`;
|
|
594
|
+
const response = await fetch(url, {
|
|
595
|
+
headers: {
|
|
596
|
+
Authorization: `Bearer ${token}`
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
if (!response.ok) {
|
|
600
|
+
if (response.status === 401) {
|
|
601
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
602
|
+
}
|
|
603
|
+
const error = await response.json();
|
|
604
|
+
throw new Error(error.error || "Failed to list activity");
|
|
605
|
+
}
|
|
606
|
+
return await response.json();
|
|
607
|
+
}
|
|
608
|
+
async function getActivity(id, includeContent) {
|
|
609
|
+
const token = getValidToken();
|
|
610
|
+
if (!token) {
|
|
611
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
612
|
+
}
|
|
613
|
+
const params = new URLSearchParams();
|
|
614
|
+
if (includeContent) params.set("includeContent", "true");
|
|
615
|
+
const url = `${getBaseUrl()}/api/activity/prompts/${id}${params.toString() ? `?${params}` : ""}`;
|
|
616
|
+
const response = await fetch(url, {
|
|
617
|
+
headers: {
|
|
618
|
+
Authorization: `Bearer ${token}`
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
if (!response.ok) {
|
|
622
|
+
if (response.status === 401) {
|
|
623
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
624
|
+
}
|
|
625
|
+
if (response.status === 404) {
|
|
626
|
+
throw new Error("Prompt request not found");
|
|
627
|
+
}
|
|
628
|
+
const error = await response.json();
|
|
629
|
+
throw new Error(error.error || "Failed to get activity");
|
|
630
|
+
}
|
|
631
|
+
return await response.json();
|
|
632
|
+
}
|
|
633
|
+
async function getActivityKpis(options) {
|
|
634
|
+
const token = getValidToken();
|
|
635
|
+
if (!token) {
|
|
636
|
+
throw new Error("Not logged in. Run 'olakai login' first.");
|
|
637
|
+
}
|
|
638
|
+
if (!options.agentId && !options.workflowId) {
|
|
639
|
+
throw new Error("Either agentId or workflowId is required");
|
|
640
|
+
}
|
|
641
|
+
const params = new URLSearchParams();
|
|
642
|
+
if (options.agentId) params.set("agentId", options.agentId);
|
|
643
|
+
if (options.workflowId) params.set("workflowId", options.workflowId);
|
|
644
|
+
if (options.since) params.set("since", options.since);
|
|
645
|
+
if (options.until) params.set("until", options.until);
|
|
646
|
+
if (options.period) params.set("period", options.period);
|
|
647
|
+
if (options.includeAtoms) params.set("includeAtoms", "true");
|
|
648
|
+
const url = `${getBaseUrl()}/api/activity/kpis${params.toString() ? `?${params}` : ""}`;
|
|
649
|
+
const response = await fetch(url, {
|
|
650
|
+
headers: {
|
|
651
|
+
Authorization: `Bearer ${token}`
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
if (!response.ok) {
|
|
655
|
+
if (response.status === 401) {
|
|
656
|
+
throw new Error("Session expired. Run 'olakai login' to authenticate again.");
|
|
657
|
+
}
|
|
658
|
+
const error = await response.json();
|
|
659
|
+
throw new Error(error.error || "Failed to get activity KPIs");
|
|
660
|
+
}
|
|
661
|
+
return await response.json();
|
|
662
|
+
}
|
|
407
663
|
|
|
408
664
|
// src/commands/login.ts
|
|
409
665
|
var POLL_INTERVAL_MS = 5e3;
|
|
@@ -834,6 +1090,502 @@ function registerWorkflowsCommand(program2) {
|
|
|
834
1090
|
workflows.command("delete <id>").description("Delete a workflow").option("--force", "Skip confirmation").action(deleteCommand2);
|
|
835
1091
|
}
|
|
836
1092
|
|
|
1093
|
+
// src/commands/kpis.ts
|
|
1094
|
+
var AGGREGATION_METHODS = [
|
|
1095
|
+
"SUM",
|
|
1096
|
+
"AVERAGE",
|
|
1097
|
+
"COUNT",
|
|
1098
|
+
"MIN",
|
|
1099
|
+
"MAX",
|
|
1100
|
+
"LATEST"
|
|
1101
|
+
];
|
|
1102
|
+
var CALCULATOR_IDS = ["formula", "classifier", "llm-data"];
|
|
1103
|
+
function formatKpiTable(kpis) {
|
|
1104
|
+
if (kpis.length === 0) {
|
|
1105
|
+
console.log("No KPI definitions found.");
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const headers = ["ID", "NAME", "CALCULATOR", "AGGREGATION", "STATUS"];
|
|
1109
|
+
const rows = kpis.map((kpi) => [
|
|
1110
|
+
kpi.id.slice(0, 12) + "...",
|
|
1111
|
+
kpi.name.slice(0, 25),
|
|
1112
|
+
kpi.calculatorId,
|
|
1113
|
+
kpi.defaultAggregationMethod,
|
|
1114
|
+
kpi.isActive ? "Active" : "Inactive"
|
|
1115
|
+
]);
|
|
1116
|
+
const widths = headers.map(
|
|
1117
|
+
(h, i) => Math.max(h.length, ...rows.map((r) => r[i].length))
|
|
1118
|
+
);
|
|
1119
|
+
console.log(headers.map((h, i) => h.padEnd(widths[i])).join(" "));
|
|
1120
|
+
console.log(widths.map((w) => "-".repeat(w)).join(" "));
|
|
1121
|
+
for (const row of rows) {
|
|
1122
|
+
console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(" "));
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
function formatKpiDetail(kpi) {
|
|
1126
|
+
console.log(`ID: ${kpi.id}`);
|
|
1127
|
+
console.log(`Name: ${kpi.name}`);
|
|
1128
|
+
console.log(`Description: ${kpi.description || "-"}`);
|
|
1129
|
+
console.log(`Type: ${kpi.type}`);
|
|
1130
|
+
console.log(`Category: ${kpi.category || "-"}`);
|
|
1131
|
+
console.log(`Agent ID: ${kpi.agentId || "-"}`);
|
|
1132
|
+
console.log(`Calculator: ${kpi.calculatorId}`);
|
|
1133
|
+
console.log(`Aggregation: ${kpi.defaultAggregationMethod}`);
|
|
1134
|
+
console.log(`Unit: ${kpi.unit || "-"}`);
|
|
1135
|
+
console.log(`Status: ${kpi.isActive ? "Active" : "Inactive"}`);
|
|
1136
|
+
if (kpi.calculatorParams) {
|
|
1137
|
+
console.log("");
|
|
1138
|
+
console.log("Calculator Parameters:");
|
|
1139
|
+
console.log(JSON.stringify(kpi.calculatorParams, null, 2));
|
|
1140
|
+
}
|
|
1141
|
+
if (kpi.createdAt) {
|
|
1142
|
+
console.log("");
|
|
1143
|
+
console.log(`Created: ${new Date(kpi.createdAt).toISOString()}`);
|
|
1144
|
+
}
|
|
1145
|
+
if (kpi.updatedAt) {
|
|
1146
|
+
console.log(`Updated: ${new Date(kpi.updatedAt).toISOString()}`);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
function formatContextVariablesTable(variables) {
|
|
1150
|
+
if (variables.length === 0) {
|
|
1151
|
+
console.log("No context variables found.");
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const headers = ["NAME", "TYPE", "SOURCE", "DESCRIPTION"];
|
|
1155
|
+
const rows = variables.map((v) => [
|
|
1156
|
+
v.name,
|
|
1157
|
+
v.type,
|
|
1158
|
+
v.source,
|
|
1159
|
+
v.description.slice(0, 50)
|
|
1160
|
+
]);
|
|
1161
|
+
const widths = headers.map(
|
|
1162
|
+
(h, i) => Math.max(h.length, ...rows.map((r) => r[i].length))
|
|
1163
|
+
);
|
|
1164
|
+
console.log(headers.map((h, i) => h.padEnd(widths[i])).join(" "));
|
|
1165
|
+
console.log(widths.map((w) => "-".repeat(w)).join(" "));
|
|
1166
|
+
for (const row of rows) {
|
|
1167
|
+
console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(" "));
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
async function listCommand3(options) {
|
|
1171
|
+
try {
|
|
1172
|
+
const kpis = await listKpis({
|
|
1173
|
+
agentId: options.agentId,
|
|
1174
|
+
includeInactive: options.includeInactive
|
|
1175
|
+
});
|
|
1176
|
+
if (options.json) {
|
|
1177
|
+
console.log(JSON.stringify(kpis, null, 2));
|
|
1178
|
+
} else {
|
|
1179
|
+
formatKpiTable(kpis);
|
|
1180
|
+
}
|
|
1181
|
+
} catch (error) {
|
|
1182
|
+
console.error(
|
|
1183
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1184
|
+
);
|
|
1185
|
+
process.exit(1);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
async function getCommand3(id, options) {
|
|
1189
|
+
try {
|
|
1190
|
+
const kpi = await getKpi(id);
|
|
1191
|
+
if (options.json) {
|
|
1192
|
+
console.log(JSON.stringify(kpi, null, 2));
|
|
1193
|
+
} else {
|
|
1194
|
+
formatKpiDetail(kpi);
|
|
1195
|
+
}
|
|
1196
|
+
} catch (error) {
|
|
1197
|
+
console.error(
|
|
1198
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1199
|
+
);
|
|
1200
|
+
process.exit(1);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
async function createCommand3(options) {
|
|
1204
|
+
try {
|
|
1205
|
+
if (!options.name) {
|
|
1206
|
+
console.error("Error: --name is required");
|
|
1207
|
+
process.exit(1);
|
|
1208
|
+
}
|
|
1209
|
+
if (!options.calculatorId) {
|
|
1210
|
+
console.error("Error: --calculator-id is required");
|
|
1211
|
+
console.error(`Valid values: ${CALCULATOR_IDS.join(", ")}`);
|
|
1212
|
+
process.exit(1);
|
|
1213
|
+
}
|
|
1214
|
+
if (!CALCULATOR_IDS.includes(options.calculatorId)) {
|
|
1215
|
+
console.error(`Error: Invalid calculator ID "${options.calculatorId}"`);
|
|
1216
|
+
console.error(`Valid values: ${CALCULATOR_IDS.join(", ")}`);
|
|
1217
|
+
process.exit(1);
|
|
1218
|
+
}
|
|
1219
|
+
let calculatorParams;
|
|
1220
|
+
if (options.calculatorId === "formula") {
|
|
1221
|
+
if (!options.formula) {
|
|
1222
|
+
console.error(
|
|
1223
|
+
"Error: --formula is required when calculator-id is 'formula'"
|
|
1224
|
+
);
|
|
1225
|
+
process.exit(1);
|
|
1226
|
+
}
|
|
1227
|
+
calculatorParams = { formula: options.formula };
|
|
1228
|
+
}
|
|
1229
|
+
let aggregation;
|
|
1230
|
+
if (options.aggregation) {
|
|
1231
|
+
const upperAggregation = options.aggregation.toUpperCase();
|
|
1232
|
+
if (!AGGREGATION_METHODS.includes(upperAggregation)) {
|
|
1233
|
+
console.error(`Error: Invalid aggregation method "${options.aggregation}"`);
|
|
1234
|
+
console.error(`Valid values: ${AGGREGATION_METHODS.join(", ")}`);
|
|
1235
|
+
process.exit(1);
|
|
1236
|
+
}
|
|
1237
|
+
aggregation = upperAggregation;
|
|
1238
|
+
}
|
|
1239
|
+
const payload = {
|
|
1240
|
+
name: options.name,
|
|
1241
|
+
calculatorId: options.calculatorId,
|
|
1242
|
+
description: options.description,
|
|
1243
|
+
type: options.type === "PREDEFINED" ? "PREDEFINED" : "USER_DEFINED",
|
|
1244
|
+
category: options.category,
|
|
1245
|
+
agentId: options.agentId,
|
|
1246
|
+
calculatorParams,
|
|
1247
|
+
unit: options.unit,
|
|
1248
|
+
defaultAggregationMethod: aggregation
|
|
1249
|
+
};
|
|
1250
|
+
const kpi = await createKpi(payload);
|
|
1251
|
+
if (options.json) {
|
|
1252
|
+
console.log(JSON.stringify(kpi, null, 2));
|
|
1253
|
+
} else {
|
|
1254
|
+
console.log("KPI definition created successfully!");
|
|
1255
|
+
console.log("");
|
|
1256
|
+
formatKpiDetail(kpi);
|
|
1257
|
+
}
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
console.error(
|
|
1260
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1261
|
+
);
|
|
1262
|
+
process.exit(1);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
async function updateCommand3(id, options) {
|
|
1266
|
+
try {
|
|
1267
|
+
const payload = {};
|
|
1268
|
+
if (options.name !== void 0) payload.name = options.name;
|
|
1269
|
+
if (options.description !== void 0)
|
|
1270
|
+
payload.description = options.description;
|
|
1271
|
+
if (options.category !== void 0) payload.category = options.category;
|
|
1272
|
+
if (options.agentId !== void 0) payload.agentId = options.agentId;
|
|
1273
|
+
if (options.calculatorId !== void 0)
|
|
1274
|
+
payload.calculatorId = options.calculatorId;
|
|
1275
|
+
if (options.unit !== void 0) payload.unit = options.unit;
|
|
1276
|
+
if (options.active) payload.isActive = true;
|
|
1277
|
+
if (options.inactive) payload.isActive = false;
|
|
1278
|
+
if (options.formula !== void 0) {
|
|
1279
|
+
payload.calculatorParams = { formula: options.formula };
|
|
1280
|
+
}
|
|
1281
|
+
if (options.aggregation) {
|
|
1282
|
+
const upperAggregation = options.aggregation.toUpperCase();
|
|
1283
|
+
if (!AGGREGATION_METHODS.includes(upperAggregation)) {
|
|
1284
|
+
console.error(`Error: Invalid aggregation method "${options.aggregation}"`);
|
|
1285
|
+
console.error(`Valid values: ${AGGREGATION_METHODS.join(", ")}`);
|
|
1286
|
+
process.exit(1);
|
|
1287
|
+
}
|
|
1288
|
+
payload.defaultAggregationMethod = upperAggregation;
|
|
1289
|
+
}
|
|
1290
|
+
if (Object.keys(payload).length === 0) {
|
|
1291
|
+
console.error("Error: At least one field to update is required");
|
|
1292
|
+
process.exit(1);
|
|
1293
|
+
}
|
|
1294
|
+
const kpi = await updateKpi(id, payload);
|
|
1295
|
+
if (options.json) {
|
|
1296
|
+
console.log(JSON.stringify(kpi, null, 2));
|
|
1297
|
+
} else {
|
|
1298
|
+
console.log("KPI definition updated successfully!");
|
|
1299
|
+
console.log("");
|
|
1300
|
+
formatKpiDetail(kpi);
|
|
1301
|
+
}
|
|
1302
|
+
} catch (error) {
|
|
1303
|
+
console.error(
|
|
1304
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1305
|
+
);
|
|
1306
|
+
process.exit(1);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
async function deleteCommand3(id, options) {
|
|
1310
|
+
try {
|
|
1311
|
+
if (!options.force) {
|
|
1312
|
+
console.log("Are you sure you want to delete this KPI definition?");
|
|
1313
|
+
console.log("Use --force to confirm deletion.");
|
|
1314
|
+
process.exit(1);
|
|
1315
|
+
}
|
|
1316
|
+
await deleteKpi(id);
|
|
1317
|
+
console.log("KPI definition deleted successfully.");
|
|
1318
|
+
} catch (error) {
|
|
1319
|
+
console.error(
|
|
1320
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1321
|
+
);
|
|
1322
|
+
process.exit(1);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
async function contextVariablesCommand(options) {
|
|
1326
|
+
try {
|
|
1327
|
+
const variables = await getKpiContextVariables(options.agentId);
|
|
1328
|
+
if (options.json) {
|
|
1329
|
+
console.log(JSON.stringify(variables, null, 2));
|
|
1330
|
+
} else {
|
|
1331
|
+
console.log("Available context variables for KPI formulas:");
|
|
1332
|
+
console.log("");
|
|
1333
|
+
formatContextVariablesTable(variables);
|
|
1334
|
+
console.log("");
|
|
1335
|
+
console.log(
|
|
1336
|
+
"Use these variable names in your formula expressions, e.g.:"
|
|
1337
|
+
);
|
|
1338
|
+
console.log(" IF(PII detected, 1, 0)");
|
|
1339
|
+
console.log(" Documents count * 10");
|
|
1340
|
+
console.log(' IF(CODE detected AND SECRET detected, "high-risk", "normal")');
|
|
1341
|
+
}
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
console.error(
|
|
1344
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1345
|
+
);
|
|
1346
|
+
process.exit(1);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
async function validateCommand(options) {
|
|
1350
|
+
try {
|
|
1351
|
+
if (!options.formula) {
|
|
1352
|
+
console.error("Error: --formula is required");
|
|
1353
|
+
process.exit(1);
|
|
1354
|
+
}
|
|
1355
|
+
const result = await validateKpiFormula(options.formula, options.agentId);
|
|
1356
|
+
if (options.json) {
|
|
1357
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1358
|
+
} else {
|
|
1359
|
+
if (result.valid) {
|
|
1360
|
+
console.log("Formula is valid!");
|
|
1361
|
+
console.log(`Result type: ${result.type || "unknown"}`);
|
|
1362
|
+
} else {
|
|
1363
|
+
console.error("Formula is invalid:");
|
|
1364
|
+
console.error(` ${result.error}`);
|
|
1365
|
+
if (result.charIndex !== void 0) {
|
|
1366
|
+
console.error(` Position: character ${result.charIndex}`);
|
|
1367
|
+
}
|
|
1368
|
+
process.exit(1);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
} catch (error) {
|
|
1372
|
+
console.error(
|
|
1373
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1374
|
+
);
|
|
1375
|
+
process.exit(1);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
function registerKpisCommand(program2) {
|
|
1379
|
+
const kpis = program2.command("kpis").description("Manage KPI definitions");
|
|
1380
|
+
kpis.command("list").description("List all KPI definitions").option("--json", "Output as JSON").option("--agent-id <id>", "Filter by agent ID").option("--include-inactive", "Include inactive KPI definitions").action(listCommand3);
|
|
1381
|
+
kpis.command("get <id>").description("Get KPI definition details").option("--json", "Output as JSON").action(getCommand3);
|
|
1382
|
+
kpis.command("create").description("Create a new KPI definition").requiredOption("--name <name>", "KPI name").requiredOption(
|
|
1383
|
+
"--calculator-id <id>",
|
|
1384
|
+
"Calculator type: formula, classifier, or llm-data"
|
|
1385
|
+
).option("--description <description>", "KPI description").option("--type <type>", "KPI type: PREDEFINED or USER_DEFINED (default)").option("--category <category>", "KPI category for grouping").option("--agent-id <id>", "Associate KPI with a specific agent").option("--formula <formula>", "Formula expression (required for formula calculator)").option("--unit <unit>", 'Display unit (e.g., "ms", "%", "count")').option(
|
|
1386
|
+
"--aggregation <method>",
|
|
1387
|
+
"Default aggregation: SUM, AVERAGE, COUNT, MIN, MAX, LATEST (default)"
|
|
1388
|
+
).option("--json", "Output as JSON").action(createCommand3);
|
|
1389
|
+
kpis.command("update <id>").description("Update a KPI definition").option("--name <name>", "KPI name").option("--description <description>", "KPI description").option("--category <category>", "KPI category").option("--agent-id <id>", "Associate with agent").option("--calculator-id <id>", "Calculator type").option("--formula <formula>", "Formula expression").option("--unit <unit>", "Display unit").option("--aggregation <method>", "Default aggregation method").option("--active", "Set KPI as active").option("--inactive", "Set KPI as inactive").option("--json", "Output as JSON").action(updateCommand3);
|
|
1390
|
+
kpis.command("delete <id>").description("Delete a KPI definition").option("--force", "Skip confirmation").action(deleteCommand3);
|
|
1391
|
+
kpis.command("context-variables").description("List available context variables for formulas").option("--json", "Output as JSON").option("--agent-id <id>", "Include agent-specific variables").action(contextVariablesCommand);
|
|
1392
|
+
kpis.command("validate").description("Validate a KPI formula expression").requiredOption("--formula <formula>", "Formula expression to validate").option("--agent-id <id>", "Include agent-specific context").option("--json", "Output as JSON").action(validateCommand);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// src/commands/activity.ts
|
|
1396
|
+
function formatActivityTable(data) {
|
|
1397
|
+
if (data.prompts.length === 0) {
|
|
1398
|
+
console.log("No activity found.");
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
const headers = ["ID", "AGENT", "APP", "MODEL", "TOKENS", "TIME(ms)", "RISK", "STATUS"];
|
|
1402
|
+
const rows = data.prompts.map((prompt) => [
|
|
1403
|
+
prompt.id.slice(0, 12) + "...",
|
|
1404
|
+
prompt.agentName || (prompt.agentId ? prompt.agentId.slice(0, 12) + "..." : "-"),
|
|
1405
|
+
prompt.app.slice(0, 12),
|
|
1406
|
+
prompt.modelId?.slice(0, 15) || "-",
|
|
1407
|
+
String(prompt.tokens),
|
|
1408
|
+
String(prompt.requestTime),
|
|
1409
|
+
prompt.isHighRisk ? "Yes" : "No",
|
|
1410
|
+
prompt.decorationStatus.slice(0, 10)
|
|
1411
|
+
]);
|
|
1412
|
+
const widths = headers.map(
|
|
1413
|
+
(h, i) => Math.max(h.length, ...rows.map((r) => r[i].length))
|
|
1414
|
+
);
|
|
1415
|
+
console.log(headers.map((h, i) => h.padEnd(widths[i])).join(" "));
|
|
1416
|
+
console.log(widths.map((w) => "-".repeat(w)).join(" "));
|
|
1417
|
+
for (const row of rows) {
|
|
1418
|
+
console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(" "));
|
|
1419
|
+
}
|
|
1420
|
+
console.log("");
|
|
1421
|
+
console.log(`Showing ${data.prompts.length} of ${data.total} results (offset: ${data.offset})`);
|
|
1422
|
+
if (data.hasMore) {
|
|
1423
|
+
console.log(`Use --offset ${data.offset + data.limit} to see more results`);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function formatActivityDetail(prompt) {
|
|
1427
|
+
console.log(`ID: ${prompt.id}`);
|
|
1428
|
+
console.log(`Created: ${prompt.createdAt}`);
|
|
1429
|
+
console.log(`Agent: ${prompt.agentName || "-"} (${prompt.agentId || "-"})`);
|
|
1430
|
+
console.log(`Workflow: ${prompt.workflowName || "-"} (${prompt.workflowId || "-"})`);
|
|
1431
|
+
console.log(`App: ${prompt.app}`);
|
|
1432
|
+
console.log(`Model: ${prompt.modelId || "-"} (${prompt.modelType || "-"})`);
|
|
1433
|
+
console.log(`Tokens: ${prompt.tokens}`);
|
|
1434
|
+
console.log(`Request Time: ${prompt.requestTime}ms`);
|
|
1435
|
+
console.log(`High Risk: ${prompt.isHighRisk ? "Yes" : "No"}`);
|
|
1436
|
+
console.log(`Blocked: ${prompt.blocked ? "Yes" : "No"}`);
|
|
1437
|
+
console.log(`Status: ${prompt.decorationStatus}`);
|
|
1438
|
+
if (prompt.sensitivity && prompt.sensitivity.length > 0) {
|
|
1439
|
+
console.log(`Sensitivity: ${prompt.sensitivity.join(", ")}`);
|
|
1440
|
+
}
|
|
1441
|
+
if (prompt.analytics) {
|
|
1442
|
+
console.log("");
|
|
1443
|
+
console.log("Analytics:");
|
|
1444
|
+
console.log(` Task: ${prompt.analytics.task || "-"}`);
|
|
1445
|
+
console.log(` Subtask: ${prompt.analytics.subtask || "-"}`);
|
|
1446
|
+
console.log(` Time Saved: ${prompt.analytics.timesaved_minutes ?? "-"} minutes`);
|
|
1447
|
+
console.log(` Risk Score: ${prompt.analytics.riskassessment_dangerousity ?? "-"}`);
|
|
1448
|
+
}
|
|
1449
|
+
if (prompt.kpiData && Object.keys(prompt.kpiData).length > 0) {
|
|
1450
|
+
console.log("");
|
|
1451
|
+
console.log("KPIs:");
|
|
1452
|
+
for (const [key, value] of Object.entries(prompt.kpiData)) {
|
|
1453
|
+
console.log(` ${key}: ${value}`);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (prompt.prompt !== void 0) {
|
|
1457
|
+
console.log("");
|
|
1458
|
+
console.log("Prompt:");
|
|
1459
|
+
console.log("---");
|
|
1460
|
+
console.log(prompt.prompt.slice(0, 1e3) + (prompt.prompt.length > 1e3 ? "..." : ""));
|
|
1461
|
+
console.log("---");
|
|
1462
|
+
}
|
|
1463
|
+
if (prompt.response !== void 0) {
|
|
1464
|
+
console.log("");
|
|
1465
|
+
console.log("Response:");
|
|
1466
|
+
console.log("---");
|
|
1467
|
+
console.log(prompt.response.slice(0, 1e3) + (prompt.response.length > 1e3 ? "..." : ""));
|
|
1468
|
+
console.log("---");
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
function formatCoreKpi(kpi) {
|
|
1472
|
+
const prefix = kpi.unitPrefix || "";
|
|
1473
|
+
const suffix = kpi.unitSuffix || "";
|
|
1474
|
+
return `${prefix}${kpi.value}${suffix}`;
|
|
1475
|
+
}
|
|
1476
|
+
function formatKpisResponse(data) {
|
|
1477
|
+
console.log("Core KPIs:");
|
|
1478
|
+
for (const kpi of data.coreKpis) {
|
|
1479
|
+
console.log(` ${kpi.name.padEnd(25)} ${formatCoreKpi(kpi)}`);
|
|
1480
|
+
}
|
|
1481
|
+
if (data.kpis.length > 0) {
|
|
1482
|
+
console.log("");
|
|
1483
|
+
console.log("Custom KPIs:");
|
|
1484
|
+
const headers = ["NAME", "VALUE", "UNIT", "AGGREGATION", "DATA POINTS"];
|
|
1485
|
+
const rows = data.kpis.map((kpi) => [
|
|
1486
|
+
kpi.name.slice(0, 25),
|
|
1487
|
+
kpi.value !== null ? String(kpi.value) : "-",
|
|
1488
|
+
kpi.unit || "-",
|
|
1489
|
+
kpi.aggregationMethod,
|
|
1490
|
+
String(kpi.dataPointCount)
|
|
1491
|
+
]);
|
|
1492
|
+
const widths = headers.map(
|
|
1493
|
+
(h, i) => Math.max(h.length, ...rows.map((r) => r[i].length))
|
|
1494
|
+
);
|
|
1495
|
+
console.log(" " + headers.map((h, i) => h.padEnd(widths[i])).join(" "));
|
|
1496
|
+
console.log(" " + widths.map((w) => "-".repeat(w)).join(" "));
|
|
1497
|
+
for (const row of rows) {
|
|
1498
|
+
console.log(" " + row.map((cell, i) => cell.padEnd(widths[i])).join(" "));
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
if (data.periodData && data.periodData.length > 0) {
|
|
1502
|
+
console.log("");
|
|
1503
|
+
console.log("Period Breakdown:");
|
|
1504
|
+
for (const period of data.periodData) {
|
|
1505
|
+
console.log(` ${period.periodStart} - ${period.periodEnd}`);
|
|
1506
|
+
for (const kpi of period.coreKpis) {
|
|
1507
|
+
console.log(` ${kpi.name}: ${formatCoreKpi(kpi)}`);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
if (data.atoms && data.atoms.length > 0) {
|
|
1512
|
+
console.log("");
|
|
1513
|
+
console.log(`Per-Prompt KPI Atoms: ${data.atoms.length} records`);
|
|
1514
|
+
console.log(" (Use --json for full atom data)");
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
async function listCommand4(options) {
|
|
1518
|
+
try {
|
|
1519
|
+
const data = await listActivity({
|
|
1520
|
+
agentId: options.agentId,
|
|
1521
|
+
workflowId: options.workflowId,
|
|
1522
|
+
since: options.since,
|
|
1523
|
+
until: options.until,
|
|
1524
|
+
limit: options.limit ? parseInt(options.limit, 10) : void 0,
|
|
1525
|
+
offset: options.offset ? parseInt(options.offset, 10) : void 0,
|
|
1526
|
+
includeContent: options.includeContent,
|
|
1527
|
+
includeAnalytics: options.includeAnalytics
|
|
1528
|
+
});
|
|
1529
|
+
if (options.json) {
|
|
1530
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1531
|
+
} else {
|
|
1532
|
+
formatActivityTable(data);
|
|
1533
|
+
}
|
|
1534
|
+
} catch (error) {
|
|
1535
|
+
console.error(
|
|
1536
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1537
|
+
);
|
|
1538
|
+
process.exit(1);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
async function getCommand4(id, options) {
|
|
1542
|
+
try {
|
|
1543
|
+
const prompt = await getActivity(id, options.includeContent);
|
|
1544
|
+
if (options.json) {
|
|
1545
|
+
console.log(JSON.stringify(prompt, null, 2));
|
|
1546
|
+
} else {
|
|
1547
|
+
formatActivityDetail(prompt);
|
|
1548
|
+
}
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
console.error(
|
|
1551
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1552
|
+
);
|
|
1553
|
+
process.exit(1);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
async function kpisCommand(options) {
|
|
1557
|
+
try {
|
|
1558
|
+
if (!options.agentId && !options.workflowId) {
|
|
1559
|
+
console.error("Error: Either --agent-id or --workflow-id is required");
|
|
1560
|
+
process.exit(1);
|
|
1561
|
+
}
|
|
1562
|
+
const data = await getActivityKpis({
|
|
1563
|
+
agentId: options.agentId,
|
|
1564
|
+
workflowId: options.workflowId,
|
|
1565
|
+
since: options.since,
|
|
1566
|
+
until: options.until,
|
|
1567
|
+
period: options.period,
|
|
1568
|
+
includeAtoms: options.includeAtoms
|
|
1569
|
+
});
|
|
1570
|
+
if (options.json) {
|
|
1571
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1572
|
+
} else {
|
|
1573
|
+
formatKpisResponse(data);
|
|
1574
|
+
}
|
|
1575
|
+
} catch (error) {
|
|
1576
|
+
console.error(
|
|
1577
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1578
|
+
);
|
|
1579
|
+
process.exit(1);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
function registerActivityCommand(program2) {
|
|
1583
|
+
const activity = program2.command("activity").description("Inspect AI activity and prompts");
|
|
1584
|
+
activity.command("list").description("List prompt requests with filters").option("--agent-id <id>", "Filter by agent ID").option("--workflow-id <id>", "Filter by workflow ID").option("--since <date>", "Start date (ISO format)").option("--until <date>", "End date (ISO format)").option("--limit <n>", "Results per page", "20").option("--offset <n>", "Skip first N results", "0").option("--include-content", "Include prompt/response content").option("--include-analytics", "Include advanced analytics").option("--json", "Output as JSON").action(listCommand4);
|
|
1585
|
+
activity.command("get <id>").description("Get prompt request details").option("--include-content", "Include prompt/response content").option("--json", "Output as JSON").action(getCommand4);
|
|
1586
|
+
activity.command("kpis").description("Get aggregated KPI values").option("--agent-id <id>", "Agent ID").option("--workflow-id <id>", "Workflow ID").option("--since <date>", "Period start (ISO format)").option("--until <date>", "Period end (ISO format)").option("--period <type>", "Aggregation period (hourly, daily, weekly)").option("--include-atoms", "Include per-prompt KPI data").option("--json", "Output as JSON").action(kpisCommand);
|
|
1587
|
+
}
|
|
1588
|
+
|
|
837
1589
|
// src/index.ts
|
|
838
1590
|
var program = new Command();
|
|
839
1591
|
program.name("olakai").description("Olakai CLI tool").version("0.1.0").option(
|
|
@@ -857,5 +1609,7 @@ program.command("logout").description("Log out from Olakai").action(logoutComman
|
|
|
857
1609
|
program.command("whoami").description("Show current logged-in user").action(whoamiCommand);
|
|
858
1610
|
registerAgentsCommand(program);
|
|
859
1611
|
registerWorkflowsCommand(program);
|
|
1612
|
+
registerKpisCommand(program);
|
|
1613
|
+
registerActivityCommand(program);
|
|
860
1614
|
program.parse();
|
|
861
1615
|
//# sourceMappingURL=index.js.map
|