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,614 @@
|
|
|
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.debugPromptCommand = debugPromptCommand;
|
|
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 debugPromptCommand(program) {
|
|
12
|
+
const debugGroup = program
|
|
13
|
+
.command('debug-prompt')
|
|
14
|
+
.description('š§© Deep inspect specific prompts and their processing');
|
|
15
|
+
// Main debug-prompt command
|
|
16
|
+
debugGroup
|
|
17
|
+
.option('--format <format>', 'Output format (table, json, csv)', 'table')
|
|
18
|
+
.option('--export <path>', 'Export debug data to file')
|
|
19
|
+
.option('-v, --verbose', 'Show detailed debug information')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
try {
|
|
22
|
+
await handleDebugPrompt(options);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
logger_1.logger.error('Debug prompt command failed:', error);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// Debug prompt by ID
|
|
30
|
+
debugGroup
|
|
31
|
+
.command('id <promptId>')
|
|
32
|
+
.description('š§© Debug a specific prompt by ID')
|
|
33
|
+
.option('--format <format>', 'Output format (table, json, csv)', 'table')
|
|
34
|
+
.option('--export <path>', 'Export debug data to file')
|
|
35
|
+
.option('-v, --verbose', 'Show detailed debug information')
|
|
36
|
+
.option('--include-variants', 'Include past variants of this prompt')
|
|
37
|
+
.option('--include-optimizations', 'Include optimization suggestions')
|
|
38
|
+
.option('--include-gallm', 'Include GALLM routing decisions')
|
|
39
|
+
.action(async (promptId, options) => {
|
|
40
|
+
try {
|
|
41
|
+
await handleDebugPromptById(promptId, options);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
logger_1.logger.error('Debug prompt by ID failed:', error);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// Debug prompt by content
|
|
49
|
+
debugGroup
|
|
50
|
+
.command('content')
|
|
51
|
+
.description('š§© Debug a prompt by its content')
|
|
52
|
+
.option('-p, --prompt <prompt>', 'The prompt content to debug')
|
|
53
|
+
.option('-f, --file <path>', 'File containing the prompt to debug')
|
|
54
|
+
.option('--format <format>', 'Output format (table, json, csv)', 'table')
|
|
55
|
+
.option('--export <path>', 'Export debug data to file')
|
|
56
|
+
.option('-v, --verbose', 'Show detailed debug information')
|
|
57
|
+
.option('--include-variants', 'Include past variants of this prompt')
|
|
58
|
+
.option('--include-optimizations', 'Include optimization suggestions')
|
|
59
|
+
.option('--include-gallm', 'Include GALLM routing decisions')
|
|
60
|
+
.action(async (options) => {
|
|
61
|
+
try {
|
|
62
|
+
await handleDebugPromptByContent(options);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
logger_1.logger.error('Debug prompt by content failed:', error);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Debug recent prompts
|
|
70
|
+
debugGroup
|
|
71
|
+
.command('recent')
|
|
72
|
+
.description('š Show recent prompt debug information')
|
|
73
|
+
.option('-n, --number <count>', 'Number of recent prompts to show', '10')
|
|
74
|
+
.option('--format <format>', 'Output format (table, json, csv)', 'table')
|
|
75
|
+
.option('--export <path>', 'Export debug data to file')
|
|
76
|
+
.option('-v, --verbose', 'Show detailed debug information')
|
|
77
|
+
.action(async (options) => {
|
|
78
|
+
try {
|
|
79
|
+
await handleDebugPromptRecent(options);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logger_1.logger.error('Debug prompt recent failed:', error);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// Debug prompts by model
|
|
87
|
+
debugGroup
|
|
88
|
+
.command('model <modelName>')
|
|
89
|
+
.description('š¤ Debug prompts for a specific model')
|
|
90
|
+
.option('-d, --days <days>', 'Number of days to look back', '7')
|
|
91
|
+
.option('--format <format>', 'Output format (table, json, csv)', 'table')
|
|
92
|
+
.option('--export <path>', 'Export debug data to file')
|
|
93
|
+
.option('-v, --verbose', 'Show detailed debug information')
|
|
94
|
+
.action(async (modelName, options) => {
|
|
95
|
+
try {
|
|
96
|
+
await handleDebugPromptByModel(modelName, options);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
logger_1.logger.error('Debug prompt by model failed:', error);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async function handleDebugPrompt(options) {
|
|
105
|
+
console.log(chalk_1.default.cyan.bold('\nš§© Prompt Debugging & Deep Inspection'));
|
|
106
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
107
|
+
console.log(chalk_1.default.yellow('Available commands:'));
|
|
108
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt id <promptId> Debug a specific prompt by ID'));
|
|
109
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt content Debug a prompt by content'));
|
|
110
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt recent Show recent prompt debug info'));
|
|
111
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt model <name> Debug prompts for a specific model'));
|
|
112
|
+
console.log(chalk_1.default.gray('\nExamples:'));
|
|
113
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt id prompt-38271'));
|
|
114
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt content --prompt "Explain quantum computing"'));
|
|
115
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt recent --number 5'));
|
|
116
|
+
console.log(chalk_1.default.white(' costkatana debug-prompt model gpt-4 --verbose'));
|
|
117
|
+
console.log(chalk_1.default.gray('\nDebug Information:'));
|
|
118
|
+
console.log(chalk_1.default.white(' ⢠Model used, token count, latency, cost'));
|
|
119
|
+
console.log(chalk_1.default.white(' ⢠Prompt + response analysis'));
|
|
120
|
+
console.log(chalk_1.default.white(' ⢠Caching status (HIT/MISS)'));
|
|
121
|
+
console.log(chalk_1.default.white(' ⢠GALLM verdict (routing, blocking, caching decisions)'));
|
|
122
|
+
console.log(chalk_1.default.white(' ⢠Optimization suggestions'));
|
|
123
|
+
console.log(chalk_1.default.white(' ⢠Past variants of this prompt'));
|
|
124
|
+
console.log(chalk_1.default.white(' ⢠Performance metrics and trends'));
|
|
125
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
126
|
+
}
|
|
127
|
+
async function handleDebugPromptById(promptId, options) {
|
|
128
|
+
logger_1.logger.info(`š§© Debugging prompt: ${promptId}`);
|
|
129
|
+
try {
|
|
130
|
+
const debugData = await getPromptDebugById(promptId, options);
|
|
131
|
+
displayPromptDebugResult(debugData, options);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
logger_1.logger.error('Failed to debug prompt:', error);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function getPromptDebugById(promptId, options) {
|
|
139
|
+
const baseUrl = config_1.configManager.get('baseUrl');
|
|
140
|
+
const apiKey = config_1.configManager.get('apiKey');
|
|
141
|
+
if (!baseUrl || !apiKey) {
|
|
142
|
+
console.log(chalk_1.default.red.bold('\nā Configuration Missing'));
|
|
143
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
144
|
+
if (!apiKey) {
|
|
145
|
+
console.log(chalk_1.default.yellow('⢠API Key is not set'));
|
|
146
|
+
}
|
|
147
|
+
if (!baseUrl) {
|
|
148
|
+
console.log(chalk_1.default.yellow('⢠Base URL is not set'));
|
|
149
|
+
}
|
|
150
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
151
|
+
console.log(chalk_1.default.cyan('To set up your configuration, run:'));
|
|
152
|
+
console.log(chalk_1.default.white(' cost-katana init'));
|
|
153
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
154
|
+
throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const params = new URLSearchParams();
|
|
158
|
+
if (options.includeVariants)
|
|
159
|
+
params.append('includeVariants', 'true');
|
|
160
|
+
if (options.includeOptimizations)
|
|
161
|
+
params.append('includeOptimizations', 'true');
|
|
162
|
+
if (options.includeGallm)
|
|
163
|
+
params.append('includeGallm', 'true');
|
|
164
|
+
const response = await axios_1.default.get(`${baseUrl}/api/debug/prompt/${promptId}?${params}`, {
|
|
165
|
+
headers: {
|
|
166
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
167
|
+
'Content-Type': 'application/json',
|
|
168
|
+
},
|
|
169
|
+
timeout: 30000,
|
|
170
|
+
});
|
|
171
|
+
if (response.status !== 200) {
|
|
172
|
+
throw new Error(`API returned status ${response.status}`);
|
|
173
|
+
}
|
|
174
|
+
if (response.data.success && response.data.data) {
|
|
175
|
+
return response.data.data;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
throw new Error(response.data.message || 'Invalid response format');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
if (error.response) {
|
|
183
|
+
throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
|
|
184
|
+
}
|
|
185
|
+
else if (error.request) {
|
|
186
|
+
throw new Error('No response received from API');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
throw new Error(`Request failed: ${error.message}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function displayPromptDebugResult(debug, options) {
|
|
194
|
+
const format = options.format || 'table';
|
|
195
|
+
if (format === 'json') {
|
|
196
|
+
console.log(JSON.stringify(debug, null, 2));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
else if (format === 'csv') {
|
|
200
|
+
console.log('Prompt ID,Model,Tokens,Cost,Latency,Cache Status,GALLM Verdict');
|
|
201
|
+
console.log(`"${debug.promptId}","${debug.model}","${debug.totalTokens}","${debug.cost}","${debug.latency}","${debug.cacheStatus}","${debug.gallmVerdict}"`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
console.log(chalk_1.default.cyan.bold('\nš§© Prompt Debug Analysis'));
|
|
205
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
206
|
+
// Basic Information
|
|
207
|
+
console.log(chalk_1.default.yellow.bold('\nš Basic Information'));
|
|
208
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
209
|
+
console.log(chalk_1.default.white('š Prompt ID:'), chalk_1.default.cyan(debug.promptId));
|
|
210
|
+
console.log(chalk_1.default.white('š
Timestamp:'), chalk_1.default.cyan(new Date(debug.timestamp).toLocaleString()));
|
|
211
|
+
console.log(chalk_1.default.white('š Status:'), debug.status === 'success' ? chalk_1.default.green(debug.status) : chalk_1.default.red(debug.status));
|
|
212
|
+
// Model and Performance
|
|
213
|
+
console.log(chalk_1.default.yellow.bold('\nš¤ Model & Performance'));
|
|
214
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
215
|
+
console.log(chalk_1.default.white('š§ Model:'), chalk_1.default.cyan(debug.model));
|
|
216
|
+
console.log(chalk_1.default.white('š¢ Provider:'), chalk_1.default.cyan(debug.provider));
|
|
217
|
+
console.log(chalk_1.default.white('š¢ Tokens:'), chalk_1.default.cyan(`${debug.inputTokens} input + ${debug.outputTokens} output = ${debug.totalTokens} total`));
|
|
218
|
+
console.log(chalk_1.default.white('š° Cost:'), chalk_1.default.green(`$${debug.cost.toFixed(4)}`));
|
|
219
|
+
console.log(chalk_1.default.white('ā±ļø Latency:'), chalk_1.default.cyan(`${debug.latency}ms`));
|
|
220
|
+
console.log(chalk_1.default.white('š Tokens per Second:'), chalk_1.default.cyan(debug.tokensPerSecond?.toFixed(2) || 'N/A'));
|
|
221
|
+
// Prompt and Response
|
|
222
|
+
console.log(chalk_1.default.yellow.bold('\nš¬ Prompt & Response'));
|
|
223
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
224
|
+
console.log(chalk_1.default.white('š Prompt:'));
|
|
225
|
+
console.log(chalk_1.default.gray(debug.prompt));
|
|
226
|
+
console.log(chalk_1.default.white('\nš¤ Response:'));
|
|
227
|
+
console.log(chalk_1.default.gray(debug.response));
|
|
228
|
+
// Caching Status
|
|
229
|
+
console.log(chalk_1.default.yellow.bold('\nš¾ Caching Analysis'));
|
|
230
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
231
|
+
const cacheStatus = debug.cacheStatus === 'HIT' ? chalk_1.default.green('HIT') : chalk_1.default.red('MISS');
|
|
232
|
+
console.log(chalk_1.default.white('Cache Status:'), cacheStatus);
|
|
233
|
+
if (debug.cacheAge) {
|
|
234
|
+
console.log(chalk_1.default.white('Cache Age:'), chalk_1.default.cyan(debug.cacheAge));
|
|
235
|
+
}
|
|
236
|
+
if (debug.cacheKey) {
|
|
237
|
+
console.log(chalk_1.default.white('Cache Key:'), chalk_1.default.cyan(debug.cacheKey));
|
|
238
|
+
}
|
|
239
|
+
if (debug.cacheReason) {
|
|
240
|
+
console.log(chalk_1.default.white('Cache Reason:'), chalk_1.default.cyan(debug.cacheReason));
|
|
241
|
+
}
|
|
242
|
+
// GALLM Verdict
|
|
243
|
+
if (debug.gallmVerdict) {
|
|
244
|
+
console.log(chalk_1.default.yellow.bold('\nšÆ GALLM Verdict'));
|
|
245
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
246
|
+
console.log(chalk_1.default.white('Routing Decision:'), chalk_1.default.cyan(debug.gallmVerdict.routingDecision));
|
|
247
|
+
console.log(chalk_1.default.white('Blocking Status:'), debug.gallmVerdict.blocked ? chalk_1.default.red('BLOCKED') : chalk_1.default.green('ALLOWED'));
|
|
248
|
+
if (debug.gallmVerdict.blockReason) {
|
|
249
|
+
console.log(chalk_1.default.white('Block Reason:'), chalk_1.default.red(debug.gallmVerdict.blockReason));
|
|
250
|
+
}
|
|
251
|
+
console.log(chalk_1.default.white('Caching Decision:'), chalk_1.default.cyan(debug.gallmVerdict.cachingDecision));
|
|
252
|
+
console.log(chalk_1.default.white('Load Balancing:'), chalk_1.default.cyan(debug.gallmVerdict.loadBalancing || 'N/A'));
|
|
253
|
+
console.log(chalk_1.default.white('Cost Optimization:'), chalk_1.default.cyan(debug.gallmVerdict.costOptimization || 'N/A'));
|
|
254
|
+
if (debug.gallmVerdict.fallbackUsed) {
|
|
255
|
+
console.log(chalk_1.default.white('Fallback Used:'), chalk_1.default.yellow('Yes'));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Optimization Suggestions
|
|
259
|
+
if (debug.optimizationSuggestions && debug.optimizationSuggestions.length > 0) {
|
|
260
|
+
console.log(chalk_1.default.yellow.bold('\nš§ Optimization Suggestions'));
|
|
261
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
262
|
+
debug.optimizationSuggestions.forEach((suggestion, index) => {
|
|
263
|
+
console.log(chalk_1.default.white(`${index + 1}. ${suggestion.type}:`));
|
|
264
|
+
console.log(chalk_1.default.gray(` ${suggestion.description}`));
|
|
265
|
+
if (suggestion.estimatedSavings) {
|
|
266
|
+
console.log(chalk_1.default.gray(` Estimated Savings: ${suggestion.estimatedSavings}`));
|
|
267
|
+
}
|
|
268
|
+
if (suggestion.implementation) {
|
|
269
|
+
console.log(chalk_1.default.gray(` Implementation: ${suggestion.implementation}`));
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
// Past Variants
|
|
274
|
+
if (options.includeVariants && debug.pastVariants && debug.pastVariants.length > 0) {
|
|
275
|
+
console.log(chalk_1.default.yellow.bold('\nš Past Variants'));
|
|
276
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
277
|
+
debug.pastVariants.forEach((variant, index) => {
|
|
278
|
+
console.log(chalk_1.default.white(`${index + 1}. Variant ${index + 1}:`));
|
|
279
|
+
console.log(chalk_1.default.gray(` Timestamp: ${new Date(variant.timestamp).toLocaleString()}`));
|
|
280
|
+
console.log(chalk_1.default.gray(` Tokens: ${variant.totalTokens}`));
|
|
281
|
+
console.log(chalk_1.default.gray(` Cost: $${variant.cost.toFixed(4)}`));
|
|
282
|
+
console.log(chalk_1.default.gray(` Performance: ${variant.performance || 'N/A'}`));
|
|
283
|
+
console.log(chalk_1.default.gray(` Prompt: ${variant.prompt.substring(0, 100)}${variant.prompt.length > 100 ? '...' : ''}`));
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
// Performance Metrics
|
|
287
|
+
console.log(chalk_1.default.yellow.bold('\nš Performance Metrics'));
|
|
288
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
289
|
+
console.log(chalk_1.default.white('Response Time:'), chalk_1.default.cyan(`${debug.latency}ms`));
|
|
290
|
+
console.log(chalk_1.default.white('Cost per Token:'), chalk_1.default.cyan(`$${debug.costPerToken?.toFixed(6) || '0.000000'}`));
|
|
291
|
+
console.log(chalk_1.default.white('Cost per Second:'), chalk_1.default.cyan(`$${debug.costPerSecond?.toFixed(6) || '0.000000'}`));
|
|
292
|
+
console.log(chalk_1.default.white('Throughput:'), chalk_1.default.cyan(`${debug.throughput?.toFixed(2) || 'N/A'} tokens/second`));
|
|
293
|
+
if (debug.qualityScore) {
|
|
294
|
+
console.log(chalk_1.default.white('Quality Score:'), chalk_1.default.cyan(debug.qualityScore));
|
|
295
|
+
}
|
|
296
|
+
// Error Information
|
|
297
|
+
if (debug.error) {
|
|
298
|
+
console.log(chalk_1.default.yellow.bold('\nā Error Information'));
|
|
299
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
300
|
+
console.log(chalk_1.default.white('Error Type:'), chalk_1.default.red(debug.error.type));
|
|
301
|
+
console.log(chalk_1.default.white('Error Message:'), chalk_1.default.red(debug.error.message));
|
|
302
|
+
console.log(chalk_1.default.white('Error Code:'), chalk_1.default.red(debug.error.code || 'N/A'));
|
|
303
|
+
}
|
|
304
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
305
|
+
}
|
|
306
|
+
async function handleDebugPromptByContent(options) {
|
|
307
|
+
logger_1.logger.info('š§© Debugging prompt by content...');
|
|
308
|
+
try {
|
|
309
|
+
let promptContent = '';
|
|
310
|
+
if (options.prompt) {
|
|
311
|
+
promptContent = options.prompt;
|
|
312
|
+
}
|
|
313
|
+
else if (options.file) {
|
|
314
|
+
// Read from file
|
|
315
|
+
const fs = require('fs');
|
|
316
|
+
promptContent = fs.readFileSync(options.file, 'utf8');
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
console.log(chalk_1.default.red.bold('\nā No prompt content provided'));
|
|
320
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
321
|
+
console.log(chalk_1.default.yellow('Please provide either:'));
|
|
322
|
+
console.log(chalk_1.default.white(' ⢠--prompt "your prompt content"'));
|
|
323
|
+
console.log(chalk_1.default.white(' ⢠--file path/to/prompt.txt'));
|
|
324
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const debugData = await getPromptDebugByContent(promptContent, options);
|
|
328
|
+
displayPromptDebugResult(debugData, options);
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
logger_1.logger.error('Failed to debug prompt by content:', error);
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
async function getPromptDebugByContent(promptContent, options) {
|
|
336
|
+
const baseUrl = config_1.configManager.get('baseUrl');
|
|
337
|
+
const apiKey = config_1.configManager.get('apiKey');
|
|
338
|
+
if (!baseUrl || !apiKey) {
|
|
339
|
+
console.log(chalk_1.default.red.bold('\nā Configuration Missing'));
|
|
340
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
341
|
+
if (!apiKey) {
|
|
342
|
+
console.log(chalk_1.default.yellow('⢠API Key is not set'));
|
|
343
|
+
}
|
|
344
|
+
if (!baseUrl) {
|
|
345
|
+
console.log(chalk_1.default.yellow('⢠Base URL is not set'));
|
|
346
|
+
}
|
|
347
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
348
|
+
console.log(chalk_1.default.cyan('To set up your configuration, run:'));
|
|
349
|
+
console.log(chalk_1.default.white(' cost-katana init'));
|
|
350
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
351
|
+
throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
const params = new URLSearchParams();
|
|
355
|
+
if (options.includeVariants)
|
|
356
|
+
params.append('includeVariants', 'true');
|
|
357
|
+
if (options.includeOptimizations)
|
|
358
|
+
params.append('includeOptimizations', 'true');
|
|
359
|
+
if (options.includeGallm)
|
|
360
|
+
params.append('includeGallm', 'true');
|
|
361
|
+
const response = await axios_1.default.post(`${baseUrl}/api/debug/prompt/content?${params}`, {
|
|
362
|
+
prompt: promptContent
|
|
363
|
+
}, {
|
|
364
|
+
headers: {
|
|
365
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
366
|
+
'Content-Type': 'application/json',
|
|
367
|
+
},
|
|
368
|
+
timeout: 30000,
|
|
369
|
+
});
|
|
370
|
+
if (response.status !== 200) {
|
|
371
|
+
throw new Error(`API returned status ${response.status}`);
|
|
372
|
+
}
|
|
373
|
+
if (response.data.success && response.data.data) {
|
|
374
|
+
return response.data.data;
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
throw new Error(response.data.message || 'Invalid response format');
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
if (error.response) {
|
|
382
|
+
throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
|
|
383
|
+
}
|
|
384
|
+
else if (error.request) {
|
|
385
|
+
throw new Error('No response received from API');
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
throw new Error(`Request failed: ${error.message}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async function handleDebugPromptRecent(options) {
|
|
393
|
+
logger_1.logger.info('š Fetching recent prompt debug information...');
|
|
394
|
+
try {
|
|
395
|
+
const count = parseInt(options.number) || 10;
|
|
396
|
+
const prompts = await getRecentPromptDebug(count);
|
|
397
|
+
displayRecentPromptDebug(prompts, options);
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
logger_1.logger.error('Failed to fetch recent prompt debug:', error);
|
|
401
|
+
process.exit(1);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async function getRecentPromptDebug(count) {
|
|
405
|
+
const baseUrl = config_1.configManager.get('baseUrl');
|
|
406
|
+
const apiKey = config_1.configManager.get('apiKey');
|
|
407
|
+
if (!baseUrl || !apiKey) {
|
|
408
|
+
console.log(chalk_1.default.red.bold('\nā Configuration Missing'));
|
|
409
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
410
|
+
if (!apiKey) {
|
|
411
|
+
console.log(chalk_1.default.yellow('⢠API Key is not set'));
|
|
412
|
+
}
|
|
413
|
+
if (!baseUrl) {
|
|
414
|
+
console.log(chalk_1.default.yellow('⢠Base URL is not set'));
|
|
415
|
+
}
|
|
416
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
417
|
+
console.log(chalk_1.default.cyan('To set up your configuration, run:'));
|
|
418
|
+
console.log(chalk_1.default.white(' cost-katana init'));
|
|
419
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
420
|
+
throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
const response = await axios_1.default.get(`${baseUrl}/api/debug/prompt/recent?count=${count}`, {
|
|
424
|
+
headers: {
|
|
425
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
426
|
+
'Content-Type': 'application/json',
|
|
427
|
+
},
|
|
428
|
+
timeout: 30000,
|
|
429
|
+
});
|
|
430
|
+
if (response.status !== 200) {
|
|
431
|
+
throw new Error(`API returned status ${response.status}`);
|
|
432
|
+
}
|
|
433
|
+
if (response.data.success && response.data.data) {
|
|
434
|
+
return response.data.data;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
throw new Error(response.data.message || 'Invalid response format');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
if (error.response) {
|
|
442
|
+
throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
|
|
443
|
+
}
|
|
444
|
+
else if (error.request) {
|
|
445
|
+
throw new Error('No response received from API');
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
throw new Error(`Request failed: ${error.message}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
function displayRecentPromptDebug(prompts, options) {
|
|
453
|
+
const format = options.format || 'table';
|
|
454
|
+
if (format === 'json') {
|
|
455
|
+
console.log(JSON.stringify(prompts, null, 2));
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
else if (format === 'csv') {
|
|
459
|
+
console.log('Prompt ID,Model,Tokens,Cost,Latency,Cache Status,GALLM Verdict,Timestamp');
|
|
460
|
+
prompts.forEach(prompt => {
|
|
461
|
+
console.log(`"${prompt.promptId}","${prompt.model}","${prompt.totalTokens}","${prompt.cost}","${prompt.latency}","${prompt.cacheStatus}","${prompt.gallmVerdict}","${prompt.timestamp}"`);
|
|
462
|
+
});
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
console.log(chalk_1.default.cyan.bold('\nš Recent Prompt Debug Information'));
|
|
466
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
467
|
+
if (prompts.length === 0) {
|
|
468
|
+
console.log(chalk_1.default.yellow('No recent prompts found.'));
|
|
469
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
prompts.forEach((prompt, index) => {
|
|
473
|
+
const statusColor = prompt.status === 'success' ? chalk_1.default.green : chalk_1.default.red;
|
|
474
|
+
const statusIcon = prompt.status === 'success' ? 'ā
' : 'ā';
|
|
475
|
+
const cacheIcon = prompt.cacheStatus === 'HIT' ? 'š¾' : 'ā';
|
|
476
|
+
console.log(chalk_1.default.white(`\n${index + 1}. ${statusIcon} ${prompt.promptId}`));
|
|
477
|
+
console.log(chalk_1.default.gray(' ā'.repeat(40)));
|
|
478
|
+
console.log(chalk_1.default.white(' š§ Model:'), chalk_1.default.cyan(prompt.model));
|
|
479
|
+
console.log(chalk_1.default.white(' š¢ Tokens:'), chalk_1.default.cyan(prompt.totalTokens));
|
|
480
|
+
console.log(chalk_1.default.white(' š° Cost:'), chalk_1.default.green(`$${prompt.cost.toFixed(4)}`));
|
|
481
|
+
console.log(chalk_1.default.white(' ā±ļø Latency:'), chalk_1.default.cyan(`${prompt.latency}ms`));
|
|
482
|
+
console.log(chalk_1.default.white(' š¾ Cache:'), cacheIcon, chalk_1.default.cyan(prompt.cacheStatus));
|
|
483
|
+
console.log(chalk_1.default.white(' šÆ GALLM:'), chalk_1.default.cyan(prompt.gallmVerdict || 'N/A'));
|
|
484
|
+
console.log(chalk_1.default.white(' š
Time:'), chalk_1.default.cyan(new Date(prompt.timestamp).toLocaleString()));
|
|
485
|
+
if (options.verbose && prompt.prompt) {
|
|
486
|
+
console.log(chalk_1.default.white(' š Prompt:'));
|
|
487
|
+
console.log(chalk_1.default.gray(` ${prompt.prompt.substring(0, 150)}${prompt.prompt.length > 150 ? '...' : ''}`));
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
console.log(chalk_1.default.gray('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
491
|
+
console.log(chalk_1.default.yellow('š” Commands:'));
|
|
492
|
+
console.log(chalk_1.default.white(' ⢠Debug specific prompt: costkatana debug-prompt id <promptId>'));
|
|
493
|
+
console.log(chalk_1.default.white(' ⢠Debug by content: costkatana debug-prompt content --prompt "..."'));
|
|
494
|
+
console.log(chalk_1.default.white(' ⢠Debug by model: costkatana debug-prompt model <name>'));
|
|
495
|
+
}
|
|
496
|
+
async function handleDebugPromptByModel(modelName, options) {
|
|
497
|
+
logger_1.logger.info(`š¤ Debugging prompts for model: ${modelName}`);
|
|
498
|
+
try {
|
|
499
|
+
const days = parseInt(options.days) || 7;
|
|
500
|
+
const prompts = await getPromptDebugByModel(modelName, days);
|
|
501
|
+
displayModelPromptDebug(prompts, modelName, options);
|
|
502
|
+
}
|
|
503
|
+
catch (error) {
|
|
504
|
+
logger_1.logger.error('Failed to debug model prompts:', error);
|
|
505
|
+
process.exit(1);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
async function getPromptDebugByModel(modelName, days) {
|
|
509
|
+
const baseUrl = config_1.configManager.get('baseUrl');
|
|
510
|
+
const apiKey = config_1.configManager.get('apiKey');
|
|
511
|
+
if (!baseUrl || !apiKey) {
|
|
512
|
+
console.log(chalk_1.default.red.bold('\nā Configuration Missing'));
|
|
513
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
514
|
+
if (!apiKey) {
|
|
515
|
+
console.log(chalk_1.default.yellow('⢠API Key is not set'));
|
|
516
|
+
}
|
|
517
|
+
if (!baseUrl) {
|
|
518
|
+
console.log(chalk_1.default.yellow('⢠Base URL is not set'));
|
|
519
|
+
}
|
|
520
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
521
|
+
console.log(chalk_1.default.cyan('To set up your configuration, run:'));
|
|
522
|
+
console.log(chalk_1.default.white(' cost-katana init'));
|
|
523
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
524
|
+
throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
|
|
525
|
+
}
|
|
526
|
+
try {
|
|
527
|
+
const response = await axios_1.default.get(`${baseUrl}/api/debug/prompt/model/${modelName}?days=${days}`, {
|
|
528
|
+
headers: {
|
|
529
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
530
|
+
'Content-Type': 'application/json',
|
|
531
|
+
},
|
|
532
|
+
timeout: 30000,
|
|
533
|
+
});
|
|
534
|
+
if (response.status !== 200) {
|
|
535
|
+
throw new Error(`API returned status ${response.status}`);
|
|
536
|
+
}
|
|
537
|
+
if (response.data.success && response.data.data) {
|
|
538
|
+
return response.data.data;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
throw new Error(response.data.message || 'Invalid response format');
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
if (error.response) {
|
|
546
|
+
throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
|
|
547
|
+
}
|
|
548
|
+
else if (error.request) {
|
|
549
|
+
throw new Error('No response received from API');
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
throw new Error(`Request failed: ${error.message}`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function displayModelPromptDebug(prompts, modelName, options) {
|
|
557
|
+
const format = options.format || 'table';
|
|
558
|
+
if (format === 'json') {
|
|
559
|
+
console.log(JSON.stringify(prompts, null, 2));
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
else if (format === 'csv') {
|
|
563
|
+
console.log('Prompt ID,Model,Tokens,Cost,Latency,Cache Status,GALLM Verdict,Timestamp');
|
|
564
|
+
prompts.forEach(prompt => {
|
|
565
|
+
console.log(`"${prompt.promptId}","${prompt.model}","${prompt.totalTokens}","${prompt.cost}","${prompt.latency}","${prompt.cacheStatus}","${prompt.gallmVerdict}","${prompt.timestamp}"`);
|
|
566
|
+
});
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
console.log(chalk_1.default.cyan.bold(`\nš¤ Model Prompt Debug: ${modelName}`));
|
|
570
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
571
|
+
if (prompts.length === 0) {
|
|
572
|
+
console.log(chalk_1.default.yellow(`No prompts found for model "${modelName}" in the last ${options.days} days.`));
|
|
573
|
+
console.log(chalk_1.default.gray('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
// Summary statistics
|
|
577
|
+
const totalCost = prompts.reduce((sum, prompt) => sum + prompt.cost, 0);
|
|
578
|
+
const totalTokens = prompts.reduce((sum, prompt) => sum + prompt.totalTokens, 0);
|
|
579
|
+
const avgLatency = prompts.reduce((sum, prompt) => sum + prompt.latency, 0) / prompts.length;
|
|
580
|
+
const cacheHitRate = prompts.filter(prompt => prompt.cacheStatus === 'HIT').length / prompts.length * 100;
|
|
581
|
+
console.log(chalk_1.default.yellow.bold('\nš Summary Statistics'));
|
|
582
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
583
|
+
console.log(chalk_1.default.white('Total Prompts:'), chalk_1.default.cyan(prompts.length));
|
|
584
|
+
console.log(chalk_1.default.white('Total Cost:'), chalk_1.default.green(`$${totalCost.toFixed(4)}`));
|
|
585
|
+
console.log(chalk_1.default.white('Total Tokens:'), chalk_1.default.cyan(totalTokens.toLocaleString()));
|
|
586
|
+
console.log(chalk_1.default.white('Average Latency:'), chalk_1.default.cyan(`${avgLatency.toFixed(0)}ms`));
|
|
587
|
+
console.log(chalk_1.default.white('Cache Hit Rate:'), chalk_1.default.cyan(`${cacheHitRate.toFixed(1)}%`));
|
|
588
|
+
// Detailed prompts
|
|
589
|
+
console.log(chalk_1.default.yellow.bold('\nš Prompt Details'));
|
|
590
|
+
console.log(chalk_1.default.gray('ā'.repeat(50)));
|
|
591
|
+
prompts.forEach((prompt, index) => {
|
|
592
|
+
const statusColor = prompt.status === 'success' ? chalk_1.default.green : chalk_1.default.red;
|
|
593
|
+
const statusIcon = prompt.status === 'success' ? 'ā
' : 'ā';
|
|
594
|
+
const cacheIcon = prompt.cacheStatus === 'HIT' ? 'š¾' : 'ā';
|
|
595
|
+
console.log(chalk_1.default.white(`\n${index + 1}. ${statusIcon} ${prompt.promptId}`));
|
|
596
|
+
console.log(chalk_1.default.gray(' ā'.repeat(40)));
|
|
597
|
+
console.log(chalk_1.default.white(' š¢ Tokens:'), chalk_1.default.cyan(prompt.totalTokens));
|
|
598
|
+
console.log(chalk_1.default.white(' š° Cost:'), chalk_1.default.green(`$${prompt.cost.toFixed(4)}`));
|
|
599
|
+
console.log(chalk_1.default.white(' ā±ļø Latency:'), chalk_1.default.cyan(`${prompt.latency}ms`));
|
|
600
|
+
console.log(chalk_1.default.white(' š¾ Cache:'), cacheIcon, chalk_1.default.cyan(prompt.cacheStatus));
|
|
601
|
+
console.log(chalk_1.default.white(' šÆ GALLM:'), chalk_1.default.cyan(prompt.gallmVerdict || 'N/A'));
|
|
602
|
+
console.log(chalk_1.default.white(' š
Time:'), chalk_1.default.cyan(new Date(prompt.timestamp).toLocaleString()));
|
|
603
|
+
if (options.verbose && prompt.prompt) {
|
|
604
|
+
console.log(chalk_1.default.white(' š Prompt:'));
|
|
605
|
+
console.log(chalk_1.default.gray(` ${prompt.prompt.substring(0, 150)}${prompt.prompt.length > 150 ? '...' : ''}`));
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
console.log(chalk_1.default.gray('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
609
|
+
console.log(chalk_1.default.yellow('š” Commands:'));
|
|
610
|
+
console.log(chalk_1.default.white(` ⢠Debug specific prompt: costkatana debug-prompt id <promptId>`));
|
|
611
|
+
console.log(chalk_1.default.white(` ⢠Debug by content: costkatana debug-prompt content --prompt "..."`));
|
|
612
|
+
console.log(chalk_1.default.white(` ⢠View recent prompts: costkatana debug-prompt recent`));
|
|
613
|
+
}
|
|
614
|
+
//# sourceMappingURL=debug-prompt.js.map
|