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,863 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.bulkOptimizeCommand = bulkOptimizeCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const logger_1 = require("../utils/logger");
42
+ const config_1 = require("../utils/config");
43
+ const axios_1 = __importDefault(require("axios"));
44
+ const fs = __importStar(require("fs"));
45
+ const csv_parser_1 = __importDefault(require("csv-parser"));
46
+ const csv_writer_1 = require("csv-writer");
47
+ function bulkOptimizeCommand(program) {
48
+ const bulkGroup = program
49
+ .command('bulk-optimize')
50
+ .description('šŸš€ Analyze and optimize multiple high-frequency prompts in one go');
51
+ // Main bulk-optimize command
52
+ bulkGroup
53
+ .option('--file <path>', 'CSV file with prompts to optimize')
54
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
55
+ .option('--export <path>', 'Export optimization results to file')
56
+ .option('-v, --verbose', 'Show detailed optimization analysis')
57
+ .option('--include-token-analysis', 'Include detailed token analysis')
58
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
59
+ .option('--include-optimization-suggestions', 'Include optimization suggestions')
60
+ .option('--include-priority-ranking', 'Include priority ranking')
61
+ .action(async (options) => {
62
+ try {
63
+ await handleBulkOptimize(options);
64
+ }
65
+ catch (error) {
66
+ logger_1.logger.error('Bulk optimize command failed:', error);
67
+ process.exit(1);
68
+ }
69
+ });
70
+ // Batch optimization with different strategies
71
+ bulkGroup
72
+ .command('strategies')
73
+ .description('šŸš€ Optimize prompts using different strategies')
74
+ .option('--file <path>', 'CSV file with prompts to optimize')
75
+ .option('--strategies <strategies>', 'Comma-separated optimization strategies')
76
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
77
+ .option('--export <path>', 'Export strategy results to file')
78
+ .option('-v, --verbose', 'Show detailed strategy analysis')
79
+ .option('--include-token-analysis', 'Include detailed token analysis')
80
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
81
+ .option('--include-comparison', 'Include strategy comparison')
82
+ .action(async (options) => {
83
+ try {
84
+ await handleStrategyOptimization(options);
85
+ }
86
+ catch (error) {
87
+ logger_1.logger.error('Strategy optimization failed:', error);
88
+ process.exit(1);
89
+ }
90
+ });
91
+ // Priority-based optimization
92
+ bulkGroup
93
+ .command('priority')
94
+ .description('šŸš€ Optimize prompts based on priority and impact')
95
+ .option('--file <path>', 'CSV file with prompts to optimize')
96
+ .option('--priority-criteria <criteria>', 'Priority criteria (cost, frequency, impact)', 'cost')
97
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
98
+ .option('--export <path>', 'Export priority results to file')
99
+ .option('-v, --verbose', 'Show detailed priority analysis')
100
+ .option('--include-token-analysis', 'Include detailed token analysis')
101
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
102
+ .option('--include-impact-analysis', 'Include impact analysis')
103
+ .action(async (options) => {
104
+ try {
105
+ await handlePriorityOptimization(options);
106
+ }
107
+ catch (error) {
108
+ logger_1.logger.error('Priority optimization failed:', error);
109
+ process.exit(1);
110
+ }
111
+ });
112
+ // Model-specific optimization
113
+ bulkGroup
114
+ .command('models')
115
+ .description('šŸš€ Optimize prompts for specific models')
116
+ .option('--file <path>', 'CSV file with prompts to optimize')
117
+ .option('--target-models <models>', 'Comma-separated target models')
118
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
119
+ .option('--export <path>', 'Export model results to file')
120
+ .option('-v, --verbose', 'Show detailed model analysis')
121
+ .option('--include-token-analysis', 'Include detailed token analysis')
122
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
123
+ .option('--include-model-comparison', 'Include model comparison')
124
+ .action(async (options) => {
125
+ try {
126
+ await handleModelOptimization(options);
127
+ }
128
+ catch (error) {
129
+ logger_1.logger.error('Model optimization failed:', error);
130
+ process.exit(1);
131
+ }
132
+ });
133
+ // Frequency-based optimization
134
+ bulkGroup
135
+ .command('frequency')
136
+ .description('šŸš€ Optimize prompts based on usage frequency')
137
+ .option('--file <path>', 'CSV file with prompts to optimize')
138
+ .option('--frequency-threshold <threshold>', 'Minimum frequency threshold', '100')
139
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
140
+ .option('--export <path>', 'Export frequency results to file')
141
+ .option('-v, --verbose', 'Show detailed frequency analysis')
142
+ .option('--include-token-analysis', 'Include detailed token analysis')
143
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
144
+ .option('--include-frequency-analysis', 'Include frequency analysis')
145
+ .action(async (options) => {
146
+ try {
147
+ await handleFrequencyOptimization(options);
148
+ }
149
+ catch (error) {
150
+ logger_1.logger.error('Frequency optimization failed:', error);
151
+ process.exit(1);
152
+ }
153
+ });
154
+ // Cost-based optimization
155
+ bulkGroup
156
+ .command('cost')
157
+ .description('šŸš€ Optimize prompts based on cost impact')
158
+ .option('--file <path>', 'CSV file with prompts to optimize')
159
+ .option('--cost-threshold <threshold>', 'Minimum cost threshold', '0.01')
160
+ .option('--format <format>', 'Output format (table, json, csv)', 'table')
161
+ .option('--export <path>', 'Export cost results to file')
162
+ .option('-v, --verbose', 'Show detailed cost analysis')
163
+ .option('--include-token-analysis', 'Include detailed token analysis')
164
+ .option('--include-cost-breakdown', 'Include detailed cost breakdown')
165
+ .option('--include-cost-analysis', 'Include cost analysis')
166
+ .action(async (options) => {
167
+ try {
168
+ await handleCostOptimization(options);
169
+ }
170
+ catch (error) {
171
+ logger_1.logger.error('Cost optimization failed:', error);
172
+ process.exit(1);
173
+ }
174
+ });
175
+ }
176
+ async function handleBulkOptimize(options) {
177
+ logger_1.logger.info('šŸš€ Running bulk optimization...');
178
+ try {
179
+ const prompts = await loadPromptsFromFile(options.file);
180
+ const optimization = await runBulkOptimization(prompts, options);
181
+ displayBulkOptimizationResults(optimization, options);
182
+ }
183
+ catch (error) {
184
+ logger_1.logger.error('Failed to run bulk optimization:', error);
185
+ process.exit(1);
186
+ }
187
+ }
188
+ async function loadPromptsFromFile(filePath) {
189
+ return new Promise((resolve, reject) => {
190
+ const prompts = [];
191
+ fs.createReadStream(filePath)
192
+ .pipe((0, csv_parser_1.default)())
193
+ .on('data', (row) => {
194
+ prompts.push({
195
+ promptId: row.prompt_id,
196
+ promptText: row.prompt_text,
197
+ model: row.model,
198
+ frequency: parseInt(row.frequency) || 1,
199
+ currentCost: parseFloat(row.current_cost) || 0
200
+ });
201
+ })
202
+ .on('end', () => {
203
+ resolve(prompts);
204
+ })
205
+ .on('error', (error) => {
206
+ reject(new Error(`Failed to read CSV file: ${error.message}`));
207
+ });
208
+ });
209
+ }
210
+ async function runBulkOptimization(prompts, options) {
211
+ const baseUrl = config_1.configManager.get('baseUrl');
212
+ const apiKey = config_1.configManager.get('apiKey');
213
+ if (!baseUrl || !apiKey) {
214
+ console.log(chalk_1.default.red.bold('\nāŒ Configuration Missing'));
215
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
216
+ if (!apiKey) {
217
+ console.log(chalk_1.default.yellow('• API Key is not set'));
218
+ }
219
+ if (!baseUrl) {
220
+ console.log(chalk_1.default.yellow('• Base URL is not set'));
221
+ }
222
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
223
+ console.log(chalk_1.default.cyan('To set up your configuration, run:'));
224
+ console.log(chalk_1.default.white(' cost-katana init'));
225
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
226
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
227
+ }
228
+ try {
229
+ const params = new URLSearchParams();
230
+ if (options.includeTokenAnalysis)
231
+ params.append('includeTokenAnalysis', 'true');
232
+ if (options.includeCostBreakdown)
233
+ params.append('includeCostBreakdown', 'true');
234
+ if (options.includeOptimizationSuggestions)
235
+ params.append('includeOptimizationSuggestions', 'true');
236
+ if (options.includePriorityRanking)
237
+ params.append('includePriorityRanking', 'true');
238
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize?${params}`, {
239
+ prompts: prompts,
240
+ options: {
241
+ includeTokenAnalysis: options.includeTokenAnalysis,
242
+ includeCostBreakdown: options.includeCostBreakdown,
243
+ includeOptimizationSuggestions: options.includeOptimizationSuggestions,
244
+ includePriorityRanking: options.includePriorityRanking
245
+ }
246
+ }, {
247
+ headers: {
248
+ 'Authorization': `Bearer ${apiKey}`,
249
+ 'Content-Type': 'application/json',
250
+ },
251
+ timeout: 60000,
252
+ });
253
+ if (response.status !== 200) {
254
+ throw new Error(`API returned status ${response.status}`);
255
+ }
256
+ if (response.data.success && response.data.data) {
257
+ return response.data.data;
258
+ }
259
+ else {
260
+ throw new Error(response.data.message || 'Invalid response format');
261
+ }
262
+ }
263
+ catch (error) {
264
+ if (error.response) {
265
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
266
+ }
267
+ else if (error.request) {
268
+ throw new Error('No response received from API');
269
+ }
270
+ else {
271
+ throw new Error(`Request failed: ${error.message}`);
272
+ }
273
+ }
274
+ }
275
+ function displayBulkOptimizationResults(optimization, options) {
276
+ const format = options.format || 'table';
277
+ if (format === 'json') {
278
+ console.log(JSON.stringify(optimization, null, 2));
279
+ return;
280
+ }
281
+ else if (format === 'csv') {
282
+ console.log('Prompt ID,Original Tokens,Optimized Tokens,Token Reduction,Original Cost,Optimized Cost,Cost Savings,Priority');
283
+ optimization.results.forEach((result) => {
284
+ console.log(`"${result.promptId}","${result.originalTokens}","${result.optimizedTokens}","${result.tokenReduction}","${result.originalCost}","${result.optimizedCost}","${result.costSavings}","${result.priority}"`);
285
+ });
286
+ return;
287
+ }
288
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Bulk Optimization Results'));
289
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
290
+ // Summary Statistics
291
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Summary Statistics'));
292
+ console.log(chalk_1.default.gray('─'.repeat(50)));
293
+ console.log(chalk_1.default.white('Total Prompts:'), chalk_1.default.cyan(optimization.totalPrompts));
294
+ console.log(chalk_1.default.white('Total Token Reduction:'), chalk_1.default.green(`${optimization.totalTokenReduction.toLocaleString()} tokens`));
295
+ console.log(chalk_1.default.white('Total Cost Savings:'), chalk_1.default.green(`$${optimization.totalCostSavings.toFixed(4)}`));
296
+ console.log(chalk_1.default.white('Average Token Reduction:'), chalk_1.default.cyan(`${optimization.averageTokenReduction}%`));
297
+ console.log(chalk_1.default.white('Average Cost Savings:'), chalk_1.default.cyan(`${optimization.averageCostSavings}%`));
298
+ console.log(chalk_1.default.white('High Impact Prompts:'), chalk_1.default.yellow(optimization.highImpactPrompts));
299
+ // Individual Results
300
+ console.log(chalk_1.default.yellow.bold('\nšŸ” Individual Results'));
301
+ console.log(chalk_1.default.gray('─'.repeat(50)));
302
+ optimization.results.forEach((result, index) => {
303
+ const priorityColor = result.priority === 'high' ? chalk_1.default.red :
304
+ result.priority === 'medium' ? chalk_1.default.yellow : chalk_1.default.green;
305
+ const savingsColor = result.costSavings > 0 ? chalk_1.default.green : chalk_1.default.red;
306
+ console.log(chalk_1.default.white(`\n${index + 1}. ${result.promptId}:`));
307
+ console.log(chalk_1.default.gray(' ─'.repeat(40)));
308
+ // Basic Info
309
+ console.log(chalk_1.default.white(' Model:'), chalk_1.default.cyan(result.model));
310
+ console.log(chalk_1.default.white(' Priority:'), priorityColor(result.priority));
311
+ console.log(chalk_1.default.white(' Frequency:'), chalk_1.default.cyan(result.frequency));
312
+ // Token Analysis
313
+ console.log(chalk_1.default.white(' Original Tokens:'), chalk_1.default.cyan(result.originalTokens.toLocaleString()));
314
+ console.log(chalk_1.default.white(' Optimized Tokens:'), chalk_1.default.cyan(result.optimizedTokens.toLocaleString()));
315
+ console.log(chalk_1.default.white(' Token Reduction:'), chalk_1.default.green(`${result.tokenReduction}%`));
316
+ // Cost Analysis
317
+ console.log(chalk_1.default.white(' Original Cost:'), chalk_1.default.cyan(`$${result.originalCost.toFixed(4)}`));
318
+ console.log(chalk_1.default.white(' Optimized Cost:'), chalk_1.default.cyan(`$${result.optimizedCost.toFixed(4)}`));
319
+ console.log(chalk_1.default.white(' Cost Savings:'), savingsColor(`$${result.costSavings.toFixed(4)}`));
320
+ // Impact Analysis
321
+ if (result.impact) {
322
+ console.log(chalk_1.default.white(' Impact Score:'), chalk_1.default.cyan(result.impact.score));
323
+ console.log(chalk_1.default.white(' Impact Notes:'), chalk_1.default.gray(result.impact.notes));
324
+ }
325
+ });
326
+ // Token Analysis
327
+ if (optimization.tokenAnalysis) {
328
+ console.log(chalk_1.default.yellow.bold('\nšŸ”¢ Token Analysis'));
329
+ console.log(chalk_1.default.gray('─'.repeat(50)));
330
+ console.log(chalk_1.default.white('Total Token Reduction:'), chalk_1.default.green(`${optimization.tokenAnalysis.totalReduction.toLocaleString()} tokens`));
331
+ console.log(chalk_1.default.white('Average Token Reduction:'), chalk_1.default.cyan(`${optimization.tokenAnalysis.averageReduction}%`));
332
+ console.log(chalk_1.default.white('Max Token Reduction:'), chalk_1.default.green(`${optimization.tokenAnalysis.maxReduction}%`));
333
+ console.log(chalk_1.default.white('Min Token Reduction:'), chalk_1.default.cyan(`${optimization.tokenAnalysis.minReduction}%`));
334
+ if (optimization.tokenAnalysis.breakdown) {
335
+ console.log(chalk_1.default.white('\nToken Reduction Breakdown:'));
336
+ Object.entries(optimization.tokenAnalysis.breakdown).forEach(([range, count]) => {
337
+ console.log(chalk_1.default.gray(` ${range}: ${count} prompts`));
338
+ });
339
+ }
340
+ }
341
+ // Cost Breakdown
342
+ if (optimization.costBreakdown) {
343
+ console.log(chalk_1.default.yellow.bold('\nšŸ’° Cost Breakdown'));
344
+ console.log(chalk_1.default.gray('─'.repeat(50)));
345
+ console.log(chalk_1.default.white('Total Cost Savings:'), chalk_1.default.green(`$${optimization.costBreakdown.totalSavings.toFixed(4)}`));
346
+ console.log(chalk_1.default.white('Average Cost Savings:'), chalk_1.default.cyan(`${optimization.costBreakdown.averageSavings}%`));
347
+ console.log(chalk_1.default.white('Max Cost Savings:'), chalk_1.default.green(`$${optimization.costBreakdown.maxSavings.toFixed(4)}`));
348
+ console.log(chalk_1.default.white('ROI Impact:'), chalk_1.default.cyan(`${optimization.costBreakdown.roiImpact}%`));
349
+ if (optimization.costBreakdown.byModel) {
350
+ console.log(chalk_1.default.white('\nSavings by Model:'));
351
+ Object.entries(optimization.costBreakdown.byModel).forEach(([model, data]) => {
352
+ console.log(chalk_1.default.gray(` ${model}: $${data.savings.toFixed(4)} (${data.percentage}%)`));
353
+ });
354
+ }
355
+ }
356
+ // Priority Ranking
357
+ if (optimization.priorityRanking) {
358
+ console.log(chalk_1.default.yellow.bold('\nšŸ† Priority Ranking'));
359
+ console.log(chalk_1.default.gray('─'.repeat(50)));
360
+ optimization.priorityRanking.forEach((prompt, index) => {
361
+ const rankColor = index < 3 ? chalk_1.default.green : index < 6 ? chalk_1.default.yellow : chalk_1.default.gray;
362
+ console.log(chalk_1.default.white(`${index + 1}. ${prompt.promptId}:`));
363
+ console.log(chalk_1.default.gray(` Priority: ${rankColor(prompt.priority)}`));
364
+ console.log(chalk_1.default.gray(` Impact Score: ${prompt.impactScore}`));
365
+ console.log(chalk_1.default.gray(` Potential Savings: $${prompt.potentialSavings.toFixed(4)}`));
366
+ });
367
+ }
368
+ // Optimization Suggestions
369
+ if (optimization.suggestions && optimization.suggestions.length > 0) {
370
+ console.log(chalk_1.default.yellow.bold('\nšŸ’” Optimization Suggestions'));
371
+ console.log(chalk_1.default.gray('─'.repeat(50)));
372
+ optimization.suggestions.forEach((suggestion, index) => {
373
+ console.log(chalk_1.default.white(`\n${index + 1}. ${suggestion.type}:`));
374
+ console.log(chalk_1.default.gray(` ${suggestion.description}`));
375
+ console.log(chalk_1.default.gray(` Potential Savings: $${suggestion.potentialSavings.toFixed(4)}`));
376
+ console.log(chalk_1.default.gray(` Implementation: ${suggestion.implementation}`));
377
+ console.log(chalk_1.default.gray(` Priority: ${suggestion.priority}`));
378
+ });
379
+ }
380
+ // Export Results
381
+ if (options.export) {
382
+ try {
383
+ exportResults(optimization, options.export, format);
384
+ console.log(chalk_1.default.green(`\nāœ… Results exported to: ${options.export}`));
385
+ }
386
+ catch (error) {
387
+ console.log(chalk_1.default.red(`\nāŒ Failed to export results: ${error}`));
388
+ }
389
+ }
390
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
391
+ }
392
+ async function exportResults(optimization, filePath, format) {
393
+ if (format === 'json') {
394
+ fs.writeFileSync(filePath, JSON.stringify(optimization, null, 2));
395
+ }
396
+ else if (format === 'csv') {
397
+ const csvWriter = (0, csv_writer_1.createObjectCsvWriter)({
398
+ path: filePath,
399
+ header: [
400
+ { id: 'promptId', title: 'Prompt ID' },
401
+ { id: 'model', title: 'Model' },
402
+ { id: 'originalTokens', title: 'Original Tokens' },
403
+ { id: 'optimizedTokens', title: 'Optimized Tokens' },
404
+ { id: 'tokenReduction', title: 'Token Reduction %' },
405
+ { id: 'originalCost', title: 'Original Cost' },
406
+ { id: 'optimizedCost', title: 'Optimized Cost' },
407
+ { id: 'costSavings', title: 'Cost Savings' },
408
+ { id: 'priority', title: 'Priority' },
409
+ { id: 'frequency', title: 'Frequency' }
410
+ ]
411
+ });
412
+ await csvWriter.writeRecords(optimization.results);
413
+ }
414
+ }
415
+ async function handleStrategyOptimization(options) {
416
+ logger_1.logger.info('šŸš€ Running strategy-based optimization...');
417
+ try {
418
+ const prompts = await loadPromptsFromFile(options.file);
419
+ const strategies = options.strategies ? options.strategies.split(',') : ['token-reduction', 'cost-optimization', 'quality-preservation'];
420
+ const optimization = await runStrategyOptimization(prompts, strategies, options);
421
+ displayStrategyOptimizationResults(optimization, options);
422
+ }
423
+ catch (error) {
424
+ logger_1.logger.error('Failed to run strategy optimization:', error);
425
+ process.exit(1);
426
+ }
427
+ }
428
+ async function runStrategyOptimization(prompts, strategies, options) {
429
+ const baseUrl = config_1.configManager.get('baseUrl');
430
+ const apiKey = config_1.configManager.get('apiKey');
431
+ if (!baseUrl || !apiKey) {
432
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
433
+ }
434
+ try {
435
+ const params = new URLSearchParams();
436
+ params.append('strategies', strategies.join(','));
437
+ if (options.includeTokenAnalysis)
438
+ params.append('includeTokenAnalysis', 'true');
439
+ if (options.includeCostBreakdown)
440
+ params.append('includeCostBreakdown', 'true');
441
+ if (options.includeComparison)
442
+ params.append('includeComparison', 'true');
443
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize/strategies?${params}`, {
444
+ prompts: prompts,
445
+ strategies: strategies,
446
+ options: {
447
+ includeTokenAnalysis: options.includeTokenAnalysis,
448
+ includeCostBreakdown: options.includeCostBreakdown,
449
+ includeComparison: options.includeComparison
450
+ }
451
+ }, {
452
+ headers: {
453
+ 'Authorization': `Bearer ${apiKey}`,
454
+ 'Content-Type': 'application/json',
455
+ },
456
+ timeout: 60000,
457
+ });
458
+ if (response.status !== 200) {
459
+ throw new Error(`API returned status ${response.status}`);
460
+ }
461
+ if (response.data.success && response.data.data) {
462
+ return response.data.data;
463
+ }
464
+ else {
465
+ throw new Error(response.data.message || 'Invalid response format');
466
+ }
467
+ }
468
+ catch (error) {
469
+ if (error.response) {
470
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
471
+ }
472
+ else if (error.request) {
473
+ throw new Error('No response received from API');
474
+ }
475
+ else {
476
+ throw new Error(`Request failed: ${error.message}`);
477
+ }
478
+ }
479
+ }
480
+ function displayStrategyOptimizationResults(optimization, options) {
481
+ const format = options.format || 'table';
482
+ if (format === 'json') {
483
+ console.log(JSON.stringify(optimization, null, 2));
484
+ return;
485
+ }
486
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Strategy Optimization Results'));
487
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
488
+ // Strategy Comparison
489
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Strategy Comparison'));
490
+ console.log(chalk_1.default.gray('─'.repeat(50)));
491
+ optimization.strategyResults.forEach((strategy) => {
492
+ console.log(chalk_1.default.white(`\n${strategy.name}:`));
493
+ console.log(chalk_1.default.gray(' ─'.repeat(40)));
494
+ console.log(chalk_1.default.white(' Total Savings:'), chalk_1.default.green(`$${strategy.totalSavings.toFixed(4)}`));
495
+ console.log(chalk_1.default.white(' Token Reduction:'), chalk_1.default.cyan(`${strategy.tokenReduction}%`));
496
+ console.log(chalk_1.default.white(' Cost Reduction:'), chalk_1.default.green(`${strategy.costReduction}%`));
497
+ console.log(chalk_1.default.white(' Quality Impact:'), chalk_1.default.cyan(`${strategy.qualityImpact}%`));
498
+ console.log(chalk_1.default.white(' Prompts Optimized:'), chalk_1.default.cyan(strategy.promptsOptimized));
499
+ });
500
+ // Best Strategy
501
+ console.log(chalk_1.default.yellow.bold('\nšŸ† Best Strategy'));
502
+ console.log(chalk_1.default.gray('─'.repeat(50)));
503
+ console.log(chalk_1.default.white('Strategy:'), chalk_1.default.cyan(optimization.bestStrategy.name));
504
+ console.log(chalk_1.default.white('Total Savings:'), chalk_1.default.green(`$${optimization.bestStrategy.savings.toFixed(4)}`));
505
+ console.log(chalk_1.default.white('Efficiency Score:'), chalk_1.default.cyan(`${optimization.bestStrategy.efficiencyScore}%`));
506
+ console.log(chalk_1.default.white('Implementation:'), chalk_1.default.gray(optimization.bestStrategy.implementation));
507
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
508
+ }
509
+ async function handlePriorityOptimization(options) {
510
+ logger_1.logger.info('šŸš€ Running priority-based optimization...');
511
+ try {
512
+ const prompts = await loadPromptsFromFile(options.file);
513
+ const optimization = await runPriorityOptimization(prompts, options);
514
+ displayPriorityOptimizationResults(optimization, options);
515
+ }
516
+ catch (error) {
517
+ logger_1.logger.error('Failed to run priority optimization:', error);
518
+ process.exit(1);
519
+ }
520
+ }
521
+ async function runPriorityOptimization(prompts, options) {
522
+ const baseUrl = config_1.configManager.get('baseUrl');
523
+ const apiKey = config_1.configManager.get('apiKey');
524
+ if (!baseUrl || !apiKey) {
525
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
526
+ }
527
+ try {
528
+ const params = new URLSearchParams();
529
+ params.append('priorityCriteria', options.priorityCriteria || 'cost');
530
+ if (options.includeTokenAnalysis)
531
+ params.append('includeTokenAnalysis', 'true');
532
+ if (options.includeCostBreakdown)
533
+ params.append('includeCostBreakdown', 'true');
534
+ if (options.includeImpactAnalysis)
535
+ params.append('includeImpactAnalysis', 'true');
536
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize/priority?${params}`, {
537
+ prompts: prompts,
538
+ priorityCriteria: options.priorityCriteria || 'cost',
539
+ options: {
540
+ includeTokenAnalysis: options.includeTokenAnalysis,
541
+ includeCostBreakdown: options.includeCostBreakdown,
542
+ includeImpactAnalysis: options.includeImpactAnalysis
543
+ }
544
+ }, {
545
+ headers: {
546
+ 'Authorization': `Bearer ${apiKey}`,
547
+ 'Content-Type': 'application/json',
548
+ },
549
+ timeout: 60000,
550
+ });
551
+ if (response.status !== 200) {
552
+ throw new Error(`API returned status ${response.status}`);
553
+ }
554
+ if (response.data.success && response.data.data) {
555
+ return response.data.data;
556
+ }
557
+ else {
558
+ throw new Error(response.data.message || 'Invalid response format');
559
+ }
560
+ }
561
+ catch (error) {
562
+ if (error.response) {
563
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
564
+ }
565
+ else if (error.request) {
566
+ throw new Error('No response received from API');
567
+ }
568
+ else {
569
+ throw new Error(`Request failed: ${error.message}`);
570
+ }
571
+ }
572
+ }
573
+ function displayPriorityOptimizationResults(optimization, options) {
574
+ const format = options.format || 'table';
575
+ if (format === 'json') {
576
+ console.log(JSON.stringify(optimization, null, 2));
577
+ return;
578
+ }
579
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Priority Optimization Results'));
580
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
581
+ // Priority Breakdown
582
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Priority Breakdown'));
583
+ console.log(chalk_1.default.gray('─'.repeat(50)));
584
+ console.log(chalk_1.default.white('High Priority:'), chalk_1.default.red(`${optimization.priorityBreakdown.high} prompts`));
585
+ console.log(chalk_1.default.white('Medium Priority:'), chalk_1.default.yellow(`${optimization.priorityBreakdown.medium} prompts`));
586
+ console.log(chalk_1.default.white('Low Priority:'), chalk_1.default.green(`${optimization.priorityBreakdown.low} prompts`));
587
+ // Impact Analysis
588
+ if (optimization.impactAnalysis) {
589
+ console.log(chalk_1.default.yellow.bold('\nšŸŽÆ Impact Analysis'));
590
+ console.log(chalk_1.default.gray('─'.repeat(50)));
591
+ console.log(chalk_1.default.white('High Impact Savings:'), chalk_1.default.green(`$${optimization.impactAnalysis.highImpactSavings.toFixed(4)}`));
592
+ console.log(chalk_1.default.white('Medium Impact Savings:'), chalk_1.default.yellow(`$${optimization.impactAnalysis.mediumImpactSavings.toFixed(4)}`));
593
+ console.log(chalk_1.default.white('Low Impact Savings:'), chalk_1.default.cyan(`$${optimization.impactAnalysis.lowImpactSavings.toFixed(4)}`));
594
+ }
595
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
596
+ }
597
+ async function handleModelOptimization(options) {
598
+ logger_1.logger.info('šŸš€ Running model-specific optimization...');
599
+ try {
600
+ const prompts = await loadPromptsFromFile(options.file);
601
+ const targetModels = options.targetModels ? options.targetModels.split(',') : ['gpt-4', 'gpt-3.5-turbo', 'claude-3-sonnet'];
602
+ const optimization = await runModelOptimization(prompts, targetModels, options);
603
+ displayModelOptimizationResults(optimization, options);
604
+ }
605
+ catch (error) {
606
+ logger_1.logger.error('Failed to run model optimization:', error);
607
+ process.exit(1);
608
+ }
609
+ }
610
+ async function runModelOptimization(prompts, targetModels, options) {
611
+ const baseUrl = config_1.configManager.get('baseUrl');
612
+ const apiKey = config_1.configManager.get('apiKey');
613
+ if (!baseUrl || !apiKey) {
614
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
615
+ }
616
+ try {
617
+ const params = new URLSearchParams();
618
+ params.append('targetModels', targetModels.join(','));
619
+ if (options.includeTokenAnalysis)
620
+ params.append('includeTokenAnalysis', 'true');
621
+ if (options.includeCostBreakdown)
622
+ params.append('includeCostBreakdown', 'true');
623
+ if (options.includeModelComparison)
624
+ params.append('includeModelComparison', 'true');
625
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize/models?${params}`, {
626
+ prompts: prompts,
627
+ targetModels: targetModels,
628
+ options: {
629
+ includeTokenAnalysis: options.includeTokenAnalysis,
630
+ includeCostBreakdown: options.includeCostBreakdown,
631
+ includeModelComparison: options.includeModelComparison
632
+ }
633
+ }, {
634
+ headers: {
635
+ 'Authorization': `Bearer ${apiKey}`,
636
+ 'Content-Type': 'application/json',
637
+ },
638
+ timeout: 60000,
639
+ });
640
+ if (response.status !== 200) {
641
+ throw new Error(`API returned status ${response.status}`);
642
+ }
643
+ if (response.data.success && response.data.data) {
644
+ return response.data.data;
645
+ }
646
+ else {
647
+ throw new Error(response.data.message || 'Invalid response format');
648
+ }
649
+ }
650
+ catch (error) {
651
+ if (error.response) {
652
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
653
+ }
654
+ else if (error.request) {
655
+ throw new Error('No response received from API');
656
+ }
657
+ else {
658
+ throw new Error(`Request failed: ${error.message}`);
659
+ }
660
+ }
661
+ }
662
+ function displayModelOptimizationResults(optimization, options) {
663
+ const format = options.format || 'table';
664
+ if (format === 'json') {
665
+ console.log(JSON.stringify(optimization, null, 2));
666
+ return;
667
+ }
668
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Model Optimization Results'));
669
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
670
+ // Model Comparison
671
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Model Comparison'));
672
+ console.log(chalk_1.default.gray('─'.repeat(50)));
673
+ optimization.modelResults.forEach((model) => {
674
+ console.log(chalk_1.default.white(`\n${model.name}:`));
675
+ console.log(chalk_1.default.gray(' ─'.repeat(40)));
676
+ console.log(chalk_1.default.white(' Total Savings:'), chalk_1.default.green(`$${model.totalSavings.toFixed(4)}`));
677
+ console.log(chalk_1.default.white(' Token Reduction:'), chalk_1.default.cyan(`${model.tokenReduction}%`));
678
+ console.log(chalk_1.default.white(' Cost Reduction:'), chalk_1.default.green(`${model.costReduction}%`));
679
+ console.log(chalk_1.default.white(' Prompts Optimized:'), chalk_1.default.cyan(model.promptsOptimized));
680
+ });
681
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
682
+ }
683
+ async function handleFrequencyOptimization(options) {
684
+ logger_1.logger.info('šŸš€ Running frequency-based optimization...');
685
+ try {
686
+ const prompts = await loadPromptsFromFile(options.file);
687
+ const threshold = parseInt(options.frequencyThreshold) || 100;
688
+ const optimization = await runFrequencyOptimization(prompts, threshold, options);
689
+ displayFrequencyOptimizationResults(optimization, options);
690
+ }
691
+ catch (error) {
692
+ logger_1.logger.error('Failed to run frequency optimization:', error);
693
+ process.exit(1);
694
+ }
695
+ }
696
+ async function runFrequencyOptimization(prompts, threshold, options) {
697
+ const baseUrl = config_1.configManager.get('baseUrl');
698
+ const apiKey = config_1.configManager.get('apiKey');
699
+ if (!baseUrl || !apiKey) {
700
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
701
+ }
702
+ try {
703
+ const params = new URLSearchParams();
704
+ params.append('threshold', threshold.toString());
705
+ if (options.includeTokenAnalysis)
706
+ params.append('includeTokenAnalysis', 'true');
707
+ if (options.includeCostBreakdown)
708
+ params.append('includeCostBreakdown', 'true');
709
+ if (options.includeFrequencyAnalysis)
710
+ params.append('includeFrequencyAnalysis', 'true');
711
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize/frequency?${params}`, {
712
+ prompts: prompts,
713
+ threshold: threshold,
714
+ options: {
715
+ includeTokenAnalysis: options.includeTokenAnalysis,
716
+ includeCostBreakdown: options.includeCostBreakdown,
717
+ includeFrequencyAnalysis: options.includeFrequencyAnalysis
718
+ }
719
+ }, {
720
+ headers: {
721
+ 'Authorization': `Bearer ${apiKey}`,
722
+ 'Content-Type': 'application/json',
723
+ },
724
+ timeout: 60000,
725
+ });
726
+ if (response.status !== 200) {
727
+ throw new Error(`API returned status ${response.status}`);
728
+ }
729
+ if (response.data.success && response.data.data) {
730
+ return response.data.data;
731
+ }
732
+ else {
733
+ throw new Error(response.data.message || 'Invalid response format');
734
+ }
735
+ }
736
+ catch (error) {
737
+ if (error.response) {
738
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
739
+ }
740
+ else if (error.request) {
741
+ throw new Error('No response received from API');
742
+ }
743
+ else {
744
+ throw new Error(`Request failed: ${error.message}`);
745
+ }
746
+ }
747
+ }
748
+ function displayFrequencyOptimizationResults(optimization, options) {
749
+ const format = options.format || 'table';
750
+ if (format === 'json') {
751
+ console.log(JSON.stringify(optimization, null, 2));
752
+ return;
753
+ }
754
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Frequency Optimization Results'));
755
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
756
+ // Frequency Analysis
757
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Frequency Analysis'));
758
+ console.log(chalk_1.default.gray('─'.repeat(50)));
759
+ console.log(chalk_1.default.white('Threshold:'), chalk_1.default.cyan(optimization.threshold));
760
+ console.log(chalk_1.default.white('High Frequency Prompts:'), chalk_1.default.red(optimization.highFrequencyPrompts));
761
+ console.log(chalk_1.default.white('Medium Frequency Prompts:'), chalk_1.default.yellow(optimization.mediumFrequencyPrompts));
762
+ console.log(chalk_1.default.white('Low Frequency Prompts:'), chalk_1.default.green(optimization.lowFrequencyPrompts));
763
+ // Frequency Impact
764
+ if (optimization.frequencyImpact) {
765
+ console.log(chalk_1.default.yellow.bold('\nšŸŽÆ Frequency Impact'));
766
+ console.log(chalk_1.default.gray('─'.repeat(50)));
767
+ console.log(chalk_1.default.white('High Frequency Savings:'), chalk_1.default.green(`$${optimization.frequencyImpact.highFrequencySavings.toFixed(4)}`));
768
+ console.log(chalk_1.default.white('Medium Frequency Savings:'), chalk_1.default.yellow(`$${optimization.frequencyImpact.mediumFrequencySavings.toFixed(4)}`));
769
+ console.log(chalk_1.default.white('Low Frequency Savings:'), chalk_1.default.cyan(`$${optimization.frequencyImpact.lowFrequencySavings.toFixed(4)}`));
770
+ }
771
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
772
+ }
773
+ async function handleCostOptimization(options) {
774
+ logger_1.logger.info('šŸš€ Running cost-based optimization...');
775
+ try {
776
+ const prompts = await loadPromptsFromFile(options.file);
777
+ const threshold = parseFloat(options.costThreshold) || 0.01;
778
+ const optimization = await runCostOptimization(prompts, threshold, options);
779
+ displayCostOptimizationResults(optimization, options);
780
+ }
781
+ catch (error) {
782
+ logger_1.logger.error('Failed to run cost optimization:', error);
783
+ process.exit(1);
784
+ }
785
+ }
786
+ async function runCostOptimization(prompts, threshold, options) {
787
+ const baseUrl = config_1.configManager.get('baseUrl');
788
+ const apiKey = config_1.configManager.get('apiKey');
789
+ if (!baseUrl || !apiKey) {
790
+ throw new Error('Configuration incomplete. Please run "cost-katana init" to set up your API key and base URL.');
791
+ }
792
+ try {
793
+ const params = new URLSearchParams();
794
+ params.append('threshold', threshold.toString());
795
+ if (options.includeTokenAnalysis)
796
+ params.append('includeTokenAnalysis', 'true');
797
+ if (options.includeCostBreakdown)
798
+ params.append('includeCostBreakdown', 'true');
799
+ if (options.includeCostAnalysis)
800
+ params.append('includeCostAnalysis', 'true');
801
+ const response = await axios_1.default.post(`${baseUrl}/api/bulk-optimize/cost?${params}`, {
802
+ prompts: prompts,
803
+ threshold: threshold,
804
+ options: {
805
+ includeTokenAnalysis: options.includeTokenAnalysis,
806
+ includeCostBreakdown: options.includeCostBreakdown,
807
+ includeCostAnalysis: options.includeCostAnalysis
808
+ }
809
+ }, {
810
+ headers: {
811
+ 'Authorization': `Bearer ${apiKey}`,
812
+ 'Content-Type': 'application/json',
813
+ },
814
+ timeout: 60000,
815
+ });
816
+ if (response.status !== 200) {
817
+ throw new Error(`API returned status ${response.status}`);
818
+ }
819
+ if (response.data.success && response.data.data) {
820
+ return response.data.data;
821
+ }
822
+ else {
823
+ throw new Error(response.data.message || 'Invalid response format');
824
+ }
825
+ }
826
+ catch (error) {
827
+ if (error.response) {
828
+ throw new Error(`API Error: ${error.response.status} - ${error.response.data?.message || 'Unknown error'}`);
829
+ }
830
+ else if (error.request) {
831
+ throw new Error('No response received from API');
832
+ }
833
+ else {
834
+ throw new Error(`Request failed: ${error.message}`);
835
+ }
836
+ }
837
+ }
838
+ function displayCostOptimizationResults(optimization, options) {
839
+ const format = options.format || 'table';
840
+ if (format === 'json') {
841
+ console.log(JSON.stringify(optimization, null, 2));
842
+ return;
843
+ }
844
+ console.log(chalk_1.default.cyan.bold('\nšŸš€ Cost Optimization Results'));
845
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
846
+ // Cost Analysis
847
+ console.log(chalk_1.default.yellow.bold('\nšŸ“Š Cost Analysis'));
848
+ console.log(chalk_1.default.gray('─'.repeat(50)));
849
+ console.log(chalk_1.default.white('Threshold:'), chalk_1.default.cyan(`$${optimization.threshold}`));
850
+ console.log(chalk_1.default.white('High Cost Prompts:'), chalk_1.default.red(optimization.highCostPrompts));
851
+ console.log(chalk_1.default.white('Medium Cost Prompts:'), chalk_1.default.yellow(optimization.mediumCostPrompts));
852
+ console.log(chalk_1.default.white('Low Cost Prompts:'), chalk_1.default.green(optimization.lowCostPrompts));
853
+ // Cost Impact
854
+ if (optimization.costImpact) {
855
+ console.log(chalk_1.default.yellow.bold('\nšŸŽÆ Cost Impact'));
856
+ console.log(chalk_1.default.gray('─'.repeat(50)));
857
+ console.log(chalk_1.default.white('High Cost Savings:'), chalk_1.default.green(`$${optimization.costImpact.highCostSavings.toFixed(4)}`));
858
+ console.log(chalk_1.default.white('Medium Cost Savings:'), chalk_1.default.yellow(`$${optimization.costImpact.mediumCostSavings.toFixed(4)}`));
859
+ console.log(chalk_1.default.white('Low Cost Savings:'), chalk_1.default.cyan(`$${optimization.costImpact.lowCostSavings.toFixed(4)}`));
860
+ }
861
+ console.log(chalk_1.default.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
862
+ }
863
+ //# sourceMappingURL=bulk-optimize.js.map