cost-katana-cli 2.0.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.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +343 -0
  3. package/bin/cost-katana.js +20 -0
  4. package/dist/commands/agent-inspect.d.ts +3 -0
  5. package/dist/commands/agent-inspect.d.ts.map +1 -0
  6. package/dist/commands/agent-inspect.js +630 -0
  7. package/dist/commands/agent-inspect.js.map +1 -0
  8. package/dist/commands/analytics.d.ts +3 -0
  9. package/dist/commands/analytics.d.ts.map +1 -0
  10. package/dist/commands/analytics.js +375 -0
  11. package/dist/commands/analytics.js.map +1 -0
  12. package/dist/commands/analyze.d.ts +3 -0
  13. package/dist/commands/analyze.d.ts.map +1 -0
  14. package/dist/commands/analyze.js +286 -0
  15. package/dist/commands/analyze.js.map +1 -0
  16. package/dist/commands/ask.d.ts +3 -0
  17. package/dist/commands/ask.d.ts.map +1 -0
  18. package/dist/commands/ask.js +137 -0
  19. package/dist/commands/ask.js.map +1 -0
  20. package/dist/commands/audit-firewall.d.ts +3 -0
  21. package/dist/commands/audit-firewall.d.ts.map +1 -0
  22. package/dist/commands/audit-firewall.js +737 -0
  23. package/dist/commands/audit-firewall.js.map +1 -0
  24. package/dist/commands/budget.d.ts +3 -0
  25. package/dist/commands/budget.d.ts.map +1 -0
  26. package/dist/commands/budget.js +283 -0
  27. package/dist/commands/budget.js.map +1 -0
  28. package/dist/commands/bulk-optimize.d.ts +3 -0
  29. package/dist/commands/bulk-optimize.d.ts.map +1 -0
  30. package/dist/commands/bulk-optimize.js +863 -0
  31. package/dist/commands/bulk-optimize.js.map +1 -0
  32. package/dist/commands/chat.d.ts +3 -0
  33. package/dist/commands/chat.d.ts.map +1 -0
  34. package/dist/commands/chat.js +292 -0
  35. package/dist/commands/chat.js.map +1 -0
  36. package/dist/commands/check-cache.d.ts +3 -0
  37. package/dist/commands/check-cache.d.ts.map +1 -0
  38. package/dist/commands/check-cache.js +267 -0
  39. package/dist/commands/check-cache.js.map +1 -0
  40. package/dist/commands/compare.d.ts +3 -0
  41. package/dist/commands/compare.d.ts.map +1 -0
  42. package/dist/commands/compare.js +131 -0
  43. package/dist/commands/compare.js.map +1 -0
  44. package/dist/commands/config.d.ts +3 -0
  45. package/dist/commands/config.d.ts.map +1 -0
  46. package/dist/commands/config.js +421 -0
  47. package/dist/commands/config.js.map +1 -0
  48. package/dist/commands/craft-workflow.d.ts +3 -0
  49. package/dist/commands/craft-workflow.d.ts.map +1 -0
  50. package/dist/commands/craft-workflow.js +844 -0
  51. package/dist/commands/craft-workflow.js.map +1 -0
  52. package/dist/commands/debug-prompt.d.ts +3 -0
  53. package/dist/commands/debug-prompt.d.ts.map +1 -0
  54. package/dist/commands/debug-prompt.js +614 -0
  55. package/dist/commands/debug-prompt.js.map +1 -0
  56. package/dist/commands/diff-prompts.d.ts +3 -0
  57. package/dist/commands/diff-prompts.d.ts.map +1 -0
  58. package/dist/commands/diff-prompts.js +553 -0
  59. package/dist/commands/diff-prompts.js.map +1 -0
  60. package/dist/commands/high-cost-prompts.d.ts +3 -0
  61. package/dist/commands/high-cost-prompts.d.ts.map +1 -0
  62. package/dist/commands/high-cost-prompts.js +719 -0
  63. package/dist/commands/high-cost-prompts.js.map +1 -0
  64. package/dist/commands/init.d.ts +3 -0
  65. package/dist/commands/init.d.ts.map +1 -0
  66. package/dist/commands/init.js +325 -0
  67. package/dist/commands/init.js.map +1 -0
  68. package/dist/commands/key.d.ts +3 -0
  69. package/dist/commands/key.d.ts.map +1 -0
  70. package/dist/commands/key.js +574 -0
  71. package/dist/commands/key.js.map +1 -0
  72. package/dist/commands/list-models.d.ts +3 -0
  73. package/dist/commands/list-models.d.ts.map +1 -0
  74. package/dist/commands/list-models.js +154 -0
  75. package/dist/commands/list-models.js.map +1 -0
  76. package/dist/commands/models.d.ts +3 -0
  77. package/dist/commands/models.d.ts.map +1 -0
  78. package/dist/commands/models.js +107 -0
  79. package/dist/commands/models.js.map +1 -0
  80. package/dist/commands/optimize.d.ts +3 -0
  81. package/dist/commands/optimize.d.ts.map +1 -0
  82. package/dist/commands/optimize.js +345 -0
  83. package/dist/commands/optimize.js.map +1 -0
  84. package/dist/commands/project.d.ts +3 -0
  85. package/dist/commands/project.d.ts.map +1 -0
  86. package/dist/commands/project.js +475 -0
  87. package/dist/commands/project.js.map +1 -0
  88. package/dist/commands/prompt-metrics.d.ts +3 -0
  89. package/dist/commands/prompt-metrics.d.ts.map +1 -0
  90. package/dist/commands/prompt-metrics.js +665 -0
  91. package/dist/commands/prompt-metrics.js.map +1 -0
  92. package/dist/commands/replay-session.d.ts +3 -0
  93. package/dist/commands/replay-session.d.ts.map +1 -0
  94. package/dist/commands/replay-session.js +615 -0
  95. package/dist/commands/replay-session.js.map +1 -0
  96. package/dist/commands/retry-log.d.ts +3 -0
  97. package/dist/commands/retry-log.d.ts.map +1 -0
  98. package/dist/commands/retry-log.js +686 -0
  99. package/dist/commands/retry-log.js.map +1 -0
  100. package/dist/commands/rewrite-prompt.d.ts +3 -0
  101. package/dist/commands/rewrite-prompt.d.ts.map +1 -0
  102. package/dist/commands/rewrite-prompt.js +802 -0
  103. package/dist/commands/rewrite-prompt.js.map +1 -0
  104. package/dist/commands/set-budget.d.ts +3 -0
  105. package/dist/commands/set-budget.d.ts.map +1 -0
  106. package/dist/commands/set-budget.js +909 -0
  107. package/dist/commands/set-budget.js.map +1 -0
  108. package/dist/commands/simulate-cost.d.ts +3 -0
  109. package/dist/commands/simulate-cost.d.ts.map +1 -0
  110. package/dist/commands/simulate-cost.js +873 -0
  111. package/dist/commands/simulate-cost.js.map +1 -0
  112. package/dist/commands/suggest-models.d.ts +3 -0
  113. package/dist/commands/suggest-models.d.ts.map +1 -0
  114. package/dist/commands/suggest-models.js +674 -0
  115. package/dist/commands/suggest-models.js.map +1 -0
  116. package/dist/commands/test.d.ts +3 -0
  117. package/dist/commands/test.d.ts.map +1 -0
  118. package/dist/commands/test.js +187 -0
  119. package/dist/commands/test.js.map +1 -0
  120. package/dist/commands/trace-workflow.d.ts +3 -0
  121. package/dist/commands/trace-workflow.d.ts.map +1 -0
  122. package/dist/commands/trace-workflow.js +651 -0
  123. package/dist/commands/trace-workflow.js.map +1 -0
  124. package/dist/commands/trace.d.ts +3 -0
  125. package/dist/commands/trace.d.ts.map +1 -0
  126. package/dist/commands/trace.js +468 -0
  127. package/dist/commands/trace.js.map +1 -0
  128. package/dist/commands/track.d.ts +3 -0
  129. package/dist/commands/track.d.ts.map +1 -0
  130. package/dist/commands/track.js +404 -0
  131. package/dist/commands/track.js.map +1 -0
  132. package/dist/index.d.ts +4 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +169 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/utils/config.d.ts +46 -0
  137. package/dist/utils/config.d.ts.map +1 -0
  138. package/dist/utils/config.js +321 -0
  139. package/dist/utils/config.js.map +1 -0
  140. package/dist/utils/logger.d.ts +21 -0
  141. package/dist/utils/logger.d.ts.map +1 -0
  142. package/dist/utils/logger.js +101 -0
  143. package/dist/utils/logger.js.map +1 -0
  144. package/dist/utils/models.d.ts +22 -0
  145. package/dist/utils/models.d.ts.map +1 -0
  146. package/dist/utils/models.js +2251 -0
  147. package/dist/utils/models.js.map +1 -0
  148. package/package.json +107 -0
