codereview-aia 0.1.2 → 0.1.4

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 (200) hide show
  1. package/dist/analysis/static/wpPhpcsRunner.d.ts +11 -0
  2. package/dist/analysis/static/wpPhpcsRunner.js +219 -0
  3. package/dist/analysis/static/wpPhpcsRunner.js.map +1 -0
  4. package/dist/clients/implementations/openRouterClient.js +2 -2
  5. package/dist/clients/implementations/openRouterClient.js.map +1 -1
  6. package/dist/clients/openRouterClient.js +2 -2
  7. package/dist/clients/openRouterClient.js.map +1 -1
  8. package/dist/clients/utils/promptFormatter.d.ts +3 -2
  9. package/dist/clients/utils/promptFormatter.js +82 -24
  10. package/dist/clients/utils/promptFormatter.js.map +1 -1
  11. package/dist/core/ConfigurationService.d.ts +21 -0
  12. package/dist/core/ConfigurationService.js +39 -0
  13. package/dist/core/ConfigurationService.js.map +1 -1
  14. package/dist/core/handlers/FileProcessingHandler.js +5 -0
  15. package/dist/core/handlers/FileProcessingHandler.js.map +1 -1
  16. package/dist/core/reviewOrchestrator.js +61 -1
  17. package/dist/core/reviewOrchestrator.js.map +1 -1
  18. package/dist/index.d.ts +0 -1
  19. package/dist/index.js +0 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/runtime/cliEntry.js +57 -4
  22. package/dist/runtime/cliEntry.js.map +1 -1
  23. package/dist/runtime/fileCollector.d.ts +10 -1
  24. package/dist/runtime/fileCollector.js +217 -2
  25. package/dist/runtime/fileCollector.js.map +1 -1
  26. package/dist/runtime/reporting/markdownReportBuilder.d.ts +2 -0
  27. package/dist/runtime/reporting/markdownReportBuilder.js +57 -0
  28. package/dist/runtime/reporting/markdownReportBuilder.js.map +1 -1
  29. package/dist/runtime/reviewPipeline.d.ts +22 -3
  30. package/dist/runtime/reviewPipeline.js +46 -7
  31. package/dist/runtime/reviewPipeline.js.map +1 -1
  32. package/dist/runtime/runAiCodeReview.d.ts +19 -1
  33. package/dist/runtime/runAiCodeReview.js +243 -8
  34. package/dist/runtime/runAiCodeReview.js.map +1 -1
  35. package/dist/runtime/ui/RuntimeApp.js +15 -4
  36. package/dist/runtime/ui/RuntimeApp.js.map +1 -1
  37. package/dist/runtime/ui/screens/ProgressScreen.d.ts +6 -1
  38. package/dist/runtime/ui/screens/ProgressScreen.js +28 -2
  39. package/dist/runtime/ui/screens/ProgressScreen.js.map +1 -1
  40. package/dist/runtime/ui/screens/ResultsScreen.js +8 -1
  41. package/dist/runtime/ui/screens/ResultsScreen.js.map +1 -1
  42. package/dist/types/review.d.ts +60 -0
  43. package/dist/utils/detection/frameworkDetector.js +55 -0
  44. package/dist/utils/detection/frameworkDetector.js.map +1 -1
  45. package/dist/utils/promptTemplateManager.js +1 -0
  46. package/dist/utils/promptTemplateManager.js.map +1 -1
  47. package/package.json +13 -10
  48. package/.cr-aia.yml +0 -23
  49. package/.crignore +0 -0
  50. package/src/analysis/FindingsExtractor.ts +0 -431
  51. package/src/analysis/ai-detection/analyzers/BaseAnalyzer.ts +0 -267
  52. package/src/analysis/ai-detection/analyzers/DocumentationAnalyzer.ts +0 -622
  53. package/src/analysis/ai-detection/analyzers/GitHistoryAnalyzer.ts +0 -430
  54. package/src/analysis/ai-detection/core/AIDetectionEngine.ts +0 -467
  55. package/src/analysis/ai-detection/types/DetectionTypes.ts +0 -406
  56. package/src/analysis/ai-detection/utils/SubmissionConverter.ts +0 -390
  57. package/src/analysis/context/ReviewContext.ts +0 -378
  58. package/src/analysis/context/index.ts +0 -7
  59. package/src/analysis/index.ts +0 -8
  60. package/src/analysis/tokens/TokenAnalysisFormatter.ts +0 -154
  61. package/src/analysis/tokens/TokenAnalyzer.ts +0 -747
  62. package/src/analysis/tokens/index.ts +0 -8
  63. package/src/clients/base/abstractClient.ts +0 -190
  64. package/src/clients/base/httpClient.ts +0 -160
  65. package/src/clients/base/index.ts +0 -12
  66. package/src/clients/base/modelDetection.ts +0 -107
  67. package/src/clients/base/responseProcessor.ts +0 -586
  68. package/src/clients/factory/clientFactory.ts +0 -55
  69. package/src/clients/factory/index.ts +0 -8
  70. package/src/clients/implementations/index.ts +0 -8
  71. package/src/clients/implementations/openRouterClient.ts +0 -411
  72. package/src/clients/openRouterClient.ts +0 -863
  73. package/src/clients/openRouterClientWrapper.ts +0 -44
  74. package/src/clients/utils/directoryStructure.ts +0 -52
  75. package/src/clients/utils/index.ts +0 -11
  76. package/src/clients/utils/languageDetection.ts +0 -44
  77. package/src/clients/utils/promptFormatter.ts +0 -105
  78. package/src/clients/utils/promptLoader.ts +0 -53
  79. package/src/clients/utils/tokenCounter.ts +0 -297
  80. package/src/core/ApiClientSelector.ts +0 -37
  81. package/src/core/ConfigurationService.ts +0 -591
  82. package/src/core/ConsolidationService.ts +0 -423
  83. package/src/core/InteractiveDisplayManager.ts +0 -81
  84. package/src/core/OutputManager.ts +0 -275
  85. package/src/core/ReviewGenerator.ts +0 -140
  86. package/src/core/fileDiscovery.ts +0 -237
  87. package/src/core/handlers/EstimationHandler.ts +0 -104
  88. package/src/core/handlers/FileProcessingHandler.ts +0 -204
  89. package/src/core/handlers/OutputHandler.ts +0 -125
  90. package/src/core/handlers/ReviewExecutor.ts +0 -104
  91. package/src/core/reviewOrchestrator.ts +0 -333
  92. package/src/core/utils/ModelInfoUtils.ts +0 -56
  93. package/src/formatters/outputFormatter.ts +0 -62
  94. package/src/formatters/utils/IssueFormatters.ts +0 -83
  95. package/src/formatters/utils/JsonFormatter.ts +0 -77
  96. package/src/formatters/utils/MarkdownFormatters.ts +0 -609
  97. package/src/formatters/utils/MetadataFormatter.ts +0 -269
  98. package/src/formatters/utils/ModelInfoExtractor.ts +0 -115
  99. package/src/index.ts +0 -28
  100. package/src/plugins/PluginInterface.ts +0 -50
  101. package/src/plugins/PluginManager.ts +0 -126
  102. package/src/prompts/PromptManager.ts +0 -69
  103. package/src/prompts/cache/PromptCache.ts +0 -50
  104. package/src/prompts/promptText/common/variables/css-frameworks.json +0 -33
  105. package/src/prompts/promptText/common/variables/framework-versions.json +0 -45
  106. package/src/prompts/promptText/frameworks/react/comprehensive.hbs +0 -19
  107. package/src/prompts/promptText/languages/css/comprehensive.hbs +0 -18
  108. package/src/prompts/promptText/languages/generic/comprehensive.hbs +0 -20
  109. package/src/prompts/promptText/languages/html/comprehensive.hbs +0 -18
  110. package/src/prompts/promptText/languages/javascript/comprehensive.hbs +0 -18
  111. package/src/prompts/promptText/languages/python/comprehensive.hbs +0 -18
  112. package/src/prompts/promptText/languages/typescript/comprehensive.hbs +0 -18
  113. package/src/runtime/auth/service.ts +0 -58
  114. package/src/runtime/auth/session.ts +0 -103
  115. package/src/runtime/auth/types.ts +0 -11
  116. package/src/runtime/cliEntry.ts +0 -196
  117. package/src/runtime/debug/logManager.ts +0 -37
  118. package/src/runtime/errors.ts +0 -13
  119. package/src/runtime/fileCollector.ts +0 -222
  120. package/src/runtime/manifest.ts +0 -64
  121. package/src/runtime/openrouterProxy.ts +0 -45
  122. package/src/runtime/preprod/webCheck.ts +0 -104
  123. package/src/runtime/proxyConfig.ts +0 -94
  124. package/src/runtime/proxyEnvironment.ts +0 -71
  125. package/src/runtime/reportMerge.ts +0 -102
  126. package/src/runtime/reporting/markdownReportBuilder.ts +0 -138
  127. package/src/runtime/reporting/reportDataCollector.ts +0 -234
  128. package/src/runtime/reporting/summaryGenerator.ts +0 -86
  129. package/src/runtime/reviewPipeline.ts +0 -161
  130. package/src/runtime/runAiCodeReview.ts +0 -153
  131. package/src/runtime/runtimeConfig.ts +0 -5
  132. package/src/runtime/ui/Layout.tsx +0 -57
  133. package/src/runtime/ui/RuntimeApp.tsx +0 -233
  134. package/src/runtime/ui/inkModules.ts +0 -73
  135. package/src/runtime/ui/screens/AuthScreen.tsx +0 -128
  136. package/src/runtime/ui/screens/ModeSelection.tsx +0 -185
  137. package/src/runtime/ui/screens/ProgressScreen.tsx +0 -62
  138. package/src/runtime/ui/screens/ResultsScreen.tsx +0 -83
  139. package/src/strategies/ArchitecturalReviewStrategy.ts +0 -54
  140. package/src/strategies/CodingTestReviewStrategy.ts +0 -920
  141. package/src/strategies/ConsolidatedReviewStrategy.ts +0 -59
  142. package/src/strategies/ExtractPatternsReviewStrategy.ts +0 -64
  143. package/src/strategies/MultiPassReviewStrategy.ts +0 -785
  144. package/src/strategies/ReviewStrategy.ts +0 -64
  145. package/src/strategies/StrategyFactory.ts +0 -79
  146. package/src/strategies/index.ts +0 -14
  147. package/src/tokenizers/baseTokenizer.ts +0 -61
  148. package/src/tokenizers/gptTokenizer.ts +0 -27
  149. package/src/tokenizers/index.ts +0 -8
  150. package/src/types/apiResponses.ts +0 -40
  151. package/src/types/cli.ts +0 -24
  152. package/src/types/common.ts +0 -39
  153. package/src/types/configuration.ts +0 -201
  154. package/src/types/handlebars.d.ts +0 -5
  155. package/src/types/patch.d.ts +0 -25
  156. package/src/types/review.ts +0 -294
  157. package/src/types/reviewContext.d.ts +0 -65
  158. package/src/types/reviewSchema.ts +0 -181
  159. package/src/types/structuredReview.ts +0 -167
  160. package/src/types/tokenAnalysis.ts +0 -56
  161. package/src/utils/FileReader.ts +0 -93
  162. package/src/utils/FileWriter.ts +0 -76
  163. package/src/utils/PathGenerator.ts +0 -97
  164. package/src/utils/api/apiUtils.ts +0 -14
  165. package/src/utils/api/index.ts +0 -1
  166. package/src/utils/apiErrorHandler.ts +0 -287
  167. package/src/utils/ciDataCollector.ts +0 -252
  168. package/src/utils/codingTestConfigLoader.ts +0 -466
  169. package/src/utils/dependencies/aiDependencyAnalyzer.ts +0 -454
  170. package/src/utils/detection/frameworkDetector.ts +0 -879
  171. package/src/utils/detection/index.ts +0 -10
  172. package/src/utils/detection/projectTypeDetector.ts +0 -518
  173. package/src/utils/diagramGenerator.ts +0 -206
  174. package/src/utils/errorLogger.ts +0 -60
  175. package/src/utils/estimationUtils.ts +0 -407
  176. package/src/utils/fileFilters.ts +0 -373
  177. package/src/utils/fileSystem.ts +0 -57
  178. package/src/utils/index.ts +0 -36
  179. package/src/utils/logger.ts +0 -290
  180. package/src/utils/pathValidator.ts +0 -98
  181. package/src/utils/priorityFilter.ts +0 -59
  182. package/src/utils/projectDocs.ts +0 -189
  183. package/src/utils/promptPaths.ts +0 -29
  184. package/src/utils/promptTemplateManager.ts +0 -157
  185. package/src/utils/review/consolidateReview.ts +0 -553
  186. package/src/utils/review/fixDisplay.ts +0 -100
  187. package/src/utils/review/fixImplementation.ts +0 -61
  188. package/src/utils/review/index.ts +0 -36
  189. package/src/utils/review/interactiveProcessing.ts +0 -294
  190. package/src/utils/review/progressTracker.ts +0 -296
  191. package/src/utils/review/reviewExtraction.ts +0 -382
  192. package/src/utils/review/types.ts +0 -46
  193. package/src/utils/reviewActionHandler.ts +0 -18
  194. package/src/utils/reviewParser.ts +0 -253
  195. package/src/utils/sanitizer.ts +0 -238
  196. package/src/utils/smartFileSelector.ts +0 -255
  197. package/src/utils/templateLoader.ts +0 -514
  198. package/src/utils/treeGenerator.ts +0 -153
  199. package/tsconfig.build.json +0 -14
  200. package/tsconfig.json +0 -59
