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/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