@@ -0,0 +1,630 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.agentInspectCommand = agentInspectCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const logger_1 = require("../utils/logger");
9
+ const config_1 = require("../utils/config");
10
+ const axios_1 = __importDefault(require("axios"));
11
+ function agentInspectCommand(program) {
12
+ const inspectGroup = program
13
+ .command('agent-inspect')
14
+ .description('šŸ” Audit specific agents in workflows');
15
+ // Main agent-inspect command
16
+ inspectGroup
17
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
18
+ .option('--export <path>', 'Export inspection data to file')
19
+ .option('-v, --verbose', 'Show detailed inspection information')
20
+ .action(async (options) => {
21
+ try {
22
+ await handleAgentInspect(options);
23
+ }
24
+ catch (error) {
25
+ logger_1.logger.error('Agent inspect command failed:', error);
26
+ process.exit(1);
27
+ }
28
+ });
29
+ // Inspect agent by ID
30
+ inspectGroup
31
+ .command('id <agentId>')
32
+ .description('šŸ” Audit a specific agent by ID')
33
+ .option('-d, --days <days>', 'Number of days to look back', '7')
34
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
35
+ .option('--export <path>', 'Export inspection data to file')
36
+ .option('-v, --verbose', 'Show detailed inspection information')
37
+ .option('--include-prompts', 'Include detailed prompt analysis')
38
+ .option('--include-failures', 'Include detailed failure analysis')
39
+ .option('--include-model-switching', 'Include model switching behavior')
40
+ .action(async (agentId, options) => {
41
+ try {
42
+ await handleAgentInspectById(agentId, options);
43
+ }
44
+ catch (error) {
45
+ logger_1.logger.error('Agent inspect by ID failed:', error);
46
+ process.exit(1);
47
+ }
48
+ });
49
+ // Inspect agent by name
50
+ inspectGroup
51
+ .command('name <agentName>')
52
+ .description('šŸ” Audit agents by name')
53
+ .option('-d, --days <days>', 'Number of days to look back', '7')
54
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
55
+ .option('--export <path>', 'Export inspection data to file')
56
+ .option('-v, --verbose', 'Show detailed inspection information')
57
+ .option('--include-prompts', 'Include detailed prompt analysis')
58
+ .option('--include-failures', 'Include detailed failure analysis')
59
+ .option('--include-model-switching', 'Include model switching behavior')
60
+ .action(async (agentName, options) => {
61
+ try {
62
+ await handleAgentInspectByName(agentName, options);
63
+ }
64
+ catch (error) {
65
+ logger_1.logger.error('Agent inspect by name failed:', error);
66
+ process.exit(1);
67
+ }
68
+ });
69
+ // Inspect agent by workflow
70
+ inspectGroup
71
+ .command('workflow <workflowId>')
72
+ .description('šŸ” Audit all agents in a specific workflow')
73
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
74
+ .option('--export <path>', 'Export inspection data to file')
75
+ .option('-v, --verbose', 'Show detailed inspection information')
76
+ .option('--include-prompts', 'Include detailed prompt analysis')
77
+ .option('--include-failures', 'Include detailed failure analysis')
78
+ .option('--include-model-switching', 'Include model switching behavior')
79
+ .action(async (workflowId, options) => {
80
+ try {
81
+ await handleAgentInspectByWorkflow(workflowId, options);
82
+ }
83
+ catch (error) {
84
+ logger_1.logger.error('Agent inspect by workflow failed:', error);
85
+ process.exit(1);
86
+ }
87
+ });
88
+ // Inspect recent agents
89
+ inspectGroup
90
+ .command('recent')
91
+ .description('šŸ“‹ Show recent agent inspections')
92
+ .option('-n, --number <count>', 'Number of recent agents to show', '10')
93
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
94
+ .option('--export <path>', 'Export inspection data to file')
95
+ .option('-v, --verbose', 'Show detailed inspection information')
96
+ .action(async (options) => {
97
+ try {
98
+ await handleAgentInspectRecent(options);
99
+ }
100
+ catch (error) {
101
+ logger_1.logger.error('Agent inspect recent failed:', error);
102
+ process.exit(1);
103
+ }
104
+ });
105
+ }
106
+ async function handleAgentInspect(options) {
107
+ console.log(chalk_1.default.cyan.bold('\nšŸ” Agent Inspection & Audit Analysis'));
108
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
109
+ console.log(chalk_1.default.yellow('Available commands:'));
110
+ console.log(chalk_1.default.white(' costkatana agent-inspect id <agentId> Audit specific agent by ID'));
111
+ console.log(chalk_1.default.white(' costkatana agent-inspect name <agentName> Audit agents by name'));
112
+ console.log(chalk_1.default.white(' costkatana agent-inspect workflow <workflowId> Audit all agents in workflow'));
113
+ console.log(chalk_1.default.white(' costkatana agent-inspect recent Show recent agent inspections'));
114
+ console.log(chalk_1.default.gray('\nExamples:'));
115
+ console.log(chalk_1.default.white(' costkatana agent-inspect id agent-buyer-ranker'));
116
+ console.log(chalk_1.default.white(' costkatana agent-inspect name buyer-ranker --days 30'));
117
+ console.log(chalk_1.default.white(' costkatana agent-inspect workflow workflow-98765'));
118
+ console.log(chalk_1.default.white(' costkatana agent-inspect recent --number 5'));
119
+ console.log(chalk_1.default.gray('\nInspection Information:'));
120
+ console.log(chalk_1.default.white(' • Prompts issued by agent (with timestamps)'));
121
+ console.log(chalk_1.default.white(' • Response patterns and behavior analysis'));
122
+ console.log(chalk_1.default.white(' • Usage and cost footprint'));
123
+ console.log(chalk_1.default.white(' • Failure cases and retry log'));
124
+ console.log(chalk_1.default.white(' • Model switching behavior (if used)'));
125
+ console.log(chalk_1.default.white(' • Performance metrics and trends'));
126
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
127
+ }
128
+ async function handleAgentInspectById(agentId, options) {
129
+ logger_1.logger.info(`šŸ” Inspecting agent: ${agentId}`);
130
+ try {
131
+ const days = parseInt(options.days) || 7;
132
+ const inspectData = await getAgentInspectById(agentId, days, options);
133
+ displayAgentInspectResult(inspectData, options);
134
+ }
135
+ catch (error) {
136
+ logger_1.logger.error('Failed to inspect agent:', error);
137
+ process.exit(1);
138
+ }
139
+ }
140
+ async function getAgentInspectById(agentId, days, options) {
141
+ const baseUrl = config_1.configManager.get('baseUrl');
142
+ const apiKey = config_1.configManager.get('apiKey');
143
+ if (!baseUrl || !apiKey) {
144
+ console.log(chalk_1.default.red.bold('\nāŒ Configuration Missing'));
145
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
146
+ if (!apiKey) {
147
+ console.log(chalk_1.default.yellow('• API Key is not set'));
148
+ }
149
+ if (!baseUrl) {
150
+ console.log(chalk_1.default.yellow('• Base URL is not set'));
151
+ }
152
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
153
+ console.log(chalk_1.default.cyan('To set up your configuration, run:'));
154
+ console.log(chalk_1.default.white(' cost-katana init'));
155
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
156
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
157
+ }
158
+ try {
159
+ const params = new URLSearchParams();
160
+ params.append('days', days.toString());
161
+ if (options.includePrompts)
162
+ params.append('includePrompts', 'true');
163
+ if (options.includeFailures)
164
+ params.append('includeFailures', 'true');
165
+ if (options.includeModelSwitching)
166
+ params.append('includeModelSwitching', 'true');
167
+ const response = await axios_1.default.get(`${baseUrl}/api/agent/inspect/${agentId}?${params}`, {
168
+ headers: {
169
+ 'Authorization': `Bearer ${apiKey}`,
170
+ 'Content-Type': 'application/json',
171
+ },
172
+ timeout: 30000,
173
+ });
174
+ if (response.status !== 200) {
175
+ throw new Error(`API returned status ${response.status}`);
176
+ }
177
+ if (response.data.success && response.data.data) {
178
+ return response.data.data;
179
+ }
180
+ else {
181
+ throw new Error(response.data.message || 'Invalid response format');
182
+ }
183
+ }
184
+ catch (error) {
185
+ if (error.response) {
186
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
187
+ }
188
+ else if (error.request) {
189
+ throw new Error('No response received from API');
190
+ }
191
+ else {
192
+ throw new Error(`Request failed: ${error.message}`);
193
+ }
194
+ }
195
+ }
196
+ function displayAgentInspectResult(inspect, options) {
197
+ const format = options.format || 'table';
198
+ if (format === 'json') {
199
+ console.log(JSON.stringify(inspect, null, 2));
200
+ return;
201
+ }
202
+ else if (format === 'csv') {
203
+ console.log('Agent ID,Name,Role,Total Requests,Success Rate,Total Cost,Total Tokens,Average Latency');
204
+ console.log(`"${inspect.agentId}","${inspect.name}","${inspect.role}","${inspect.totalRequests}","${inspect.successRate}","${inspect.totalCost}","${inspect.totalTokens}","${inspect.averageLatency}"`);
205
+ return;
206
+ }
207
+ console.log(chalk_1.default.cyan.bold('\nšŸ” Agent Inspection Report'));
208
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
209
+ // Basic Agent Information
210
+ console.log(chalk_1.default.yellow.bold('\nšŸ“‹ Agent Information'));
211
+ console.log(chalk_1.default.gray('─'.repeat(50)));
212
+ console.log(chalk_1.default.white('šŸ†” Agent ID:'), chalk_1.default.cyan(inspect.agentId));
213
+ console.log(chalk_1.default.white('šŸ“ Name:'), chalk_1.default.cyan(inspect.name));
214
+ console.log(chalk_1.default.white('šŸŽ­ Role:'), chalk_1.default.cyan(inspect.role));
215
+ console.log(chalk_1.default.white('šŸ“… Created:'), chalk_1.default.cyan(new Date(inspect.createdAt).toLocaleString()));
216
+ console.log(chalk_1.default.white('šŸ“Š Status:'), inspect.status === 'active' ? chalk_1.default.green(inspect.status) : chalk_1.default.red(inspect.status));
217
+ // Usage Statistics
218
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Usage Statistics'));
219
+ console.log(chalk_1.default.gray('─'.repeat(50)));
220
+ console.log(chalk_1.default.white('šŸ“ˆ Total Requests:'), chalk_1.default.cyan(inspect.totalRequests.toLocaleString()));
221
+ console.log(chalk_1.default.white('āœ… Successful Requests:'), chalk_1.default.green(inspect.successfulRequests.toLocaleString()));
222
+ console.log(chalk_1.default.white('āŒ Failed Requests:'), chalk_1.default.red(inspect.failedRequests.toLocaleString()));
223
+ console.log(chalk_1.default.white('šŸ“Š Success Rate:'), chalk_1.default.cyan(`${(inspect.successRate * 100).toFixed(1)}%`));
224
+ console.log(chalk_1.default.white('ā±ļø Average Latency:'), chalk_1.default.cyan(`${inspect.averageLatency}ms`));
225
+ // Cost and Performance
226
+ console.log(chalk_1.default.yellow.bold('\nšŸ’° Cost & Performance'));
227
+ console.log(chalk_1.default.gray('─'.repeat(50)));
228
+ console.log(chalk_1.default.white('šŸ’µ Total Cost:'), chalk_1.default.green(`$${inspect.totalCost.toFixed(4)}`));
229
+ console.log(chalk_1.default.white('šŸ”¢ Total Tokens:'), chalk_1.default.cyan(inspect.totalTokens.toLocaleString()));
230
+ console.log(chalk_1.default.white('šŸ“Š Average Cost per Request:'), chalk_1.default.cyan(`$${(inspect.totalCost / inspect.totalRequests).toFixed(4)}`));
231
+ console.log(chalk_1.default.white('šŸ“ˆ Average Tokens per Request:'), chalk_1.default.cyan(Math.round(inspect.totalTokens / inspect.totalRequests)));
232
+ console.log(chalk_1.default.white('⚔ Throughput:'), chalk_1.default.cyan(`${inspect.throughput?.toFixed(2) || 'N/A'} requests/min`));
233
+ // Model Usage
234
+ if (inspect.modelUsage && Object.keys(inspect.modelUsage).length > 0) {
235
+ console.log(chalk_1.default.yellow.bold('\nšŸ¤– Model Usage'));
236
+ console.log(chalk_1.default.gray('─'.repeat(50)));
237
+ Object.entries(inspect.modelUsage).forEach(([model, usage]) => {
238
+ console.log(chalk_1.default.white(`• ${model}:`));
239
+ console.log(chalk_1.default.gray(` Requests: ${usage.requests}`));
240
+ console.log(chalk_1.default.gray(` Cost: $${usage.cost.toFixed(4)}`));
241
+ console.log(chalk_1.default.gray(` Tokens: ${usage.tokens.toLocaleString()}`));
242
+ console.log(chalk_1.default.gray(` Success Rate: ${(usage.successRate * 100).toFixed(1)}%`));
243
+ });
244
+ }
245
+ // Model Switching Behavior
246
+ if (options.includeModelSwitching && inspect.modelSwitching) {
247
+ console.log(chalk_1.default.yellow.bold('\nšŸ”„ Model Switching Behavior'));
248
+ console.log(chalk_1.default.gray('─'.repeat(50)));
249
+ console.log(chalk_1.default.white('Total Switches:'), chalk_1.default.cyan(inspect.modelSwitching.totalSwitches));
250
+ console.log(chalk_1.default.white('Switch Frequency:'), chalk_1.default.cyan(`${inspect.modelSwitching.switchFrequency} switches/day`));
251
+ console.log(chalk_1.default.white('Primary Model:'), chalk_1.default.cyan(inspect.modelSwitching.primaryModel));
252
+ console.log(chalk_1.default.white('Fallback Models:'), chalk_1.default.cyan(inspect.modelSwitching.fallbackModels?.join(', ') || 'None'));
253
+ if (inspect.modelSwitching.switchReasons) {
254
+ console.log(chalk_1.default.white('Switch Reasons:'));
255
+ Object.entries(inspect.modelSwitching.switchReasons).forEach(([reason, count]) => {
256
+ console.log(chalk_1.default.gray(` • ${reason}: ${count} times`));
257
+ });
258
+ }
259
+ }
260
+ // Response Patterns
261
+ if (inspect.responsePatterns) {
262
+ console.log(chalk_1.default.yellow.bold('\nšŸ“ Response Patterns'));
263
+ console.log(chalk_1.default.gray('─'.repeat(50)));
264
+ console.log(chalk_1.default.white('Average Response Length:'), chalk_1.default.cyan(`${inspect.responsePatterns.averageLength} characters`));
265
+ console.log(chalk_1.default.white('Response Length Range:'), chalk_1.default.cyan(`${inspect.responsePatterns.minLength} - ${inspect.responsePatterns.maxLength} characters`));
266
+ console.log(chalk_1.default.white('Common Response Types:'), chalk_1.default.cyan(inspect.responsePatterns.commonTypes?.join(', ') || 'N/A'));
267
+ console.log(chalk_1.default.white('Response Quality Score:'), chalk_1.default.cyan(inspect.responsePatterns.qualityScore?.toFixed(2) || 'N/A'));
268
+ }
269
+ // Failure Analysis
270
+ if (options.includeFailures && inspect.failures && inspect.failures.length > 0) {
271
+ console.log(chalk_1.default.yellow.bold('\nāŒ Failure Analysis'));
272
+ console.log(chalk_1.default.gray('─'.repeat(50)));
273
+ console.log(chalk_1.default.white('Total Failures:'), chalk_1.default.red(inspect.failures.length));
274
+ console.log(chalk_1.default.white('Failure Rate:'), chalk_1.default.red(`${(inspect.failures.length / inspect.totalRequests * 100).toFixed(1)}%`));
275
+ const failureTypes = inspect.failures.reduce((acc, failure) => {
276
+ acc[failure.type] = (acc[failure.type] || 0) + 1;
277
+ return acc;
278
+ }, {});
279
+ console.log(chalk_1.default.white('Failure Types:'));
280
+ Object.entries(failureTypes).forEach(([type, count]) => {
281
+ console.log(chalk_1.default.gray(` • ${type}: ${count} occurrences`));
282
+ });
283
+ if (options.verbose) {
284
+ console.log(chalk_1.default.white('\nRecent Failures:'));
285
+ inspect.failures.slice(0, 5).forEach((failure, index) => {
286
+ console.log(chalk_1.default.gray(`${index + 1}. ${failure.timestamp}: ${failure.error}`));
287
+ });
288
+ }
289
+ }
290
+ // Prompt Analysis
291
+ if (options.includePrompts && inspect.prompts && inspect.prompts.length > 0) {
292
+ console.log(chalk_1.default.yellow.bold('\nšŸ’¬ Prompt Analysis'));
293
+ console.log(chalk_1.default.gray('─'.repeat(50)));
294
+ console.log(chalk_1.default.white('Total Prompts:'), chalk_1.default.cyan(inspect.prompts.length));
295
+ console.log(chalk_1.default.white('Average Prompt Length:'), chalk_1.default.cyan(`${inspect.prompts.averageLength} characters`));
296
+ console.log(chalk_1.default.white('Prompt Complexity:'), chalk_1.default.cyan(inspect.prompts.complexity || 'N/A'));
297
+ if (inspect.prompts.commonPatterns) {
298
+ console.log(chalk_1.default.white('Common Patterns:'));
299
+ inspect.prompts.commonPatterns.forEach((pattern, index) => {
300
+ console.log(chalk_1.default.gray(` ${index + 1}. ${pattern.description} (${pattern.frequency} times)`));
301
+ });
302
+ }
303
+ if (options.verbose) {
304
+ console.log(chalk_1.default.white('\nRecent Prompts:'));
305
+ inspect.prompts.slice(0, 3).forEach((prompt, index) => {
306
+ console.log(chalk_1.default.gray(`${index + 1}. ${new Date(prompt.timestamp).toLocaleString()}:`));
307
+ console.log(chalk_1.default.gray(` ${prompt.content.substring(0, 100)}${prompt.content.length > 100 ? '...' : ''}`));
308
+ });
309
+ }
310
+ }
311
+ // Performance Trends
312
+ if (inspect.performanceTrends) {
313
+ console.log(chalk_1.default.yellow.bold('\nšŸ“ˆ Performance Trends'));
314
+ console.log(chalk_1.default.gray('─'.repeat(50)));
315
+ console.log(chalk_1.default.white('Cost Trend:'), chalk_1.default.cyan(inspect.performanceTrends.costTrend));
316
+ console.log(chalk_1.default.white('Latency Trend:'), chalk_1.default.cyan(inspect.performanceTrends.latencyTrend));
317
+ console.log(chalk_1.default.white('Success Rate Trend:'), chalk_1.default.cyan(inspect.performanceTrends.successRateTrend));
318
+ console.log(chalk_1.default.white('Usage Trend:'), chalk_1.default.cyan(inspect.performanceTrends.usageTrend));
319
+ }
320
+ // Recommendations
321
+ if (inspect.recommendations && inspect.recommendations.length > 0) {
322
+ console.log(chalk_1.default.yellow.bold('\nšŸ’” Recommendations'));
323
+ console.log(chalk_1.default.gray('─'.repeat(50)));
324
+ inspect.recommendations.forEach((rec, index) => {
325
+ console.log(chalk_1.default.white(`${index + 1}. ${rec.type}:`));
326
+ console.log(chalk_1.default.gray(` ${rec.description}`));
327
+ if (rec.impact) {
328
+ console.log(chalk_1.default.gray(` Impact: ${rec.impact}`));
329
+ }
330
+ if (rec.implementation) {
331
+ console.log(chalk_1.default.gray(` Implementation: ${rec.implementation}`));
332
+ }
333
+ });
334
+ }
335
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
336
+ }
337
+ async function handleAgentInspectByName(agentName, options) {
338
+ logger_1.logger.info(`šŸ” Inspecting agents by name: ${agentName}`);
339
+ try {
340
+ const days = parseInt(options.days) || 7;
341
+ const inspectData = await getAgentInspectByName(agentName, days, options);
342
+ displayAgentInspectResult(inspectData, options);
343
+ }
344
+ catch (error) {
345
+ logger_1.logger.error('Failed to inspect agents by name:', error);
346
+ process.exit(1);
347
+ }
348
+ }
349
+ async function getAgentInspectByName(agentName, days, options) {
350
+ const baseUrl = config_1.configManager.get('baseUrl');
351
+ const apiKey = config_1.configManager.get('apiKey');
352
+ if (!baseUrl || !apiKey) {
353
+ console.log(chalk_1.default.red.bold('\nāŒ Configuration Missing'));
354
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
355
+ if (!apiKey) {
356
+ console.log(chalk_1.default.yellow('• API Key is not set'));
357
+ }
358
+ if (!baseUrl) {
359
+ console.log(chalk_1.default.yellow('• Base URL is not set'));
360
+ }
361
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
362
+ console.log(chalk_1.default.cyan('To set up your configuration, run:'));
363
+ console.log(chalk_1.default.white(' cost-katana init'));
364
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
365
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
366
+ }
367
+ try {
368
+ const params = new URLSearchParams();
369
+ params.append('name', agentName);
370
+ params.append('days', days.toString());
371
+ if (options.includePrompts)
372
+ params.append('includePrompts', 'true');
373
+ if (options.includeFailures)
374
+ params.append('includeFailures', 'true');
375
+ if (options.includeModelSwitching)
376
+ params.append('includeModelSwitching', 'true');
377
+ const response = await axios_1.default.get(`${baseUrl}/api/agent/inspect/name?${params}`, {
378
+ headers: {
379
+ 'Authorization': `Bearer ${apiKey}`,
380
+ 'Content-Type': 'application/json',
381
+ },
382
+ timeout: 30000,
383
+ });
384
+ if (response.status !== 200) {
385
+ throw new Error(`API returned status ${response.status}`);
386
+ }
387
+ if (response.data.success && response.data.data) {
388
+ return response.data.data;
389
+ }
390
+ else {
391
+ throw new Error(response.data.message || 'Invalid response format');
392
+ }
393
+ }
394
+ catch (error) {
395
+ if (error.response) {
396
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
397
+ }
398
+ else if (error.request) {
399
+ throw new Error('No response received from API');
400
+ }
401
+ else {
402
+ throw new Error(`Request failed: ${error.message}`);
403
+ }
404
+ }
405
+ }
406
+ async function handleAgentInspectByWorkflow(workflowId, options) {
407
+ logger_1.logger.info(`šŸ” Inspecting agents in workflow: ${workflowId}`);
408
+ try {
409
+ const inspectData = await getAgentInspectByWorkflow(workflowId, options);
410
+ displayWorkflowAgentInspectResult(inspectData, workflowId, options);
411
+ }
412
+ catch (error) {
413
+ logger_1.logger.error('Failed to inspect workflow agents:', error);
414
+ process.exit(1);
415
+ }
416
+ }
417
+ async function getAgentInspectByWorkflow(workflowId, options) {
418
+ const baseUrl = config_1.configManager.get('baseUrl');
419
+ const apiKey = config_1.configManager.get('apiKey');
420
+ if (!baseUrl || !apiKey) {
421
+ console.log(chalk_1.default.red.bold('\nāŒ Configuration Missing'));
422
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
423
+ if (!apiKey) {
424
+ console.log(chalk_1.default.yellow('• API Key is not set'));
425
+ }
426
+ if (!baseUrl) {
427
+ console.log(chalk_1.default.yellow('• Base URL is not set'));
428
+ }
429
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
430
+ console.log(chalk_1.default.cyan('To set up your configuration, run:'));
431
+ console.log(chalk_1.default.white(' cost-katana init'));
432
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
433
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
434
+ }
435
+ try {
436
+ const params = new URLSearchParams();
437
+ if (options.includePrompts)
438
+ params.append('includePrompts', 'true');
439
+ if (options.includeFailures)
440
+ params.append('includeFailures', 'true');
441
+ if (options.includeModelSwitching)
442
+ params.append('includeModelSwitching', 'true');
443
+ const response = await axios_1.default.get(`${baseUrl}/api/agent/inspect/workflow/${workflowId}?${params}`, {
444
+ headers: {
445
+ 'Authorization': `Bearer ${apiKey}`,
446
+ 'Content-Type': 'application/json',
447
+ },
448
+ timeout: 30000,
449
+ });
450
+ if (response.status !== 200) {
451
+ throw new Error(`API returned status ${response.status}`);
452
+ }
453
+ if (response.data.success && response.data.data) {
454
+ return response.data.data;
455
+ }
456
+ else {
457
+ throw new Error(response.data.message || 'Invalid response format');
458
+ }
459
+ }
460
+ catch (error) {
461
+ if (error.response) {
462
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
463
+ }
464
+ else if (error.request) {
465
+ throw new Error('No response received from API');
466
+ }
467
+ else {
468
+ throw new Error(`Request failed: ${error.message}`);
469
+ }
470
+ }
471
+ }
472
+ function displayWorkflowAgentInspectResult(inspect, workflowId, options) {
473
+ const format = options.format || 'table';
474
+ if (format === 'json') {
475
+ console.log(JSON.stringify(inspect, null, 2));
476
+ return;
477
+ }
478
+ else if (format === 'csv') {
479
+ console.log('Agent ID,Name,Role,Requests,Success Rate,Cost,Tokens,Latency');
480
+ inspect.agents.forEach((agent) => {
481
+ console.log(`"${agent.agentId}","${agent.name}","${agent.role}","${agent.totalRequests}","${agent.successRate}","${agent.totalCost}","${agent.totalTokens}","${agent.averageLatency}"`);
482
+ });
483
+ return;
484
+ }
485
+ console.log(chalk_1.default.cyan.bold(`\nšŸ” Workflow Agent Inspection: ${workflowId}`));
486
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
487
+ if (!inspect.agents || inspect.agents.length === 0) {
488
+ console.log(chalk_1.default.yellow('No agents found in this workflow.'));
489
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
490
+ return;
491
+ }
492
+ // Summary Statistics
493
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Summary Statistics'));
494
+ console.log(chalk_1.default.gray('─'.repeat(50)));
495
+ console.log(chalk_1.default.white('Total Agents:'), chalk_1.default.cyan(inspect.agents.length));
496
+ console.log(chalk_1.default.white('Total Requests:'), chalk_1.default.cyan(inspect.totalRequests.toLocaleString()));
497
+ console.log(chalk_1.default.white('Total Cost:'), chalk_1.default.green(`$${inspect.totalCost.toFixed(4)}`));
498
+ console.log(chalk_1.default.white('Average Success Rate:'), chalk_1.default.cyan(`${(inspect.averageSuccessRate * 100).toFixed(1)}%`));
499
+ // Agent Details
500
+ console.log(chalk_1.default.yellow.bold('\nšŸ¤– Agent Details'));
501
+ console.log(chalk_1.default.gray('─'.repeat(50)));
502
+ inspect.agents.forEach((agent, index) => {
503
+ const successColor = agent.successRate > 0.8 ? chalk_1.default.green : agent.successRate > 0.6 ? chalk_1.default.yellow : chalk_1.default.red;
504
+ console.log(chalk_1.default.white(`\n${index + 1}. ${agent.name} (${agent.agentId})`));
505
+ console.log(chalk_1.default.gray(' ─'.repeat(40)));
506
+ console.log(chalk_1.default.white(' šŸŽ­ Role:'), chalk_1.default.cyan(agent.role));
507
+ console.log(chalk_1.default.white(' šŸ“ˆ Requests:'), chalk_1.default.cyan(agent.totalRequests));
508
+ console.log(chalk_1.default.white(' šŸ“Š Success Rate:'), successColor(`${(agent.successRate * 100).toFixed(1)}%`));
509
+ console.log(chalk_1.default.white(' šŸ’° Cost:'), chalk_1.default.green(`$${agent.totalCost.toFixed(4)}`));
510
+ console.log(chalk_1.default.white(' šŸ”¢ Tokens:'), chalk_1.default.cyan(agent.totalTokens.toLocaleString()));
511
+ console.log(chalk_1.default.white(' ā±ļø Avg Latency:'), chalk_1.default.cyan(`${agent.averageLatency}ms`));
512
+ if (agent.primaryModel) {
513
+ console.log(chalk_1.default.white(' šŸ¤– Primary Model:'), chalk_1.default.cyan(agent.primaryModel));
514
+ }
515
+ });
516
+ // Agent Interaction Analysis
517
+ if (inspect.interactions) {
518
+ console.log(chalk_1.default.yellow.bold('\nšŸ”„ Agent Interactions'));
519
+ console.log(chalk_1.default.gray('─'.repeat(50)));
520
+ console.log(chalk_1.default.white('Sequential Calls:'), chalk_1.default.cyan(inspect.interactions.sequentialCalls));
521
+ console.log(chalk_1.default.white('Parallel Calls:'), chalk_1.default.cyan(inspect.interactions.parallelCalls));
522
+ console.log(chalk_1.default.white('Dependencies:'), chalk_1.default.cyan(inspect.interactions.dependencies?.length || 0));
523
+ if (inspect.interactions.bottlenecks) {
524
+ console.log(chalk_1.default.white('Bottlenecks:'));
525
+ inspect.interactions.bottlenecks.forEach((bottleneck, index) => {
526
+ console.log(chalk_1.default.gray(` ${index + 1}. ${bottleneck.agent}: ${bottleneck.reason}`));
527
+ });
528
+ }
529
+ }
530
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
531
+ }
532
+ async function handleAgentInspectRecent(options) {
533
+ logger_1.logger.info('šŸ“‹ Fetching recent agent inspections...');
534
+ try {
535
+ const count = parseInt(options.number) || 10;
536
+ const agents = await getRecentAgentInspect(count);
537
+ displayRecentAgentInspect(agents, options);
538
+ }
539
+ catch (error) {
540
+ logger_1.logger.error('Failed to fetch recent agent inspections:', error);
541
+ process.exit(1);
542
+ }
543
+ }
544
+ async function getRecentAgentInspect(count) {
545
+ const baseUrl = config_1.configManager.get('baseUrl');
546
+ const apiKey = config_1.configManager.get('apiKey');
547
+ if (!baseUrl || !apiKey) {
548
+ console.log(chalk_1.default.red.bold('\nāŒ Configuration Missing'));
549
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
550
+ if (!apiKey) {
551
+ console.log(chalk_1.default.yellow('• API Key is not set'));
552
+ }
553
+ if (!baseUrl) {
554
+ console.log(chalk_1.default.yellow('• Base URL is not set'));
555
+ }
556
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
557
+ console.log(chalk_1.default.cyan('To set up your configuration, run:'));
558
+ console.log(chalk_1.default.white(' cost-katana init'));
559
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
560
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
561
+ }
562
+ try {
563
+ const response = await axios_1.default.get(`${baseUrl}/api/agent/inspect/recent?count=${count}`, {
564
+ headers: {
565
+ 'Authorization': `Bearer ${apiKey}`,
566
+ 'Content-Type': 'application/json',
567
+ },
568
+ timeout: 30000,
569
+ });
570
+ if (response.status !== 200) {
571
+ throw new Error(`API returned status ${response.status}`);
572
+ }
573
+ if (response.data.success && response.data.data) {
574
+ return response.data.data;
575
+ }
576
+ else {
577
+ throw new Error(response.data.message || 'Invalid response format');
578
+ }
579
+ }
580
+ catch (error) {
581
+ if (error.response) {
582
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
583
+ }
584
+ else if (error.request) {
585
+ throw new Error('No response received from API');
586
+ }
587
+ else {
588
+ throw new Error(`Request failed: ${error.message}`);
589
+ }
590
+ }
591
+ }
592
+ function displayRecentAgentInspect(agents, options) {
593
+ const format = options.format || 'table';
594
+ if (format === 'json') {
595
+ console.log(JSON.stringify(agents, null, 2));
596
+ return;
597
+ }
598
+ else if (format === 'csv') {
599
+ console.log('Agent ID,Name,Role,Requests,Success Rate,Cost,Tokens,Last Active');
600
+ agents.forEach(agent => {
601
+ console.log(`"${agent.agentId}","${agent.name}","${agent.role}","${agent.totalRequests}","${agent.successRate}","${agent.totalCost}","${agent.totalTokens}","${agent.lastActive}"`);
602
+ });
603
+ return;
604
+ }
605
+ console.log(chalk_1.default.cyan.bold('\nšŸ“‹ Recent Agent Inspections'));
606
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
607
+ if (agents.length === 0) {
608
+ console.log(chalk_1.default.yellow('No recent agents found.'));
609
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
610
+ return;
611
+ }
612
+ agents.forEach((agent, index) => {
613
+ const successColor = agent.successRate > 0.8 ? chalk_1.default.green : agent.successRate > 0.6 ? chalk_1.default.yellow : chalk_1.default.red;
614
+ console.log(chalk_1.default.white(`\n${index + 1}. ${agent.name} (${agent.agentId})`));
615
+ console.log(chalk_1.default.gray(' ─'.repeat(40)));
616
+ console.log(chalk_1.default.white(' šŸŽ­ Role:'), chalk_1.default.cyan(agent.role));
617
+ console.log(chalk_1.default.white(' šŸ“ˆ Requests:'), chalk_1.default.cyan(agent.totalRequests));
618
+ console.log(chalk_1.default.white(' šŸ“Š Success Rate:'), successColor(`${(agent.successRate * 100).toFixed(1)}%`));
619
+ console.log(chalk_1.default.white(' šŸ’° Cost:'), chalk_1.default.green(`$${agent.totalCost.toFixed(4)}`));
620
+ console.log(chalk_1.default.white(' šŸ”¢ Tokens:'), chalk_1.default.cyan(agent.totalTokens.toLocaleString()));
621
+ console.log(chalk_1.default.white(' ā±ļø Avg Latency:'), chalk_1.default.cyan(`${agent.averageLatency}ms`));
622
+ console.log(chalk_1.default.white(' šŸ“… Last Active:'), chalk_1.default.cyan(new Date(agent.lastActive).toLocaleString()));
623
+ });
624
+ console.log(chalk_1.default.gray('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
625
+ console.log(chalk_1.default.yellow('šŸ’” Commands:'));
626
+ console.log(chalk_1.default.white(' • Inspect specific agent: costkatana agent-inspect id <agentId>'));
627
+ console.log(chalk_1.default.white(' • Inspect by name: costkatana agent-inspect name <agentName>'));
628
+ console.log(chalk_1.default.white(' • Inspect workflow agents: costkatana agent-inspect workflow <workflowId>'));
629
+ }
630
+ //# sourceMappingURL=agent-inspect.js.map