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