research-powerpack-mcp 3.0.14 → 3.1.1

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 (37) hide show
  1. package/dist/clients/reddit.d.ts +9 -1
  2. package/dist/clients/reddit.d.ts.map +1 -1
  3. package/dist/clients/reddit.js +121 -41
  4. package/dist/clients/reddit.js.map +1 -1
  5. package/dist/clients/research.d.ts +16 -0
  6. package/dist/clients/research.d.ts.map +1 -1
  7. package/dist/clients/research.js +135 -31
  8. package/dist/clients/research.js.map +1 -1
  9. package/dist/clients/scraper.d.ts +27 -1
  10. package/dist/clients/scraper.d.ts.map +1 -1
  11. package/dist/clients/scraper.js +206 -101
  12. package/dist/clients/scraper.js.map +1 -1
  13. package/dist/clients/search.d.ts +15 -0
  14. package/dist/clients/search.d.ts.map +1 -1
  15. package/dist/clients/search.js +174 -52
  16. package/dist/clients/search.js.map +1 -1
  17. package/dist/index.d.ts +4 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +51 -6
  20. package/dist/index.js.map +1 -1
  21. package/dist/services/llm-processor.d.ts +18 -0
  22. package/dist/services/llm-processor.d.ts.map +1 -1
  23. package/dist/services/llm-processor.js +174 -24
  24. package/dist/services/llm-processor.js.map +1 -1
  25. package/dist/tools/research.d.ts +5 -0
  26. package/dist/tools/research.d.ts.map +1 -1
  27. package/dist/tools/research.js +63 -18
  28. package/dist/tools/research.js.map +1 -1
  29. package/dist/tools/scrape.d.ts +5 -0
  30. package/dist/tools/scrape.d.ts.map +1 -1
  31. package/dist/tools/scrape.js +144 -81
  32. package/dist/tools/scrape.js.map +1 -1
  33. package/dist/utils/errors.d.ts +79 -1
  34. package/dist/utils/errors.d.ts.map +1 -1
  35. package/dist/utils/errors.js +253 -22
  36. package/dist/utils/errors.js.map +1 -1
  37. package/package.json +1 -1
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * LLM Processor for content extraction
3
3
  * Uses OpenRouter via OPENROUTER_API_KEY for AI-powered content filtering
4
+ * Implements robust retry logic and NEVER throws
4
5
  */
5
6
  import OpenAI from 'openai';
6
7
  import { RESEARCH, LLM_EXTRACTION, getCapabilities } from '../config/index.js';
8
+ import { classifyError, sleep, ErrorCode, } from '../utils/errors.js';
9
+ // LLM-specific retry configuration
10
+ const LLM_RETRY_CONFIG = {
11
+ maxRetries: 3,
12
+ baseDelayMs: 2000,
13
+ maxDelayMs: 30000,
14
+ };
15
+ // OpenRouter/OpenAI specific retryable error codes (using Set for type-safe lookup)
16
+ const RETRYABLE_LLM_ERROR_CODES = new Set([
17
+ 'rate_limit_exceeded',
18
+ 'server_error',
19
+ 'timeout',
20
+ 'service_unavailable',
21
+ ]);
7
22
  let llmClient = null;
8
23
  export function createLLMProcessor() {
9
24
  if (!getCapabilities().llmExtraction)
@@ -13,41 +28,176 @@ export function createLLMProcessor() {
13
28
  baseURL: RESEARCH.BASE_URL,
14
29
  apiKey: RESEARCH.API_KEY,
15
30
  timeout: 120000,
31
+ maxRetries: 0, // We handle retries ourselves for more control
16
32
  });
17
33
  }
18
34
  return llmClient;
19
35
  }
