callkaro-cli-unofficial 0.7.2 → 0.9.0

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.
@@ -18,6 +18,13 @@ exports.adminAgentActionCommand = adminAgentActionCommand;
18
18
  exports.adminNumbersCommand = adminNumbersCommand;
19
19
  exports.adminVoiceCacheCommand = adminVoiceCacheCommand;
20
20
  exports.adminApiCommand = adminApiCommand;
21
+ exports.adminBotFailuresCommand = adminBotFailuresCommand;
22
+ exports.adminClientAgentsCommand = adminClientAgentsCommand;
23
+ exports.adminClientAgentVersionsCommand = adminClientAgentVersionsCommand;
24
+ exports.adminContextListCommand = adminContextListCommand;
25
+ exports.adminContextSearchCommand = adminContextSearchCommand;
26
+ exports.adminContextSetCommand = adminContextSetCommand;
27
+ exports.adminContextRemoveCommand = adminContextRemoveCommand;
21
28
  const adminApi_1 = require("../lib/adminApi");
22
29
  const adminAuth_1 = require("../lib/adminAuth");
23
30
  const config_1 = require("../lib/config");
@@ -25,6 +32,7 @@ Object.defineProperty(exports, "getClient", { enumerable: true, get: function ()
25
32
  Object.defineProperty(exports, "activeAccount", { enumerable: true, get: function () { return config_1.activeAccount; } });
26
33
  const ui_1 = require("../lib/ui");
27
34
  const jsonInput_1 = require("./jsonInput");
35
+ const setJson_1 = require("./setJson");
28
36
  const looseJson_1 = require("../lib/looseJson");
29
37
  /** The route segments the path may contain — see `repairPosixPath`. */
30
38
  const PATH_SEGMENTS = ['monitor'];
@@ -518,3 +526,139 @@ async function adminApiCommand(method, path, opts) {
518
526
  (0, ui_1.handleError)(err);
519
527
  }
520
528
  }
529
+ // --- bot failures, client agents ---------------------------------------------
530
+ async function adminBotFailuresCommand(agentId, opts) {
531
+ try {
532
+ const win = defaultWindow();
533
+ const startDate = dateArg(opts.start, '--start', win.startDate);
534
+ const endDate = dateArg(opts.end, '--end', win.endDate);
535
+ const base = { versionId: opts.version, startDate, endDate };
536
+ const limit = Number(opts.limit) || 20;
537
+ const res = opts.api
538
+ ? opts.response
539
+ ? await (0, adminApi_1.adminApi)().botFailedApiResponseCalls(agentId, { response: opts.response, endpoint: opts.endpoint, ...base, limit })
540
+ : await (0, adminApi_1.adminApi)().botFailedApiResponses(agentId, base)
541
+ : opts.response
542
+ ? await (0, adminApi_1.adminApi)().botFailedResponseCalls(agentId, { response: opts.response, ...base, limit })
543
+ : await (0, adminApi_1.adminApi)().botFailedResponses(agentId, base);
544
+ if (opts.json)
545
+ return void console.log(JSON.stringify(res, null, 2));
546
+ if (opts.response) {
547
+ const ids = res?.callIds || res?.calls || res?.data || [];
548
+ if (!ids.length)
549
+ return void (0, ui_1.info)('No matching calls.');
550
+ return (0, ui_1.table)(['CALL ID'], ids.map((c) => [typeof c === 'string' ? c : c.callId || c.call_id || c._id || '']));
551
+ }
552
+ const rows = res?.responses || res?.failures || res?.data || [];
553
+ if (!rows.length)
554
+ return void (0, ui_1.info)('No failed responses in this window.');
555
+ (0, ui_1.table)(['RESPONSE / ENDPOINT', 'CALLS', 'SAMPLE CALL IDS'], rows.map((r) => [
556
+ r.response || r.endpoint || r.name || '',
557
+ r.count ?? r.calls ?? '',
558
+ (r.sampleCallIds || r.callIds || []).slice(0, 3).join(', '),
559
+ ]));
560
+ }
561
+ catch (err) {
562
+ (0, ui_1.handleError)(err);
563
+ }
564
+ }
565
+ async function adminClientAgentsCommand(clientId, opts) {
566
+ try {
567
+ const res = await (0, adminApi_1.adminApi)().clientAgents(clientId);
568
+ const rows = res.agents || [];
569
+ if (opts.json)
570
+ return void console.log(JSON.stringify(rows, null, 2));
571
+ if (!rows.length)
572
+ return void (0, ui_1.info)('No agents for this client.');
573
+ (0, ui_1.table)(['ID', 'NAME', 'STATUS', 'CREATED'], rows.map((a) => [a._id || a.id || '', a.name || '', a.status || '', a.createdAt || '']));
574
+ }
575
+ catch (err) {
576
+ (0, ui_1.handleError)(err);
577
+ }
578
+ }
579
+ async function adminClientAgentVersionsCommand(agentId, opts) {
580
+ try {
581
+ const res = await (0, adminApi_1.adminApi)().clientAgentVersions(agentId);
582
+ const rows = res.versions || [];
583
+ if (opts.json)
584
+ return void console.log(JSON.stringify(rows, null, 2));
585
+ if (!rows.length)
586
+ return void (0, ui_1.info)('No versions for this agent.');
587
+ (0, ui_1.table)(['VERSION ID', 'NAME', 'ACTIVE', 'CREATED'], rows.map((v) => [v._id || v.id || '', v.versionName || v.name || v.version_name || '', v.active ?? v.isActive ?? '', v.createdAt || '']));
588
+ }
589
+ catch (err) {
590
+ (0, ui_1.handleError)(err);
591
+ }
592
+ }
593
+ // --- FDE reference library -----------------------------------------------------
594
+ const tagText = (t) => (Array.isArray(t) ? t.join(', ') : String(t ?? ''));
595
+ async function adminContextListCommand(opts) {
596
+ try {
597
+ const res = await (0, adminApi_1.adminApi)().listAgentContext();
598
+ let rows = Array.isArray(res) ? res : res?.versions || res?.data || res?.results || res?.contexts || [];
599
+ if (opts.search) {
600
+ const q = opts.search.toLowerCase();
601
+ rows = rows.filter((r) => [r.versionId, r.useCase, r.description, tagText(r.tags)].some((f) => String(f ?? '').toLowerCase().includes(q)));
602
+ }
603
+ if (opts.json)
604
+ return void console.log(JSON.stringify(rows, null, 2));
605
+ if (!rows.length)
606
+ return void (0, ui_1.info)('No reference contexts.');
607
+ (0, ui_1.table)(['VERSION ID', 'USE CASE', 'TAGS', 'DESCRIPTION'], rows.map((r) => [r.versionId || '', r.useCase || '', tagText(r.tags), String(r.description || '').slice(0, 80)]));
608
+ }
609
+ catch (err) {
610
+ (0, ui_1.handleError)(err);
611
+ }
612
+ }
613
+ async function adminContextSearchCommand(query, opts) {
614
+ try {
615
+ const res = await (0, adminApi_1.adminApi)().searchAgentContext({
616
+ query,
617
+ topK: opts.topK ? Number(opts.topK) : 3,
618
+ minScore: opts.minScore ? Number(opts.minScore) : 0.5,
619
+ });
620
+ const rows = res?.results || (Array.isArray(res) ? res : []);
621
+ if (opts.json)
622
+ return void console.log(JSON.stringify(res?.results || res, null, 2));
623
+ if (!rows.length)
624
+ return void (0, ui_1.info)('No matches above the score threshold.');
625
+ (0, ui_1.table)(['SCORE', 'VERSION ID', 'USE CASE', 'TAGS', 'DESCRIPTION'], rows.map((r) => [r.score ?? '', r.versionId || '', r.useCase || '', tagText(r.tags), String(r.description || '').slice(0, 80)]));
626
+ }
627
+ catch (err) {
628
+ (0, ui_1.handleError)(err);
629
+ }
630
+ }
631
+ async function adminContextSetCommand(versionId, opts) {
632
+ try {
633
+ const patch = opts.set ? (0, setJson_1.readSetJson)(opts.set) : {};
634
+ const body = {
635
+ versionId,
636
+ description: opts.description ?? patch.description ?? '',
637
+ useCase: opts.useCase ?? patch.useCase ?? '',
638
+ tags: opts.tags ? opts.tags.split(',').map((s) => s.trim()).filter(Boolean) : patch.tags || [],
639
+ ...(patch.metadata ? { metadata: patch.metadata } : {}),
640
+ };
641
+ if (!body.description.trim())
642
+ throw new Error('--description (or description in --set) is required.');
643
+ const res = opts.update ? await (0, adminApi_1.adminApi)().updateAgentContext(versionId, body) : await (0, adminApi_1.adminApi)().createAgentContext(body);
644
+ if (opts.json)
645
+ return void console.log(JSON.stringify(res, null, 2));
646
+ (0, ui_1.success)(`${opts.update ? 'Updated' : 'Added'} reference context ${versionId}.`);
647
+ }
648
+ catch (err) {
649
+ (0, ui_1.handleError)(err);
650
+ }
651
+ }
652
+ async function adminContextRemoveCommand(versionId, opts) {
653
+ try {
654
+ if (!(await (0, ui_1.confirm)(`Remove reference context ${versionId} from FDE index?`, opts.yes)))
655
+ return;
656
+ const res = await (0, adminApi_1.adminApi)().deleteAgentContext(versionId);
657
+ if (opts.json)
658
+ return void console.log(JSON.stringify(res, null, 2));
659
+ (0, ui_1.success)(`Removed reference context ${versionId}.`);
660
+ }
661
+ catch (err) {
662
+ (0, ui_1.handleError)(err);
663
+ }
664
+ }
@@ -5,7 +5,17 @@ exports.agentsPublishCommand = agentsPublishCommand;
5
5
  exports.agentsToggleActiveCommand = agentsToggleActiveCommand;
6
6
  exports.agentsAbCommand = agentsAbCommand;
7
7
  exports.agentsAbAdvancedCommand = agentsAbAdvancedCommand;
8
+ exports.agentsCommitsCommand = agentsCommitsCommand;
9
+ exports.agentsCommitShowCommand = agentsCommitShowCommand;
10
+ exports.agentsDiffCommand = agentsDiffCommand;
11
+ exports.agentsRevertCommand = agentsRevertCommand;
12
+ exports.agentsSaveV2Command = agentsSaveV2Command;
13
+ exports.agentsDeleteVersionCommand = agentsDeleteVersionCommand;
14
+ exports.agentsDuplicateCommand = agentsDuplicateCommand;
15
+ exports.agentsSetLanguagesCommand = agentsSetLanguagesCommand;
16
+ exports.agentsPostcallInfoCommand = agentsPostcallInfoCommand;
8
17
  const session_1 = require("../lib/session");
18
+ const dashboardApi_1 = require("../lib/dashboardApi");
9
19
  const ui_1 = require("../lib/ui");
10
20
  const versions_1 = require("../lib/versions");
11
21
  const agentUpdate_1 = require("../lib/agentUpdate");
@@ -226,3 +236,185 @@ async function agentsAbAdvancedCommand(agentId, opts) {
226
236
  (0, ui_1.handleError)(err);
227
237
  }
228
238
  }