@@ -1,411 +0,0 @@
1
- /**
2
- * @fileoverview OpenRouter client implementation using the abstract client interface.
3
- *
4
- * This module implements the OpenRouter client using the abstract client base class.
5
- * It provides functionality for interacting with OpenRouter's API, which gives access
6
- * to a variety of AI models from different providers.
7
- */
8
-
9
- import type { FileInfo, ReviewOptions, ReviewResult, ReviewType } from '../../types/review';
10
- import logger from '../../utils/logger';
11
- import type { ProjectDocs } from '../../utils/projectDocs';
12
- import {
13
- AbstractClient,
14
- createStandardReviewResult,
15
- detectModelProvider,
16
- fetchWithRetry,
17
- handleApiError,
18
- validateApiKey,
19
- } from '../base';
20
- import {
21
- formatConsolidatedReviewPrompt,
22
- formatSingleFileReviewPrompt,
23
- } from '../utils/promptFormatter';
24
- import { loadPromptTemplate } from '../utils/promptLoader';
25
-
26
- // import { getLanguageFromExtension } from '../utils/languageDetection'; // Not used in this implementation
27
-
28
- const MAX_TOKENS_PER_REQUEST = 4000;
29
-
30
- /**
31
- * OpenRouter client implementation
32
- */
33
- export class OpenRouterClient extends AbstractClient {
34
- protected apiKey: string | undefined;
35
-
36
- /**
37
- * Initialize with default values
38
- */
39
- constructor() {
40
- super();
41
- this.modelName = '';
42
- this.isInitialized = false;
43
- this.apiKey = process.env.AI_CODE_REVIEW_OPENROUTER_API_KEY;
44
- }
45
-
46
- /**
47
- * Check if the provided model name is supported by this client
48
- * @param modelName The full model name (potentially with provider prefix)
49
- * @returns Object indicating if this is the correct client for the model
50
- */
51
- public isModelSupported(modelName: string): {
52
- isCorrect: boolean;
53
- adapter: string;
54
- modelName: string;
55
- } {
56
- return detectModelProvider('openrouter', modelName);
57
- }
58
-
59
- /**
60
- * Get the provider name for this client
61
- * @returns The provider name
62
- */
63
- protected getProviderName(): string {
64
- return 'openrouter';
65
- }
66
-
67
- /**
68
- * Initialize the OpenRouter client
69
- * @returns Promise resolving to a boolean indicating success
70
- */
71
- public async initialize(): Promise<boolean> {
72
- // If already initialized, return true
73
- if (this.isInitialized) {
74
- return true;
75
- }
76
-
77
- // Get model information - clean the model name to handle malformed input
78
- const rawModel = process.env.AI_CODE_REVIEW_MODEL || '';
79
- const cleanedModel = rawModel.replace(/['"``]/g, '').trim();
80
- const { isCorrect, modelName } = this.isModelSupported(cleanedModel);
81
-
82
- // If this is not an OpenRouter model, just return true without initializing
83
- if (!isCorrect) {
84
- return true;
85
- }
86
-
87
- // Set the model name
88
- this.modelName = modelName;
89
-
90
- // Validate the API key
91
- if (!validateApiKey('openrouter', 'AI_CODE_REVIEW_OPENROUTER_API_KEY')) {
92
- process.exit(1);
93
- }
94
-
95
- try {
96
- logger.info(`Initializing OpenRouter model: ${this.modelName}...`);
97
-
98
- // Mark as initialized
99
- this.isInitialized = true;
100
- logger.info(`Successfully initialized OpenRouter model: ${this.modelName}`);
101
- return true;
102
- } catch (error) {
103
- logger.error(
104
- `Error initializing OpenRouter model ${this.modelName}: ${
105
- error instanceof Error ? error.message : String(error)
106
- }`,
107
- );
108
- return false;
109
- }
110
- }
111
-
112
- /**
113
- * Generate a review for a single file
114
- * @param fileContent Content of the file to review
115
- * @param filePath Path to the file
116
- * @param reviewType Type of review to perform
117
- * @param projectDocs Optional project documentation
118
- * @param options Review options
119
- * @returns Promise resolving to the review result
120
- */
121
- public async generateReview(
122
- fileContent: string,
123
- filePath: string,
124
- reviewType: ReviewType,
125
- projectDocs?: ProjectDocs | null,
126
- options?: ReviewOptions,
127
- ): Promise<ReviewResult> {
128
- // During consolidation, the model may have been overridden.
129
- // If we're already initialized with a valid model, trust that initialization was correct.
130
- // Only check the environment if we're not initialized.
131
- if (!this.isInitialized) {
132
- // If not initialized, check against the current environment variable
133
- const rawModel = process.env.AI_CODE_REVIEW_MODEL || '';
134
- // Clean the model name to handle malformed input (quotes, backticks, whitespace)
135
- const currentModel = rawModel.replace(/['"``]/g, '').trim();
136
- const { isCorrect } = this.isModelSupported(currentModel);
137
-
138
- // Make sure this is the correct client
139
- if (!isCorrect) {
140
- logger.error(
141
- `[OpenRouter] Invalid model for OpenRouter client: ${currentModel} (original: ${rawModel})`,
142
- );
143
- throw new Error(
144
- `OpenRouter client was called with an invalid model: ${currentModel}. This is likely a bug in the client selection logic.`,
145
- );
146
- }
147
-
148
- // Initialize if this is the correct client
149
- await this.initialize();
150
- }
151
-
152
- // At this point we should be initialized with a valid model
153
- if (!this.modelName) {
154
- logger.error(`[OpenRouter] Client is initialized but has no model name`);
155
- throw new Error(`OpenRouter client is in an invalid state: initialized but no model name`);
156
- }
157
-
158
- try {
159
- // Get the language from file extension
160
- // const language = getLanguageFromExtension(filePath); // Currently unused
161
-
162
- // Load the appropriate prompt template
163
- const promptTemplate = await loadPromptTemplate(reviewType, options);
164
-
165
- // Format the prompt
166
- const prompt = formatSingleFileReviewPrompt(
167
- promptTemplate,
168
- fileContent,
169
- filePath,
170
- projectDocs,
171
- );
172
-
173
- try {
174
- logger.info(`Generating review with OpenRouter ${this.modelName}...`);
175
-
176
- // Make the API request
177
- const response = await fetchWithRetry('https://openrouter.ai/api/v1/chat/completions', {
178
- method: 'POST',
179
- headers: {
180
- 'Content-Type': 'application/json',
181
- Authorization: `Bearer ${this.apiKey}`,
182
- 'HTTP-Referer': 'https://cr-aia.app', // Required by OpenRouter
183
- 'X-Title': 'cr-aia', // Optional for OpenRouter stats
184
- },
185
- body: JSON.stringify({
186
- model: this.modelName,
187
- messages: [
188
- {
189
- role: 'user',
190
- content: prompt,
191
- },
192
- ],
193
- temperature: 0.2,
194
- // For consolidation, don't limit tokens to avoid truncation
195
- ...(options?.isConsolidation ? {} : { max_tokens: MAX_TOKENS_PER_REQUEST }),
196
- }),
197
- });
198
-
199
- const data = await response.json();
200
- if (!Array.isArray(data.choices) || !data.choices[0]?.message?.content) {
201
- throw new Error(`Invalid response format from OpenRouter ${this.modelName}`);
202
- }
203
-
204
- const content = data.choices[0].message.content;
205
-
206
- // Check for truncated response
207
- const usage = data.usage;
208
- if (usage && usage.completion_tokens < 50) {
209
- logger.warn(
210
- `Response appears truncated - only ${usage.completion_tokens} output tokens generated. ` +
211
- `This may indicate an API issue with model ${this.modelName}.`,
212
- );
213
-
214
- // If response is truncated and appears to be incomplete JSON
215
- if (content.trim().startsWith('{') && !content.includes('}')) {
216
- const errorMessage =
217
- `The AI model response was truncated and incomplete. ` +
218
- `Only ${usage.completion_tokens} tokens were generated instead of the expected response. ` +
219
- `This is likely an issue with the OpenRouter API or the ${this.modelName} model. ` +
220
- `Please try again or use a different model.`;
221
-
222
- logger.error(`Truncated response detected: ${content.substring(0, 100)}...`);
223
- throw new Error(errorMessage);
224
- }
225
- }
226
-
227
- // Log response details for debugging
228
- if (usage) {
229
- logger.debug(
230
- `OpenRouter response stats - Input tokens: ${usage.prompt_tokens}, ` +
231
- `Output tokens: ${usage.completion_tokens}, Total: ${usage.total_tokens}`,
232
- );
233
- }
234
-
235
- logger.info(`Successfully generated review with OpenRouter ${this.modelName}`);
236
-
237
- // Create and return the review result
238
- return createStandardReviewResult(
239
- content,
240
- prompt,
241
- this.getFullModelName(),
242
- filePath,
243
- reviewType,
244
- options,
245
- );
246
- } catch (error) {
247
- throw handleApiError(error, 'generate review', this.getFullModelName());
248
- }
249
- } catch (error) {
250
- this.handleApiError(error, 'generating review', filePath);
251
- }
252
- }
253
-
254
- /**
255
- * Generate a consolidated review for multiple files
256
- * @param files Array of file information objects
257
- * @param projectName Name of the project
258
- * @param reviewType Type of review to perform
259
- * @param projectDocs Optional project documentation
260
- * @param options Review options
261
- * @returns Promise resolving to the review result
262
- */
263
- public async generateConsolidatedReview(
264
- files: FileInfo[],
265
- projectName: string,
266
- reviewType: ReviewType,
267
- projectDocs?: ProjectDocs | null,
268
- options?: ReviewOptions,
269
- ): Promise<ReviewResult> {
270
- // During consolidation, the model may have been overridden. We should check if we're already initialized
271
- // with a valid model rather than checking the current environment variable.
272
- if (!this.isInitialized || !this.modelName) {
273
- // If not initialized, check against the current environment variable
274
- const { isCorrect } = this.isModelSupported(process.env.AI_CODE_REVIEW_MODEL || '');
275
-
276
- // Make sure this is the correct client
277
- if (!isCorrect) {
278
- throw new Error(
279
- `OpenRouter client was called with an invalid model. This is likely a bug in the client selection logic.`,
280
- );
281
- }
282
- }
283
- // If we're already initialized with a model, trust that initialization was correct
284
-
285
- try {
286
- // Initialize if needed
287
- if (!this.isInitialized) {
288
- await this.initialize();
289
- }
290
-
291
- // Load the appropriate prompt template
292
- const promptTemplate = await loadPromptTemplate(reviewType, options);
293
-
294
- // Format the prompt
295
- const prompt = formatConsolidatedReviewPrompt(
296
- promptTemplate,
297
- projectName,
298
- files.map((file) => ({
299
- relativePath: file.relativePath || '',
300
- content: file.content,
301
- sizeInBytes: file.content.length,
302
- })),
303
- projectDocs,
304
- );
305
-
306
- try {
307
- logger.info(`Generating consolidated review with OpenRouter ${this.modelName}...`);
308
-
309
- // Make the API request
310
- const response = await fetchWithRetry('https://openrouter.ai/api/v1/chat/completions', {
311
- method: 'POST',
312
- headers: {
313
- 'Content-Type': 'application/json',
314
- Authorization: `Bearer ${this.apiKey}`,
315
- 'HTTP-Referer': 'https://cr-aia.app', // Required by OpenRouter
316
- 'X-Title': 'cr-aia', // Optional for OpenRouter stats
317
- },
318
- body: JSON.stringify({
319
- model: this.modelName,
320
- messages: [
321
- {
322
- role: 'user',
323
- content: prompt,
324
- },
325
- ],
326
- temperature: 0.2,
327
- // For consolidated reviews, don't limit tokens to avoid truncation
328
- // max_tokens is omitted to allow unlimited output
329
- }),
330
- });
331
-
332
- const data = await response.json();
333
- if (!Array.isArray(data.choices) || !data.choices[0]?.message?.content) {
334
- throw new Error(`Invalid response format from OpenRouter ${this.modelName}`);
335
- }
336
-
337
- const content = data.choices[0].message.content;
338
-
339
- // Check for truncated response
340
- const usage = data.usage;
341
- if (usage && usage.completion_tokens < 50) {
342
- logger.warn(
343
- `Response appears truncated - only ${usage.completion_tokens} output tokens generated. ` +
344
- `This may indicate an API issue with model ${this.modelName}.`,
345
- );
346
-
347
- // If response is truncated and appears to be incomplete JSON
348
- if (content.trim().startsWith('{') && !content.includes('}')) {
349
- const errorMessage =
350
- `The AI model response was truncated and incomplete. ` +
351
- `Only ${usage.completion_tokens} tokens were generated instead of the expected response. ` +
352
- `This is likely an issue with the OpenRouter API or the ${this.modelName} model. ` +
353
- `Please try again or use a different model.`;
354
-
355
- logger.error(`Truncated response detected: ${content.substring(0, 100)}...`);
356
- throw new Error(errorMessage);
357
- }
358
- }
359
-
360
- // Log response details for debugging
361
- if (usage) {
362
- logger.debug(
363
- `OpenRouter response stats - Input tokens: ${usage.prompt_tokens}, ` +
364
- `Output tokens: ${usage.completion_tokens}, Total: ${usage.total_tokens}`,
365
- );
366
- }
367
-
368
- logger.info(`Successfully generated consolidated review with OpenRouter ${this.modelName}`);
369
-
370
- // Create and return the review result
371
- return createStandardReviewResult(
372
- content,
373
- prompt,
374
- this.getFullModelName(),
375
- 'consolidated',
376
- reviewType,
377
- options,
378
- );
379
- } catch (error) {
380
- throw handleApiError(error, 'generate consolidated review', this.getFullModelName());
381
- }
382
- } catch (error) {
383
- this.handleApiError(error, 'generating consolidated review', projectName);
384
- }
385
- }
386
-
387
- /**
388
- * Generate an architectural review for a project
389
- * @param files Array of file information objects
390
- * @param projectName Name of the project
391
- * @param projectDocs Optional project documentation
392
- * @param options Review options
393
- * @returns Promise resolving to the review result
394
- */
395
- public async generateArchitecturalReview(
396
- files: FileInfo[],
397
- projectName: string,
398
- projectDocs?: ProjectDocs | null,
399
- options?: ReviewOptions,
400
- ): Promise<ReviewResult> {
401
- // For OpenRouter, architectural reviews are handled by the consolidated review function
402
- // with the review type set to 'architectural'
403
- return this.generateConsolidatedReview(
404
- files,
405
- projectName,
406
- 'architectural',
407
- projectDocs,
408
- options,
409
- );
410
- }
411
- }