36
+ /**
37
+ * Check if an LLM error is retryable
38
+ */
39
+ function isRetryableLLMError(error) {
40
+ if (!error)
41
+ return false;
42
+ const err = error;
43
+ // Check HTTP status codes
44
+ const status = err.status;
45
+ if (status === 429 || status === 500 || status === 502 || status === 503 || status === 504) {
46
+ return true;
47
+ }
48
+ // Check error codes from OpenAI/OpenRouter
49
+ const errorCode = err.code || err.error?.code || err.error?.type;
50
+ if (errorCode && RETRYABLE_LLM_ERROR_CODES.has(errorCode)) {
51
+ return true;
52
+ }
53
+ // Check message for common patterns
54
+ const message = (err.message || '').toLowerCase();
55
+ if (message.includes('rate limit') ||
56
+ message.includes('timeout') ||
57
+ message.includes('timed out') ||
58
+ message.includes('service unavailable') ||
59
+ message.includes('server error') ||
60
+ message.includes('connection') ||
61
+ message.includes('econnreset')) {
62
+ return true;
63
+ }
64
+ return false;
65
+ }
66
+ /**
67
+ * Calculate backoff delay with jitter for LLM retries
68
+ */
69
+ function calculateLLMBackoff(attempt) {
70
+ const exponentialDelay = LLM_RETRY_CONFIG.baseDelayMs * Math.pow(2, attempt);
71
+ const jitter = Math.random() * 0.3 * exponentialDelay;
72
+ return Math.min(exponentialDelay + jitter, LLM_RETRY_CONFIG.maxDelayMs);
73
+ }
74
+ /**
75
+ * Process content with LLM extraction
76
+ * NEVER throws - always returns a valid LLMResult
77
+ * Implements retry logic with exponential backoff for transient failures
78
+ */
20
79
  export async function processContentWithLLM(content, config, processor) {
21
- if (!config.use_llm || !processor || !content?.trim()) {
80
+ // Early returns for invalid/skip conditions
81
+ if (!config.use_llm) {
22
82
  return { content, processed: false };
23
83
  }
24
- const prompt = config.what_to_extract
25
- ? `Extract and clean the following content. Focus on: ${config.what_to_extract}\n\nContent:\n${content}`
26
- : `Clean and extract the main content from the following text, removing navigation, ads, and irrelevant elements:\n\n${content}`;
27
- try {
28
- console.error(`[LLM Processor] Using model: ${LLM_EXTRACTION.MODEL}, max_tokens: ${config.max_tokens || LLM_EXTRACTION.MAX_TOKENS}, reasoning: ${LLM_EXTRACTION.ENABLE_REASONING}`);
29
- // Build request body with reasoning support for gpt-oss models
30
- const requestBody = {
31
- model: LLM_EXTRACTION.MODEL,
32
- messages: [{ role: 'user', content: prompt }],
33
- max_tokens: config.max_tokens || LLM_EXTRACTION.MAX_TOKENS,
84
+ if (!processor) {
85
+ return {
86
+ content,
87
+ processed: false,
88
+ error: 'LLM processor not available (OPENROUTER_API_KEY not set)',
89
+ errorDetails: {
90
+ code: ErrorCode.AUTH_ERROR,
91
+ message: 'LLM processor not available',
92
+ retryable: false,
93
+ },
34
94
  };
35
- // Add reasoning parameter if enabled (for models that support it like gpt-oss-120b)
36
- if (LLM_EXTRACTION.ENABLE_REASONING) {
37
- requestBody.reasoning = { enabled: true };
95
+ }
96
+ if (!content?.trim()) {
97
+ return { content: content || '', processed: false, error: 'Empty content provided' };
98
+ }
99
+ // Truncate extremely long content to avoid token limits
100
+ const maxInputChars = 100000; // ~25k tokens
101
+ const truncatedContent = content.length > maxInputChars
102
+ ? content.substring(0, maxInputChars) + '\n\n[Content truncated due to length]'
103
+ : content;
104
+ const prompt = config.what_to_extract
105
+ ? `Extract and clean the following content. Focus on: ${config.what_to_extract}\n\nContent:\n${truncatedContent}`
106
+ : `Clean and extract the main content from the following text, removing navigation, ads, and irrelevant elements:\n\n${truncatedContent}`;
107
+ // Build request body
108
+ const requestBody = {
109
+ model: LLM_EXTRACTION.MODEL,
110
+ messages: [{ role: 'user', content: prompt }],
111
+ max_tokens: config.max_tokens || LLM_EXTRACTION.MAX_TOKENS,
112
+ };
113
+ if (LLM_EXTRACTION.ENABLE_REASONING) {
114
+ requestBody.reasoning = { enabled: true };
115
+ }
116
+ let lastError;
117
+ // Retry loop
118
+ for (let attempt = 0; attempt <= LLM_RETRY_CONFIG.maxRetries; attempt++) {
119
+ try {
120
+ if (attempt === 0) {
121
+ console.error(`[LLM Processor] Starting extraction with ${LLM_EXTRACTION.MODEL}`);
122
+ }
123
+ else {
124
+ console.error(`[LLM Processor] Retry attempt ${attempt}/${LLM_RETRY_CONFIG.maxRetries}`);
125
+ }
126
+ const response = await processor.chat.completions.create(requestBody);
127
+ const result = response.choices?.[0]?.message?.content;
128
+ if (result && result.trim()) {
129
+ console.error(`[LLM Processor] Successfully extracted ${result.length} characters`);
130
+ return { content: result, processed: true };
131
+ }
132
+ // Empty response - not retryable
133
+ console.error('[LLM Processor] Received empty response from LLM');
134
+ return {
135
+ content,
136
+ processed: false,
137
+ error: 'LLM returned empty response',
138
+ errorDetails: {
139
+ code: ErrorCode.INTERNAL_ERROR,
140
+ message: 'LLM returned empty response',
141
+ retryable: false,
142
+ },
143
+ };
38
144
  }
39
- const response = await processor.chat.completions.create(requestBody);
40
- const result = response.choices?.[0]?.message?.content;
41
- if (result) {
42
- console.error(`[LLM Processor] Successfully extracted ${result.length} characters`);
43
- return { content: result, processed: true };
145
+ catch (err) {
146
+ lastError = classifyError(err);
147
+ // Log the error
148
+ const errDetails = err;
149
+ console.error(`[LLM Processor] Error (attempt ${attempt + 1}): ${lastError.message}`, {
150
+ status: errDetails.status,
151
+ code: errDetails.code,
152
+ retryable: isRetryableLLMError(err),
153
+ });
154
+ // Check if we should retry
155
+ if (isRetryableLLMError(err) && attempt < LLM_RETRY_CONFIG.maxRetries) {
156
+ const delayMs = calculateLLMBackoff(attempt);
157
+ console.error(`[LLM Processor] Retrying in ${delayMs}ms...`);
158
+ await sleep(delayMs);
159
+ continue;
160
+ }
161
+ // Non-retryable or max retries reached
162
+ break;
44
163
  }
45
- return { content, processed: false, error: 'No content in response' };
46
164
  }
47
- catch (err) {
48
- const error = err instanceof Error ? err.message : String(err);
49
- console.error(`[LLM Processor] Error: ${error}`);
50
- return { content, processed: false, error };
165
+ // All attempts failed - return original content with error info
166
+ const errorMessage = lastError?.message || 'Unknown LLM error';
167
+ console.error(`[LLM Processor] All attempts failed: ${errorMessage}. Returning original content.`);
168
+ return {
169
+ content, // Return original content as fallback
170
+ processed: false,
171
+ error: `LLM extraction failed: ${errorMessage}`,
172
+ errorDetails: lastError || {
173
+ code: ErrorCode.UNKNOWN_ERROR,
174
+ message: errorMessage,
175
+ retryable: false,
176
+ },
177
+ };
178
+ }
179
+ /**
180
+ * Process multiple contents with LLM in parallel with rate limiting
181
+ * NEVER throws - always returns results array
182
+ */
183
+ export async function processMultipleWithLLM(contents, config, processor, concurrency = 3) {
184
+ if (!config.use_llm || !processor || contents.length === 0) {
185
+ return contents.map(c => ({ content: c.content, processed: false, url: c.url }));
186
+ }
187
+ const results = [];
188
+ // Process in batches to avoid overwhelming the API
189
+ for (let i = 0; i < contents.length; i += concurrency) {
190
+ const batch = contents.slice(i, i + concurrency);
191
+ const batchResults = await Promise.all(batch.map(async ({ content, url }) => {
192
+ const result = await processContentWithLLM(content, config, processor);
193
+ return { ...result, url };
194
+ }));
195
+ results.push(...batchResults);
196
+ // Small delay between batches if more batches to process
197
+ if (i + concurrency < contents.length) {
198
+ await sleep(500);
199
+ }
51
200
  }
201
+ return results;
52
202
  }
53
203
  //# sourceMappingURL=llm-processor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-processor.js","sourceRoot":"","sources":["../../src/services/llm-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAc/E,IAAI,SAAS,GAAkB,IAAI,CAAC;AAEpC,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC,eAAe,EAAE,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAElD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,IAAI,MAAM,CAAC;YACrB,OAAO,EAAE,QAAQ,CAAC,QAAQ;YAC1B,MAAM,EAAE,QAAQ,CAAC,OAAO;YACxB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAe,EACf,MAAwB,EACxB,SAAyB;IAEzB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe;QACnC,CAAC,CAAC,sDAAsD,MAAM,CAAC,eAAe,iBAAiB,OAAO,EAAE;QACxG,CAAC,CAAC,qHAAqH,OAAO,EAAE,CAAC;IAEnI,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,gCAAgC,cAAc,CAAC,KAAK,iBAAiB,MAAM,CAAC,UAAU,IAAI,cAAc,CAAC,UAAU,gBAAgB,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAEpL,+DAA+D;QAC/D,MAAM,WAAW,GAAQ;YACvB,KAAK,EAAE,cAAc,CAAC,KAAK;YAC3B,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC7C,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,cAAc,CAAC,UAAU;SAC3D,CAAC;QAEF,oFAAoF;QACpF,IAAI,cAAc,CAAC,gBAAgB,EAAE,CAAC;YACpC,WAAW,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;QACvD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,0CAA0C,MAAM,CAAC,MAAM,aAAa,CAAC,CAAC;YACpF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IACxE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;QACjD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"llm-processor.js","sourceRoot":"","sources":["../../src/services/llm-processor.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,16 @@
1
1
  /**
2
2
  * Deep Research Tool Handler - Batch processing with dynamic token allocation
3
+ * Implements robust error handling that NEVER crashes
3
4
  */
4
5
  import type { DeepResearchParams } from '../schemas/deep-research.js';
5
6
  interface ResearchOptions {
6
7
  sessionId?: string;
7
8
  logger?: (level: 'info' | 'error' | 'debug', message: string, sessionId: string) => Promise<void>;
8
9
  }
10
+ /**
11
+ * Handle deep research request
12
+ * NEVER throws - always returns a valid response
13
+ */
9
14
  export declare function handleDeepResearch(params: DeepResearchParams, options?: ResearchOptions): Promise<{
10
15
  content: string;
11
16
  structuredContent: object;
@@ -1 +1 @@
1
- {"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAWtE,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnG;AA+BD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CA2GzD"}
1
+ {"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAWtE,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnG;AAiDD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAoIzD"}
@@ -1,17 +1,33 @@
1
1
  /**
2
2
  * Deep Research Tool Handler - Batch processing with dynamic token allocation
3
+ * Implements robust error handling that NEVER crashes
3
4
  */
4
5
  import { ResearchClient } from '../clients/research.js';
5
6
  import { FileAttachmentService } from '../services/file-attachment.js';
6
7
  import { RESEARCH } from '../config/index.js';
7
- import { createSimpleError } from '../utils/errors.js';
8
+ import { classifyError } from '../utils/errors.js';
8
9
  // Constants
9
10
  const TOTAL_TOKEN_BUDGET = 32000;
10
- const MIN_QUESTIONS = 2;
11
+ const MIN_QUESTIONS = 1; // Allow single question for flexibility
11
12
  const MAX_QUESTIONS = 10;
12
13
  function calculateTokenAllocation(questionCount) {
14
+ if (questionCount <= 0)
15
+ return TOTAL_TOKEN_BUDGET;
13
16
  return Math.floor(TOTAL_TOKEN_BUDGET / questionCount);
14
17
  }
18
+ /**
19
+ * Safe logger wrapper - NEVER throws
20
+ */
21
+ async function safeLog(logger, sessionId, level, message) {
22
+ if (!logger || !sessionId)
23
+ return;
24
+ try {
25
+ await logger(level, message, sessionId);
26
+ }
27
+ catch {
28
+ console.error(`[Research Tool] Logger failed: ${message}`);
29
+ }
30
+ }
15
31
  const SYSTEM_PROMPT = `You are an expert research consultant. Provide evidence-based, multi-perspective analysis.
16
32
 
17
33
  METHODOLOGY:
@@ -28,14 +44,18 @@ FORMAT (high info density):
28
44
  - WHAT'S CHANGING: Recent developments
29
45
 
30
46
  Be dense with insights, light on filler. Use examples and citations.`;
47
+ /**
48
+ * Handle deep research request
49
+ * NEVER throws - always returns a valid response
50
+ */
31
51
  export async function handleDeepResearch(params, options = {}) {
32
52
  const { sessionId, logger } = options;
33
- const questions = params.questions;
53
+ const questions = params.questions || [];
34
54
  // Validation
35
55
  if (questions.length < MIN_QUESTIONS) {
36
56
  return {
37
- content: `# ❌ Error\n\nMinimum ${MIN_QUESTIONS} research questions required. Received: ${questions.length}`,
38
- structuredContent: { error: true, message: `Minimum ${MIN_QUESTIONS} questions required` },
57
+ content: `# ❌ Error\n\nMinimum ${MIN_QUESTIONS} research question(s) required. Received: ${questions.length}`,
58
+ structuredContent: { error: true, message: `Minimum ${MIN_QUESTIONS} question(s) required` },
39
59
  };
40
60
  }
41
61
  if (questions.length > MAX_QUESTIONS) {
@@ -45,21 +65,37 @@ export async function handleDeepResearch(params, options = {}) {
45
65
  };
46
66
  }
47
67
  const tokensPerQuestion = calculateTokenAllocation(questions.length);
48
- if (sessionId && logger) {
49
- await logger('info', `Starting batch research: ${questions.length} questions, ${tokensPerQuestion.toLocaleString()} tokens/question`, sessionId);
68
+ await safeLog(logger, sessionId, 'info', `Starting batch research: ${questions.length} questions, ${tokensPerQuestion.toLocaleString()} tokens/question`);
69
+ // Initialize client safely
70
+ let client;
71
+ try {
72
+ client = new ResearchClient();
73
+ }
74
+ catch (error) {
75
+ const err = classifyError(error);
76
+ return {
77
+ content: `# ❌ Error\n\nFailed to initialize research client: ${err.message}`,
78
+ structuredContent: { error: true, message: `Failed to initialize: ${err.message}` },
79
+ };
50
80
  }
51
- const client = new ResearchClient();
52
81
  const fileService = new FileAttachmentService();
53
82
  const results = [];
54
- // Process all questions in parallel
83
+ // Process all questions in parallel - each handler NEVER throws
55
84
  const researchPromises = questions.map(async (q, index) => {
56
85
  try {
57
86
  // Enhance question with file attachments if present
58
87
  let enhancedQuestion = q.question;
59
88
  if (q.file_attachments && q.file_attachments.length > 0) {
60
- const attachmentsMarkdown = await fileService.formatAttachments(q.file_attachments);
61
- enhancedQuestion = q.question + attachmentsMarkdown;
89
+ try {
90
+ const attachmentsMarkdown = await fileService.formatAttachments(q.file_attachments);
91
+ enhancedQuestion = q.question + attachmentsMarkdown;
92
+ }
93
+ catch {
94
+ // If attachment processing fails, continue with original question
95
+ console.error(`[Research] Failed to process attachments for question ${index + 1}`);
96
+ }
62
97
  }
98
+ // ResearchClient.research() now returns error in response instead of throwing
63
99
  const response = await client.research({
64
100
  question: enhancedQuestion,
65
101
  systemPrompt: SYSTEM_PROMPT,
@@ -67,20 +103,31 @@ export async function handleDeepResearch(params, options = {}) {
67
103
  maxSearchResults: Math.min(RESEARCH.MAX_URLS, 20),
68
104
  maxTokens: tokensPerQuestion,
69
105
  });
106
+ // Check if response contains an error
107
+ if (response.error) {
108
+ return {
109
+ question: q.question,
110
+ content: response.content || '',
111
+ success: false,
112
+ error: response.error.message,
113
+ };
114
+ }
70
115
  return {
71
116
  question: q.question,
72
- content: response.content,
73
- success: true,
117
+ content: response.content || '',
118
+ success: !!response.content,
74
119
  tokensUsed: response.usage?.totalTokens,
120
+ error: response.content ? undefined : 'Empty response received',
75
121
  };
76
122
  }
77
123
  catch (error) {
78
- const simpleError = createSimpleError(error);
124
+ // This catch is a safety net - ResearchClient should not throw
125
+ const structuredError = classifyError(error);
79
126
  return {
80
127
  question: q.question,
81
128
  content: '',
82
129
  success: false,
83
- error: simpleError.message,
130
+ error: structuredError.message,
84
131
  };
85
132
  }
86
133
  });
@@ -108,9 +155,7 @@ export async function handleDeepResearch(params, options = {}) {
108
155
  }
109
156
  markdown += `---\n\n`;
110
157
  }
111
- if (sessionId && logger) {
112
- await logger('info', `Research completed: ${successful.length}/${questions.length} successful, ${totalTokens.toLocaleString()} tokens`, sessionId);
113
- }
158
+ await safeLog(logger, sessionId, 'info', `Research completed: ${successful.length}/${questions.length} successful, ${totalTokens.toLocaleString()} tokens`);
114
159
  return {
115
160
  content: markdown.trim(),
116
161
  structuredContent: {
@@ -1 +1 @@
1
- {"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAyB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,YAAY;AACZ,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,wCAAwC;AACjE,MAAM,aAAa,GAAG,EAAE,CAAC;AAezB,SAAS,wBAAwB,CAAC,aAAqB;IACrD,IAAI,aAAa,IAAI,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,aAAa,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CACpB,MAAiC,EACjC,SAA6B,EAC7B,KAAiC,EACjC,OAAe;IAEf,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;QAAE,OAAO;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;qEAe+C,CAAC;AAEtE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAA0B,EAC1B,UAA2B,EAAE;IAE7B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;IAEzC,aAAa;IACb,IAAI,SAAS,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QACrC,OAAO;YACL,OAAO,EAAE,wBAAwB,aAAa,6CAA6C,SAAS,CAAC,MAAM,EAAE;YAC7G,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,aAAa,uBAAuB,EAAE;SAC7F,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QACrC,OAAO;YACL,OAAO,EAAE,wBAAwB,aAAa,0CAA0C,SAAS,CAAC,MAAM,EAAE;YAC1G,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,aAAa,oBAAoB,EAAE;SAC1F,CAAC;IACJ,CAAC;IAED,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAErE,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,4BAA4B,SAAS,CAAC,MAAM,eAAe,iBAAiB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAE1J,2BAA2B;IAC3B,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO;YACL,OAAO,EAAE,sDAAsD,GAAG,CAAC,OAAO,EAAE;YAC5E,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,yBAAyB,GAAG,CAAC,OAAO,EAAE,EAAE;SACpF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAChD,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,gEAAgE;IAChE,MAAM,gBAAgB,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAA2B,EAAE;QACjF,IAAI,CAAC;YACH,oDAAoD;YACpD,IAAI,gBAAgB,GAAG,CAAC,CAAC,QAAQ,CAAC;YAClC,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,mBAAmB,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBACpF,gBAAgB,GAAG,CAAC,CAAC,QAAQ,GAAG,mBAAmB,CAAC;gBACtD,CAAC;gBAAC,MAAM,CAAC;oBACP,kEAAkE;oBAClE,OAAO,CAAC,KAAK,CAAC,yDAAyD,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;gBACtF,CAAC;YACH,CAAC;YAED,8EAA8E;YAC9E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;gBACrC,QAAQ,EAAE,gBAAgB;gBAC1B,YAAY,EAAE,aAAa;gBAC3B,eAAe,EAAE,QAAQ,CAAC,gBAAgB;gBAC1C,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACjD,SAAS,EAAE,iBAAiB;aAC7B,CAAC,CAAC;YAEH,sCAAsC;YACtC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO;oBACL,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;oBAC/B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO;iBAC9B,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;gBAC/B,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO;gBAC3B,UAAU,EAAE,QAAQ,CAAC,KAAK,EAAE,WAAW;gBACvC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB;aAChE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,+DAA+D;YAC/D,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YAC7C,OAAO;gBACL,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,eAAe,CAAC,OAAO;aAC/B,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IAE5B,wBAAwB;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEhF,IAAI,QAAQ,GAAG,4BAA4B,SAAS,CAAC,MAAM,iBAAiB,CAAC;IAC7E,QAAQ,IAAI,yBAAyB,iBAAiB,CAAC,cAAc,EAAE,qBAAqB,SAAS,CAAC,MAAM,eAAe,kBAAkB,CAAC,cAAc,EAAE,kBAAkB,CAAC;IACjL,QAAQ,IAAI,iBAAiB,UAAU,CAAC,MAAM,mBAAmB,MAAM,CAAC,MAAM,gBAAgB,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC7I,QAAQ,IAAI,SAAS,CAAC;IAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,QAAQ,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAE/G,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACd,QAAQ,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC;YAC/B,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBACjB,QAAQ,IAAI,iBAAiB,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC;YACpE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,IAAI,gBAAgB,CAAC,CAAC,KAAK,MAAM,CAAC;QAC5C,CAAC;QAED,QAAQ,IAAI,SAAS,CAAC;IACxB,CAAC;IAED,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,UAAU,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,gBAAgB,WAAW,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAE5J,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE;QACxB,iBAAiB,EAAE;YACjB,cAAc,EAAE,SAAS,CAAC,MAAM;YAChC,UAAU,EAAE,UAAU,CAAC,MAAM;YAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,iBAAiB;YACjB,eAAe,EAAE,WAAW;YAC5B,OAAO;SACR;KACF,CAAC;AACJ,CAAC"}
@@ -1,11 +1,16 @@
1
1
  /**
2
2
  * Scrape Links Tool Handler
3
+ * Implements robust error handling that NEVER crashes the MCP server
3
4
  */
4
5
  import type { ScrapeLinksParams, ScrapeLinksOutput } from '../schemas/scrape-links.js';
5
6
  interface ToolOptions {
6
7
  sessionId?: string;
7
8
  logger?: (level: 'info' | 'error' | 'debug', message: string, sessionId: string) => Promise<void>;
8
9
  }
10
+ /**
11
+ * Handle scrape links request
12
+ * NEVER throws - always returns a valid response with content and metadata
13
+ */
9
14
  export declare function handleScrapeLinks(params: ScrapeLinksParams, options?: ToolOptions): Promise<{
10
15
  content: string;
11
16
  structuredContent: ScrapeLinksOutput;
@@ -1 +1 @@
1
- {"version":3,"file":"scrape.d.ts","sourceRoot":"","sources":["../../src/tools/scrape.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAOvF,UAAU,WAAW;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnG;AAWD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAuHpE"}
1
+ {"version":3,"file":"scrape.d.ts","sourceRoot":"","sources":["../../src/tools/scrape.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAQvF,UAAU,WAAW;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnG;AA8BD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAoKpE"}