239
+ /** `cku agents commits <agentId>` */
240
+ async function agentsCommitsCommand(agentId, opts) {
241
+ try {
242
+ const res = await (0, dashboardApi_1.dashboardApi)().agentCommits(agentId, {
243
+ version: opts.versions ? (0, versions_1.firstVersion)(opts.versions) : undefined,
244
+ page: Number(opts.page) || 1,
245
+ pageSize: Number(opts.limit) || 25,
246
+ });
247
+ if (opts.json)
248
+ return void console.log(JSON.stringify(res?.commits || res, null, 2));
249
+ const rows = res?.commits || [];
250
+ if (!rows.length)
251
+ return void (0, ui_1.info)('No commits.');
252
+ (0, ui_1.table)(['COMMIT ID', 'VERSION', 'MESSAGE', 'AUTHOR', 'CREATED'], rows.map((c) => [
253
+ c._id,
254
+ c.versionId,
255
+ c.commitMessage || c.message || '',
256
+ c.author?.name || c.author?.email || c.user?.email || '',
257
+ c.createdAt,
258
+ ]));
259
+ }
260
+ catch (err) {
261
+ (0, ui_1.handleError)(err);
262
+ }
263
+ }
264
+ /** `cku agents commit-show <commitId>` */
265
+ async function agentsCommitShowCommand(commitId, opts) {
266
+ try {
267
+ const res = await (0, dashboardApi_1.dashboardApi)().agentCommit(commitId);
268
+ const c = res?.commit || res;
269
+ if (opts.json)
270
+ return void console.log(JSON.stringify(c, null, 2));
271
+ (0, ui_1.keyValue)({
272
+ id: c?._id,
273
+ versionId: c?.versionId,
274
+ commitMessage: c?.commitMessage,
275
+ createdAt: c?.createdAt,
276
+ model: c?.model,
277
+ voice_provider: c?.voice_provider,
278
+ functions: (c?.functions || []).length,
279
+ });
280
+ }
281
+ catch (err) {
282
+ (0, ui_1.handleError)(err);
283
+ }
284
+ }
285
+ /** `cku agents diff <agentId> --commits a,b | --versions a,b` */
286
+ async function agentsDiffCommand(agentId, opts) {
287
+ const usage = 'Pass --commits <idA,idB> or --versions <vA,vB> (two comma-separated ids).';
288
+ const commits = opts.commits ? (0, versions_1.versionList)(opts.commits) : [];
289
+ const versions = opts.versions ? (0, versions_1.versionList)(opts.versions) : [];
290
+ const ids = commits.length ? commits : versions;
291
+ if (ids.length < 2)
292
+ return (0, ui_1.handleError)(new Error(usage));
293
+ try {
294
+ const api = (0, dashboardApi_1.dashboardApi)();
295
+ const res = commits.length
296
+ ? await api.compareAgentCommits(agentId, ids[0], ids[1])
297
+ : await api.compareAgentVersions([ids[0], ids[1]]);
298
+ if (opts.json)
299
+ return void console.log(JSON.stringify(res, null, 2));
300
+ const diff = res?.diff ?? res?.changes ?? res;
301
+ if (Array.isArray(diff)) {
302
+ if (!diff.length)
303
+ return void (0, ui_1.info)('No differences.');
304
+ (0, ui_1.table)(['FIELD', 'A', 'B'], diff.map((d) => [d.field || d.key || d.path || '', clipVal(d.a ?? d.before ?? d.from), clipVal(d.b ?? d.after ?? d.to)]));
305
+ return;
306
+ }
307
+ const keys = diff && typeof diff === 'object' ? Object.keys(diff) : [];
308
+ if (!keys.length)
309
+ return void (0, ui_1.info)('No differences.');
310
+ (0, ui_1.info)(`Changed keys (${keys.length}):`);
311
+ keys.forEach((k) => (0, ui_1.info)(` ${k}`));
312
+ (0, ui_1.info)('Full detail: add --json');
313
+ }
314
+ catch (err) {
315
+ (0, ui_1.handleError)(err);
316
+ }
317
+ }
318
+ function clipVal(v) {
319
+ const t = v === undefined || v === null ? '' : typeof v === 'string' ? v : JSON.stringify(v);
320
+ return t.length > 60 ? `${t.slice(0, 59)}…` : t;
321
+ }
322
+ /** `cku agents revert <agentId> <commitId>` */
323
+ async function agentsRevertCommand(agentId, commitId, opts) {
324
+ try {
325
+ if (!(await (0, ui_1.confirm)(`Revert agent ${agentId} to commit ${commitId}?`, opts.yes)))
326
+ return;
327
+ const res = await (0, dashboardApi_1.dashboardApi)().revertAgentCommit(agentId, commitId);
328
+ if (opts.json)
329
+ return void console.log(JSON.stringify(res, null, 2));
330
+ (0, ui_1.success)(`Reverted ${agentId} to commit ${commitId}.`);
331
+ }
332
+ catch (err) {
333
+ (0, ui_1.handleError)(err);
334
+ }
335
+ }
336
+ /** `cku agents save-v2 <agentId> --set <json>` */
337
+ async function agentsSaveV2Command(agentId, opts) {
338
+ try {
339
+ const body = { ...(0, setJson_1.readSetJson)(opts.set) };
340
+ if (opts.message)
341
+ body.commitMessage = opts.message;
342
+ const versionId = opts.versions ? (0, versions_1.firstVersion)(opts.versions) : undefined;
343
+ const res = await (0, dashboardApi_1.dashboardApi)().updateAgentV2(agentId, versionId, body);
344
+ if (opts.json)
345
+ return void console.log(JSON.stringify(res, null, 2));
346
+ (0, ui_1.success)(`Saved ${agentId}${opts.versions ? ` (version ${(0, versions_1.firstVersion)(opts.versions)})` : ''} via /v2/agents.`);
347
+ }
348
+ catch (err) {
349
+ (0, ui_1.handleError)(err);
350
+ }
351
+ }
352
+ /** `cku agents delete-version <agentId> <versionId>` */
353
+ async function agentsDeleteVersionCommand(agentId, versionId, opts) {
354
+ try {
355
+ if (!(await (0, ui_1.confirm)(`Delete version ${versionId} of agent ${agentId}?`, opts.yes)))
356
+ return;
357
+ const res = await (0, dashboardApi_1.dashboardApi)().deleteAgentVersionV2(agentId, versionId);
358
+ if (opts.json)
359
+ return void console.log(JSON.stringify(res, null, 2));
360
+ (0, ui_1.success)(`Deleted version ${versionId}.`);
361
+ }
362
+ catch (err) {
363
+ (0, ui_1.handleError)(err);
364
+ }
365
+ }
366
+ /** `cku agents duplicate <agentId> --name <n>` */
367
+ async function agentsDuplicateCommand(agentId, opts) {
368
+ if (!opts.name?.trim())
369
+ return (0, ui_1.handleError)(new Error('--name <newName> is required'));
370
+ try {
371
+ const res = await (0, dashboardApi_1.dashboardApi)().duplicateAgentV2(agentId, {
372
+ name: opts.name.trim(),
373
+ ...(opts.versions ? { versions: (0, versions_1.versionList)(opts.versions) } : {}),
374
+ });
375
+ if (opts.json)
376
+ return void console.log(JSON.stringify(res, null, 2));
377
+ const newId = res?.agent?._id || res?._id || res?.agentId;
378
+ (0, ui_1.success)(`Duplicated ${agentId} as "${opts.name.trim()}"${newId ? ` (id ${newId})` : ''}.`);
379
+ }
380
+ catch (err) {
381
+ (0, ui_1.handleError)(err);
382
+ }
383
+ }
384
+ const csv = (s) => (s || '').split(',').map((x) => x.trim()).filter(Boolean);
385
+ /** `cku agents set-languages <agentId> --languages en,hi --versions v1,v2` */
386
+ async function agentsSetLanguagesCommand(agentId, opts) {
387
+ try {
388
+ const langs = csv(opts.languages);
389
+ const vers = csv(opts.versions);
390
+ if (!langs.length)
391
+ throw new Error('--languages <csv> is required.');
392
+ if (!vers.length)
393
+ throw new Error('--versions <csv> is required.');
394
+ const res = await (0, dashboardApi_1.dashboardApi)().updateAllSwitchableLanguage(agentId, langs, vers);
395
+ if (opts.json)
396
+ return void console.log(JSON.stringify(res, null, 2));
397
+ (0, ui_1.success)(`Set switchable languages [${langs.join(', ')}] on ${vers.length} version(s).`);
398
+ }
399
+ catch (err) {
400
+ (0, ui_1.handleError)(err);
401
+ }
402
+ }
403
+ /** `cku agents postcall-info <agentId>` */
404
+ async function agentsPostcallInfoCommand(agentId, opts) {
405
+ try {
406
+ const res = await (0, dashboardApi_1.dashboardApi)().agentPostcallInfo(agentId);
407
+ if (opts.json)
408
+ return void console.log(JSON.stringify(res, null, 2));
409
+ const vars = res?.postcallVars || [];
410
+ const reasons = res?.dropOffReasons || [];
411
+ (0, ui_1.keyValue)({ agent: agentId, 'post-call variables': vars.length, 'drop-off reasons': reasons.length });
412
+ if (vars.length)
413
+ (0, ui_1.table)(['VARIABLE', 'TYPE'], vars.map((v) => [typeof v === 'string' ? v : v.name || '', typeof v === 'string' ? '' : v.type || '']));
414
+ if (reasons.length)
415
+ (0, ui_1.table)(['DROP-OFF REASON'], reasons.map((r) => [typeof r === 'string' ? r : r.name || r.reason || '']));
416
+ }
417
+ catch (err) {
418
+ (0, ui_1.handleError)(err);
419
+ }
420
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aiGenerateFunctionCommand = aiGenerateFunctionCommand;
4
+ exports.aiGeneratePostcallCommand = aiGeneratePostcallCommand;
5
+ exports.aiGenerateAuditStrategyCommand = aiGenerateAuditStrategyCommand;
6
+ exports.aiGenerateCallflowSummaryCommand = aiGenerateCallflowSummaryCommand;
7
+ exports.aiGenerateWorkflowCodeCommand = aiGenerateWorkflowCodeCommand;
8
+ const dashboardApi_1 = require("../lib/dashboardApi");
9
+ const ui_1 = require("../lib/ui");
10
+ const setJson_1 = require("./setJson");
11
+ const show = (res) => console.log(typeof res === 'string' ? res : JSON.stringify(res, null, 2));
12
+ async function aiGenerateFunctionCommand(opts) {
13
+ try {
14
+ const api = (0, dashboardApi_1.dashboardApi)();
15
+ const vars = opts.vars ? opts.vars.split(',').map((s) => s.trim()).filter(Boolean) : undefined;
16
+ const body = {
17
+ prompt: opts.prompt,
18
+ ...(opts.code ? { existingCode: opts.code } : {}),
19
+ ...(opts.name ? { name: opts.name } : {}),
20
+ ...(opts.description ? { description: opts.description } : {}),
21
+ ...(opts.type ? { type: opts.type } : {}),
22
+ ...(vars ? { prompt_variables: vars } : {}),
23
+ };
24
+ const res = opts.chat
25
+ ? await api.request('POST', '/openai-tools/generate-chat-function', body)
26
+ : await api.generateFunctionCode(body);
27
+ show(res);
28
+ }
29
+ catch (err) {
30
+ (0, ui_1.handleError)(err);
31
+ }
32
+ }
33
+ async function aiGeneratePostcallCommand(opts) {
34
+ try {
35
+ show(await (0, dashboardApi_1.dashboardApi)().generatePostcallConfig((0, setJson_1.readSetJson)(opts.set)));
36
+ }
37
+ catch (err) {
38
+ (0, ui_1.handleError)(err);
39
+ }
40
+ }
41
+ async function aiGenerateAuditStrategyCommand(agentId, opts) {
42
+ try {
43
+ show(await (0, dashboardApi_1.dashboardApi)().generateAuditStrategyDraft({ agentId, text_input: opts.prompt, existingAuditStrategy: opts.existing }));
44
+ }
45
+ catch (err) {
46
+ (0, ui_1.handleError)(err);
47
+ }
48
+ }
49
+ async function aiGenerateCallflowSummaryCommand(agentId, opts) {
50
+ try {
51
+ show(await (0, dashboardApi_1.dashboardApi)().generateCallflowSummaryDraft({ agentId, text_input: opts.prompt, existingCallflowSummary: opts.existing }));
52
+ }
53
+ catch (err) {
54
+ (0, ui_1.handleError)(err);
55
+ }
56
+ }
57
+ async function aiGenerateWorkflowCodeCommand(opts) {
58
+ try {
59
+ show(await (0, dashboardApi_1.dashboardApi)().generateWorkflowCode({ prompt: opts.prompt, stepName: opts.name, stepKey: opts.key, existingCode: opts.existing }));
60
+ }
61
+ catch (err) {
62
+ (0, ui_1.handleError)(err);
63
+ }
64
+ }
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.analyticsOverviewCommand = analyticsOverviewCommand;
4
4
  exports.analyticsPerformanceCommand = analyticsPerformanceCommand;
5
5
  exports.analyticsVersionCommand = analyticsVersionCommand;
6
+ exports.analyticsFailedResponsesCommand = analyticsFailedResponsesCommand;
7
+ exports.analyticsFunctionsCommand = analyticsFunctionsCommand;
8
+ exports.analyticsChatCommand = analyticsChatCommand;
9
+ const dashboardApi_1 = require("../lib/dashboardApi");
6
10
  const session_1 = require("../lib/session");
7
11
  const ui_1 = require("../lib/ui");
8
12
  async function analyticsOverviewCommand(opts) {
@@ -75,3 +79,65 @@ async function analyticsVersionCommand(agentId, opts) {
75
79
  (0, ui_1.handleError)(err);
76
80
  }
77
81
  }
82
+ /** Render rows of objects as a table over their scalar keys. */
83
+ function objectTable(rows) {
84
+ const keys = Object.keys(rows[0] || {}).filter((k) => rows[0][k] === null || typeof rows[0][k] !== 'object');
85
+ (0, ui_1.table)(keys.map((k) => k.toUpperCase()), rows.map((r) => keys.map((k) => r[k] ?? '')));
86
+ }
87
+ /** `cku analytics failed-responses` */
88
+ async function analyticsFailedResponsesCommand(opts) {
89
+ try {
90
+ const q = { agent_ids: opts.agent, startDate: opts.start, endDate: opts.end };
91
+ const res = opts.response
92
+ ? await (0, dashboardApi_1.dashboardApi)().failedResponseCalls({ ...q, response: opts.response, limit: Number(opts.limit) || 25 })
93
+ : await (0, dashboardApi_1.dashboardApi)().failedResponses(q);
94
+ if (opts.json)
95
+ return void console.log(JSON.stringify(res, null, 2));
96
+ const rows = res?.data || res?.calls || res?.responses || (Array.isArray(res) ? res : []);
97
+ if (!rows.length)
98
+ return void (0, ui_1.info)('No failed responses.');
99
+ objectTable(rows);
100
+ }
101
+ catch (err) {
102
+ (0, ui_1.handleError)(err);
103
+ }
104
+ }
105
+ /** `cku analytics functions` */
106
+ async function analyticsFunctionsCommand(opts) {
107
+ try {
108
+ const res = await (0, dashboardApi_1.dashboardApi)().functionAnalytics({ agent_ids: opts.agent, startDate: opts.start, endDate: opts.end });
109
+ if (opts.json)
110
+ return void console.log(JSON.stringify(res, null, 2));
111
+ const rows = res?.data || res?.functions || (Array.isArray(res) ? res : []);
112
+ if (!rows.length)
113
+ return void (0, ui_1.info)('No function analytics.');
114
+ objectTable(rows);
115
+ }
116
+ catch (err) {
117
+ (0, ui_1.handleError)(err);
118
+ }
119
+ }
120
+ /** `cku analytics chat` */
121
+ async function analyticsChatCommand(opts) {
122
+ try {
123
+ const res = await (0, dashboardApi_1.dashboardApi)().chatAnalytics({
124
+ chat_agent_id: opts.agent,
125
+ agent_ids: opts.agent,
126
+ startDate: opts.start,
127
+ endDate: opts.end,
128
+ });
129
+ if (opts.json)
130
+ return void console.log(JSON.stringify(res, null, 2));
131
+ const d = res?.data ?? res;
132
+ if (Array.isArray(d))
133
+ return void (d.length ? objectTable(d) : (0, ui_1.info)('No chat analytics.'));
134
+ const scalars = {};
135
+ for (const [k, v] of Object.entries(d || {}))
136
+ if (v === null || typeof v !== 'object')
137
+ scalars[k] = v;
138
+ (0, ui_1.keyValue)(scalars);
139
+ }
140
+ catch (err) {
141
+ (0, ui_1.handleError)(err);
142
+ }
143
+ }
@@ -4,8 +4,15 @@ exports.analyzersListCommand = analyzersListCommand;
4
4
  exports.analyzersShowCommand = analyzersShowCommand;
5
5
  exports.analyzersAuditReportsCommand = analyzersAuditReportsCommand;
6
6
  exports.analyzersAuditStrategiesCommand = analyzersAuditStrategiesCommand;
7
+ exports.analyzersSummaryCommand = analyzersSummaryCommand;
8
+ exports.analyzersCallsCommand = analyzersCallsCommand;
9
+ exports.analyzersCallDetailCommand = analyzersCallDetailCommand;
10
+ exports.analyzersBatchListCommand = analyzersBatchListCommand;
11
+ exports.analyzersBatchCreateCommand = analyzersBatchCreateCommand;
12
+ exports.analyzersBatchCallsCommand = analyzersBatchCallsCommand;
7
13
  const dashboardApi_1 = require("../lib/dashboardApi");
8
14
  const ui_1 = require("../lib/ui");
15
+ const setJson_1 = require("./setJson");
9
16
  const when = (value) => {
10
17
  if (!value)
11
18
  return '';
@@ -128,3 +135,145 @@ async function analyzersAuditStrategiesCommand(opts) {
128
135
  (0, ui_1.handleError)(err);
129
136
  }
130
137
  }
138
+ const resolveScope = (opts) => (opts.batch ? 'batches' : 'strategies');
139
+ /** Print an object-or-array breakdown as a two-column table. */
140
+ function breakdown(title, v) {
141
+ if (!v)
142
+ return;
143
+ const rows = Array.isArray(v)
144
+ ? v.map((x) => [x?.name ?? x?.category ?? x?.severity ?? x?.value ?? x?._id ?? '', x?.count ?? x?.total ?? clip(JSON.stringify(x))])
145
+ : typeof v === 'object'
146
+ ? Object.entries(v).map(([k, x]) => [k, typeof x === 'object' ? clip(JSON.stringify(x), 80) : x])
147
+ : [];
148
+ if (!rows.length)
149
+ return;
150
+ (0, ui_1.info)(`\n${title}:`);
151
+ (0, ui_1.table)(['NAME', 'VALUE'], rows);
152
+ }
153
+ /** `cku analyzers summary <id> [--batch]` */
154
+ async function analyzersSummaryCommand(id, opts) {
155
+ try {
156
+ const res = await (0, dashboardApi_1.dashboardApi)().auditSummary(resolveScope(opts), id, {
157
+ severity: opts.severity,
158
+ dimension: opts.dimension,
159
+ startDate: opts.since,
160
+ endDate: opts.until,
161
+ });
162
+ if (opts.json)
163
+ return void console.log(JSON.stringify(res, null, 2));
164
+ const d = res?.data ?? res ?? {};
165
+ const scalars = {};
166
+ for (const [k, v] of Object.entries(d))
167
+ if (v === null || typeof v !== 'object')
168
+ scalars[k] = v;
169
+ (0, ui_1.keyValue)(scalars);
170
+ for (const [k, v] of Object.entries(d))
171
+ if (v && typeof v === 'object')
172
+ breakdown(k, v);
173
+ }
174
+ catch (err) {
175
+ (0, ui_1.handleError)(err);
176
+ }
177
+ }
178
+ /** `cku analyzers calls <id>` — drill into audited calls. */
179
+ async function analyzersCallsCommand(id, opts) {
180
+ const scope = resolveScope(opts);
181
+ const q = { page: Number(opts.page) || 1, page_size: pageSize(opts.limit) };
182
+ try {
183
+ const api = (0, dashboardApi_1.dashboardApi)();
184
+ let res;
185
+ if (opts.below80)
186
+ res = await api.auditBelow80Calls(scope, id, { ...q, sort: opts.sort });
187
+ else if (opts.severity)
188
+ res = await api.auditSeverityCalls(scope, id, opts.severity, q);
189
+ else if (opts.dimension && opts.category)
190
+ res = await api.auditCategoryCalls(scope, id, opts.dimension, opts.category, q);
191
+ else if (opts.varName && opts.varValue !== undefined)
192
+ res = await api.auditExtraVariableCalls(scope, id, opts.varName, opts.varValue, q);
193
+ else {
194
+ return (0, ui_1.handleError)(new Error('Pass one filter: --below-80, --severity <sev>, --dimension <d> --category <c>, or --var-name <n> --var-value <v>.'));
195
+ }
196
+ if (opts.json)
197
+ return void console.log(JSON.stringify(res, null, 2));
198
+ const rows = res?.calls || res?.data || (Array.isArray(res) ? res : []);
199
+ if (!rows.length)
200
+ return void (0, ui_1.info)('No calls.');
201
+ (0, ui_1.table)(['CALL ID', 'SCORE', 'SEVERITY', 'SUMMARY'], rows.map((c) => [
202
+ c.callId || c.call_id || c._id || '',
203
+ score(c.overallScore ?? c.score ?? c.overall_score),
204
+ c.severity || '',
205
+ clip(c.summary || c.reason, 70),
206
+ ]));
207
+ }
208
+ catch (err) {
209
+ (0, ui_1.handleError)(err);
210
+ }
211
+ }
212
+ /** `cku analyzers call <id> <callId>` */
213
+ async function analyzersCallDetailCommand(id, callId, opts) {
214
+ try {
215
+ const res = await (0, dashboardApi_1.dashboardApi)().auditCallDetail(resolveScope(opts), id, callId);
216
+ if (opts.json)
217
+ return void console.log(JSON.stringify(res, null, 2));
218
+ const d = res?.data ?? res?.call ?? res ?? {};
219
+ const scalars = {};
220
+ for (const [k, v] of Object.entries(d))
221
+ if (v === null || typeof v !== 'object')
222
+ scalars[k] = v;
223
+ (0, ui_1.keyValue)(scalars);
224
+ const findings = d.findings || d.issues;
225
+ if (Array.isArray(findings) && findings.length) {
226
+ (0, ui_1.info)('\nFindings:');
227
+ findings.forEach((f) => (0, ui_1.info)(` - ${clip(typeof f === 'string' ? f : f.description || f.summary || JSON.stringify(f), 200)}`));
228
+ }
229
+ }
230
+ catch (err) {
231
+ (0, ui_1.handleError)(err);
232
+ }
233
+ }
234
+ // --- batch analysis runs -----------------------------------------------------
235
+ async function analyzersBatchListCommand(opts) {
236
+ try {
237
+ const res = await (0, dashboardApi_1.dashboardApi)().listBatchAnalyses();
238
+ const rows = res?.data || [];
239
+ if (opts.json)
240
+ return void console.log(JSON.stringify(rows, null, 2));
241
+ if (!rows.length)
242
+ return void (0, ui_1.info)('No batch analyses.');
243
+ (0, ui_1.table)(['ID', 'BATCH NAME', 'ANALYZER', 'STATUS', 'CALLS', 'CREATED'], rows.map((r) => [
244
+ r._id || r.id || '', clip(r.batchName || r.name), clip(r.analyzerName || r.analyzerId),
245
+ r.status || '', r.totalCalls ?? r.callCount ?? '', when(r.createdAt),
246
+ ]));
247
+ }
248
+ catch (err) {
249
+ (0, ui_1.handleError)(err);
250
+ }
251
+ }
252
+ async function analyzersBatchCreateCommand(opts) {
253
+ try {
254
+ const res = await (0, dashboardApi_1.dashboardApi)().createBatchAnalysis((0, setJson_1.readSetJson)(opts.set));
255
+ if (opts.json)
256
+ return void console.log(JSON.stringify(res, null, 2));
257
+ (0, ui_1.success)(`Batch analysis created${res?.data?._id ? `: ${res.data._id}` : ''}.`);
258
+ }
259
+ catch (err) {
260
+ (0, ui_1.handleError)(err);
261
+ }
262
+ }
263
+ async function analyzersBatchCallsCommand(batchId, opts) {
264
+ try {
265
+ const res = await (0, dashboardApi_1.dashboardApi)().batchAnalysisCalls(batchId, {
266
+ page: opts.page ? Number(opts.page) : 1,
267
+ is_export: opts.export,
268
+ });
269
+ if (opts.json)
270
+ return void console.log(JSON.stringify(res, null, 2));
271
+ const rows = res?.data?.calls || res?.calls || (Array.isArray(res?.data) ? res.data : []);
272
+ if (!rows.length)
273
+ return void (0, ui_1.info)('No calls in this batch.');
274
+ (0, ui_1.table)(['CALL ID', 'STATUS', 'SCORE'], rows.map((c) => [c.callId || c.call_id || c._id || '', c.status || '', score(c.score ?? c.overallScore)]));
275
+ }
276
+ catch (err) {
277
+ (0, ui_1.handleError)(err);
278
+ }
279
+ }