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.
- package/LICENSE +21 -0
- package/README.md +343 -0
- package/bin/cost-katana.js +20 -0
- package/dist/commands/agent-inspect.d.ts +3 -0
- package/dist/commands/agent-inspect.d.ts.map +1 -0
- package/dist/commands/agent-inspect.js +630 -0
- package/dist/commands/agent-inspect.js.map +1 -0
- package/dist/commands/analytics.d.ts +3 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +375 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/analyze.d.ts +3 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +286 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/ask.d.ts +3 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +137 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/audit-firewall.d.ts +3 -0
- package/dist/commands/audit-firewall.d.ts.map +1 -0
- package/dist/commands/audit-firewall.js +737 -0
- package/dist/commands/audit-firewall.js.map +1 -0
- package/dist/commands/budget.d.ts +3 -0
- package/dist/commands/budget.d.ts.map +1 -0
- package/dist/commands/budget.js +283 -0
- package/dist/commands/budget.js.map +1 -0
- package/dist/commands/bulk-optimize.d.ts +3 -0
- package/dist/commands/bulk-optimize.d.ts.map +1 -0
- package/dist/commands/bulk-optimize.js +863 -0
- package/dist/commands/bulk-optimize.js.map +1 -0
- package/dist/commands/chat.d.ts +3 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +292 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/check-cache.d.ts +3 -0
- package/dist/commands/check-cache.d.ts.map +1 -0
- package/dist/commands/check-cache.js +267 -0
- package/dist/commands/check-cache.js.map +1 -0
- package/dist/commands/compare.d.ts +3 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +131 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +421 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/craft-workflow.d.ts +3 -0
- package/dist/commands/craft-workflow.d.ts.map +1 -0
- package/dist/commands/craft-workflow.js +844 -0
- package/dist/commands/craft-workflow.js.map +1 -0
- package/dist/commands/debug-prompt.d.ts +3 -0
- package/dist/commands/debug-prompt.d.ts.map +1 -0
- package/dist/commands/debug-prompt.js +614 -0
- package/dist/commands/debug-prompt.js.map +1 -0
- package/dist/commands/diff-prompts.d.ts +3 -0
- package/dist/commands/diff-prompts.d.ts.map +1 -0
- package/dist/commands/diff-prompts.js +553 -0
- package/dist/commands/diff-prompts.js.map +1 -0
- package/dist/commands/high-cost-prompts.d.ts +3 -0
- package/dist/commands/high-cost-prompts.d.ts.map +1 -0
- package/dist/commands/high-cost-prompts.js +719 -0
- package/dist/commands/high-cost-prompts.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +325 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/key.d.ts +3 -0
- package/dist/commands/key.d.ts.map +1 -0
- package/dist/commands/key.js +574 -0
- package/dist/commands/key.js.map +1 -0
- package/dist/commands/list-models.d.ts +3 -0
- package/dist/commands/list-models.d.ts.map +1 -0
- package/dist/commands/list-models.js +154 -0
- package/dist/commands/list-models.js.map +1 -0
- package/dist/commands/models.d.ts +3 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +107 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/optimize.d.ts +3 -0
- package/dist/commands/optimize.d.ts.map +1 -0
- package/dist/commands/optimize.js +345 -0
- package/dist/commands/optimize.js.map +1 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +475 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/prompt-metrics.d.ts +3 -0
- package/dist/commands/prompt-metrics.d.ts.map +1 -0
- package/dist/commands/prompt-metrics.js +665 -0
- package/dist/commands/prompt-metrics.js.map +1 -0
- package/dist/commands/replay-session.d.ts +3 -0
- package/dist/commands/replay-session.d.ts.map +1 -0
- package/dist/commands/replay-session.js +615 -0
- package/dist/commands/replay-session.js.map +1 -0
- package/dist/commands/retry-log.d.ts +3 -0
- package/dist/commands/retry-log.d.ts.map +1 -0
- package/dist/commands/retry-log.js +686 -0
- package/dist/commands/retry-log.js.map +1 -0
- package/dist/commands/rewrite-prompt.d.ts +3 -0
- package/dist/commands/rewrite-prompt.d.ts.map +1 -0
- package/dist/commands/rewrite-prompt.js +802 -0
- package/dist/commands/rewrite-prompt.js.map +1 -0
- package/dist/commands/set-budget.d.ts +3 -0
- package/dist/commands/set-budget.d.ts.map +1 -0
- package/dist/commands/set-budget.js +909 -0
- package/dist/commands/set-budget.js.map +1 -0
- package/dist/commands/simulate-cost.d.ts +3 -0
- package/dist/commands/simulate-cost.d.ts.map +1 -0
- package/dist/commands/simulate-cost.js +873 -0
- package/dist/commands/simulate-cost.js.map +1 -0
- package/dist/commands/suggest-models.d.ts +3 -0
- package/dist/commands/suggest-models.d.ts.map +1 -0
- package/dist/commands/suggest-models.js +674 -0
- package/dist/commands/suggest-models.js.map +1 -0
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +187 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/trace-workflow.d.ts +3 -0
- package/dist/commands/trace-workflow.d.ts.map +1 -0
- package/dist/commands/trace-workflow.js +651 -0
- package/dist/commands/trace-workflow.js.map +1 -0
- package/dist/commands/trace.d.ts +3 -0
- package/dist/commands/trace.d.ts.map +1 -0
- package/dist/commands/trace.js +468 -0
- package/dist/commands/trace.js.map +1 -0
- package/dist/commands/track.d.ts +3 -0
- package/dist/commands/track.d.ts.map +1 -0
- package/dist/commands/track.js +404 -0
- package/dist/commands/track.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +169 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +46 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +321 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +101 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/models.d.ts +22 -0
- package/dist/utils/models.d.ts.map +1 -0
- package/dist/utils/models.js +2251 -0
- package/dist/utils/models.js.map +1 -0
- 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
|