cadr-cli 0.0.1 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adr.d.ts +50 -0
- package/dist/adr.d.ts.map +1 -0
- package/dist/adr.js +156 -0
- package/dist/adr.js.map +1 -0
- package/dist/adr.test.d.ts +8 -0
- package/dist/adr.test.d.ts.map +1 -0
- package/dist/adr.test.js +256 -0
- package/dist/adr.test.js.map +1 -0
- package/dist/analysis.d.ts +24 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +281 -0
- package/dist/analysis.js.map +1 -0
- package/dist/analysis.test.d.ts +8 -0
- package/dist/analysis.test.d.ts.map +1 -0
- package/dist/analysis.test.js +351 -0
- package/dist/analysis.test.js.map +1 -0
- package/dist/commands/analyze.d.ts +14 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +56 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +93 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +56 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/config.d.ts +40 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +208 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +97 -0
- package/dist/config.test.js.map +1 -0
- package/dist/git.d.ts +42 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +157 -0
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -62
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +51 -0
- package/dist/index.test.js.map +1 -0
- package/dist/llm.d.ts +73 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +263 -0
- package/dist/llm.js.map +1 -0
- package/dist/llm.test.d.ts +2 -0
- package/dist/llm.test.d.ts.map +1 -0
- package/dist/llm.test.js +592 -0
- package/dist/llm.test.js.map +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +5 -3
- package/dist/logger.js.map +1 -1
- package/dist/logger.test.d.ts +2 -0
- package/dist/logger.test.d.ts.map +1 -0
- package/dist/logger.test.js +78 -0
- package/dist/logger.test.js.map +1 -0
- package/dist/prompts.d.ts +49 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +195 -0
- package/dist/prompts.js.map +1 -0
- package/dist/prompts.test.d.ts +2 -0
- package/dist/prompts.test.d.ts.map +1 -0
- package/dist/prompts.test.js +427 -0
- package/dist/prompts.test.js.map +1 -0
- package/dist/providers/gemini.d.ts +3 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +39 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +6 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +25 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/registry.d.ts +4 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +16 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/types.d.ts +12 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +5 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/version.test.d.ts +3 -0
- package/dist/version.test.d.ts.map +1 -0
- package/dist/version.test.js +25 -0
- package/dist/version.test.js.map +1 -0
- package/package.json +14 -5
- package/src/adr.test.ts +278 -0
- package/src/adr.ts +136 -0
- package/src/analysis.test.ts +396 -0
- package/src/analysis.ts +262 -0
- package/src/commands/analyze.ts +56 -0
- package/src/commands/init.test.ts +27 -0
- package/src/commands/init.ts +99 -0
- package/src/config.test.ts +79 -0
- package/src/config.ts +214 -0
- package/src/git.ts +240 -0
- package/src/index.test.ts +59 -0
- package/src/index.ts +80 -60
- package/src/llm.test.ts +701 -0
- package/src/llm.ts +344 -0
- package/src/logger.test.ts +90 -0
- package/src/logger.ts +6 -3
- package/src/prompts.test.ts +515 -0
- package/src/prompts.ts +174 -0
- package/src/providers/gemini.ts +41 -0
- package/src/providers/index.ts +1 -0
- package/src/providers/openai.ts +22 -0
- package/src/providers/registry.ts +16 -0
- package/src/providers/types.ts +14 -0
- package/src/version.test.ts +29 -0
- package/bin/cadr.js +0 -16
package/dist/llm.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Client Module
|
|
3
|
+
*
|
|
4
|
+
* Provider-based wrapper for analyzing code changes.
|
|
5
|
+
* Implements fail-open error handling per constitution requirements.
|
|
6
|
+
*/
|
|
7
|
+
import { AnalysisConfig } from './config';
|
|
8
|
+
/**
|
|
9
|
+
* Analysis request data structure
|
|
10
|
+
*/
|
|
11
|
+
export interface AnalysisRequest {
|
|
12
|
+
file_paths: string[];
|
|
13
|
+
diff_content: string;
|
|
14
|
+
repository_context: string;
|
|
15
|
+
analysis_prompt: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Analysis result from LLM
|
|
19
|
+
*/
|
|
20
|
+
export interface AnalysisResult {
|
|
21
|
+
is_significant: boolean;
|
|
22
|
+
reason: string;
|
|
23
|
+
confidence?: number;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Analysis response including potential errors
|
|
28
|
+
*/
|
|
29
|
+
export interface AnalysisResponse {
|
|
30
|
+
result: AnalysisResult | null;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Analyze staged changes using OpenAI LLM
|
|
35
|
+
*
|
|
36
|
+
* @param config - Analysis configuration with API settings
|
|
37
|
+
* @param request - Analysis request with code changes
|
|
38
|
+
* @returns Promise resolving to analysis response with result or error
|
|
39
|
+
*/
|
|
40
|
+
export declare function analyzeChanges(config: AnalysisConfig, request: AnalysisRequest): Promise<AnalysisResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Generation request data structure
|
|
43
|
+
*/
|
|
44
|
+
export interface GenerationRequest {
|
|
45
|
+
file_paths: string[];
|
|
46
|
+
diff_content: string;
|
|
47
|
+
reason: string;
|
|
48
|
+
generation_prompt: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generation result from LLM
|
|
52
|
+
*/
|
|
53
|
+
export interface GenerationResult {
|
|
54
|
+
content: string;
|
|
55
|
+
title: string;
|
|
56
|
+
timestamp: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generation response including potential errors
|
|
60
|
+
*/
|
|
61
|
+
export interface GenerationResponse {
|
|
62
|
+
result: GenerationResult | null;
|
|
63
|
+
error?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Generate ADR content using LLM
|
|
67
|
+
*
|
|
68
|
+
* @param config - Analysis configuration with API settings
|
|
69
|
+
* @param request - Generation request with code changes
|
|
70
|
+
* @returns Promise resolving to generation response with result or error
|
|
71
|
+
*/
|
|
72
|
+
export declare function generateADRContent(config: AnalysisConfig, request: GenerationRequest): Promise<GenerationResponse>;
|
|
73
|
+
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAUD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAiK3B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAsF7B"}
|
package/dist/llm.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LLM Client Module
|
|
4
|
+
*
|
|
5
|
+
* Provider-based wrapper for analyzing code changes.
|
|
6
|
+
* Implements fail-open error handling per constitution requirements.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.analyzeChanges = analyzeChanges;
|
|
10
|
+
exports.generateADRContent = generateADRContent;
|
|
11
|
+
const providers_1 = require("./providers");
|
|
12
|
+
const logger_1 = require("./logger");
|
|
13
|
+
/**
|
|
14
|
+
* Rough token estimation (1 token ≈ 4 characters for English text)
|
|
15
|
+
* This is a conservative estimate
|
|
16
|
+
*/
|
|
17
|
+
function estimateTokens(text) {
|
|
18
|
+
return Math.ceil(text.length / 4);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Analyze staged changes using OpenAI LLM
|
|
22
|
+
*
|
|
23
|
+
* @param config - Analysis configuration with API settings
|
|
24
|
+
* @param request - Analysis request with code changes
|
|
25
|
+
* @returns Promise resolving to analysis response with result or error
|
|
26
|
+
*/
|
|
27
|
+
async function analyzeChanges(config, request) {
|
|
28
|
+
try {
|
|
29
|
+
// Check if API key is available
|
|
30
|
+
const apiKey = process.env[config.api_key_env];
|
|
31
|
+
if (!apiKey) {
|
|
32
|
+
logger_1.loggerInstance.warn('API key not found in environment', {
|
|
33
|
+
api_key_env: config.api_key_env,
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
result: null,
|
|
37
|
+
error: `API key not found: ${config.api_key_env} environment variable is not set`
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Estimate tokens for logging and validation
|
|
41
|
+
const estimatedTokens = estimateTokens(request.analysis_prompt);
|
|
42
|
+
logger_1.loggerInstance.info('Sending analysis request to LLM', {
|
|
43
|
+
provider: config.provider,
|
|
44
|
+
model: config.analysis_model,
|
|
45
|
+
file_count: request.file_paths.length,
|
|
46
|
+
estimated_tokens: estimatedTokens,
|
|
47
|
+
});
|
|
48
|
+
// Warn if token estimate is high (most models have 8k-32k limits)
|
|
49
|
+
if (estimatedTokens > 7000) {
|
|
50
|
+
logger_1.loggerInstance.warn('High token count detected', {
|
|
51
|
+
estimated_tokens: estimatedTokens,
|
|
52
|
+
provider: config.provider,
|
|
53
|
+
model: config.analysis_model,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const provider = (0, providers_1.getProvider)(config.provider);
|
|
57
|
+
const responseContent = await provider.analyze(request.analysis_prompt, {
|
|
58
|
+
apiKey,
|
|
59
|
+
model: config.analysis_model,
|
|
60
|
+
timeoutMs: config.timeout_seconds * 1000,
|
|
61
|
+
});
|
|
62
|
+
if (!responseContent) {
|
|
63
|
+
logger_1.loggerInstance.warn('No response content from LLM', { provider: config.provider });
|
|
64
|
+
return {
|
|
65
|
+
result: null,
|
|
66
|
+
error: 'No response content from LLM'
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Parse JSON response - handle markdown-wrapped JSON
|
|
70
|
+
let parsedResponse;
|
|
71
|
+
try {
|
|
72
|
+
// Try to extract JSON from markdown code blocks if present
|
|
73
|
+
let jsonContent = responseContent.trim();
|
|
74
|
+
// Remove markdown code block if present: ```json ... ``` or ``` ... ```
|
|
75
|
+
const codeBlockMatch = jsonContent.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
76
|
+
if (codeBlockMatch) {
|
|
77
|
+
jsonContent = codeBlockMatch[1].trim();
|
|
78
|
+
}
|
|
79
|
+
// Try to find JSON object if there's surrounding text
|
|
80
|
+
const jsonMatch = jsonContent.match(/\{[\s\S]*\}/);
|
|
81
|
+
if (jsonMatch) {
|
|
82
|
+
jsonContent = jsonMatch[0];
|
|
83
|
+
}
|
|
84
|
+
parsedResponse = JSON.parse(jsonContent);
|
|
85
|
+
}
|
|
86
|
+
catch (parseError) {
|
|
87
|
+
logger_1.loggerInstance.warn('Failed to parse LLM response as JSON', {
|
|
88
|
+
error: parseError,
|
|
89
|
+
response: responseContent,
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
result: null,
|
|
93
|
+
error: `Failed to parse LLM response as JSON. Response was:\n${responseContent.substring(0, 200)}...`
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Validate response format
|
|
97
|
+
if (typeof parsedResponse.is_significant !== 'boolean' ||
|
|
98
|
+
typeof parsedResponse.reason !== 'string') {
|
|
99
|
+
logger_1.loggerInstance.warn('Invalid response format from LLM', {
|
|
100
|
+
response: parsedResponse,
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
result: null,
|
|
104
|
+
error: `Invalid response format from LLM. Expected {is_significant: boolean, reason: string}, got: ${JSON.stringify(parsedResponse).substring(0, 150)}...`
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Reason is required when is_significant is true, but can be empty when false
|
|
108
|
+
if (parsedResponse.is_significant && !parsedResponse.reason) {
|
|
109
|
+
logger_1.loggerInstance.warn('Missing reason for significant change', {
|
|
110
|
+
response: parsedResponse,
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
result: null,
|
|
114
|
+
error: 'LLM indicated significant change but provided no reason'
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Build result with timestamp
|
|
118
|
+
const result = {
|
|
119
|
+
is_significant: parsedResponse.is_significant,
|
|
120
|
+
reason: parsedResponse.reason,
|
|
121
|
+
timestamp: new Date().toISOString(),
|
|
122
|
+
};
|
|
123
|
+
// Include confidence if provided
|
|
124
|
+
if (typeof parsedResponse.confidence === 'number' &&
|
|
125
|
+
parsedResponse.confidence >= 0 &&
|
|
126
|
+
parsedResponse.confidence <= 1) {
|
|
127
|
+
result.confidence = parsedResponse.confidence;
|
|
128
|
+
}
|
|
129
|
+
logger_1.loggerInstance.info('Analysis completed successfully', {
|
|
130
|
+
is_significant: result.is_significant,
|
|
131
|
+
has_confidence: result.confidence !== undefined,
|
|
132
|
+
});
|
|
133
|
+
return { result, error: undefined };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
// Fail-open: log error and return descriptive error message
|
|
137
|
+
const errorObj = error;
|
|
138
|
+
let errorMessage;
|
|
139
|
+
// Check for specific error types and provide helpful messages
|
|
140
|
+
if (errorObj.status === 401) {
|
|
141
|
+
errorMessage = 'Invalid API key - please check your API key configuration';
|
|
142
|
+
logger_1.loggerInstance.warn('LLM API authentication failed', { error: errorObj });
|
|
143
|
+
}
|
|
144
|
+
else if (errorObj.status === 400 && errorObj.message?.includes('maximum context length')) {
|
|
145
|
+
// Extract token counts from error message if available
|
|
146
|
+
const tokenMatch = errorObj.message.match(/(\d+)\s+tokens/g);
|
|
147
|
+
errorMessage = 'Diff too large for model context window. Try:\n' +
|
|
148
|
+
' • Stage fewer files at once\n' +
|
|
149
|
+
' • Use a model with larger context window in cadr.yaml\n' +
|
|
150
|
+
' • Add ignore patterns to filter large files';
|
|
151
|
+
logger_1.loggerInstance.warn('LLM context length exceeded', {
|
|
152
|
+
error: errorObj,
|
|
153
|
+
tokens: tokenMatch,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else if (errorObj.status === 429) {
|
|
157
|
+
errorMessage = 'Rate limit exceeded - please try again later or check your API quota';
|
|
158
|
+
logger_1.loggerInstance.warn('LLM API rate limit exceeded', { error: errorObj });
|
|
159
|
+
}
|
|
160
|
+
else if (errorObj.code === 'ETIMEDOUT' || errorObj.message?.includes('timeout')) {
|
|
161
|
+
errorMessage = `Request timeout (${config.timeout_seconds}s) - the LLM took too long to respond`;
|
|
162
|
+
logger_1.loggerInstance.warn('LLM API request timeout', { error: errorObj });
|
|
163
|
+
}
|
|
164
|
+
else if (errorObj.code === 'ENOTFOUND' || errorObj.message?.includes('ENOTFOUND')) {
|
|
165
|
+
errorMessage = 'Network error - unable to reach LLM API (check internet connection)';
|
|
166
|
+
logger_1.loggerInstance.warn('LLM API network error', { error: errorObj });
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
errorMessage = `API error: ${errorObj.message || 'Unknown error occurred'}`;
|
|
170
|
+
logger_1.loggerInstance.warn('LLM API request failed', { error: errorObj });
|
|
171
|
+
}
|
|
172
|
+
return { result: null, error: errorMessage };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Generate ADR content using LLM
|
|
177
|
+
*
|
|
178
|
+
* @param config - Analysis configuration with API settings
|
|
179
|
+
* @param request - Generation request with code changes
|
|
180
|
+
* @returns Promise resolving to generation response with result or error
|
|
181
|
+
*/
|
|
182
|
+
async function generateADRContent(config, request) {
|
|
183
|
+
try {
|
|
184
|
+
// Check if API key is available
|
|
185
|
+
const apiKey = process.env[config.api_key_env];
|
|
186
|
+
if (!apiKey) {
|
|
187
|
+
logger_1.loggerInstance.warn('API key not found in environment for generation', {
|
|
188
|
+
api_key_env: config.api_key_env,
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
result: null,
|
|
192
|
+
error: `API key not found: ${config.api_key_env} environment variable is not set`
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
logger_1.loggerInstance.info('Sending generation request to LLM', {
|
|
196
|
+
provider: config.provider,
|
|
197
|
+
model: config.analysis_model,
|
|
198
|
+
file_count: request.file_paths.length,
|
|
199
|
+
});
|
|
200
|
+
const provider = (0, providers_1.getProvider)(config.provider);
|
|
201
|
+
const responseContent = await provider.analyze(request.generation_prompt, {
|
|
202
|
+
apiKey,
|
|
203
|
+
model: config.analysis_model, // Using same model per user request
|
|
204
|
+
timeoutMs: config.timeout_seconds * 1000,
|
|
205
|
+
});
|
|
206
|
+
if (!responseContent) {
|
|
207
|
+
logger_1.loggerInstance.warn('No response content from LLM for generation', {
|
|
208
|
+
provider: config.provider
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
result: null,
|
|
212
|
+
error: 'No response content from LLM'
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// Clean up the response - remove markdown code fences if LLM added them
|
|
216
|
+
let cleanedContent = responseContent.trim();
|
|
217
|
+
// Remove markdown code block if present
|
|
218
|
+
const codeBlockMatch = cleanedContent.match(/```(?:markdown|md)?\s*\n?([\s\S]*?)\n?```/);
|
|
219
|
+
if (codeBlockMatch) {
|
|
220
|
+
cleanedContent = codeBlockMatch[1].trim();
|
|
221
|
+
}
|
|
222
|
+
// Extract title from first line (should be # Title)
|
|
223
|
+
const titleMatch = cleanedContent.match(/^#\s+(.+)$/m);
|
|
224
|
+
const title = titleMatch ? titleMatch[1].trim() : 'Untitled Decision';
|
|
225
|
+
const result = {
|
|
226
|
+
content: cleanedContent,
|
|
227
|
+
title,
|
|
228
|
+
timestamp: new Date().toISOString(),
|
|
229
|
+
};
|
|
230
|
+
logger_1.loggerInstance.info('ADR generation completed successfully', {
|
|
231
|
+
title,
|
|
232
|
+
content_length: cleanedContent.length,
|
|
233
|
+
});
|
|
234
|
+
return { result, error: undefined };
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
// Fail-open: log error and return descriptive error message
|
|
238
|
+
const errorObj = error;
|
|
239
|
+
let errorMessage;
|
|
240
|
+
if (errorObj.status === 401) {
|
|
241
|
+
errorMessage = 'Invalid API key - please check your API key configuration';
|
|
242
|
+
logger_1.loggerInstance.warn('LLM API authentication failed during generation', { error: errorObj });
|
|
243
|
+
}
|
|
244
|
+
else if (errorObj.status === 400 && errorObj.message?.includes('maximum context length')) {
|
|
245
|
+
errorMessage = 'Diff too large for model context window';
|
|
246
|
+
logger_1.loggerInstance.warn('LLM context length exceeded during generation', { error: errorObj });
|
|
247
|
+
}
|
|
248
|
+
else if (errorObj.status === 429) {
|
|
249
|
+
errorMessage = 'Rate limit exceeded - please try again later';
|
|
250
|
+
logger_1.loggerInstance.warn('LLM API rate limit exceeded during generation', { error: errorObj });
|
|
251
|
+
}
|
|
252
|
+
else if (errorObj.code === 'ETIMEDOUT' || errorObj.message?.includes('timeout')) {
|
|
253
|
+
errorMessage = `Request timeout (${config.timeout_seconds}s)`;
|
|
254
|
+
logger_1.loggerInstance.warn('LLM API request timeout during generation', { error: errorObj });
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
errorMessage = `API error: ${errorObj.message || 'Unknown error occurred'}`;
|
|
258
|
+
logger_1.loggerInstance.warn('LLM API request failed during generation', { error: errorObj });
|
|
259
|
+
}
|
|
260
|
+
return { result: null, error: errorMessage };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=llm.js.map
|
package/dist/llm.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.test.d.ts","sourceRoot":"","sources":["../src/llm.test.ts"],"names":[],"mappings":""}
|