mcp-image 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/api/geminiClient.d.ts +55 -0
- package/dist/api/geminiClient.d.ts.map +1 -0
- package/dist/api/geminiClient.js +194 -0
- package/dist/api/geminiClient.js.map +1 -0
- package/dist/api/urlContextClient.d.ts +149 -0
- package/dist/api/urlContextClient.d.ts.map +1 -0
- package/dist/api/urlContextClient.js +320 -0
- package/dist/api/urlContextClient.js.map +1 -0
- package/dist/business/errorHandler.d.ts +97 -0
- package/dist/business/errorHandler.d.ts.map +1 -0
- package/dist/business/errorHandler.js +511 -0
- package/dist/business/errorHandler.js.map +1 -0
- package/dist/business/fileManager.d.ts +20 -0
- package/dist/business/fileManager.d.ts.map +1 -0
- package/dist/business/fileManager.js +112 -0
- package/dist/business/fileManager.js.map +1 -0
- package/dist/business/imageGenerator.d.ts +64 -0
- package/dist/business/imageGenerator.d.ts.map +1 -0
- package/dist/business/imageGenerator.js +147 -0
- package/dist/business/imageGenerator.js.map +1 -0
- package/dist/business/imageGeneratorRobust.d.ts +60 -0
- package/dist/business/imageGeneratorRobust.d.ts.map +1 -0
- package/dist/business/imageGeneratorRobust.js +242 -0
- package/dist/business/imageGeneratorRobust.js.map +1 -0
- package/dist/business/inputValidator.d.ts +29 -0
- package/dist/business/inputValidator.d.ts.map +1 -0
- package/dist/business/inputValidator.js +132 -0
- package/dist/business/inputValidator.js.map +1 -0
- package/dist/business/performanceManager.d.ts +88 -0
- package/dist/business/performanceManager.d.ts.map +1 -0
- package/dist/business/performanceManager.js +142 -0
- package/dist/business/performanceManager.js.map +1 -0
- package/dist/business/responseBuilder.d.ts +20 -0
- package/dist/business/responseBuilder.d.ts.map +1 -0
- package/dist/business/responseBuilder.js +162 -0
- package/dist/business/responseBuilder.js.map +1 -0
- package/dist/business/secureFileManager.d.ts +56 -0
- package/dist/business/secureFileManager.d.ts.map +1 -0
- package/dist/business/secureFileManager.js +185 -0
- package/dist/business/secureFileManager.js.map +1 -0
- package/dist/business/urlExtractor.d.ts +60 -0
- package/dist/business/urlExtractor.d.ts.map +1 -0
- package/dist/business/urlExtractor.js +144 -0
- package/dist/business/urlExtractor.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/server/concurrencyManager.d.ts +56 -0
- package/dist/server/concurrencyManager.d.ts.map +1 -0
- package/dist/server/concurrencyManager.js +133 -0
- package/dist/server/concurrencyManager.js.map +1 -0
- package/dist/server/errorHandler.d.ts +29 -0
- package/dist/server/errorHandler.d.ts.map +1 -0
- package/dist/server/errorHandler.js +93 -0
- package/dist/server/errorHandler.js.map +1 -0
- package/dist/server/mcpServer.d.ts +111 -0
- package/dist/server/mcpServer.d.ts.map +1 -0
- package/dist/server/mcpServer.js +353 -0
- package/dist/server/mcpServer.js.map +1 -0
- package/dist/types/mcp.d.ts +72 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +7 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/result.d.ts +27 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +31 -0
- package/dist/types/result.js.map +1 -0
- package/dist/utils/config.d.ts +26 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +53 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +84 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +218 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +80 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +223 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/security.d.ts +50 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +153 -0
- package/dist/utils/security.js.map +1 -0
- package/package.json +73 -0
- package/vitest.config.mjs +47 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* URL Context API client for processing URLs and extracting context
|
|
4
|
+
* Uses @google/genai SDK for URL context processing
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.UrlContextClient = void 0;
|
|
8
|
+
const urlExtractor_1 = require("../business/urlExtractor");
|
|
9
|
+
const result_1 = require("../types/result");
|
|
10
|
+
const errors_1 = require("../utils/errors");
|
|
11
|
+
/**
|
|
12
|
+
* Client for processing URLs and extracting context
|
|
13
|
+
* Basic implementation for Phase 2 - will be enhanced in later phases
|
|
14
|
+
*/
|
|
15
|
+
class UrlContextClient {
|
|
16
|
+
constructor(textClient) {
|
|
17
|
+
this.textClient = textClient;
|
|
18
|
+
/**
|
|
19
|
+
* Maximum number of retry attempts
|
|
20
|
+
*/
|
|
21
|
+
this.MAX_RETRIES = 2;
|
|
22
|
+
/**
|
|
23
|
+
* Timeout for URL context processing in milliseconds
|
|
24
|
+
*/
|
|
25
|
+
this.TIMEOUT_MS = 15000;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Process multiple URLs and extract context for image generation
|
|
29
|
+
* @param urls Array of URLs to process
|
|
30
|
+
* @param originalPrompt Original prompt containing URLs
|
|
31
|
+
* @returns Result containing URL context response with combined prompt or error
|
|
32
|
+
*/
|
|
33
|
+
async processUrls(urls, originalPrompt) {
|
|
34
|
+
try {
|
|
35
|
+
// Handle empty URL array
|
|
36
|
+
if (urls.length === 0) {
|
|
37
|
+
return (0, result_1.Ok)({
|
|
38
|
+
contextContent: '',
|
|
39
|
+
combinedPrompt: `Generate image: ${originalPrompt}`,
|
|
40
|
+
extractedInfo: {},
|
|
41
|
+
success: true,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Limit URLs to maximum allowed
|
|
45
|
+
const limitedUrls = urls.slice(0, UrlContextClient.MAX_URLS);
|
|
46
|
+
// Use retry mechanism with timeout
|
|
47
|
+
const result = await this.processUrlsWithRetry(limitedUrls, originalPrompt);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return (0, result_1.Err)(this.createProcessingError(error));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Process URLs with retry mechanism and timeout
|
|
56
|
+
* @param urls Array of URLs to process
|
|
57
|
+
* @param originalPrompt Original prompt containing URLs
|
|
58
|
+
* @returns Result containing URL context response with retry information
|
|
59
|
+
*/
|
|
60
|
+
async processUrlsWithRetry(urls, originalPrompt) {
|
|
61
|
+
let lastError;
|
|
62
|
+
for (let attempt = 0; attempt <= this.MAX_RETRIES; attempt++) {
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.processUrlsWithTimeout(urls, originalPrompt);
|
|
65
|
+
if (result.success) {
|
|
66
|
+
// Add retry information to extracted info
|
|
67
|
+
const enrichedExtractedInfo = {
|
|
68
|
+
...result.data.extractedInfo,
|
|
69
|
+
retryCount: attempt,
|
|
70
|
+
finalAttempt: attempt + 1,
|
|
71
|
+
maxRetries: this.MAX_RETRIES,
|
|
72
|
+
};
|
|
73
|
+
return (0, result_1.Ok)({
|
|
74
|
+
...result.data,
|
|
75
|
+
extractedInfo: enrichedExtractedInfo,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
lastError = result.error;
|
|
79
|
+
// Check if error is retryable
|
|
80
|
+
if (attempt < this.MAX_RETRIES && this.isRetryableError(result.error)) {
|
|
81
|
+
await this.delay(1000 * 2 ** attempt); // Exponential backoff
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
return (0, result_1.Err)(result.error);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
lastError = error instanceof Error ? error : new Error('Unknown error');
|
|
88
|
+
if (attempt === this.MAX_RETRIES) {
|
|
89
|
+
return (0, result_1.Err)(new errors_1.URLContextError(`Max retries exceeded: ${lastError.message}`, 'Try again later or check your network connection'));
|
|
90
|
+
}
|
|
91
|
+
if (this.isRetryableError(lastError)) {
|
|
92
|
+
await this.delay(1000 * 2 ** attempt); // Exponential backoff
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return (0, result_1.Err)(this.createProcessingError(lastError));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return (0, result_1.Err)(new errors_1.URLContextError(`Max retries exceeded: ${lastError?.message || 'Unknown error'}`, 'Check your network connection and try again'));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Process URLs with timeout protection
|
|
103
|
+
* @param urls Array of URLs to process
|
|
104
|
+
* @param originalPrompt Original prompt containing URLs
|
|
105
|
+
* @returns Result with timeout protection
|
|
106
|
+
*/
|
|
107
|
+
async processUrlsWithTimeout(urls, originalPrompt) {
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
const timeoutId = setTimeout(() => {
|
|
110
|
+
resolve((0, result_1.Err)(new errors_1.NetworkError('URL context processing timed out', 'Try reducing the number of URLs or check your network connection')));
|
|
111
|
+
}, this.TIMEOUT_MS);
|
|
112
|
+
this.processUrlsCore(urls, originalPrompt)
|
|
113
|
+
.then((result) => {
|
|
114
|
+
clearTimeout(timeoutId);
|
|
115
|
+
resolve(result);
|
|
116
|
+
})
|
|
117
|
+
.catch((error) => {
|
|
118
|
+
clearTimeout(timeoutId);
|
|
119
|
+
resolve((0, result_1.Err)(this.createProcessingError(error)));
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Core URL processing logic without retry/timeout
|
|
125
|
+
* @param urls Array of URLs to process
|
|
126
|
+
* @param originalPrompt Original prompt containing URLs
|
|
127
|
+
* @returns Result containing URL context response
|
|
128
|
+
*/
|
|
129
|
+
async processUrlsCore(urls, originalPrompt) {
|
|
130
|
+
// Process all URLs in a single context extraction request
|
|
131
|
+
const contextPrompt = this.buildContextPrompt(urls, originalPrompt);
|
|
132
|
+
const result = await this.textClient.generateText(contextPrompt);
|
|
133
|
+
if (!result.success) {
|
|
134
|
+
return (0, result_1.Err)(this.createContextError(result.error));
|
|
135
|
+
}
|
|
136
|
+
const contextContent = result.data.text || '';
|
|
137
|
+
// Combine context with original prompt
|
|
138
|
+
const combinedPrompt = this.combineContextWithPrompt([contextContent], originalPrompt, urls);
|
|
139
|
+
const extractedInfo = this.parseExtractedInfo(contextContent, urls.length);
|
|
140
|
+
return (0, result_1.Ok)({
|
|
141
|
+
contextContent,
|
|
142
|
+
combinedPrompt,
|
|
143
|
+
extractedInfo,
|
|
144
|
+
success: true,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a context extraction prompt for Gemini API
|
|
149
|
+
* @param urls Array of URLs to process
|
|
150
|
+
* @param originalPrompt Original prompt containing URLs
|
|
151
|
+
* @returns Formatted prompt for context extraction
|
|
152
|
+
*/
|
|
153
|
+
buildContextPrompt(urls, originalPrompt) {
|
|
154
|
+
const urlList = urls.map((url, index) => `${index + 1}. ${url}`).join('\n');
|
|
155
|
+
return `
|
|
156
|
+
Please analyze the following URLs and extract relevant context for image generation:
|
|
157
|
+
|
|
158
|
+
URLs to analyze:
|
|
159
|
+
${urlList}
|
|
160
|
+
|
|
161
|
+
Original prompt: ${originalPrompt}
|
|
162
|
+
|
|
163
|
+
Extract key information that would be relevant for generating an image based on these URLs. Focus on:
|
|
164
|
+
- Visual descriptions
|
|
165
|
+
- Key concepts or themes
|
|
166
|
+
- Relevant details for image creation
|
|
167
|
+
|
|
168
|
+
Provide a concise summary of the most relevant visual information.
|
|
169
|
+
`.trim();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Combine URL context with original prompt for image generation
|
|
173
|
+
* @param contextPrompts Array of context content from URLs
|
|
174
|
+
* @param originalPrompt Original prompt containing URLs
|
|
175
|
+
* @param urls Array of processed URLs
|
|
176
|
+
* @returns Combined prompt for image generation
|
|
177
|
+
*/
|
|
178
|
+
combineContextWithPrompt(contextPrompts, originalPrompt, urls) {
|
|
179
|
+
const cleanPrompt = this.cleanPromptFromUrls(originalPrompt);
|
|
180
|
+
const finalPrompt = cleanPrompt || originalPrompt;
|
|
181
|
+
const contextContent = this.formatContextContent(contextPrompts);
|
|
182
|
+
return this.formatCombinedPrompt(urls, contextContent, finalPrompt);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Remove URLs and clean up common action words from prompt
|
|
186
|
+
* @param originalPrompt Original prompt containing URLs
|
|
187
|
+
* @returns Cleaned prompt suitable for final instruction
|
|
188
|
+
*/
|
|
189
|
+
cleanPromptFromUrls(originalPrompt) {
|
|
190
|
+
// Remove URLs from original prompt to get clean instruction
|
|
191
|
+
let cleanPrompt = urlExtractor_1.URLExtractor.removeUrls(originalPrompt).trim();
|
|
192
|
+
// Enhanced cleaning: remove common action words that become awkward after URL removal
|
|
193
|
+
// e.g., "Create image of https://example.com with sunset" -> "with sunset"
|
|
194
|
+
const actionPatterns = [
|
|
195
|
+
/^(create|generate|make)\s+(an?\s+)?(image|picture|photo)\s+(of|from|based\s+on)\s*/i,
|
|
196
|
+
/^(show|display|illustrate)\s*/i,
|
|
197
|
+
];
|
|
198
|
+
for (const pattern of actionPatterns) {
|
|
199
|
+
cleanPrompt = cleanPrompt.replace(pattern, '').trim();
|
|
200
|
+
}
|
|
201
|
+
return cleanPrompt;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Format and clean context content from multiple sources
|
|
205
|
+
* @param contextPrompts Array of raw context content
|
|
206
|
+
* @returns Formatted context content
|
|
207
|
+
*/
|
|
208
|
+
formatContextContent(contextPrompts) {
|
|
209
|
+
return contextPrompts.filter((p) => p?.trim()).join('\n\n');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Format the final combined prompt with context and instruction sections
|
|
213
|
+
* @param urls Array of processed URLs
|
|
214
|
+
* @param contextContent Formatted context content
|
|
215
|
+
* @param finalPrompt Final instruction prompt
|
|
216
|
+
* @returns Complete combined prompt
|
|
217
|
+
*/
|
|
218
|
+
formatCombinedPrompt(urls, contextContent, finalPrompt) {
|
|
219
|
+
const urlList = urls.join(', ');
|
|
220
|
+
const displayContext = contextContent || '(No specific context extracted)';
|
|
221
|
+
return `Context from URLs (${urlList}):\n${displayContext}\n\nGenerate image: ${finalPrompt}`;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Create a standardized context error from API failure
|
|
225
|
+
* @param originalError The original error from text generation
|
|
226
|
+
* @returns Formatted URLContextError
|
|
227
|
+
*/
|
|
228
|
+
createContextError(originalError) {
|
|
229
|
+
return new errors_1.URLContextError(`URL context processing failed: ${originalError.message}`, 'Check your network connection and try again, or disable URL context processing');
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create appropriate error based on error type
|
|
233
|
+
* @param error The original error that occurred
|
|
234
|
+
* @returns Formatted error (NetworkError or URLContextError)
|
|
235
|
+
*/
|
|
236
|
+
createProcessingError(error) {
|
|
237
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
238
|
+
// Check if it's a network-related error
|
|
239
|
+
if (this.isNetworkError(error)) {
|
|
240
|
+
return new errors_1.NetworkError(`Network error during URL context processing: ${errorMessage}`, 'Check your internet connection and try again', error instanceof Error ? error : undefined);
|
|
241
|
+
}
|
|
242
|
+
// Generic URL context error
|
|
243
|
+
return new errors_1.URLContextError(`URL context processing error: ${errorMessage}`, 'Try again with fewer URLs or disable URL context processing');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Parse extracted information from context content
|
|
247
|
+
* @param contextContent The context content to parse
|
|
248
|
+
* @param processedUrlCount Number of URLs that were processed
|
|
249
|
+
* @returns Structured extracted information
|
|
250
|
+
*/
|
|
251
|
+
parseExtractedInfo(contextContent, processedUrlCount) {
|
|
252
|
+
// Enhanced implementation with content analysis
|
|
253
|
+
const wordCount = contextContent.split(/\s+/).filter((word) => word.length > 0).length;
|
|
254
|
+
const hasVisualDescriptions = /\b(color|image|visual|picture|photo|scene|view|appearance)\b/i.test(contextContent);
|
|
255
|
+
return {
|
|
256
|
+
processedUrls: processedUrlCount,
|
|
257
|
+
contentLength: contextContent.length,
|
|
258
|
+
wordCount,
|
|
259
|
+
processedAt: new Date().toISOString(),
|
|
260
|
+
hasContent: contextContent.length > 0,
|
|
261
|
+
hasVisualDescriptions,
|
|
262
|
+
contentPreview: contextContent.substring(0, 100) + (contextContent.length > 100 ? '...' : ''),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Check if an error is network-related
|
|
267
|
+
* @param error The error to check
|
|
268
|
+
* @returns True if it's a network error
|
|
269
|
+
*/
|
|
270
|
+
isNetworkError(error) {
|
|
271
|
+
if (error instanceof Error) {
|
|
272
|
+
const networkErrorCodes = [
|
|
273
|
+
'ECONNRESET',
|
|
274
|
+
'ECONNREFUSED',
|
|
275
|
+
'ETIMEDOUT',
|
|
276
|
+
'ENOTFOUND',
|
|
277
|
+
'ENETUNREACH',
|
|
278
|
+
];
|
|
279
|
+
const networkErrorKeywords = ['network', 'connection', 'timeout', 'unreachable', 'dns'];
|
|
280
|
+
return (networkErrorCodes.some((code) => error.message.includes(code) || error.code === code) || networkErrorKeywords.some((keyword) => error.message.toLowerCase().includes(keyword)));
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Check if an error is retryable
|
|
286
|
+
* @param error The error to check
|
|
287
|
+
* @returns True if the error should trigger a retry
|
|
288
|
+
*/
|
|
289
|
+
isRetryableError(error) {
|
|
290
|
+
// Network errors are retryable
|
|
291
|
+
if (this.isNetworkError(error)) {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
// Rate limit and temporary errors are retryable
|
|
295
|
+
const retryableKeywords = [
|
|
296
|
+
'rate limit',
|
|
297
|
+
'temporary',
|
|
298
|
+
'throttle',
|
|
299
|
+
'service unavailable',
|
|
300
|
+
'503',
|
|
301
|
+
'429',
|
|
302
|
+
];
|
|
303
|
+
const errorMessage = error.message.toLowerCase();
|
|
304
|
+
return retryableKeywords.some((keyword) => errorMessage.includes(keyword));
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Add a delay for exponential backoff
|
|
308
|
+
* @param ms Milliseconds to delay
|
|
309
|
+
* @returns Promise that resolves after the delay
|
|
310
|
+
*/
|
|
311
|
+
async delay(ms) {
|
|
312
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.UrlContextClient = UrlContextClient;
|
|
316
|
+
/**
|
|
317
|
+
* Maximum number of URLs to process (performance consideration)
|
|
318
|
+
*/
|
|
319
|
+
UrlContextClient.MAX_URLS = 10;
|
|
320
|
+
//# sourceMappingURL=urlContextClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlContextClient.js","sourceRoot":"","sources":["../../src/api/urlContextClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive Error Handler for complete error management
|
|
3
|
+
* Provides error classification, recovery mechanisms, and structured response generation
|
|
4
|
+
*/
|
|
5
|
+
import type { McpToolResponse } from '../types/mcp';
|
|
6
|
+
import type { Result } from '../types/result';
|
|
7
|
+
import { BaseError } from '../utils/errors';
|
|
8
|
+
/**
|
|
9
|
+
* Structured logger interface for error handling
|
|
10
|
+
*/
|
|
11
|
+
interface StructuredLogger {
|
|
12
|
+
error(context: string, message: string, error: Error, metadata?: Record<string, unknown>): void;
|
|
13
|
+
warn(context: string, message: string, metadata?: Record<string, unknown>): void;
|
|
14
|
+
info(context: string, message: string, metadata?: Record<string, unknown>): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Comprehensive error handler with classification and recovery capabilities
|
|
18
|
+
*/
|
|
19
|
+
export declare class ComprehensiveErrorHandler {
|
|
20
|
+
private logger;
|
|
21
|
+
constructor(logger?: StructuredLogger);
|
|
22
|
+
/**
|
|
23
|
+
* Handle any error and convert it to a structured BaseError Result
|
|
24
|
+
* @param error Error or unknown value to handle
|
|
25
|
+
* @param context Context string for logging
|
|
26
|
+
* @param operation Operation name for logging
|
|
27
|
+
* @returns Result with structured error
|
|
28
|
+
*/
|
|
29
|
+
handleError<T>(error: Error | unknown, context: string, operation: string): Result<T, BaseError>;
|
|
30
|
+
/**
|
|
31
|
+
* Classify a generic Error into appropriate BaseError subclass
|
|
32
|
+
* @param error Original error to classify
|
|
33
|
+
* @param context Context for additional information
|
|
34
|
+
* @returns Classified BaseError
|
|
35
|
+
*/
|
|
36
|
+
private classifyError;
|
|
37
|
+
/**
|
|
38
|
+
* Check if error is API-related with enhanced pattern matching
|
|
39
|
+
*/
|
|
40
|
+
private isAPIError;
|
|
41
|
+
/**
|
|
42
|
+
* Check if error is network-related with enhanced pattern matching
|
|
43
|
+
*/
|
|
44
|
+
private isNetworkError;
|
|
45
|
+
/**
|
|
46
|
+
* Check if error is file operation related
|
|
47
|
+
*/
|
|
48
|
+
private isFileError;
|
|
49
|
+
/**
|
|
50
|
+
* Check if error is concurrency-related
|
|
51
|
+
*/
|
|
52
|
+
private isConcurrencyError;
|
|
53
|
+
/**
|
|
54
|
+
* Check if error is security-related
|
|
55
|
+
*/
|
|
56
|
+
private isSecurityError;
|
|
57
|
+
/**
|
|
58
|
+
* Check if error is validation-related
|
|
59
|
+
*/
|
|
60
|
+
private isValidationError;
|
|
61
|
+
/**
|
|
62
|
+
* Convert BaseError to MCP tool response format
|
|
63
|
+
* @param error BaseError to convert
|
|
64
|
+
* @returns MCP tool response
|
|
65
|
+
*/
|
|
66
|
+
convertToMcpResponse(error: BaseError): McpToolResponse;
|
|
67
|
+
/**
|
|
68
|
+
* Sanitize error context to prevent sensitive information leakage
|
|
69
|
+
* @param context Original context object
|
|
70
|
+
* @returns Sanitized context object
|
|
71
|
+
*/
|
|
72
|
+
private sanitizeContext;
|
|
73
|
+
/**
|
|
74
|
+
* Check if an error is retryable with enhanced retry logic
|
|
75
|
+
* @param error Error to check
|
|
76
|
+
* @returns True if error should be retried
|
|
77
|
+
*/
|
|
78
|
+
isRetryableError(error: BaseError): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Get retry delay in milliseconds with adaptive exponential backoff
|
|
81
|
+
* @param attempt Current attempt number (1-based)
|
|
82
|
+
* @param error Optional error to adapt delay based on error type
|
|
83
|
+
* @param baseDelay Base delay in milliseconds (default: 1000)
|
|
84
|
+
* @returns Delay in milliseconds
|
|
85
|
+
*/
|
|
86
|
+
getRetryDelay(attempt: number, error?: BaseError, baseDelay?: number): number;
|
|
87
|
+
/**
|
|
88
|
+
* Get human-readable retry advice based on error type and attempt
|
|
89
|
+
* @param error Error that occurred
|
|
90
|
+
* @param attempt Current attempt number
|
|
91
|
+
* @param maxAttempts Maximum retry attempts
|
|
92
|
+
* @returns Human-readable retry advice
|
|
93
|
+
*/
|
|
94
|
+
getRetryAdvice(error: BaseError, attempt: number, maxAttempts: number): string;
|
|
95
|
+
}
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=errorHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/business/errorHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,EACL,SAAS,EASV,MAAM,iBAAiB,CAAA;AAGxB;;GAEG;AACH,UAAU,gBAAgB;IACxB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC/F,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAChF,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CACjF;AAED;;GAEG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,CAAC,EAAE,gBAAgB;IAIrC;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC;IA0BhG;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA8CrB;;OAEG;IACH,OAAO,CAAC,UAAU;IA2DlB;;OAEG;IACH,OAAO,CAAC,cAAc;IA4EtB;;OAEG;IACH,OAAO,CAAC,WAAW;IAwBnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe;IAuBvD;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA+BvB;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAiG3C;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,SAAO,GAAG,MAAM;IA6C3E;;;;;;OAMG;IACH,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAkB/E"}
|